dsh-claude-style 0.11.0 → 0.12.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/LICENSE +11 -8
  3. package/README.en.md +44 -57
  4. package/README.md +47 -64
  5. package/docs/FEATURES.en.md +37 -0
  6. package/docs/FEATURES.md +37 -0
  7. package/docs/SETTINGS.en.md +37 -0
  8. package/docs/SETTINGS.md +37 -0
  9. package/docs/STYLE.md +125 -66
  10. package/docs/decisions/D10-settings-transport.md +3 -2
  11. package/docs/decisions/D11-private-routes.md +3 -3
  12. package/docs/decisions/D12-fail-fast.md +4 -4
  13. package/docs/decisions/D14-account-surface.md +3 -2
  14. package/docs/decisions/D15-hdsl-contract.md +2 -1
  15. package/docs/decisions/D16-popover-baseline.md +3 -2
  16. package/docs/decisions/D17-permission-presets.md +1 -0
  17. package/docs/decisions/D19-host-contracts.md +4 -3
  18. package/docs/decisions/D20-sliding-pill.md +1 -0
  19. package/docs/decisions/D21-archived-list.md +1 -0
  20. package/docs/decisions/D22-search-panel.md +2 -1
  21. package/docs/decisions/D23-turn-status.md +1 -0
  22. package/docs/decisions/D24-mascot.md +8 -10
  23. package/docs/decisions/D25-ban-screen-titlebar.md +2 -1
  24. package/docs/decisions/D26-motion-preference.md +2 -1
  25. package/docs/decisions/D27-context-stats.md +3 -2
  26. package/docs/decisions/D28-desktop-band.md +2 -1
  27. package/docs/decisions/D29-feature-switches.md +3 -3
  28. package/docs/decisions/D3-host-selectors.md +3 -2
  29. package/docs/decisions/D30-palette-and-typeface.md +3 -3
  30. package/docs/decisions/D31-windows-titlebar.md +1 -0
  31. package/docs/decisions/D32-chat-interactions.md +5 -4
  32. package/docs/decisions/D33-stylesheet-ownership.md +4 -3
  33. package/docs/decisions/D34-turn-navigator.md +2 -1
  34. package/docs/decisions/D35-selection-scope.md +1 -0
  35. package/docs/decisions/D36-modules-and-bundling.md +16 -15
  36. package/docs/decisions/D38-assets.md +12 -12
  37. package/docs/decisions/D39-on-demand-loading.md +3 -2
  38. package/docs/decisions/D4-composer-gate.md +3 -3
  39. package/docs/decisions/D40-observation-bus.md +13 -11
  40. package/docs/decisions/D41-scroll-owner.md +25 -9
  41. package/docs/decisions/D42-feature-manifest.md +12 -8
  42. package/docs/decisions/D43-overlay-and-upstream.md +12 -15
  43. package/docs/decisions/D44-contract-module.md +14 -3
  44. package/docs/decisions/D45-testing.md +14 -12
  45. package/docs/decisions/D46-monorepo.md +11 -14
  46. package/docs/decisions/D47-build-output.md +14 -7
  47. package/docs/decisions/D48-documentation.md +9 -8
  48. package/docs/decisions/D49-visual-yield.md +30 -0
  49. package/docs/decisions/D5-model-copy.md +2 -2
  50. package/docs/decisions/D50-brand.md +24 -0
  51. package/docs/decisions/D51-css-toolchain.md +32 -0
  52. package/docs/decisions/D52-header-band.md +31 -0
  53. package/docs/decisions/D53-usage-merge.md +32 -0
  54. package/docs/decisions/D7-one-package.md +1 -0
  55. package/docs/decisions/D9-style-performance.md +3 -3
  56. package/docs/decisions/README.md +21 -15
  57. package/lib/assets/07ba49c55318.svg.br +0 -0
  58. package/lib/assets/192fda8da55a.svg.br +0 -0
  59. package/lib/assets/22360387d0e1.svg.br +0 -0
  60. package/lib/assets/2d4bd629514d.svg.br +0 -0
  61. package/lib/assets/3b6d7b199795.svg.br +0 -0
  62. package/lib/assets/5ff45ccd6396.svg.br +0 -0
  63. package/lib/assets/62647b81453f.svg.br +0 -0
  64. package/lib/assets/6cda22c8c355.svg.br +0 -0
  65. package/lib/assets/7f10aaf08b36.svg.br +0 -0
  66. package/lib/assets/84bc02d65566.svg.br +0 -0
  67. package/lib/assets/917b19426a88.svg.br +0 -0
  68. package/lib/assets/ae2250afa4d4.svg.br +0 -0
  69. package/lib/assets/aee0b9809ae6.svg.br +0 -0
  70. package/lib/assets/b5c88fffcd08.svg.br +0 -0
  71. package/lib/assets/bd48fda92d54.svg.br +0 -0
  72. package/lib/assets/c94f98071b0f.svg.br +0 -0
  73. package/lib/assets/d0b76604f76f.svg.br +0 -0
  74. package/lib/assets/e4c4d54e666e.svg.br +0 -0
  75. package/lib/assets/manifest.json +95 -0
  76. package/lib/client.js +7757 -28459
  77. package/lib/client.js.map +7 -0
  78. package/lib/host/harness-home.js +11 -0
  79. package/lib/host/hdsl.js +33 -0
  80. package/lib/host/index.js +17 -0
  81. package/lib/host/package-root.js +25 -0
  82. package/lib/host/routes.js +374 -0
  83. package/lib/host/search.js +113 -0
  84. package/lib/host/settings.js +72 -0
  85. package/lib/host/usage-cache.js +95 -0
  86. package/lib/host/usage-fold.js +155 -0
  87. package/lib/host/usage-ledger.js +71 -0
  88. package/lib/host/usage-summary.js +128 -0
  89. package/lib/host/usage.js +107 -0
  90. package/lib/model-descriptions.json +57 -61
  91. package/package.json +35 -13
  92. package/docs/decisions/D37-css-toolchain.md +0 -27
  93. package/host/harness-home.js +0 -21
  94. package/host/hdsl.js +0 -69
  95. package/host/index.js +0 -62
  96. package/host/routes.js +0 -540
  97. package/host/search.js +0 -167
  98. package/host/settings.js +0 -138
  99. package/host/usage.js +0 -630
  100. package/lib/deepy/building.png +0 -0
  101. package/lib/deepy/compacting.png +0 -0
  102. package/lib/deepy/conducting.png +0 -0
  103. package/lib/deepy/drag.png +0 -0
  104. package/lib/deepy/error.png +0 -0
  105. package/lib/deepy/happy.png +0 -0
  106. package/lib/deepy/idle-look.png +0 -0
  107. package/lib/deepy/idle-spout.png +0 -0
  108. package/lib/deepy/idle.png +0 -0
  109. package/lib/deepy/music.png +0 -0
  110. package/lib/deepy/notification.png +0 -0
  111. package/lib/deepy/poke-left.png +0 -0
  112. package/lib/deepy/poke-right.png +0 -0
  113. package/lib/deepy/sleeping.png +0 -0
  114. package/lib/deepy/thinking.png +0 -0
  115. package/lib/deepy/tickle.png +0 -0
  116. package/lib/deepy/typing.png +0 -0
  117. package/lib/deepy/waking.png +0 -0
  118. /package/{fonts → lib/fonts}/AUTHORS.txt +0 -0
  119. /package/{fonts → lib/fonts}/InterVariable.woff2 +0 -0
  120. /package/{fonts → lib/fonts}/JetBrainsMonoItalicVariable.ttf +0 -0
  121. /package/{fonts → lib/fonts}/JetBrainsMonoVariable.ttf +0 -0
  122. /package/{fonts → lib/fonts}/NotoSerifVariable.woff2 +0 -0
  123. /package/{fonts → lib/fonts}/OFL-Inter.txt +0 -0
  124. /package/{fonts → lib/fonts}/OFL-NotoSerif.txt +0 -0
  125. /package/{fonts → lib/fonts}/OFL.txt +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,100 @@
2
2
 
3
3
  All notable changes to `dsh-claude-style` are documented here, newest first.
4
4
 
5
+ ## [Unreleased]
6
+
7
+ ## [0.12.0] - 2026-10-07
8
+
9
+ [中文](#cn-0.12.0) | [English](#en-0.12.0)
10
+
11
+ <h3 id="cn-0.12.0">新增功能</h3>
12
+
13
+ - 桌面端把会话标题与标题行里的控件抬进窗口顶端的标题栏:标题靠左、控件靠右排在窗口按钮之前,标题行剩下的内容左移并上提到标题下面;放不下的一侧留在原来的行里。
14
+
15
+ ### 体验优化
16
+
17
+ - **插件主文件缩小一半**:浏览器每次启动都要读取并解析的插件主文件此前是 1.6 MB(1,619,502 字节),现在压缩后是 0.8 MB(816,520 字节)。
18
+ - 右侧栏停靠的面板改成一枚悬浮卡片:四周各留 8px、16px 圆角、1px 描边与宿主面板自己的投影,列后面的画布从缝隙里透出来;分栏后每一栏的面板各有一枚卡片,拖出来的浮动面板保持宿主自己的窗口样式。
19
+ - **小鲸鱼的帧图改为矢量取用**:Deepy 的 18 张帧图此前由浏览器在某个动作第一次出现时下载 PNG、在画布上重建成矢量、再存进 Cache API;现在构建期就把它们转成矢量,按内容哈希长期缓存。第一次播放不再有重建的停顿,观感与之前一致;随包携带的帧图从 426 KB 变为 658 KB(brotli 后)。
20
+ - **浏览器里的侧栏品牌行**:非桌面外壳(浏览器页面)下侧栏品牌行是这一列的第一行,列顶部只有 6px 内边距,logo 贴着窗口上沿;品牌左侧也比「新会话」的加号圆片靠左 8px。现在浏览器页面给这一行加 8px 顶部边距,品牌带上这一行自己的 8px 左内边距,鲸鱼/星芒的左缘与加号圆片的左缘对齐。桌面外壳(Windows 标题栏、macOS)与折叠后的窄栏不变。
21
+ - **进行中的状态行不再随内容上下跳动**:宿主把「深度求索中」这一行画成聊天流的最后一行,答案流式追加时它跟着内容底部一起被推下去、跟随的滑动再把它拉回来,盯着末尾看时就是不停跳动。现在只要读者的跟随还开着,这一行就钉在输入框上方(输入框高度 + 上方的渐隐带 + 宿主的 16px 正文内边距),也就是跟随追上时它本来停的位置:突发的追加不再带动它,往回翻看历史时它照常留在文档位置,不会浮在读者正在读的内容上。
22
+ - 分栏的右侧栏:两栏各自仍是独立的圆角卡片,中间那条分栏线不再画(拖动时的提示照旧),两栏之间的距离从 16px 收到 6px,每栏到列边的距离从 8px 收到 6px。
23
+ - 手机宽度下的输入框下沿:权限选择器收起下三角,权限与模型选择器按窄屏上限截断,上下文只留圆环不显示数字;那一行同时不再溢出卡片——模型名随行收缩、输入框下方的停靠层不再保留桌面那两份留白,圆环因此回到卡片里、也不再压在推理等级上。
24
+ - 输入框下沿的权限档位:按钮不再画下三角(任何宽度都是),档位名过长时在按钮内截断;已经打开的档位卡在布局移动时会重新贴回它的触发按钮,而不再留在原处。
25
+ - 宿主的「回到底部」按钮改到输入框上方的正中:它原先长在对话栏右缘,正好压在站在输入卡片上的吉祥物身上;按钮仍是宿主的那个,皮肤只挪位置。
26
+
27
+ ### 问题修复
28
+
29
+ - **启动之后才选的皮肤也会接手页面**:页面载入后才在皮肤中心选中别的皮肤时,本主题不让出页面,两套视觉叠在一起。现在无论页面启动时归谁,皮肤到来就让出、离开就接回,都不需要刷新。
30
+ - 右侧栏「开始」页的项目一屏放不下时,整列被上下同时裁掉,既看不到第一项也滚不到最后一项;现在这一列自己滚动,列表短时依旧居中。
31
+ - **发送时飞行的气泡从第一帧就是气泡的颜色**(#29):替身此前带两层底色——输入卡片的底色压在上面、气泡的底色在下面——随形状一起互相过渡;形状早已收成气泡,上层还没退完,读者看到的气泡先发白,在 DeepSeek 档下正是 Claude 档那条灰气泡的样子,过半秒才变蓝。现在底色画在那层始终等于形状的壳上,按下那一刻起就是目标气泡自己的颜色,没有哪一层能落在形状后面。卡片的描边与阴影照旧随形状收掉,并在形状归位的那一刻写定、撤掉各自的动画,不会在收窄完成后多留一帧。
32
+ - 成本计量插件停止写入后,用量面板把它覆盖的历史(8/24 起 26 天、11.23B Token)整份丢掉,改由会话日志现折,面板只剩日志还在的那部分(13 天、6.47B);现在两个来源按日期合并,账本认识的天仍用账本的数,只有它没覆盖的日期由折算补上,面板恢复完整历史。
33
+ - **与壁纸插件共存**:0.11.1 在启动时已有壁纸渲染(`body[data-we-wallpaper]`)的页面上整页让出,「与其他主题插件同时使用」里壁纸透过侧栏与玻璃弹层的效果随之失效。现在只为皮肤中心的皮肤(`html[data-dsh-skin]`)让路,壁纸在渲染时本主题照常工作。对外契约:不再读取 `body[data-we-wallpaper]`。
34
+ - **发送的替身不再在真实消息行缺席时淡出**:宿主的回显气泡只活约 159 毫秒,真实消息行要一秒以上才挂上,而替身按自己的时间表在 400 毫秒落地淡出,那一段里目标位置空着——读者看到刚发出的气泡淡成页面背景,随后整条又冒出来。现在降落前先确认有一条行在页面上可以交接:没有就把替身停在原地(保持可见、继续跟随目标位置),真实行一到立刻交接;宿主始终没挂上行时按 2.5 秒兜底把页面交还宿主。
35
+ - **设置页不再多出一层内边距**:皮肤自己的设置页带了 24px 横向内边距,而宿主的选项列本来就有 24px,于是整页比其余设置页(宿主自己的与别的插件的)向右缩进 24px、顶部也多 20px。现在横向不留内边距,顶部只留宿主行自己的 16px,标题与第一行文字和其余设置页在同一条竖线上。
36
+ - **吉祥物的分段控件回到右侧**:吉祥物这一行此前固定把控件排到文字下面(与品牌卡片同一套排法)。现在控件与文字同占一行、靠右对齐,只有在放不下时才落到下一行并从左边开始——判定用文字列的最小宽度(220px),控件本身不收缩。
37
+ - **欢迎语与账号区跟随登录的 DeepSeek 账号**:此前这两处只显示自定义用户名或本机系统用户名,登录账号的昵称从不出现;现在桌面端登录后显示账号昵称,自定义用户名仍然优先,账号资料读不到时才回退到 HDSL 昵称与本机系统用户名。
38
+ - 顶栏里的对话 / 轨迹标签条:标题与控件分列两侧时,标签条改取两者之间余下空当的中线(原先按窗口居中,两侧有内容后看着偏左);鼠标在对话区时标签条重新能唤起(本表自己的静置透明度带 !important,唤起规则少了它就一直压不过去,网页端同样受影响)。
39
+ - 顶栏里的会话标题不再过早截断:标题的可用宽度改为直接留出标签条自身的宽度与两侧的空隙,而不是去读标签条「按窗口居中」时的位置——标签条随后会被推到标题与控件之间的中线,那个位置本来就会被放弃,标题因此在小一半的宽度上就开始省略号。标题同时下移 2px,在标题栏里读起来才是垂直居中。
40
+ - 用对话导航跳到某一轮之后,新输出不再把位置拖回页底:跳转算读者自己选定的阅读位置,接管与滚轮相同,跟随与流式滑行在这一期间让开,读者自己回到页底时解除。
41
+
42
+ ### 其他变更
43
+
44
+ - **公开路由变化**:`GET /dsh-claude-style/deepy/<动作>.png` 不再提供,帧图改由 `GET /dsh-claude-style/assets/<内容哈希>.svg` 提供;品牌标志、厂商组合标与螃蟹帧图同样由这份构建清单决定内联进产物还是走这条路由(小鲸鱼的 18 张帧图走路由)。更新插件后需要重启宿主,早于本次构建的宿主半边没有这条路由,小鲸鱼不会出现(控制台提示一次)。
45
+ - **附带 source map**:npm 包里新增 `lib/client.js.map`,浏览器开发者工具里的报错位置与断点能对应到插件源码。
46
+ - **Anthropic 字体的投放点迁到宿主目录**:把两款 Anthropic 字体复制进插件包 `fonts/` 目录后界面仍用替代字体,那个位置已不再被读取。现在的投放点是 `$DSH_HOME/dsh-claude-style/fonts/`(没有设置 `DSH_HOME` 时是 `~/.dsh/dsh-claude-style/fonts/`):放在这里的文件优先于包内的同名文件,缺失时照旧 404 回退到系统字体与替代字体。随包分发的四款字体与它们的授权文件改由构建写入 `lib/fonts/`,仓库里的字体文件移到了 `packages/assets/src/fonts/`,两款 Anthropic 字体在其 `anthropic/` 子目录里,仍然不随 npm 包分发。
47
+
48
+ <h3 id="en-0.12.0">New Features</h3>
49
+
50
+ - On the desktop the conversation's title and the header's controls rise into the window's own caption row — the title at the left, the controls at the right before the window buttons — and what is left of the title row closes up to the left and rides up under the title. A side without room stays in the header's own row.
51
+
52
+ ### Improvements
53
+
54
+ - **The plugin's main file is half the size**: the file the browser reads and parses on every start was 1.6 MB (1,619,502 bytes); minified it is now 0.8 MB (816,520 bytes).
55
+ - A panel docked in the right sidebar is a floating card: 8px inside the column on every side, a 16px radius, a 1px hairline and the host's own panel elevation, with the column's canvas showing through the gap. Each column of a split dock gets its own card, and a panel pulled out of the sidebar keeps the host's own floating window.
56
+ - **Deepy's frames are taken as vectors**: the whale's 18 sheets used to be downloaded as PNGs the first time an animation appeared, rebuilt into a vector on a canvas and kept in the Cache API; the build now produces the vectors and they are cached for good under their content hash. The first play no longer pauses to rebuild and the whale looks the same; the sheets that ship with the package go from 426 KB to 658 KB (brotli).
57
+ - **The sidebar brand row in a browser**: without a desktop shell the brand row is the column's first row, so 6px of column padding was the whole inset and the logo sat against the window's top edge; the brand also started 8px left of the New session plus chip. A browser page now gives that row 8px of top margin and the brand the row's own 8px leading inset, so the whale or starburst's left edge lands on the chip's. The desktop shells (Windows titlebar, macOS) and the collapsed rail are unchanged.
58
+ - **The running status line no longer rides the content**: the host draws its "deep diving" row as the chat flow's last row, so every burst of a streaming answer pushes it down and the follow's glide drags it back, which reads as continuous jumping at the tail. While the reader's follow is on, the row is now pinned above the composer — the composer's height, the fade band above it and the host's 16px transcript padding — which is where it already comes to rest once the glide has caught up: a burst no longer moves it, and scrolled back through history it keeps its document place instead of floating over what the reader went back to read.
59
+ - In a split right sidebar each pane stays its own rounded card: the line the dock draws between them is gone (the drag highlight stays), the gap between the two comes in from 16px to 6px, and each pane now sits 6px from the column's edge instead of 8px.
60
+ - The composer's bottom line at a phone's width: the permission control drops its chevron, the permission and model controls truncate at narrow-screen caps, and the context meter keeps the ring without its number. The row no longer runs past the card either — the model name shrinks with it and the dock line under the card gives up the two desktop-sized reserves — so the ring lands inside the card instead of under the reasoning level.
61
+ - The permission tier control on the composer's bottom line drops its chevron at every width, not just on a phone, and a long tier name truncates inside the button. An open tier card is also placed again when the layout under it moves, instead of hanging where its trigger used to be.
62
+ - The host's back-to-end button now sits centred above the composer. Its shipped place is the conversation column's right edge, which is where the mascot stands on the composer card; the button stays the host's own and only its placement is the skin's.
63
+
64
+ ### Bug Fixes
65
+
66
+ - **A skin picked after the page loaded takes the page too**: picking another skin in the Skin Center once the page had loaded left this theme on the page, two looks painted over each other. Now the theme gives the page up when a skin arrives and takes it back when the skin leaves, whichever way the page booted, without a reload.
67
+ - The right sidebar's start page clipped its entries at both ends once the list outgrew the pane, hiding the first rows with no way to scroll; the column scrolls now, and still centers the list while it fits.
68
+ - **The flying bubble is the bubble's colour from the first frame** (#29): the stand-in carried two fills — the composer card's over the bubble's — cross-fading as the shape narrowed, and the shape was already a bubble while the upper fill was still there, so the reader saw a pale bubble (in the DeepSeek palette, the colour the grey bubble has under Claude) that only turned blue half a second later. The fill is now painted on the one layer that is the shape at every step, so it is the destination bubble's own colour from the moment of the press and no fill can fall behind the shape. The card's hairline and shadow still leave with the shape, written and cancelled on the frame the shape settles rather than lingering a frame past it.
69
+ - Once the cost-meter plugin stopped writing, the usage panel discarded the whole history the ledger covered (11.23B tokens over 26 days from 8/24) and fell back to folding the session logs, which left it with only the part the logs still held (6.47B over 13 days); the two accounts now merge by date, the ledger keeps the days it knows and the fold fills only the dates past its newest, so the panel shows the whole history again.
70
+ - **Sharing the page with a wallpaper plugin**: 0.11.1 gave the whole page up when a wallpaper was already rendering at boot (`body[data-we-wallpaper]`), which lost the wallpaper showing through the sidebar and the glass popovers described under Alongside other theme plugins. Now only a Skin Center skin (`html[data-dsh-skin]`) makes the theme yield; while a wallpaper renders the theme keeps working. External contract: `body[data-we-wallpaper]` is no longer read.
71
+ - **The stand-in no longer fades out with no message row to land on**: the host's echo bubble lives about 159 ms while the real row takes over a second to mount, and the stand-in faded out on its own 400 ms schedule — with nothing at the destination, the reader watched the bubble they had just sent fade into the page and then the whole message pop back. The hand-over now waits until there is a row on the page to take the message: the stand-in holds where it is (visible, still following the destination) and hands over the moment the row mounts, with a 2.5 s backstop that gives the page back to the host if no row ever comes.
72
+ - **The settings page no longer adds an inset of its own**: the skin's page carried 24px of side padding while the host's options column already has 24px, which set the whole page — and its top, by another 20px — 24px inside the host's own pages and other plugins'. The page now keeps no side padding and only the host row's own 16px on top, so its heading and first row line up with every other page's.
73
+ - **The mascot's segmented control is back on the right**: the mascot row used to stack its control under the text, the layout the brand cards use. The control now shares the row and sits at its right edge, and drops to a line of its own starting at the left only when it no longer fits — decided by the text column's minimum width (220px), since the control itself never shrinks.
74
+ - **The welcome line and the account area follow the signed-in DeepSeek account**: both used to show the custom username or the local system user, never the signed-in account's nickname; on the desktop they now show the account nickname, a custom username still wins, and the HDSL name and the local system user remain the fallbacks for a profile that cannot be read.
75
+ - The Chat / Trajectory strip in the caption row: with the title and the controls standing on either side, the strip now takes the middle of the room left between them (it was centred on the window, which reads off-centre once both sides carry something), and hovering the conversation brings it back — the sheet's own resting opacity is stated with !important, so the reveal rule needed it too, on the web as much as on the desktop.
76
+ - The session title in the caption row no longer truncates early: its room is now the space up to the controls with the tab strip's own width and the air on both sides reserved, rather than the strip's window-centred position — the strip is then pushed to the middle between the title and the controls, so that position was one it was about to leave and the title began ellipsizing at half the width it had. The title also sits 2px lower, which is what reads as vertically centred in the caption row.
77
+ - After a jump to a turn from the conversation navigator, new output no longer drags the position back to the end: the jump counts as the reader choosing where to read, so it holds the conversation the way his own wheel does — the follow and the stream glide stand down until he comes back to the end himself.
78
+
79
+ ### Chores
80
+
81
+ - **Public route change**: `GET /dsh-claude-style/deepy/<animation>.png` is gone; the frames are served by `GET /dsh-claude-style/assets/<content hash>.svg`, and the brand marks, the vendor lockups and the crab's sheets follow the same build manifest, which decides per file between an inline form and that route (the whale's 18 sheets take the route). Restart the host after updating: a host half older than this build has no such route and the whale will not appear (one console message).
82
+ - **Source map included**: the npm package now carries `lib/client.js.map`, so error locations and breakpoints in the browser's developer tools map back to the plugin's sources.
83
+ - **The Anthropic fonts are dropped into the harness home now**: copying the two Anthropic faces into the plugin package's `fonts/` directory left the look-alike faces in place, because that location is no longer read. The drop point is `$DSH_HOME/dsh-claude-style/fonts/` (`~/.dsh/dsh-claude-style/fonts/` when `DSH_HOME` is unset): a file there wins over a bundled face of the same name, and a missing one still answers 404 and falls back to the system and the look-alike faces. The four faces the package ships, with their licences, are written to `lib/fonts/` by the build, and the repository's font files moved to `packages/assets/src/fonts/`, the two Anthropic ones under its `anthropic/` directory and still outside the npm package.
84
+
85
+ ## [0.11.1] - 2026-10-06
86
+
87
+ [中文](#cn-0.11.1) | [English](#en-0.11.1)
88
+
89
+ <h3 id="cn-0.11.1">新增功能</h3>
90
+
91
+ - **与皮肤中心交接**:DSH 皮肤中心把本主题列为可选皮肤。选中它即把整页交给本插件,换选其他皮肤、官方默认或壁纸在跑时页面自动交还,无需刷新。判定读皮肤中心注入服务端 HTML 的 `html[data-dsh-skin]` 与壁纸插件的 `body[data-we-wallpaper]`,两者任一存在即让路:让路期间不挂样式表、不安装功能、不占用任何文档属性,只保留设置页与偏好。构建在 `body` 上盖 `data-dsh-claude-style-handoff` 标记自己支持让路。
92
+
93
+ <h3 id="en-0.11.1">New Features</h3>
94
+
95
+ - **Skin center handoff**: the DSH Skin Center offers this theme as a selectable skin. Selecting it hands the whole page to this plugin; selecting another skin, the official default, or a running wallpaper takes the page back without a reload. The verdict reads the `html[data-dsh-skin]` attribute the Skin Center injects into the served document and the wallpaper plugin's `body[data-we-wallpaper]`; either one means yielding, and while yielded the theme mounts no stylesheet, installs no feature and claims no document attribute, keeping only its settings page and preferences. A build stamps `data-dsh-claude-style-handoff` on `body` to say it can do this.
96
+
97
+ **Full Changelog**: [v0.11.0...v0.11.1](https://github.com/Nwflower/dsh-claude-style/compare/v0.11.0...v0.11.1)
98
+
5
99
  ## [0.11.0] - 2026-10-06
6
100
 
7
101
  [中文](#cn-0.11.0) | [English](#en-0.11.0)
package/LICENSE CHANGED
@@ -24,25 +24,28 @@ SOFTWARE.
24
24
 
25
25
  Font files notice:
26
26
 
27
- - `fonts/AnthropicSansWebText.ttf` and `fonts/AnthropicSerifWebText.ttf` are
27
+ - `packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf` and
28
+ `packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf` are
28
29
  proprietary typefaces of Anthropic, extracted from Anthropic's web products.
29
30
  They are included in this repository for personal use only and are **not**
30
31
  covered by the MIT license above; all rights remain with Anthropic. The npm
31
32
  package does not ship these files.
32
- Provider icon notice: the files under `src/assets/icons/providers/` (and their
33
+ Provider icon notice: the files under `packages/assets/src/icons/providers/` (and their
33
34
  `lib/icons/providers/` build copy) are vendored from farion1231/cc-switch
34
35
  (MIT License, Copyright (c) 2025 Jason Young). They are redistributed under
35
36
  the MIT License; brand names and logos remain trademarks of their respective
36
37
  owners.
37
38
 
38
- - `fonts/JetBrainsMonoVariable.ttf` and `fonts/JetBrainsMonoItalicVariable.ttf`
39
- are JetBrains Mono, distributed under the SIL Open Font License
40
- (`fonts/OFL.txt`). They may be redistributed with this plugin.
39
+ - `packages/assets/src/fonts/JetBrainsMonoVariable.ttf` and
40
+ `packages/assets/src/fonts/JetBrainsMonoItalicVariable.ttf` are JetBrains Mono,
41
+ distributed under the SIL Open Font License
42
+ (`packages/assets/src/fonts/OFL.txt`; the package carries them under
43
+ `lib/fonts/`). They may be redistributed with this plugin.
41
44
 
42
45
  Crab artwork notice: the pixel crab (Clawd) is a character of Anthropic, and
43
- all rights in it remain with Anthropic. `src/assets/mascot/crab-laptop-body.png`
44
- and `src/assets/mascot/crab-laptop-ink.png` are frames of Claude Code's own
45
- animation; the sheets under `src/assets/mascot/crab/` are drawn by this project
46
+ all rights in it remain with Anthropic. `packages/assets/src/mascot/crab-laptop-body.png`
47
+ and `packages/assets/src/mascot/crab-laptop-ink.png` are frames of Claude Code's own
48
+ animation; the sheets under `packages/assets/src/mascot/crab/` are drawn by this project
46
49
  after that character (by `scripts/draw-crab.py`, which carries the drawings).
47
50
  These files, and their copies inlined into `lib/client.js`, are **not** covered
48
51
  by the MIT license above. This plugin is an unofficial fan work, not affiliated
package/README.en.md CHANGED
@@ -24,12 +24,12 @@ The settings page's Brand mark row switches between the Claude and DeepSeek pale
24
24
 
25
25
  <table>
26
26
  <tr>
27
- <td align="center" width="50%"><img src="./docs/claude-home-light.png" alt="Claude brand, Studio home — light" /></td>
28
- <td align="center" width="50%"><img src="./docs/claude-home-dark.png" alt="Claude brand, Studio home — dark" /></td>
27
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-home-light.png" alt="Claude brand, Studio home — light" /></td>
28
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-home-dark.png" alt="Claude brand, Studio home — dark" /></td>
29
29
  </tr>
30
30
  <tr>
31
- <td align="center" width="50%"><img src="./docs/claude-conversation-light.png" alt="Claude brand, Markdown conversation — light" /></td>
32
- <td align="center" width="50%"><img src="./docs/claude-conversation-dark.png" alt="Claude brand, Markdown conversation — dark" /></td>
31
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-conversation-light.png" alt="Claude brand, Markdown conversation — light" /></td>
32
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-conversation-dark.png" alt="Claude brand, Markdown conversation — dark" /></td>
33
33
  </tr>
34
34
  </table>
35
35
 
@@ -39,12 +39,12 @@ The settings page's Brand mark row switches between the Claude and DeepSeek pale
39
39
 
40
40
  <table>
41
41
  <tr>
42
- <td align="center" width="50%"><img src="./docs/deepseek-home-light.png" alt="DeepSeek brand, Studio home — light" /></td>
43
- <td align="center" width="50%"><img src="./docs/deepseek-home-dark.png" alt="DeepSeek brand, Studio home — dark" /></td>
42
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-home-light.png" alt="DeepSeek brand, Studio home — light" /></td>
43
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-home-dark.png" alt="DeepSeek brand, Studio home — dark" /></td>
44
44
  </tr>
45
45
  <tr>
46
- <td align="center" width="50%"><img src="./docs/deepseek-conversation-light.png" alt="DeepSeek brand, Markdown conversation — light" /></td>
47
- <td align="center" width="50%"><img src="./docs/deepseek-conversation-dark.png" alt="DeepSeek brand, Markdown conversation — dark" /></td>
46
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-conversation-light.png" alt="DeepSeek brand, Markdown conversation — light" /></td>
47
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-conversation-dark.png" alt="DeepSeek brand, Markdown conversation — dark" /></td>
48
48
  </tr>
49
49
  </table>
50
50
 
@@ -52,66 +52,36 @@ The settings page's Brand mark row switches between the Claude and DeepSeek pale
52
52
  >
53
53
  > <table>
54
54
  > <tr>
55
- > <td align="center" width="25%"><img src="./showcase/gifs/idle.gif" width="120" alt="Idle" /><br />Idle</td>
56
- > <td align="center" width="25%"><img src="./showcase/gifs/thinking.gif" width="120" alt="Thinking" /><br />Thinking</td>
57
- > <td align="center" width="25%"><img src="./showcase/gifs/typing.gif" width="120" alt="Answering and calling tools" /><br />Answering and calling tools</td>
58
- > <td align="center" width="25%"><img src="./showcase/gifs/conducting.gif" width="120" alt="Conducting subagents" /><br />Conducting subagents</td>
55
+ > <td align="center" width="25%"><img src="./docs/gifs/idle.gif" width="120" alt="Idle" /><br />Idle</td>
56
+ > <td align="center" width="25%"><img src="./docs/gifs/thinking.gif" width="120" alt="Thinking" /><br />Thinking</td>
57
+ > <td align="center" width="25%"><img src="./docs/gifs/typing.gif" width="120" alt="Answering and calling tools" /><br />Answering and calling tools</td>
58
+ > <td align="center" width="25%"><img src="./docs/gifs/conducting.gif" width="120" alt="Conducting subagents" /><br />Conducting subagents</td>
59
59
  > </tr>
60
60
  > <tr>
61
- > <td align="center" width="25%"><img src="./showcase/gifs/notification.gif" width="120" alt="Waiting on you" /><br />Waiting on you</td>
62
- > <td align="center" width="25%"><img src="./showcase/gifs/error.gif" width="120" alt="Failed" /><br />Failed</td>
63
- > <td align="center" width="25%"><img src="./showcase/gifs/happy.gif" width="120" alt="Finished" /><br />Finished</td>
64
- > <td align="center" width="25%"><img src="./showcase/gifs/sleeping.gif" width="120" alt="Asleep" /><br />Asleep</td>
61
+ > <td align="center" width="25%"><img src="./docs/gifs/notification.gif" width="120" alt="Waiting on you" /><br />Waiting on you</td>
62
+ > <td align="center" width="25%"><img src="./docs/gifs/error.gif" width="120" alt="Failed" /><br />Failed</td>
63
+ > <td align="center" width="25%"><img src="./docs/gifs/happy.gif" width="120" alt="Finished" /><br />Finished</td>
64
+ > <td align="center" width="25%"><img src="./docs/gifs/sleeping.gif" width="120" alt="Asleep" /><br />Asleep</td>
65
65
  > </tr>
66
66
  > </table>
67
67
 
68
68
  > The workspaces, sessions, usage figures and nickname in the screenshots are sample data.
69
69
 
70
- ## Settings
70
+ ## Features and settings
71
71
 
72
- The settings page appears both in the settings dialog (the "Claude Style" tab) and on the plugin page, in five tabs:
73
-
74
- | Tab | Settings |
75
- |---|---|
76
- | General | Username, Animation, Open popovers on hover, Account-hold easter egg language |
77
- | Appearance | Brand mark, Colours, Typefaces, Mascot, Where it appears |
78
- | Composer | Composer restyle, Home layout, Redraw the model picker (with Quick providers under it), Redraw the permission control |
79
- | Sidebar | Collapse the sidebar settings area, Sidebar search, In progress / Archived view |
80
- | Conversation | Turn status line, Conversation navigator, Chat-area animations, Composer caret motion, Chat / Trajectory tabs |
81
-
82
- Every feature that takes over part of the host's interface has its own switch; turning it off brings the host's original back at once, without a reload. The conversation area's animations — the follow, the automatic folding with its rolling door, the text fade, the file change rows and the send flight — share one Chat-area animations switch; the caret keeps its own three-way choice.
83
-
84
- **Alongside other theme plugins**: with Colours and Typefaces set to Follow the host, the skin no longer rewrites the host's colours and fonts and keeps only its layout and controls; the colours are left to DSH itself, or to another theme plugin enabled at the same time. With [dsh-wallpaper-engine](https://github.com/elysia395/dsh-wallpaper-engine), for example, the wallpaper shows through the sidebar and the conversation, and the skin's own popovers take that plugin's glass, translucent and blurring the picture behind them. **Alongside [dsh-chat-ux](https://github.com/alm-allen/dsh-chat-ux)**: that plugin implements the same chat-area interactions (the rolling door, automatic folding, the token fade, file change rows, the send flight, the drawn caret), and two copies of them intercept each other's clicks and press the same controls. So this skin stands down when it sees that plugin: the Chat-area animations and Composer caret motion rows on the settings page's Conversation tab have their controls disabled while each still shows the value you set, with a line underneath in the accent colour reading "Managed by dsh-chat-ux". Your settings are not rewritten, and they take effect as they are once dsh-chat-ux is removed.
85
-
86
- **Chat-area follow**: at the structural moments — a thinking row folding, a tool call row arriving — a reader sitting at the bottom is handed back to the host's own follow, instead of being left tens of pixels short by the burst of content; a process group capped in the Standard and Compact tiers (thinking and tool output kept in one scrolling body) is caught up the same way. Catching up runs on a curve: a trickle of characters settles softly and a burst glides at one steady speed before landing. While content streams, the main scroller's own follow is walked along that curve too rather than written to the end in a single frame — with a fast stream the newest lines trail just below the fold and slide into place once it stops. A message you send does not go through it: the host's scroll to bring it into view lands at once. Once the reader scrolls away from the bottom himself, the plugin stays out of it until he returns.
87
-
88
- **Automatic folding**: a thinking row opens while the model reasons and folds back when it stops; a running process group opens and folds back once that piece of work ends. A row or group the reader pressed himself keeps what he chose for that phase.
89
-
90
- **Send flight**: on submission the composer card lifts as it is and narrows into the bubble as it travels, its words re-flowing into the shape, landing on the message row: the real bubble shows underneath and the flying copy fades out, so the words sharpen into place.
91
-
92
- **File change rows**: a write or edit dispatched from inside a run_code program carries the `+n -m` tail and an expandable diff card, and its path opens the file; a failed or interrupted row keeps its verdict.
93
-
94
- **New text fades in**: characters arriving in a streaming answer start faint and settle over about 0.12 s, staggered slightly by arrival order; a block arriving whole, a burst of thousands of characters and text that just reflowed from a fold stay solid.
95
-
96
- **A rolling door for folds**: opening or closing a row (a tool card, a thinking row, a command card) or a process group moves the height frame by frame, really pushing the content below away or pulling it back. The door only rolls the stretch the reader can see, so any length moves at the same speed, and a body holding several cards rolls as one door. It rides the Chat-area animations switch, together with the entrance fade of an expanded body.
97
-
98
- **Composer caret motion**: the composer's text caret is drawn by the plugin and glides when it moves; a question card's answer box and a queued message's inline editor are covered as well. The Conversation tab offers Every move (the default), Explicit moves and Off.
99
-
100
- **Conversation navigator**: the column of short marks at the conversation's right edge holds one per turn and follows where you are reading. Reach it with the pointer and it opens into a list: each row carries the message that started its turn and sits exactly where that turn's mark was — the turn you are reading stays in place, and the turn under the pointer is still under it. The wheel scrolls the list and a click glides the page to the turn, loading earlier history first when it is not loaded yet; the Chat / Trajectory tabs at the top of the conversation stay up while the pointer is on the list. Alt+↑ / Alt+↓ jump to the previous or the next turn, and held or repeated they keep stepping; while the composer holds a draft the keys stay with it. The turn you land on flashes a short line over its start. With [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) installed too, Alt+↑ / Alt+↓ stay with that plugin.
101
-
102
- **Mascot**: a pixel companion stands on the composer's top edge and changes its animation with what the agent is doing (thinking, writing and calling tools, several sessions at work, subagents, waiting on you, compacting the context, finished, failed, asleep). Follow the brand shows the pixel crab under Claude and Deepy the whale under DeepSeek; either can be picked for good, or none. Where it appears keeps it to the new-conversation page, or puts it in conversations as well.
72
+ What the plugin does and what each setting changes is documented: [Features](docs/FEATURES.en.md), [Settings](docs/SETTINGS.en.md).
103
73
 
104
74
  ## Fonts
105
75
 
106
- > **Important: the Anthropic fonts are not bundled with the npm package.** They are available for download in this repository under [`fonts/`](fonts/). You can either install them on your system, or skip the install entirely — drop the two `.ttf` files into the plugin package's `fonts/` directory and the host will serve them as webfonts (the files are identical, so the result is the same). Either way, refresh or restart the web UI for the fonts to take effect.
76
+ > **Important: the Anthropic fonts are not bundled with the npm package.** They are available for download in this repository under [`packages/assets/src/fonts/anthropic/`](packages/assets/src/fonts/anthropic/). You can either install them on your system, or skip the install entirely — drop the two `.ttf` files into `$DSH_HOME/dsh-claude-style/fonts/` (`~/.dsh/dsh-claude-style/fonts/` when `DSH_HOME` is unset) and the host will serve them as webfonts (the files are identical, so the result is the same). Either way, refresh or restart the web UI for the fonts to take effect.
107
77
 
108
78
  | Font | Used for | File |
109
79
  |---|---|---|
110
- | Anthropic Sans Web Text | Interface / UI | [`fonts/AnthropicSansWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/AnthropicSansWebText.ttf) |
111
- | Anthropic Serif Web Text | Conversation body / Markdown | [`fonts/AnthropicSerifWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/AnthropicSerifWebText.ttf) |
112
- | JetBrains Mono Variable | Code / code blocks | [`fonts/JetBrainsMonoVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/JetBrainsMonoVariable.ttf), [`fonts/JetBrainsMonoItalicVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/JetBrainsMonoItalicVariable.ttf) |
113
- | Inter | Interface when Anthropic Sans is absent | [`fonts/InterVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/InterVariable.woff2) |
114
- | Noto Serif | Conversation body when Anthropic Serif is absent | [`fonts/NotoSerifVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/NotoSerifVariable.woff2) |
80
+ | Anthropic Sans Web Text | Interface / UI | [`packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf) |
81
+ | Anthropic Serif Web Text | Conversation body / Markdown | [`packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf) |
82
+ | JetBrains Mono Variable | Code / code blocks | [`packages/assets/src/fonts/JetBrainsMonoVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/JetBrainsMonoVariable.ttf), [`packages/assets/src/fonts/JetBrainsMonoItalicVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/JetBrainsMonoItalicVariable.ttf) |
83
+ | Inter | Interface when Anthropic Sans is absent | [`packages/assets/src/fonts/InterVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/InterVariable.woff2) |
84
+ | Noto Serif | Conversation body when Anthropic Serif is absent | [`packages/assets/src/fonts/NotoSerifVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/NotoSerifVariable.woff2) |
115
85
 
116
86
  JetBrains Mono, Inter and Noto Serif are licensed under the SIL Open Font License 1.1 and ship with the npm package; nothing to set up. Inter and Noto Serif nearly match the two Anthropic fonts in letter height and width, so without the Anthropic fonts they stand in and the interface and conversation text keep their layout. Both carry only the Latin characters the Anthropic fonts cover; Chinese text keeps using the system's Chinese fonts.
117
87
 
@@ -119,10 +89,27 @@ To enable the Anthropic fonts, choose one of the following:
119
89
 
120
90
  ① Install them on your system — on Windows, double-click each `.ttf` and choose "Install"; on macOS, import them with Font Book.
121
91
 
122
- ② Skip the install — copy the `.ttf` files into the plugin package's `fonts/` directory, then refresh the page.
92
+ ② Skip the install — copy the `.ttf` files into `$DSH_HOME/dsh-claude-style/fonts/`, then refresh the page.
123
93
 
124
94
  > The Anthropic Sans and Serif fonts are the property of Anthropic, licensed for personal use only, and are not covered by this project's MIT license.
125
95
 
96
+ ## Skin center handoff
97
+
98
+ This theme is also offered as a **skin** in the DSH Skin Center. Selecting it there hands the whole page to this
99
+ plugin; selecting another skin or the official default takes the page back without a reload.
100
+
101
+ - The answer holds from the first frame: the Skin Center stamps `html[data-dsh-skin]` into the served document, so a
102
+ page that boots with a skin already painting never flashes a frame of this theme first.
103
+ - While another skin paints the page this theme mounts no stylesheet, installs no feature and claims no document
104
+ attribute at all. It takes the page back when the skin leaves and gives it back when a skin returns, a skin
105
+ picked after the page loaded included.
106
+ - A wallpaper plugin is not another owner: while a wallpaper renders this theme keeps working, as described in
107
+ [Settings](docs/SETTINGS.en.md) under "Alongside other theme plugins".
108
+ - The settings page and every stored preference survive the handoff. A skin taking the screen does not uninstall
109
+ anything, and closing the Skin Center does not throw away what you configured here.
110
+ - `data-dsh-claude-style-handoff` on `body` marks a build that can do this; the Skin Center offers the row only
111
+ while it is there.
112
+
126
113
  ## Installation
127
114
 
128
115
  1. From the official plugin page, add the plugin below and it installs.
@@ -149,13 +136,13 @@ Keep only one theme enabled at a time. dsh ≥ 0.1.7 is required, and a restart
149
136
  | [Design tokens](docs/STYLE.md) | Palette, typography, shapes, source layout, and host-selector discipline (in English) |
150
137
  | [Architecture decisions](docs/decisions/README.md) | One file per decision: build and source, the host boundary, the runtime and each feature's trade-offs, and the architecture migration in progress (in Chinese) |
151
138
  | [Changelog](CHANGELOG.md) | Version history |
152
- | [Contributing](CONTRIBUTING.md) | Building from `src/`, commit conventions, and the screenshot and regression tooling (in English) |
139
+ | [Contributing](CONTRIBUTING.md) | Building from `packages/client/src/`, commit conventions, and the screenshot and regression tooling (in English) |
153
140
 
154
141
  ## Acknowledgements
155
142
 
156
143
  The conversation navigator's opening list, keyboard jumps and landing line follow SherUnlocked-4869's [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) (MIT).
157
144
 
158
- The animation frames of Deepy the pixel whale come from the Deepy whale theme pack drawn by calmly-eating-bugs ([@wp3171216237](https://github.com/wp3171216237)), and ship with the plugin by the author's permission. Many thanks to the author! GIFs of all 20 animations, contributed by the author, are in [showcase/gifs/](showcase/gifs/).
145
+ The animation frames of Deepy the pixel whale come from the Deepy whale theme pack drawn by calmly-eating-bugs ([@wp3171216237](https://github.com/wp3171216237)), and ship with the plugin by the author's permission. Many thanks to the author! GIFs of all 20 animations, contributed by the author, are in [docs/gifs/](docs/gifs/).
159
146
 
160
147
  The pixel crab (Clawd) is a character of Anthropic, and all rights in it remain with Anthropic. Its laptop animation is taken from Claude Code; the animations of its other states are drawn by this project after that character. The crab's frames are not covered by the MIT license (see [LICENSE](LICENSE)). This plugin is an unofficial fan work, not affiliated with or endorsed by Anthropic.
161
148
 
package/README.md CHANGED
@@ -24,12 +24,12 @@
24
24
 
25
25
  <table>
26
26
  <tr>
27
- <td align="center" width="50%"><img src="./docs/claude-home-light.png" alt="Claude 档工作台首页 —— 亮色" /></td>
28
- <td align="center" width="50%"><img src="./docs/claude-home-dark.png" alt="Claude 档工作台首页 —— 暗色" /></td>
27
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-home-light.png" alt="Claude 档工作台首页 —— 亮色" /></td>
28
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-home-dark.png" alt="Claude 档工作台首页 —— 暗色" /></td>
29
29
  </tr>
30
30
  <tr>
31
- <td align="center" width="50%"><img src="./docs/claude-conversation-light.png" alt="Claude 档 Markdown 对话 —— 亮色" /></td>
32
- <td align="center" width="50%"><img src="./docs/claude-conversation-dark.png" alt="Claude 档 Markdown 对话 —— 暗色" /></td>
31
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-conversation-light.png" alt="Claude 档 Markdown 对话 —— 亮色" /></td>
32
+ <td align="center" width="50%"><img src="./docs/screenshots/claude-conversation-dark.png" alt="Claude 档 Markdown 对话 —— 暗色" /></td>
33
33
  </tr>
34
34
  </table>
35
35
 
@@ -39,12 +39,12 @@
39
39
 
40
40
  <table>
41
41
  <tr>
42
- <td align="center" width="50%"><img src="./docs/deepseek-home-light.png" alt="DeepSeek 档工作台首页 —— 亮色" /></td>
43
- <td align="center" width="50%"><img src="./docs/deepseek-home-dark.png" alt="DeepSeek 档工作台首页 —— 暗色" /></td>
42
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-home-light.png" alt="DeepSeek 档工作台首页 —— 亮色" /></td>
43
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-home-dark.png" alt="DeepSeek 档工作台首页 —— 暗色" /></td>
44
44
  </tr>
45
45
  <tr>
46
- <td align="center" width="50%"><img src="./docs/deepseek-conversation-light.png" alt="DeepSeek 档 Markdown 对话 —— 亮色" /></td>
47
- <td align="center" width="50%"><img src="./docs/deepseek-conversation-dark.png" alt="DeepSeek 档 Markdown 对话 —— 暗色" /></td>
46
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-conversation-light.png" alt="DeepSeek 档 Markdown 对话 —— 亮色" /></td>
47
+ <td align="center" width="50%"><img src="./docs/screenshots/deepseek-conversation-dark.png" alt="DeepSeek 档 Markdown 对话 —— 暗色" /></td>
48
48
  </tr>
49
49
  </table>
50
50
 
@@ -52,52 +52,40 @@
52
52
  >
53
53
  > <table>
54
54
  > <tr>
55
- > <td align="center" width="25%"><img src="./showcase/gifs/idle.gif" width="120" alt="空闲" /><br />空闲</td>
56
- > <td align="center" width="25%"><img src="./showcase/gifs/thinking.gif" width="120" alt="思考" /><br />思考</td>
57
- > <td align="center" width="25%"><img src="./showcase/gifs/typing.gif" width="120" alt="写回答、调用工具" /><br />写回答、调用工具</td>
58
- > <td align="center" width="25%"><img src="./showcase/gifs/conducting.gif" width="120" alt="指挥子代理" /><br />指挥子代理</td>
55
+ > <td align="center" width="25%"><img src="./docs/gifs/idle.gif" width="120" alt="空闲" /><br />空闲</td>
56
+ > <td align="center" width="25%"><img src="./docs/gifs/thinking.gif" width="120" alt="思考" /><br />思考</td>
57
+ > <td align="center" width="25%"><img src="./docs/gifs/typing.gif" width="120" alt="写回答、调用工具" /><br />写回答、调用工具</td>
58
+ > <td align="center" width="25%"><img src="./docs/gifs/conducting.gif" width="120" alt="指挥子代理" /><br />指挥子代理</td>
59
59
  > </tr>
60
60
  > <tr>
61
- > <td align="center" width="25%"><img src="./showcase/gifs/notification.gif" width="120" alt="等你操作" /><br />等你操作</td>
62
- > <td align="center" width="25%"><img src="./showcase/gifs/error.gif" width="120" alt="失败" /><br />失败</td>
63
- > <td align="center" width="25%"><img src="./showcase/gifs/happy.gif" width="120" alt="完成" /><br />完成</td>
64
- > <td align="center" width="25%"><img src="./showcase/gifs/sleeping.gif" width="120" alt="睡着" /><br />睡着</td>
61
+ > <td align="center" width="25%"><img src="./docs/gifs/notification.gif" width="120" alt="等你操作" /><br />等你操作</td>
62
+ > <td align="center" width="25%"><img src="./docs/gifs/error.gif" width="120" alt="失败" /><br />失败</td>
63
+ > <td align="center" width="25%"><img src="./docs/gifs/happy.gif" width="120" alt="完成" /><br />完成</td>
64
+ > <td align="center" width="25%"><img src="./docs/gifs/sleeping.gif" width="120" alt="睡着" /><br />睡着</td>
65
65
  > </tr>
66
66
  > </table>
67
67
 
68
- ## 设置
69
-
70
- 设置页同时出现在设置对话框(「Claude Style」标签页)与插件页,分为五个分页:
71
-
72
- | 分页 | 设置项 |
73
- |---|---|
74
- | 通用 | 用户名、动画效果、悬停展开弹层、封号彩蛋语言 |
75
- | 外观 | 品牌标识、配色、字体、吉祥物、出现位置 |
76
- | 输入区 | 输入区重绘范围、首页版面、重绘模型选择器(及其下的快捷供应商)、重绘权限控件 |
77
- | 侧栏 | 折叠侧栏设置区、侧栏搜索、进行中 / 已归档视图 |
78
- | 对话 | 轮次状态行、对话导航、聊天区动画效果、输入框插入符动效、对话 / 轨迹标签条 |
79
-
80
- 每一项接管宿主界面的功能都有自己的开关,关闭后宿主原来的界面原样回来,不需要刷新页面。对话区的那几项动画(跟随、自动开合与卷帘门、新文字淡入、文件变更行、聊天气泡动效)合成一个「聊天区动画效果」开关,插入符动效仍是自己的三档。
81
-
82
- **与其他主题插件同时使用**:「配色」与「字体」选「跟随宿主」后,本插件不再改写宿主的颜色与字体,只保留布局和控件;颜色交给 DSH 自己,或者交给同时启用的其他主题插件。例如与 [dsh-wallpaper-engine](https://github.com/elysia395/dsh-wallpaper-engine) 一起用时,壁纸透过侧栏与对话区显示出来,插件自己的弹层随壁纸插件的玻璃效果变成半透明并模糊背后的画面。**与 [dsh-chat-ux](https://github.com/alm-allen/dsh-chat-ux) 同时使用时**:那个插件实现了同一批聊天区交互(卷帘门、自动开合、文字淡入、文件变更行、聊天气泡动效、插入符动效),两套同时生效会互相拦点击、抢同一批按钮。所以本插件在检测到它时让位:设置页「对话」页的「聊天区动画效果」与「输入框插入符动效」两行控件禁用,但仍显示你自己设的值,下面另起一行用强调色注明「该选项由 dsh-chat-ux 管理」;你的设置不会被改写,卸载 dsh-chat-ux 之后原样生效。
83
-
84
- **聊天区跟随**:思考行收起、工具调用行出现这些结构时刻,贴着底部的读者被交还给系统自己的跟随,内容成片到达时不再停在离底部几十像素的地方;「标准」与「简洁」档里封顶的过程组(思考与工具输出收在一个带滚动条的组体里)同样补到底部。补到底部走的是曲线:零散到达的字收得住尾巴,成片涌进的文字以一段稳速滑过去,再落到末尾。流式输出期间主滚动条的新内容也沿这条曲线推进,不再一帧写到底;输出很快时最新几行会短暂拖在屏幕下缘之外,流一停就滑到位。你自己发出的消息不走这条曲线:宿主把它滚进视野的那一下照旧一步到位。读者自己滚动离开底部之后,插件不再插手,直到他自己回到底部。
68
+ ## 安装
85
69
 
86
- **思考与过程自动开合**:模型还在思考时思考行开着,思考停下就收回去;运行中的过程组自动展开,这一段结束再收起。读者自己按过的行或组在当时的阶段里不再被改动。
70
+ 1. 官方插件页,添加以下插件即可快速安装
87
71
 
88
- **聊天气泡动效**:提交消息时输入卡片原样浮起、一路收成那条气泡,草稿里的字跟着形状重新排,落地正好接上真实的消息行:真实气泡在下面先显示出来,飞行的那份淡出,文字逐渐变清晰。
72
+ ```
73
+ dsh-claude-style
74
+ ```
89
75
 
90
- **文件变更行**:run_code 程序里派发出去的写入与编辑带上行尾的 `+n -m` 与可展开的改动卡片,路径可点开文件;失败与中断的行保留裁决信息。
76
+ 2. 通过终端安装
91
77
 
92
- **新文字淡入**:流式回答里新出现的字符先淡后实(约 0.12 秒),并按到达次序略作错开;整段一次到达的内容、几千字的突发与刚被折叠重排过的文字保持本色。
78
+ ```bash
79
+ dsh plugin --profile web add dsh-claude-style # npm 包(推荐)
80
+ ```
93
81
 
94
- **卷帘门过渡**:点开或收起一行(工具卡片、思考行、命令卡片)以及过程组时,高度逐帧变化,下方内容被真的推开或收回;门只走读者看得见的那一段,内容再长也是同一速度,多张卡片的展开体整扇门一起走。它与展开体的入场淡入一起挂在「聊天区动画效果」这个开关上。
82
+ 3. 通过[插件市场](https://github.com/dsh-market/dsh-market)安装
95
83
 
96
- **输入框插入符动效**:输入框里的光标由插件自己绘制,移动时滑过去;提问卡片的作答框与排队消息的行内编辑框同样覆盖。设置页的「对话」页有三档:每一格(默认)、只在移动时、关闭。
84
+ 同一时刻建议只启用一个主题。安装后推荐重启 `DeepSeek Harness`以获得完整能力。
97
85
 
98
- **对话导航**:对话区右侧那列短横线每一轮一条,跟着你读到的位置走。鼠标碰到它,它就展开成一张列表:每一行写着开启这一轮的那条消息,正好落在它那条短横线原来的位置上——你正在读的那一轮还在原处,鼠标下面还是刚才那一轮;滚轮上下翻,点一行页面滑到那一轮,还没加载的早期对话先加载再跳;指针停在列表上时,对话区顶部的对话 / 轨迹标签照常显示。Alt+↑ / Alt+↓ 跳到上一轮或下一轮,连按会一轮一轮接着走;输入框里有草稿时这两个键留给输入框。跳到的那一轮开头会闪一条短横线。同时装着 [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) 时,Alt+↑ / Alt+↓ 留给它。
86
+ ## 功能与设置
99
87
 
100
- **吉祥物**:输入框上沿站着一只像素小伙伴,随智能体的工作状态换动画(思考、写回答与调用工具、多个会话同时工作、子代理、等你操作、压缩上下文、完成、失败、睡着)。「跟随品牌」在 Claude 品牌下是像素螃蟹,在 DeepSeek 品牌下是小鲸鱼 Deepy,也可以固定选一个或者关闭;「出现位置」决定它只在新会话页出现,还是新会话页和对话页都出现。
88
+ 本插件的功能与设置说明都在文档里:[功能一览](docs/FEATURES.md)、[设置说明](docs/SETTINGS.md)。
101
89
 
102
90
  ## 字体
103
91
 
@@ -105,15 +93,15 @@
105
93
  >
106
94
  > Anthropic Sans/Serif 字体版权归 Anthropic 所有,仅供个人使用,不适用 MIT 许可。
107
95
  >
108
- > **重要:Anthropic 字体不随 npm 包分发,仅在仓库 [`fonts/`](fonts/) 供下载**。
96
+ > **重要:Anthropic 字体不随 npm 包分发,仅在仓库 [`packages/assets/src/fonts/anthropic/`](packages/assets/src/fonts/anthropic/) 供下载**。
109
97
 
110
98
  | 字体 | 用途 | 文件 |
111
99
  |---|---|---|
112
- | Anthropic Sans Web Text | 界面 / UI | [`fonts/AnthropicSansWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/AnthropicSansWebText.ttf) |
113
- | Anthropic Serif Web Text | 对话正文 / Markdown | [`fonts/AnthropicSerifWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/AnthropicSerifWebText.ttf) |
114
- | JetBrains Mono Variable | 代码 / 代码块 | [`fonts/JetBrainsMonoVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/JetBrainsMonoVariable.ttf)、[`fonts/JetBrainsMonoItalicVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/JetBrainsMonoItalicVariable.ttf) |
115
- | Inter | 没有 Anthropic Sans 时的界面字体 | [`fonts/InterVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/InterVariable.woff2) |
116
- | Noto Serif | 没有 Anthropic Serif 时的正文字体 | [`fonts/NotoSerifVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/fonts/NotoSerifVariable.woff2) |
100
+ | Anthropic Sans Web Text | 界面 / UI | [`packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSansWebText.ttf) |
101
+ | Anthropic Serif Web Text | 对话正文 / Markdown | [`packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/anthropic/AnthropicSerifWebText.ttf) |
102
+ | JetBrains Mono Variable | 代码 / 代码块 | [`packages/assets/src/fonts/JetBrainsMonoVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/JetBrainsMonoVariable.ttf)、[`packages/assets/src/fonts/JetBrainsMonoItalicVariable.ttf`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/JetBrainsMonoItalicVariable.ttf) |
103
+ | Inter | 没有 Anthropic Sans 时的界面字体 | [`packages/assets/src/fonts/InterVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/InterVariable.woff2) |
104
+ | Noto Serif | 没有 Anthropic Serif 时的正文字体 | [`packages/assets/src/fonts/NotoSerifVariable.woff2`](https://github.com/Nwflower/dsh-claude-style/raw/main/packages/assets/src/fonts/NotoSerifVariable.woff2) |
117
105
 
118
106
  JetBrains Mono、Inter 与 Noto Serif 采用 SIL Open Font License 1.1,随 npm 包分发,无需任何操作。Inter 与 Noto Serif 的字高、字宽与两款 Anthropic 字体几乎一致,没有启用 Anthropic 字体时由它们代替,界面与正文的排版不会因此变样;两者只含 Anthropic 字体覆盖的拉丁字符,中文照旧使用系统中文字体。
119
107
 
@@ -121,25 +109,20 @@ Anthropic 字体启用(二选一):
121
109
 
122
110
  ① 安装到系统——Windows 双击 `.ttf` → 「安装」,macOS 用「字体册」导入;
123
111
 
124
- ② 免安装——把 `.ttf` 复制到插件包的 `fonts/` 目录。完成后刷新页面生效。
112
+ ② 免安装——把 `.ttf` 复制到 `$DSH_HOME/dsh-claude-style/fonts/`(没有设置 `DSH_HOME` 时是 `~/.dsh/dsh-claude-style/fonts/`)。完成后刷新页面生效。
125
113
 
126
- ## 安装
127
-
128
- 1. 官方插件页,添加以下插件即可快速安装
129
-
130
- ```
131
- dsh-claude-style
132
- ```
114
+ ## 皮肤中心交接
133
115
 
134
- 2. 通过终端安装
116
+ 在 DSH 皮肤中心里,这套主题同时以**皮肤**的身份出现。选它即把整页交给本插件;换选别的皮肤或官方默认时,
117
+ 页面在不需要刷新的情况下交还回来。
135
118
 
136
- ```bash
137
- dsh plugin --profile web add dsh-claude-style # npm 包(推荐)
138
- ```
139
-
140
- 3. 通过[插件市场](https://github.com/dsh-market/dsh-market)安装
141
-
142
- 同一时刻建议只启用一个主题。安装后推荐重启 `DeepSeek Harness`以获得完整能力。
119
+ - 判定从第一帧就成立:皮肤中心把 `html[data-dsh-skin]` 注入服务端 HTML,因此带着皮肤启动的页面不会先闪过
120
+ 一帧本主题。
121
+ - 别的皮肤在画时,本主题不挂样式表、不安装任何功能、不占用任何文档属性;皮肤离开时立刻接管,皮肤回来
122
+ 时再次让出,页面启动之后才选的皮肤也一样。
123
+ - 壁纸插件不算另一个属主:壁纸在渲染时本主题照常工作,见[设置说明](docs/SETTINGS.md)里的「与其他主题插件同时使用」。
124
+ - 交接期间设置页与所有偏好都还在:别的皮肤占屏不等于卸载,关掉皮肤中心也不丢这里配过的东西。
125
+ - `body` 上的 `data-dsh-claude-style-handoff` 标记支持交接的构建;皮肤中心只在这一属性存在时才提供该选项。
143
126
 
144
127
  ## 文档
145
128
 
@@ -148,7 +131,7 @@ dsh plugin --profile web add dsh-claude-style # npm 包(推
148
131
  | [设计令牌](docs/STYLE.md) | 调色板、字体、形状,源码结构与宿主选择器纪律(英文) |
149
132
  | [架构决策](docs/decisions/README.md) | 每条决策一个文件:构建与源码、宿主边界、运行时与各个功能的取舍,以及正在进行的架构迁移 |
150
133
  | [更新日志](CHANGELOG.md) | 版本历史 |
151
- | [贡献指南](CONTRIBUTING.md) | 如何从 `src/` 构建、提交规范与截图/回归工具(英文) |
134
+ | [贡献指南](CONTRIBUTING.md) | 如何从 `packages/client/src/` 构建、提交规范与截图/回归工具(英文) |
152
135
 
153
136
  ## 鸣谢
154
137
 
@@ -0,0 +1,37 @@
1
+ # Features
2
+
3
+ > [简体中文](FEATURES.md)
4
+
5
+ What each feature does and where its switch lives; the five tabs, their rows and what each tier changes are in [Settings](SETTINGS.en.md).
6
+
7
+ <!-- features:start — written by npm run features, not by hand -->
8
+
9
+ - **Selection colour while unfocused**: Selected text takes the unfocused colours while the window is in the background and the focused ones when it comes back, as other applications do.
10
+ - **Composer**: The input card on the new-conversation page and in conversations is redrawn after Claude Code Desktop: attachments sit in one row of tiles, the context usage is a ring in the toolbar, a press anywhere on the card starts typing, and a conversation resting at the bottom moves up with the card as it grows. The Composer tab chooses the home page alone, the conversation alone, both, or neither.
11
+ - **Home layout**: Classic is the centred greeting over the input card. Studio moves the greeting to the top left, pins the input card to the window's bottom edge and fills the space between with a usage panel: a heat map of recent usage and the usage and cost of each model.
12
+ - **Mascot**: A pixel companion stands on the composer's top edge and changes its animation with what the agent is doing (thinking, writing and calling tools, several sessions at work, subagents, waiting on you, compacting the context, finished, failed, asleep). Follow the brand shows the pixel crab under Claude and Deepy the whale under DeepSeek; either can be picked for good, or none. Where it appears keeps it to the new-conversation page, or puts it in conversations as well.
13
+ - **Greeting and hint**: The new-conversation page greets you by name with a line that changes with the time of day, and the empty composer shows Claude's own hint.
14
+ - **Permission control**: The composer's permission menu becomes a row of segments. The presets are the host's own catalog, a plugin's preset included; the new-conversation page shows the one a new session will start in.
15
+ - **Session numbers**: The session statistics and the token usage move into the popover of the composer's context ring and follow the host's data live. It shares the permission control's switch: both take over the composer's bottom line.
16
+ - **Model picker**: The composer's model menu becomes a two-level card: the first level holds the official service and the quick providers you picked, each model with its vendor mark and a line of description; the second level holds the rest.
17
+ - **Effort**: The reasoning effort gets a trigger of its own beside the model, opening a slider. It switches with the model picker, since the host keeps the effort inside its own model menu.
18
+ - **Home page directory and preset menus**: The directory and agent-preset menus on the new-conversation page are drawn as the skin's popover cards, parked over their own buttons, one open at a time.
19
+ - **Quick providers**: The settings page picks which providers' models the model picker's first level carries; a provider gone from the catalog is marked Removed and can be unchecked.
20
+ - **Sidebar account area**: The sidebar footer's settings entry folds into the account popover, which carries the account header, other plugins' footer entries and the settings row; on the desktop the host's own account menu is used.
21
+ - **Account-hold easter egg**: The account row at the top of the account popover opens a full-page replica of Claude's account-hold page. Every control on it, and Esc, closes it, and nothing it names actually happens. Its language is chosen on the General tab.
22
+ - **One-frame theme switch**: Switching between light and dark changes borders, shadows and fills in the same frame, instead of the colours first and the borders easing in after.
23
+ - **In progress / Archived**: The sidebar's workspace section splits into In progress and Archived; Archived is one flat list whose rows can be restored or deleted.
24
+ - **Sidebar search**: A search box in the sidebar's brand row opens a palette that finds sessions (titles and content), projects, plugins, Skills and shortcuts, through the host's own dialog and navigation.
25
+ - **Turn status line**: A running, stopped or failed turn shows its status at the end of the turn's work: the elapsed time, the output tokens and what the model is doing now (or that it stopped or failed); while the turn runs the line is pinned above the composer, so content arriving below no longer drags it around.
26
+ - **Conversation navigator**: The column of short marks at the conversation's right edge holds one per turn and follows where you are reading. Reach it with the pointer and it opens into a list: each row carries the message that started its turn and sits exactly where that turn's mark was — the turn you are reading stays in place, and the turn under the pointer is still under it. The wheel scrolls the list and a click glides the page to the turn, loading earlier history first when it is not loaded yet; the Chat / Trajectory tabs at the top of the conversation stay up while the pointer is on the list. Alt+↑ / Alt+↓ jump to the previous or the next turn, and held or repeated they keep stepping; while the composer holds a draft the keys stay with it. The turn you land on flashes a short line over its start. With [dsh-plugin-msg-nav](https://github.com/SherUnlocked-4869/dsh-plugin-msg-nav) installed too, Alt+↑ / Alt+↓ stay with that plugin.
27
+ - **Chat-area follow**: At the structural moments — a thinking row folding, a tool call row arriving — a reader sitting at the bottom is handed back to the host's own follow, instead of being left tens of pixels short by the burst of content; a process group capped in the Standard and Compact tiers (thinking and tool output kept in one scrolling body) is caught up the same way. Catching up runs on a curve: a trickle of characters settles softly and a burst glides at one steady speed before landing. While content streams, the main scroller's own follow is walked along that curve too rather than written to the end in a single frame — with a fast stream the newest lines trail just below the fold and slide into place once it stops. A message you send does not go through it: the host's scroll to bring it into view lands at once. Once the reader scrolls away from the bottom himself, the plugin stays out of it until he returns.
28
+ - **Automatic folding and the rolling door**: A thinking row opens while the model reasons and folds back when it stops; a running process group opens and folds back once that piece of work ends. A row or group the reader pressed himself keeps what he chose for that phase. Opening or closing a row (a tool card, a thinking row, a command card) or a process group moves the height frame by frame, really pushing the content below away or pulling it back. The door only rolls the stretch the reader can see, so any length moves at the same speed, and a body holding several cards rolls as one door.
29
+ - **New text fades in**: Characters arriving in a streaming answer start faint and settle over about 0.12 s, staggered slightly by arrival order; a block arriving whole, a burst of thousands of characters and text that just reflowed from a fold stay solid.
30
+ - **File change rows**: A write or edit dispatched from inside a run_code program carries the `+n -m` tail and an expandable diff card, and its path opens the file; a failed or interrupted row keeps its verdict.
31
+ - **Send flight**: On submission the composer card lifts and narrows into the bubble as it travels, the flying copy carrying the bubble's colour from its first frame and its words re-flowing into the shape; it meets the message row, where the real bubble shows underneath and the flying copy fades out, so the words sharpen into place.
32
+ - **Composer caret motion**: The composer's text caret is drawn by the plugin and glides when it moves; a question card's answer box and a queued message's inline editor are covered as well. The Conversation tab offers Every move (the default), Explicit moves and Off.
33
+ - **Chat / Trajectory tabs**: The Chat / Trajectory tab strip at the top of the conversation is redrawn as a segmented control and lifted onto the title's line when it fits.
34
+ - **Header in the title bar**: On the desktop the session title and the header's controls rise into the window's own caption row: whichever side fits is placed there — the title at the left, the controls at the right — and the rest of the title row closes up to the left.
35
+ - **Settings page**: The settings page appears both in the settings dialog (the "Claude Style" tab) and on the plugin page, in five tabs: General, Appearance, Composer, Sidebar and Conversation. Every feature that takes over part of the host's interface has its own switch; turning it off brings the host's original back at once, without a reload.
36
+
37
+ <!-- features:end -->