dsh-claude-style 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -1,15 +1,39 @@
1
1
  /**
2
2
  * Claude Style — Claude Code Desktop theme for the DeepSeek Harness web GUI.
3
3
  *
4
- * GENERATED FILE — do not edit. Source lives in src/ (JS zones as fragments,
5
- * stylesheets as plain CSS); `node scripts/build.mjs` assembles this bundle.
6
- * - src/constants.js Zone 1: Constants & Tokens
7
- * - src/styles/*.css Zone 2: Stylesheets (tokens, typography, chrome,
8
- * composer, sidebar, components)
9
- * - src/context.js Zone 3: DSH Context & Helpers
10
- * - src/overrides.js Zone 4+5: UI Overrides, Scheduler & Teardown
11
- * - src/settings.js Settings Section (Brand)
12
- * - src/entry.js Zone 6: Plugin Entry & Export
4
+ * GENERATED FILE — do not edit. Source lives in src/ as feature fragments;
5
+ * `node scripts/build.mjs` assembles this bundle.
6
+ *
7
+ * JS fragments (in assembly order):
8
+ * - src/assets/*.svg Brand marks (inlined as CSS url() data URIs at build time)
9
+ * * - src/constants.js
10
+ * - src/context/host.js
11
+ * - src/context/prefs.js
12
+ * - src/context/model-copy.js
13
+ * - src/context/i18n.js
14
+ * - src/overrides/popover-utils.js
15
+ * - src/overrides/copy.js
16
+ * - src/overrides/permissions.js
17
+ * - src/overrides/model-picker.js
18
+ * - src/overrides/account-footer.js
19
+ * - src/overrides/scheduler.js
20
+ * - src/settings.js
21
+ * - src/entry.js
22
+ *
23
+ * Stylesheets (in assembly order):
24
+ * * - src/styles/tokens.css
25
+ * - src/styles/typography.css
26
+ * - src/styles/chrome.css
27
+ * - src/styles/composer/hero.css
28
+ * - src/styles/composer/card.css
29
+ * - src/styles/composer/inline.css
30
+ * - src/styles/sidebar.css
31
+ * - src/styles/components/permissions.css
32
+ * - src/styles/components/account-footer.css
33
+ * - src/styles/components/model-picker.css
34
+ * - src/styles/components/footer-takeover.css
35
+ * - src/styles/components/third-party.css
36
+ * - src/styles/components/settings.css
13
37
  */
14
38
  window.__ModuleLoader__.load({
15
39
  id: 'dsh-claude-style',
@@ -22,13 +46,40 @@ window.__ModuleLoader__.load({
22
46
  // section can be a real component without a host half.
23
47
  var React = require('react')
24
48
 
49
+
25
50
  // ============================================================================
26
- // Zone 1: 常量与配置定义 (Constants & Tokens)
51
+ // 常量与配置定义 (Constants & Tokens)
27
52
  // ============================================================================
28
53
  var STYLE_ID = 'dsh-claude-style-style'
29
54
 
30
55
  var COMPOSER_HINT = 'How can I help you today?'
31
56
 
57
+ /**
58
+ * Model picker copy.
59
+ *
60
+ * The copy itself is NOT here. It ships as `model-descriptions.json` beside
61
+ * the bundle, and the browser half fetches it at runtime (the host half
62
+ * serves it under MODEL_COPY_ROUTE), so the model table grows without a
63
+ * rebuild and no copy enters the bundle. The language comes from the shell's
64
+ * own `locale` service — one line per row, in the language the rest of the
65
+ * UI is in — never two languages stacked.
66
+ *
67
+ * The constants below are the neutral fallbacks painted before that document
68
+ * arrives, and kept if it never does. They are English because a failed
69
+ * fetch has no locale to honour.
70
+ */
71
+ var MODEL_OFFICIAL_GROUP = 'deepseek-official'
72
+ var MODEL_COPY_ROUTE = '/dsh-claude-style/model-descriptions.json'
73
+ var MODEL_COPY_FALLBACK_LOCALE = 'en'
74
+ var MODEL_FALLBACK_LABEL = 'Select model'
75
+ var MODEL_LOADING_LABEL = 'Loading models…'
76
+ var MODEL_EMPTY_LABEL = 'No models available.'
77
+ var MODEL_EFFORT_LABEL = 'Reasoning effort'
78
+ var MODEL_EFFORT_DEFAULT = 'Default'
79
+ var MODEL_MORE_LABEL = 'More models'
80
+ var MODEL_TRIGGER_LABEL = 'Select model, currently {model}'
81
+ var MODEL_NO_EFFORT_LABEL = 'This model offers no reasoning levels.'
82
+
32
83
  /** English weekday names, indexed by Date#getDay() (0 = Sunday). */
33
84
  var WEEKDAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
34
85
 
@@ -98,9 +149,6 @@ window.__ModuleLoader__.load({
98
149
  'Spinning', 'Twisting', 'Unfurling', 'Unravelling', 'Vibing', 'Whirring'
99
150
  ]
100
151
 
101
- /** Anthropic's starburst mark as an inline data URI, keeping the skin a single-file bundle with no asset request. */
102
- var ANTHROPIC_MARK = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z' fill='%23D97757'/%3E%3C/svg%3E\")"
103
-
104
152
  /** Segment label and the shipped /permission preset it selects. */
105
153
  var PERMISSION_SEGMENTS = [
106
154
  { label: 'Read', preset: 'read-only' },
@@ -138,106 +186,76 @@ window.__ModuleLoader__.load({
138
186
  var SEGMENTS_CLASS = 'dsh-claude-segments'
139
187
  var SEGMENT_CLASS = 'dsh-claude-segment'
140
188
 
189
+ /**
190
+ * Preferences, persisted in the host settings namespace `claude-style`
191
+ * (lib/index.js owns it; src/context/prefs.js reads and writes it). Each value is
192
+ * mirrored onto the document as an attribute so the stylesheet decides what
193
+ * a preference means, and the defaults here are the shipped behaviour.
194
+ */
195
+
141
196
  /** Brand marks selectable from the settings page. `claude` is the default. */
142
197
  var BRAND_CLAUDE = 'claude'
143
198
  var BRAND_ANTHROPIC = 'anthropic'
199
+ /** Leave the brand area entirely to the host: neither brand variant matches. */
200
+ var BRAND_OFF = 'off'
144
201
  var DEFAULT_BRAND = BRAND_CLAUDE
145
- /** localStorage key holding the chosen brand. */
146
- var BRAND_STORAGE_KEY = 'dsh-claude-style:brand'
147
202
  /** The document attribute the stylesheet switches on. */
148
203
  var BRAND_ATTR = 'data-dsh-claude-brand'
149
204
 
150
- /**
151
- * Claude's own brand lockup, taken from the official artwork (claude.ai via
152
- * Wikimedia Commons, public domain as a simple geometric/text logo). The mark
153
- * and the wordmark ship as two separate alpha masks so each can be sized
154
- * independently: the sidebar pairs the starburst with the wordmark, while the
155
- * new-conversation hero uses the starburst alone with the clay fill baked in.
156
- *
157
- * Two details are load-bearing:
158
- * - The source paths live in the artwork's own coordinate space and are
159
- * wrapped in a group transform, so every mask has to carry that same
160
- * `translate` or the tight viewBox crops the geometry away entirely.
161
- * - `#` and `'` stay percent-encoded inside the data URI. A literal `#`
162
- * starts a fragment and truncates the URI at that point.
163
- */
164
- var CLAUDE_TRANSFORM = "translate(-75.96,-223.53)"
165
- /** Tight viewBox of the starburst alone (148.09 x 148.18 user units). */
166
- var CLAUDE_MARK_VIEWBOX = '0 0 148.09 148.18'
167
- /** Tight viewBox of the wordmark alone, excluding the starburst. */
168
- var CLAUDE_WORD_VIEWBOX = '177.76 14.09 512.22 121.54'
169
- /** Aspect ratio of the wordmark, so callers can size it from the height. */
170
- var CLAUDE_WORD_ASPECT = 512.22 / 121.54
171
- /** Aspect ratio of the full mark+wordmark lockup. */
172
- var CLAUDE_LOCKUP_ASPECT = 689.98 / 148.18
173
-
174
- /** Starburst path, in the artwork's own (pre-transform) coordinates. */
175
- var CLAUDE_MARK_PATH = 'm 105.01,322.07 29.14,-16.35 0.49,-1.42 -0.49,-0.79 h -1.42 l -4.87,-0.3 -16.65,-0.45 -14.44,-0.6 -13.99,-0.75 -3.52,-0.75 -3.3,-4.35 0.34,-2.17 2.96,-1.99 4.24,0.37 9.37,0.64 14.06,0.97 10.2,0.6 15.11,1.57 h 2.4 l 0.34,-0.97 -0.82,-0.6 -0.64,-0.6 -14.55,-9.86 -15.75,-10.42 -8.25,-6 -4.46,-3.04 -2.25,-2.85 -0.97,-6.22 4.05,-4.46 5.44,0.37 1.39,0.37 5.51,4.24 11.77,9.11 15.37,11.32 2.25,1.87 0.9,-0.64 0.11,-0.45 -1.01,-1.69 -8.36,-15.11 -8.92,-15.37 -3.97,-6.37 -1.05,-3.82 c -0.37,-1.57 -0.64,-2.89 -0.64,-4.5 l 4.61,-6.26 2.55,-0.82 6.15,0.82 2.59,2.25 3.82,8.74 6.19,13.76 9.6,18.71 2.81,5.55 1.5,5.14 0.56,1.57 h 0.97 v -0.9 l 0.79,-10.54 1.46,-12.94 1.42,-16.65 0.49,-4.69 2.32,-5.62 4.61,-3.04 3.6,1.72 2.96,4.24 -0.41,2.74 -1.76,11.44 -3.45,17.92 -2.25,12 h 1.31 l 1.5,-1.5 6.07,-8.06 10.2,-12.75 4.5,-5.06 5.25,-5.59 3.37,-2.66 h 6.37 l 4.69,6.97 -2.1,7.2 -6.56,8.32 -5.44,7.05 -7.8,10.5 -4.87,8.4 0.45,0.67 1.16,-0.11 17.62,-3.75 9.52,-1.72 11.36,-1.95 5.14,2.4 0.56,2.44 -2.02,4.99 -12.15,3 -14.25,2.85 -21.22,5.02 -0.26,0.19 0.3,0.37 9.56,0.9 4.09,0.22 h 10.01 l 18.64,1.39 4.87,3.22 2.92,3.94 -0.49,3 -7.5,3.82 -10.12,-2.4 -23.62,-5.62 -8.1,-2.02 h -1.12 v 0.67 l 6.75,6.6 12.37,11.17 15.49,14.4 0.79,3.56 -1.99,2.81 -2.1,-0.3 -13.61,-10.24 -5.25,-4.61 -11.89,-10.01 h -0.79 v 1.05 l 2.74,4.01 14.47,21.75 0.75,6.67 -1.05,2.17 -3.75,1.31 -4.12,-0.75 -8.47,-11.89 -8.74,-13.39 -7.05,-12 -0.86,0.49 -4.16,44.81 -1.95,2.29 -4.5,1.72 -3.75,-2.85 -1.99,-4.61 1.99,-9.11 2.4,-11.89 1.95,-9.45 1.76,-11.74 1.05,-3.9 -0.07,-0.26 -0.86,0.11 -8.85,12.15 -13.46,18.19 -10.65,11.4 -2.55,1.01 -4.42,-2.29 0.41,-4.09 2.47,-3.64 14.74,-18.75 8.89,-11.62 5.74,-6.71 -0.04,-0.97 h -0.34 l -39.15,25.42 -6.97,0.9 -3,-2.81 0.37,-4.61 1.42,-1.5 11.77,-8.1 -0.04,0.04 z'
176
-
177
- /** Wordmark path, in the artwork's own (pre-transform) coordinates. */
178
- var CLAUDE_WORD_PATH = 'm 317.73,349.33 c -18.82,0 -31.69,-10.5 -37.76,-26.66 -3.17,-8.42 -4.74,-17.36 -4.61,-26.36 0,-27.11 12.15,-45.94 39,-45.94 18.04,0 29.17,7.87 35.51,26.66 h 7.72 l -1.05,-25.91 c -10.8,-6.97 -24.3,-10.5 -40.72,-10.5 -23.14,0 -42.82,10.35 -53.77,29.02 -5.66,9.86 -8.53,21.07 -8.32,32.44 0,20.74 9.79,39.11 28.16,49.31 10.06,5.37 21.34,8.04 32.74,7.72 17.92,0 32.14,-3.41 44.74,-9.37 l 3.26,-28.57 h -7.87 c -4.72,13.05 -10.35,20.89 -19.69,25.05 -4.57,2.06 -10.35,3.11 -17.32,3.11 z m 81.18,-98.96 0.75,-12.75 h -5.32 l -23.7,7.12 v 3.86 l 10.5,4.87 v 89.17 c 0,6.07 -3.11,7.42 -11.25,8.44 v 6.52 h 40.31 v -6.52 c -8.17,-1.01 -11.25,-2.36 -11.25,-8.44 V 250.4 l -0.04,-0.04 z m 160.31,108.75 h 3.11 l 27.26,-5.17 v -6.67 l -3.82,-0.3 c -6.37,-0.6 -8.02,-1.91 -8.02,-7.12 v -47.55 l 0.75,-15.26 h -4.31 l -25.76,3.71 v 6.52 l 2.51,0.45 c 6.97,1.01 9.04,2.96 9.04,7.84 v 42.37 c -6.67,5.17 -13.05,8.44 -20.62,8.44 -8.4,0 -13.61,-4.27 -13.61,-14.25 v -39.79 l 0.75,-15.26 h -4.42 l -25.8,3.71 v 6.52 l 2.66,0.45 c 6.97,1.01 9.04,2.96 9.04,7.84 v 39.11 c 0,16.57 9.37,24.45 24.3,24.45 11.4,0 20.74,-6.07 27.75,-14.51 l -0.75,14.51 -0.04,-0.04 z M 484.3,306.36 c 0,-21.19 -11.25,-29.32 -31.57,-29.32 -17.92,0 -30.94,7.42 -30.94,19.72 0,3.67 1.31,6.49 3.97,8.44 l 13.65,-1.8 c -0.6,-4.12 -0.9,-6.64 -0.9,-7.69 0,-6.97 3.71,-10.5 11.25,-10.5 11.14,0 16.76,7.84 16.76,20.44 v 4.12 l -28.12,8.44 c -9.37,2.55 -14.7,4.76 -18.26,9.94 -1.89,3.17 -2.8,6.82 -2.62,10.5 0,12 8.25,20.47 22.35,20.47 10.2,0 19.24,-4.61 27.11,-13.35 2.81,8.74 7.12,13.35 14.81,13.35 6.22,0 11.85,-2.51 16.87,-7.42 l -1.5,-5.17 c -2.17,0.6 -4.27,0.9 -6.49,0.9 -4.31,0 -6.37,-3.41 -6.37,-10.09 v -30.97 z m -36,40.76 c -7.69,0 -12.45,-4.46 -12.45,-12.3 0,-5.32 2.51,-8.44 7.87,-10.24 l 22.8,-7.24 v 21.9 c -7.27,5.51 -11.55,7.87 -18.22,7.87 z m 237.36,6.82 v -6.67 l -3.86,-0.3 c -6.37,-0.6 -7.99,-1.91 -7.99,-7.12 v -89.47 l 0.75,-12.75 h -5.36 l -23.7,7.12 v 3.86 l 10.5,4.87 v 29.32 c -5.91,-4.05 -12.98,-6.08 -20.14,-5.77 -23.55,0 -41.92,17.92 -41.92,44.74 0,22.09 13.2,37.35 34.95,37.35 11.25,0 21.04,-5.47 27.11,-13.95 l -0.75,13.95 h 3.15 l 27.26,-5.17 v 0 z m -49.35,-68.02 c 11.25,0 19.69,6.52 19.69,18.52 v 33.75 c -5.18,5.16 -12.23,8 -19.54,7.87 -16.12,0 -24.3,-12.75 -24.3,-29.77 0,-19.12 9.34,-30.37 24.15,-30.37 z M 743.3,302.8 c -2.1,-9.9 -8.17,-15.52 -16.61,-15.52 -12.6,0 -21.34,9.49 -21.34,23.1 0,20.14 10.65,33.19 27.86,33.19 11.48,-0.12 22.04,-6.33 27.71,-16.31 l 5.02,1.35 c -2.25,17.47 -18.07,30.52 -37.5,30.52 -22.8,0 -38.51,-16.87 -38.51,-40.87 0,-24 17.06,-41.21 39.86,-41.21 17.02,0 29.02,10.24 32.89,28.01 l -59.4,18.22 v -8.02 l 40.01,-12.41 v -0.04 z'
179
-
180
- /**
181
- * Build a CSS `url()` for one Claude mask.
182
- *
183
- * `encodeURIComponent` does the escaping, which is why the paths above are kept
184
- * as raw literals rather than pre-baked data URIs: every `#`, `'` and `<` gets
185
- * escaped exactly once, so no fill colour can accidentally terminate the URI.
186
- * `fill` defaults to `currentColor`, letting the mask follow the theme.
187
- *
188
- * @param viewBox - tight viewBox of the geometry being drawn.
189
- * @param paths - one or more path `d` strings to include.
190
- * @param fill - optional paint; omit for a currentColor alpha mask.
191
- * @returns a quoted CSS url() value.
192
- */
193
- function claudeMask(viewBox, paths, fill) {
194
- var body = ''
195
- for (var i = 0; i < paths.length; i++) {
196
- body += "<path" + (fill ? " fill='" + fill + "'" : '') + " d='" + paths[i] + "'/>"
197
- }
198
- var svg =
199
- "<svg xmlns='http://www.w3.org/2000/svg' viewBox='" + viewBox + "'>" +
200
- "<g transform='" + CLAUDE_TRANSFORM + "'>" + body + '</g></svg>'
201
- return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '")'
202
- }
203
-
204
- /** The starburst alone, as a currentColor alpha mask. */
205
- var CLAUDE_MARK = claudeMask(CLAUDE_MARK_VIEWBOX, [CLAUDE_MARK_PATH])
206
- /** The wordmark alone, as a currentColor alpha mask. */
207
- var CLAUDE_WORD = claudeMask(CLAUDE_WORD_VIEWBOX, [CLAUDE_WORD_PATH])
208
- /** The full lockup (starburst + wordmark) as one currentColor alpha mask. */
209
- var CLAUDE_LOCKUP = claudeMask('0 0 689.98 148.18', [CLAUDE_MARK_PATH, CLAUDE_WORD_PATH])
210
- /** The starburst with the clay accent baked in, for the new-conversation hero. */
211
- var CLAUDE_MARK_CLAY = claudeMask(CLAUDE_MARK_VIEWBOX, [CLAUDE_MARK_PATH], '#D97757')
212
-
213
- /** Anthropic's A\ lockup mark (the alternate sidebar brand), as an alpha mask. */
214
- var ANTHROPIC_BRAND_MARK = "url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 46 32%27%3E%3Cpath d=%27M32.73 0H25.7846L38.4499 32H45.3953L32.73 0Z%27/%3E%3Cpath d=%27M12.6653 0L0 32H7.08167L9.67193 25.28H22.9219L25.5122 32H32.5939L19.9286 0H12.6653ZM11.9626 19.3371L16.2969 8.09143L20.6313 19.3371H11.9626Z%27/%3E%3C/svg%3E\")"
215
-
216
- /** The ANTHROPIC wordmark (the alternate sidebar brand), as an alpha mask. */
217
- var ANTHROPIC_BRAND_WORD = "url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 143 16%27%3E%3Cpath transform=%27translate(18.299999237060547,0.27000001072883606)%27 d=%27 M10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 3.756195545196533,0 3.756195545196533,0 C3.756195545196533,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.2038140296936035,15.470022201538086 3.2038140296936035,15.470022201538086 C3.2038140296936035,15.470022201538086 3.2038140296936035,4.6410064697265625 3.2038140296936035,4.6410064697265625 C3.2038140296936035,4.6410064697265625 10.163809776306152,15.470022201538086 10.163809776306152,15.470022201538086 C10.163809776306152,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.716191291809082,0 10.716191291809082,0 C10.716191291809082,0 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777z%27/%3E%3Cpath transform=%27translate(34.869998931884766,0.27000001072883606)%27 d=%27 M0,2.983504056930542 C0,2.983504056930542 5.19273567199707,2.983504056930542 5.19273567199707,2.983504056930542 C5.19273567199707,2.983504056930542 5.19273567199707,15.470022201538086 5.19273567199707,15.470022201538086 C5.19273567199707,15.470022201538086 8.507256507873535,15.470022201538086 8.507256507873535,15.470022201538086 C8.507256507873535,15.470022201538086 8.507256507873535,2.983504056930542 8.507256507873535,2.983504056930542 C8.507256507873535,2.983504056930542 13.700006484985352,2.983504056930542 13.700006484985352,2.983504056930542 C13.700006484985352,2.983504056930542 13.700006484985352,0 13.700006484985352,0 C13.700006484985352,0 0,0 0,0 C0,0 0,2.983504056930542 0,2.983504056930542 C0,2.983504056930542 0,2.983504056930542 0,2.983504056930542z%27/%3E%3Cpath transform=%27translate(51.22999954223633,0.27000001072883606)%27 d=%27 M10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 3.3142902851104736,6.165900230407715 3.3142902851104736,6.165900230407715 C3.3142902851104736,6.165900230407715 3.3142902851104736,0 3.3142902851104736,0 C3.3142902851104736,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3142902851104736,15.470022201538086 3.3142902851104736,15.470022201538086 C3.3142902851104736,15.470022201538086 3.3142902851104736,9.149404525756836 3.3142902851104736,9.149404525756836 C3.3142902851104736,9.149404525756836 10.605714797973633,9.149404525756836 10.605714797973633,9.149404525756836 C10.605714797973633,9.149404525756836 10.605714797973633,15.470022201538086 10.605714797973633,15.470022201538086 C10.605714797973633,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.605714797973633,0 10.605714797973633,0 C10.605714797973633,0 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715z%27/%3E%3Cpath transform=%27translate(69.23999786376953,0.27000001072883606)%27 d=%27 M3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 7.403865814208984,2.983504056930542 7.403865814208984,2.983504056930542 C9.03934097290039,2.983504056930542 9.901290893554688,3.5801939964294434 9.901290893554688,4.707304000854492 C9.901290893554688,5.834399700164795 9.03934097290039,6.431103706359863 7.403865814208984,6.431103706359863 C7.403865814208984,6.431103706359863 3.3151700496673584,6.431103706359863 3.3151700496673584,6.431103706359863 C3.3151700496673584,6.431103706359863 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542z M13.216461181640625,4.707304000854492 C13.216461181640625,1.7900969982147217 11.072648048400879,0 7.558576583862305,0 C7.558576583862305,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3151700496673584,15.470022201538086 3.3151700496673584,15.470022201538086 C3.3151700496673584,15.470022201538086 3.3151700496673584,9.414593696594238 3.3151700496673584,9.414593696594238 C3.3151700496673584,9.414593696594238 7.005825519561768,9.414593696594238 7.005825519561768,9.414593696594238 C7.005825519561768,9.414593696594238 10.321218490600586,15.470022201538086 10.321218490600586,15.470022201538086 C10.321218490600586,15.470022201538086 13.990056991577148,15.470022201538086 13.990056991577148,15.470022201538086 C13.990056991577148,15.470022201538086 10.319005966186523,8.953378677368164 10.319005966186523,8.953378677368164 C12.161579132080078,8.245061874389648 13.216461181640625,6.753532409667969 13.216461181640625,4.707304000854492 C13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492z%27/%3E%3Cpath transform=%27translate(84.98999786376953,0)%27 d=%27 M7.622087478637695,12.906073570251465 C5.015110492706299,12.906073570251465 3.4244225025177,11.049725532531738 3.4244225025177,8.022093772888184 C3.4244225025177,4.95027494430542 5.015110492706299,3.0939269065856934 7.622087478637695,3.0939269065856934 C10.206976890563965,3.0939269065856934 11.775577545166016,4.95027494430542 11.775577545166016,8.022093772888184 C11.775577545166016,11.049725532531738 10.206976890563965,12.906073570251465 7.622087478637695,12.906073570251465 C7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465z M7.622087478637695,0 C3.1593029499053955,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1593029499053955,16 7.622087478637695,16 C12.062784194946289,16 15.200028419494629,12.685078620910645 15.200028419494629,8.022093772888184 C15.200028419494629,3.3149218559265137 12.062784194946289,0 7.622087478637695,0 C7.622087478637695,0 7.622087478637695,0 7.622087478637695,0z%27/%3E%3Cpath transform=%27translate(103.29000091552734,0.27000001072883606)%27 d=%27 M7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 3.3160574436187744,6.873104095458984 3.3160574436187744,6.873104095458984 C3.3160574436187744,6.873104095458984 3.3160574436187744,2.983504056930542 3.3160574436187744,2.983504056930542 C3.3160574436187744,2.983504056930542 7.405848026275635,2.983504056930542 7.405848026275635,2.983504056930542 C9.04176139831543,2.983504056930542 9.90394115447998,3.646505117416382 9.90394115447998,4.928304195404053 C9.90394115447998,6.2101030349731445 9.04176139831543,6.873104095458984 7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984z M7.5605998039245605,0 C7.5605998039245605,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3160574436187744,15.470022201538086 3.3160574436187744,15.470022201538086 C3.3160574436187744,15.470022201538086 3.3160574436187744,9.85659408569336 3.3160574436187744,9.85659408569336 C3.3160574436187744,9.85659408569336 7.5605998039245605,9.85659408569336 7.5605998039245605,9.85659408569336 C11.07561206817627,9.85659408569336 13.219999313354492,8.000200271606445 13.219999313354492,4.928304195404053 C13.219999313354492,1.8563942909240723 11.07561206817627,0 7.5605998039245605,0 C7.5605998039245605,0 7.5605998039245605,0 7.5605998039245605,0z%27/%3E%3Cpath transform=%27translate(128.0399932861328,0)%27 d=%27 M10.914844512939453,10.5414400100708 C10.340370178222656,12.044201850891113 9.191434860229492,12.906073570251465 7.622706890106201,12.906073570251465 C5.0155181884765625,12.906073570251465 3.4246866703033447,11.049725532531738 3.4246866703033447,8.022093772888184 C3.4246866703033447,4.95027494430542 5.0155181884765625,3.0939269065856934 7.622706890106201,3.0939269065856934 C9.191434860229492,3.0939269065856934 10.340370178222656,3.9557981491088867 10.914844512939453,5.458559989929199 C10.914844512939453,5.458559989929199 14.427860260009766,5.458559989929199 14.427860260009766,5.458559989929199 C13.566211700439453,2.1436522006988525 10.981111526489258,0 7.622706890106201,0 C3.1595458984375,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1595458984375,16 7.622706890106201,16 C11.003214836120605,16 13.588300704956055,13.834254264831543 14.449976921081543,10.5414400100708 C14.449976921081543,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 C10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708z%27/%3E%3Cpath transform=%27translate(117.83000183105469,0.27000001072883606)%27 d=%27 M0,0 C0,0 6.1677093505859375,15.470022201538086 6.1677093505859375,15.470022201538086 C6.1677093505859375,15.470022201538086 9.550004005432129,15.470022201538086 9.550004005432129,15.470022201538086 C9.550004005432129,15.470022201538086 3.382294178009033,0 3.382294178009033,0 C3.382294178009033,0 0,0 0,0 C0,0 0,0 0,0z%27/%3E%3Cpath transform=%27translate(0,0.27000001072883606)%27 d=%27 M5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 7.93500280380249,3.911694288253784 7.93500280380249,3.911694288253784 C7.93500280380249,3.911694288253784 10.045400619506836,9.348296165466309 10.045400619506836,9.348296165466309 C10.045400619506836,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309z M6.166755199432373,0 C6.166755199432373,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.4480772018432617,15.470022201538086 3.4480772018432617,15.470022201538086 C3.4480772018432617,15.470022201538086 4.709278583526611,12.22130012512207 4.709278583526611,12.22130012512207 C4.709278583526611,12.22130012512207 11.16093635559082,12.22130012512207 11.16093635559082,12.22130012512207 C11.16093635559082,12.22130012512207 12.421928405761719,15.470022201538086 12.421928405761719,15.470022201538086 C12.421928405761719,15.470022201538086 15.87000560760498,15.470022201538086 15.87000560760498,15.470022201538086 C15.87000560760498,15.470022201538086 9.703250885009766,0 9.703250885009766,0 C9.703250885009766,0 6.166755199432373,0 6.166755199432373,0 C6.166755199432373,0 6.166755199432373,0 6.166755199432373,0z%27/%3E%3C/svg%3E\")"
205
+ /** Present while the skin takes over the sidebar footer (settings area + account row). */
206
+ var FOOTER_ATTR = 'data-dsh-claude-footer-takeover'
207
+ /** Present while the composer restyle applies to the page currently shown. */
208
+ var COMPOSER_ATTR = 'data-dsh-claude-composer-active'
209
+ /** Composer surfaces the restyle may cover, in settings order. */
210
+ var COMPOSER_SCOPES = ['off', 'hero', 'conversation', 'all']
211
+ /** Route the browser half reads and writes preferences through (lib/index.js). */
212
+ var PREFS_ROUTE = '/dsh-claude-style/prefs'
218
213
 
214
+ /** Wordmark aspect ratio; scripts/build.mjs sizes the sidebar word height from it (geometry lives in src/assets/claude-word.svg). */
215
+ var CLAUDE_WORD_ASPECT = 512.22 / 121.54
219
216
 
220
217
  var SANS = "'Anthropic Sans Web Text','Noto Sans SC','Source Han Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Helvetica Neue',Helvetica,Arial,sans-serif"
221
218
  var SERIF = "'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Serif SC','Source Han Serif SC','Songti SC','SimSun',serif"
219
+ /**
220
+ * Conversation prose: Claude sets Latin text in the serif face and lets
221
+ * Chinese fall through to a sans CJK — the serif Latin faces carry no CJK
222
+ * glyphs, so the stack leads with serif and names the sans CJK families
223
+ * after it. UI chrome keeps SANS; only markdown prose uses this.
224
+ */
225
+ var PROSE = "'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Sans SC','Source Han Sans SC','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif"
222
226
  var MONO = "'Anthropic Mono Variable',ui-monospace,'SF Mono','JetBrains Mono','Fira Code',Consolas,'Liberation Mono',Menlo,Courier,monospace"
223
227
 
224
228
  // ============================================================================
225
- // Zone 2: 样式表(由 src/styles/*.css 内联生成,勿手改) (CSS Stylesheet)
229
+ // 样式表(由 src/styles/*.css 内联生成,勿手改) (CSS Stylesheet)
226
230
  // ============================================================================
227
231
  var CSS = [
228
232
  "/* --- 2.1 Design Tokens (Dark Base & Light Overrides) --- */",
229
- "/* ---------- design tokens: warm-black (dark) base ---------- */",
233
+ "/* ---------- typography tokens: theme-independent ---------- */",
230
234
  "body[data-dsh-claude-style] {",
231
235
  " --dsw-font-family: 'Anthropic Sans Web Text','Noto Sans SC','Source Han Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Helvetica Neue',Helvetica,Arial,sans-serif;",
232
236
  " --dsw-font-serif: 'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Serif SC','Source Han Serif SC','Songti SC','SimSun',serif;",
237
+ " --dsw-font-prose: 'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Sans SC','Source Han Sans SC','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;",
233
238
  " --dsw-font-code: 'Anthropic Mono Variable',ui-monospace,'SF Mono','JetBrains Mono','Fira Code',Consolas,'Liberation Mono',Menlo,Courier,monospace;",
234
- " --dsw-font-markdown-h1-font-family: var(--dsw-font-serif);",
235
- " --dsw-font-markdown-h2-font-family: var(--dsw-font-serif);",
236
- " --dsw-font-markdown-h3-font-family: var(--dsw-font-serif);",
237
- " --dsw-font-markdown-h4-font-family: var(--dsw-font-serif);",
238
- " --dsw-font-markdown-base-font-family: var(--dsw-font-family);",
239
- " --dsw-font-markdown-small-font-family: var(--dsw-font-family);",
240
- " --dsw-font-markdown-table-font-family: var(--dsw-font-family);",
239
+ " /* Markdown document headings keep the host's own ladder, steepened from",
240
+ " 21/19/18 toward Claude's measured ≈21/17/15; h1 and h4 keep the host's",
241
+ " values. The host reads these through a `font:` shorthand that names",
242
+ " --dsw-font-family directly, so overriding the `-font-family` sub-tokens",
243
+ " never reached the page — the shorthand itself is what has to be",
244
+ " re-declared. */",
245
+ " --dsw-font-markdown-h2: 700 calc(18px + var(--dsh-content-font-delta)) / calc(26px + var(--dsh-content-font-delta)) var(--dsw-font-prose);",
246
+ " --dsw-font-markdown-h3: 700 calc(16px + var(--dsh-content-font-delta)) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-prose);",
247
+ "}",
248
+ "",
249
+ "/* ---------- design tokens: warm-black (dark) palette ---------- */",
250
+ "/* The dark palette is scoped to [data-ds-dark-theme] on purpose. The host",
251
+ " ships its own dark palette on body[data-ds-dark-theme] — the same (0,1,1)",
252
+ " weight as a bare body[data-dsh-claude-style] — so the two only tie, and",
253
+ " whichever stylesheet the loader appends last wins. When the host's lands",
254
+ " after this one its blue accents (--dsw-alias-state-business-primary,",
255
+ " --dsw-alias-button-info-fill, --dsw-alias-link and the brand \"new color\")",
256
+ " replace the warm palette. Naming the attribute keeps this block at (0,2,1)",
257
+ " and makes it order-independent. */",
258
+ "body[data-dsh-claude-style][data-ds-dark-theme] {",
241
259
  " --dsw-alias-bg-base: #141413;",
242
260
  " --dsw-alias-bg-layer-1: #1c1b1a;",
243
261
  " --dsw-alias-bg-layer-2: #242320;",
@@ -255,6 +273,13 @@ window.__ModuleLoader__.load({
255
273
  " --dsw-alias-button-info-hover: #e08a6d;",
256
274
  " --dsw-alias-interactive-bg-active: rgba(217, 119, 87, 0.30);",
257
275
  " --dsh-claude-hover-bg: rgba(255, 255, 255, 0.08);",
276
+ " --dsh-claude-inline-code-fg: #e8a08a;",
277
+ " --dsh-claude-link: #8ab4f8;",
278
+ " /* The host pins the code-block surface on `pre.shiki` with !important, so it",
279
+ " is only reachable through its own token; #1c1b1a is the value the skin's",
280
+ " (inert) `pre { background }` rule always meant. */",
281
+ " --dsw-alias-markdown-code-block: #1c1b1a;",
282
+ " --dsw-alias-markdown-code-block-banner: #242320;",
258
283
  " --dsw-alias-interactive-bg-hover: var(--dsh-claude-hover-bg);",
259
284
  " --dsw-alias-interactive-bg-hover-solid: #2e2c29;",
260
285
  " --dsw-alias-label-primary: #faf9f5;",
@@ -264,10 +289,14 @@ window.__ModuleLoader__.load({
264
289
  " --dsw-alias-label-caption: #6b6a65;",
265
290
  " --dsw-alias-state-business-primary: #d97757;",
266
291
  " --dsw-alias-state-business-tertiary: #3a2a22;",
292
+ " --dsw-alias-link: #e08a6d;",
267
293
  " --dsw-shadow-lv2: 0 4px 16px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.14);",
268
294
  " --dsw-specific-input-major: #0f0e0d;",
269
295
  " --dsw-specific-selector: #2e2c29;",
270
296
  " --dsw-specific-sidebar-fill: #141413;",
297
+ " /* The host's \"new color\" brand accent (shipped under this doubled suffix)",
298
+ " resolves to a deepseek blue in both palettes; the skin has one accent. */",
299
+ " --dsw-alias-brand-primary-new-colorprimary-new-color: #d97757;",
271
300
  "}",
272
301
  "",
273
302
  "/* ================= light variant: ivory editorial ================= */",
@@ -292,6 +321,7 @@ window.__ModuleLoader__.load({
292
321
  " --dsw-alias-label-caption: #a6a094;",
293
322
  " --dsw-alias-state-business-primary: #d97757;",
294
323
  " --dsw-alias-state-business-tertiary: #e9dfd2;",
324
+ " --dsw-alias-link: #c6613f;",
295
325
  " --dsw-specific-input-major: #ffffff;",
296
326
  " --dsw-specific-menu: #ffffff;",
297
327
  " --dsw-specific-selector: #f0eee6;",
@@ -299,6 +329,23 @@ window.__ModuleLoader__.load({
299
329
  " --dsh-claude-hover-bg: rgba(0, 0, 0, 0.08);",
300
330
  " --dsw-alias-interactive-bg-hover: var(--dsh-claude-hover-bg);",
301
331
  " --dsw-shadow-lv2: 0 4px 18px rgba(20, 20, 19, 0.10), 0 1px 3px rgba(20, 20, 19, 0.05);",
332
+ " --dsw-alias-brand-primary-new-colorprimary-new-color: #d97757;",
333
+ " /* Carried over from the dark base block so the light palette stays complete",
334
+ " now that the dark palette is dark-scoped. */",
335
+ " --dsw-alias-brand-text: #faf9f5;",
336
+ " --dsw-alias-button-elevated-fill: #242320;",
337
+ " --dsw-alias-interactive-bg-active: rgba(217, 119, 87, 0.30);",
338
+ " --dsw-alias-interactive-bg-hover-solid: #2e2c29;",
339
+ " /* User message bubbles: the host's light bubble token is deepseek-50 (blue);",
340
+ " use the skin's button-hover gray instead. */",
341
+ " --dsw-specific-bubble: var(--dsh-claude-hover-bg);",
342
+ " /* Markdown surfaces, measured off Claude: a white code block, a neutral-gray",
343
+ " inline-code chip, and blue links. The chip colour is the same gray the",
344
+ " components hover with, so the two read as one material. */",
345
+ " --dsw-alias-markdown-code-block: #ffffff;",
346
+ " --dsw-alias-markdown-code-block-banner: #ffffff;",
347
+ " --dsh-claude-inline-code-fg: #943333;",
348
+ " --dsh-claude-link: #184f95;",
302
349
  "}",
303
350
  "",
304
351
  "body[data-dsh-claude-style]:not([data-ds-dark-theme]) {",
@@ -344,19 +391,14 @@ window.__ModuleLoader__.load({
344
391
  "",
345
392
  "body[data-dsh-claude-style]:not([data-ds-dark-theme]) blockquote {",
346
393
  " color: #6e6a60;",
347
- " border-left-color: #c6613f;",
348
- " background: rgba(198, 97, 63, 0.05);",
394
+ " border-left-color: var(--dsw-alias-label-caption);",
395
+ " background: rgba(20, 20, 19, 0.04);",
349
396
  "}",
350
397
  "",
351
398
  "body[data-dsh-claude-style]:not([data-ds-dark-theme]) pre {",
352
- " background: #f5f3ee;",
353
399
  " border-color: #e8e6dc;",
354
400
  "}",
355
401
  "",
356
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) code:not(pre code) {",
357
- " background: #e8e6dc;",
358
- "}",
359
- "",
360
402
  "body[data-dsh-claude-style]:not([data-ds-dark-theme]) table th {",
361
403
  " background: #f0eee6;",
362
404
  "}",
@@ -399,6 +441,46 @@ window.__ModuleLoader__.load({
399
441
  " letter-spacing: -0.015em;",
400
442
  "}",
401
443
  "",
444
+ "/* ---------- markdown document prose ---------- */",
445
+ "/* Claude sets conversation prose — body and headings alike — in the serif",
446
+ " face and lets Chinese fall through to a sans CJK; the serif display rule",
447
+ " above stays for UI headlines. */",
448
+ "body[data-dsh-claude-style] [class*=\"markdown\"] {",
449
+ " font-family: var(--dsw-font-prose);",
450
+ "}",
451
+ "",
452
+ "/* The host gives its markdown elements their own `font:` shorthand, so the",
453
+ " family has to be re-stated wherever those shorthands land. The heading",
454
+ " shorthand is re-asserted too, so the host's weight, size and line-height",
455
+ " survive the serif display rule above. */",
456
+ "body[data-dsh-claude-style] [class*=\"markdown\"] h1 { font: var(--dsw-font-markdown-h1); font-family: var(--dsw-font-prose); }",
457
+ "body[data-dsh-claude-style] [class*=\"markdown\"] h2 { font: var(--dsw-font-markdown-h2); font-family: var(--dsw-font-prose); }",
458
+ "body[data-dsh-claude-style] [class*=\"markdown\"] h3 { font: var(--dsw-font-markdown-h3); font-family: var(--dsw-font-prose); }",
459
+ "body[data-dsh-claude-style] [class*=\"markdown\"] h4 { font: var(--dsw-font-markdown-h4); font-family: var(--dsw-font-prose); }",
460
+ "",
461
+ "body[data-dsh-claude-style] [class*=\"markdown\"] :is(th, td) {",
462
+ " font-family: var(--dsw-font-prose);",
463
+ "}",
464
+ "",
465
+ "/* Heading rhythm. The host gives every heading a 32px top margin, which stacks",
466
+ " on the previous heading's 16px bottom margin: two consecutive headings open",
467
+ " ~36px of air where Claude keeps ~12px, and in the sample document that alone",
468
+ " pushed the last list past the viewport. A heading that directly follows",
469
+ " another tightens further, so a run of headings reads as one block. */",
470
+ "body[data-dsh-claude-style] [class*=\"markdown\"] :is(h1, h2, h3) {",
471
+ " margin-top: 24px;",
472
+ " margin-bottom: 12px;",
473
+ "}",
474
+ "",
475
+ "body[data-dsh-claude-style] [class*=\"markdown\"] :is(h1, h2, h3) + :is(h1, h2, h3) {",
476
+ " margin-top: 8px;",
477
+ "}",
478
+ "",
479
+ "body[data-dsh-claude-style] [class*=\"markdown\"] :is(h4, h5, h6) {",
480
+ " margin-top: 16px;",
481
+ " margin-bottom: 8px;",
482
+ "}",
483
+ "",
402
484
  "body[data-dsh-claude-style] :is(pre, code, kbd, samp, [class*=\"mono\"], [class*=\"codeBlock\"], [class*=\"CodeBlock\"]) {",
403
485
  " font-family: var(--dsw-font-code);",
404
486
  "}",
@@ -410,29 +492,49 @@ window.__ModuleLoader__.load({
410
492
  "}",
411
493
  "",
412
494
  "/* ---------- editorial markdown ---------- */",
495
+ "/* Claude's quote keeps the prose face but stands upright on a neutral bar and",
496
+ " wash; the warm accent stays reserved for controls. */",
413
497
  "body[data-dsh-claude-style] blockquote {",
414
- " font-family: var(--dsw-font-serif);",
415
- " font-style: italic;",
498
+ " font-family: var(--dsw-font-prose);",
499
+ " font-style: normal;",
416
500
  " color: #b0aea5;",
417
- " border-left: 2px solid #d97757;",
418
- " background: rgba(217, 119, 87, 0.06);",
501
+ " border-left: 2px solid var(--dsw-alias-label-caption);",
502
+ " background: rgba(250, 249, 245, 0.06);",
419
503
  " border-radius: 0 8px 8px 0;",
420
504
  " padding: 0.6em 1em;",
421
505
  "}",
422
506
  "",
507
+ "/* The fill rides the host's --dsw-alias-markdown-code-block token — the host",
508
+ " pins `pre.shiki` with !important, so a `background` here would never apply.",
509
+ " Only the frame is styled. */",
423
510
  "body[data-dsh-claude-style] pre {",
424
- " background: #1c1b1a;",
425
511
  " border: 1px solid #242320;",
426
512
  " border-radius: 8px;",
427
513
  "}",
428
514
  "",
515
+ "/* Claude's inline-code chip: warm red on the same neutral gray the components",
516
+ " hover with — both resolve per theme from the palette blocks. */",
429
517
  "body[data-dsh-claude-style] code:not(pre code) {",
430
- " background: #2e2c29;",
518
+ " background: var(--dsh-claude-hover-bg);",
519
+ " color: var(--dsh-claude-inline-code-fg);",
431
520
  " border-radius: 4px;",
432
521
  " padding: 0.15em 0.4em;",
433
522
  " font-size: 0.88em;",
434
523
  "}",
435
524
  "",
525
+ "/* Claude's links: blue, underlined at rest, and without the host's",
526
+ " link-category glyph. */",
527
+ "body[data-dsh-claude-style] [class*=\"linkIcon\"] {",
528
+ " display: none;",
529
+ "}",
530
+ "",
531
+ "body[data-dsh-claude-style] [class*=\"markdown\"] :is(a, a:hover, a:focus) {",
532
+ " color: var(--dsh-claude-link);",
533
+ " text-decoration: underline;",
534
+ " text-decoration-thickness: 1px;",
535
+ " text-underline-offset: 2px;",
536
+ "}",
537
+ "",
436
538
  "body[data-dsh-claude-style] hr {",
437
539
  " border: none;",
438
540
  " border-top: 1px solid rgba(20, 20, 19, 0.14);",
@@ -579,14 +681,15 @@ window.__ModuleLoader__.load({
579
681
  "}",
580
682
  "",
581
683
  "/* Keyboard focus ring: neutral, in the input box's own shadow colour",
582
- " (espresso #141413 in light, black in dark) instead of the clay accent. */",
684
+ " (espresso #141413 in light); dark inverts to bright ivory — a near-black",
685
+ " canvas gets a light ring, never a darker one. */",
583
686
  "body[data-dsh-claude-style] :is(button, input, textarea, select, [role=\"button\"], [role=\"tab\"], [role=\"treeitem\"]):focus-visible {",
584
687
  " outline: 2px solid rgba(20, 20, 19, 0.45);",
585
688
  " outline-offset: 1px;",
586
689
  "}",
587
690
  "",
588
691
  "body[data-dsh-claude-style][data-ds-dark-theme] :is(button, input, textarea, select, [role=\"button\"], [role=\"tab\"], [role=\"treeitem\"]):focus-visible {",
589
- " outline-color: rgba(0, 0, 0, 0.45);",
692
+ " outline-color: rgba(250, 249, 245, 0.60);",
590
693
  "}",
591
694
  "",
592
695
  "/* ---------- Claude Code layout: hero brand mark ---------- */",
@@ -595,15 +698,15 @@ window.__ModuleLoader__.load({
595
698
  " slot wrapper, not always a bare svg — and the mark is painted on the hitbox,",
596
699
  " so React keeps owning its own node. The hero keeps the clay fill in both",
597
700
  " brands, matching the shipped accent treatment. */",
598
- "body[data-dsh-claude-style] [class*=\"fishHitbox\"] > * {",
701
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) [class*=\"fishHitbox\"] > * {",
599
702
  " display: none !important;",
600
703
  "}",
601
704
  "",
602
- "body[data-dsh-claude-style] [class*=\"fishHitbox\"] svg {",
705
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) [class*=\"fishHitbox\"] svg {",
603
706
  " display: none !important;",
604
707
  "}",
605
708
  "",
606
- "body[data-dsh-claude-style] [class*=\"fishHitbox\"]::before {",
709
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) [class*=\"fishHitbox\"]::before {",
607
710
  " content: \"\";",
608
711
  " flex: none;",
609
712
  " width: 42.5px;",
@@ -613,12 +716,12 @@ window.__ModuleLoader__.load({
613
716
  " background-size: contain;",
614
717
  "}",
615
718
  "",
616
- "body[data-dsh-claude-style]:not([data-dsh-claude-brand=\"anthropic\"]) [class*=\"fishHitbox\"]::before {",
719
+ "body[data-dsh-claude-style][data-dsh-claude-brand=\"claude\"] [class*=\"fishHitbox\"]::before {",
617
720
  " background-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%20148.09%20148.18'%3E%3Cg%20transform%3D'translate(-75.96%2C-223.53)'%3E%3Cpath%20fill%3D'%23D97757'%20d%3D'm%20105.01%2C322.07%2029.14%2C-16.35%200.49%2C-1.42%20-0.49%2C-0.79%20h%20-1.42%20l%20-4.87%2C-0.3%20-16.65%2C-0.45%20-14.44%2C-0.6%20-13.99%2C-0.75%20-3.52%2C-0.75%20-3.3%2C-4.35%200.34%2C-2.17%202.96%2C-1.99%204.24%2C0.37%209.37%2C0.64%2014.06%2C0.97%2010.2%2C0.6%2015.11%2C1.57%20h%202.4%20l%200.34%2C-0.97%20-0.82%2C-0.6%20-0.64%2C-0.6%20-14.55%2C-9.86%20-15.75%2C-10.42%20-8.25%2C-6%20-4.46%2C-3.04%20-2.25%2C-2.85%20-0.97%2C-6.22%204.05%2C-4.46%205.44%2C0.37%201.39%2C0.37%205.51%2C4.24%2011.77%2C9.11%2015.37%2C11.32%202.25%2C1.87%200.9%2C-0.64%200.11%2C-0.45%20-1.01%2C-1.69%20-8.36%2C-15.11%20-8.92%2C-15.37%20-3.97%2C-6.37%20-1.05%2C-3.82%20c%20-0.37%2C-1.57%20-0.64%2C-2.89%20-0.64%2C-4.5%20l%204.61%2C-6.26%202.55%2C-0.82%206.15%2C0.82%202.59%2C2.25%203.82%2C8.74%206.19%2C13.76%209.6%2C18.71%202.81%2C5.55%201.5%2C5.14%200.56%2C1.57%20h%200.97%20v%20-0.9%20l%200.79%2C-10.54%201.46%2C-12.94%201.42%2C-16.65%200.49%2C-4.69%202.32%2C-5.62%204.61%2C-3.04%203.6%2C1.72%202.96%2C4.24%20-0.41%2C2.74%20-1.76%2C11.44%20-3.45%2C17.92%20-2.25%2C12%20h%201.31%20l%201.5%2C-1.5%206.07%2C-8.06%2010.2%2C-12.75%204.5%2C-5.06%205.25%2C-5.59%203.37%2C-2.66%20h%206.37%20l%204.69%2C6.97%20-2.1%2C7.2%20-6.56%2C8.32%20-5.44%2C7.05%20-7.8%2C10.5%20-4.87%2C8.4%200.45%2C0.67%201.16%2C-0.11%2017.62%2C-3.75%209.52%2C-1.72%2011.36%2C-1.95%205.14%2C2.4%200.56%2C2.44%20-2.02%2C4.99%20-12.15%2C3%20-14.25%2C2.85%20-21.22%2C5.02%20-0.26%2C0.19%200.3%2C0.37%209.56%2C0.9%204.09%2C0.22%20h%2010.01%20l%2018.64%2C1.39%204.87%2C3.22%202.92%2C3.94%20-0.49%2C3%20-7.5%2C3.82%20-10.12%2C-2.4%20-23.62%2C-5.62%20-8.1%2C-2.02%20h%20-1.12%20v%200.67%20l%206.75%2C6.6%2012.37%2C11.17%2015.49%2C14.4%200.79%2C3.56%20-1.99%2C2.81%20-2.1%2C-0.3%20-13.61%2C-10.24%20-5.25%2C-4.61%20-11.89%2C-10.01%20h%20-0.79%20v%201.05%20l%202.74%2C4.01%2014.47%2C21.75%200.75%2C6.67%20-1.05%2C2.17%20-3.75%2C1.31%20-4.12%2C-0.75%20-8.47%2C-11.89%20-8.74%2C-13.39%20-7.05%2C-12%20-0.86%2C0.49%20-4.16%2C44.81%20-1.95%2C2.29%20-4.5%2C1.72%20-3.75%2C-2.85%20-1.99%2C-4.61%201.99%2C-9.11%202.4%2C-11.89%201.95%2C-9.45%201.76%2C-11.74%201.05%2C-3.9%20-0.07%2C-0.26%20-0.86%2C0.11%20-8.85%2C12.15%20-13.46%2C18.19%20-10.65%2C11.4%20-2.55%2C1.01%20-4.42%2C-2.29%200.41%2C-4.09%202.47%2C-3.64%2014.74%2C-18.75%208.89%2C-11.62%205.74%2C-6.71%20-0.04%2C-0.97%20h%20-0.34%20l%20-39.15%2C25.42%20-6.97%2C0.9%20-3%2C-2.81%200.37%2C-4.61%201.42%2C-1.5%2011.77%2C-8.1%20-0.04%2C0.04%20z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");",
618
721
  "}",
619
722
  "",
620
723
  "body[data-dsh-claude-style][data-dsh-claude-brand=\"anthropic\"] [class*=\"fishHitbox\"]::before {",
621
- " background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z' fill='%23D97757'/%3E%3C/svg%3E\");",
724
+ " background-image: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2024%2024'%3E%3Cpath%20d%3D'M4.709%2015.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0%2011.784l.055-.352.48-.321.686.06%201.52.103%202.278.158%201.652.097%202.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686%201.908%201.476%202.491%201.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97%202.97%200%2001-.104-.729L6.283.134%206.696%200l.996.134.42.364.62%201.414%201.002%202.229%201.555%203.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286%201.851-.559%202.903-.364%201.942h.212l.243-.242.985-1.306%201.652-2.064.73-.82.85-.904.547-.431h1.033l.76%201.129-.34%201.166-1.064%201.347-.881%201.142-1.264%201.7-.79%201.36.073.11.188-.02%202.856-.606%201.543-.28%201.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061%201.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093%201.068%202.006%201.81%202.509%202.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649%202.345%203.521.122%201.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674%207.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434%201.967-2.18%202.945-1.726%201.845-.414.164-.717-.37.067-.662.401-.589%202.388-3.036%201.44-1.882.93-1.086-.006-.158h-.055L4.132%2018.56l-1.13.146-.487-.456.061-.746.231-.243%201.908-1.312-.006.006z'%20fill%3D'%23D97757'%2F%3E%3C%2Fsvg%3E\");",
622
725
  "}",
623
726
  "",
624
727
  "/* The preview badge has no Claude Code counterpart. */",
@@ -635,10 +738,17 @@ window.__ModuleLoader__.load({
635
738
  "}",
636
739
  "",
637
740
  "/* ---------- Claude Code layout: composer input + buttons ---------- */",
741
+ "/* @composer-gate */",
742
+ "/* Everything from here down is the \"Composer restyle\" preference's territory:",
743
+ " the build stamps `[data-dsh-claude-composer-active]` onto every rule below",
744
+ " this marker, and the skin sets that attribute on <body> only while the page",
745
+ " on screen is a surface the preference covers. Above the marker sits the hero",
746
+ " brand mark and headline, which belong to the brand preference instead — a",
747
+ " composer scope of \"conversation only\" must not revert them. */",
638
748
  "/* The composer card is the input box: one step up in type size, pure white",
639
749
  " so it separates from the canvas, and an outline 4px tighter than the",
640
750
  " shipped 22px. */",
641
- "body[data-dsh-claude-style] [data-composer-card] {",
751
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] {",
642
752
  " font-size: 15px;",
643
753
  " border-radius: 18px;",
644
754
  " border: 1px solid var(--dsw-alias-border-l1);",
@@ -658,11 +768,11 @@ window.__ModuleLoader__.load({
658
768
  " --dsh-composer-text-max-height before it starts scrolling. Both hooks are",
659
769
  " ancestors of the field, so :is() also keeps the tall field through the",
660
770
  " settling frame, while an active composer matches neither. */",
661
- "body[data-dsh-claude-style] :is([class*=\"composerHero\"], [data-phase=\"hero\"]) [data-composer-input] {",
771
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] :is([class*=\"composerHero\"], [data-phase=\"hero\"]) [data-composer-input] {",
662
772
  " min-height: 86px !important;",
663
773
  "}",
664
774
  "",
665
- "body[data-dsh-claude-style] [data-composer-input] {",
775
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-input] {",
666
776
  " min-height: 36px !important;",
667
777
  " height: auto !important;",
668
778
  "}",
@@ -671,42 +781,48 @@ window.__ModuleLoader__.load({
671
781
  " be `[class*=\"_row\"]`: a bare `[class*=\"row\"]` substring-matches the",
672
782
  " shipped input growth wrapper `.p_FcLG_grow` (\"grow\" contains \"row\"),",
673
783
  " which pins the composer field to the toolbar-row metrics. */",
674
- "body[data-dsh-claude-style] [data-composer-card] [class*=\"_row\"] {",
784
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"_row\"] {",
675
785
  " padding-bottom: 2px !important;",
676
786
  "}",
677
787
  "",
678
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card] {",
788
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card] {",
679
789
  " background: #ffffff;",
680
- " box-shadow: 0 4px 12px rgba(20, 20, 19, 0.04), 0 1px 3px rgba(20, 20, 19, 0.02);",
790
+ " box-shadow: 0 4px 12px rgba(20, 20, 19, 0.04), 0 1px 3px rgba(20, 20, 19, 0.02), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base);",
791
+ "}",
792
+ "",
793
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card] {",
794
+ " box-shadow: 0 4px 12px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.15), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base);",
681
795
  "}",
682
796
  "",
683
797
  "/* Focus: the shipped field has no focus face at all — only the caret moves —",
684
798
  " so this adds one, in the input box's own shadow colour rather than the",
685
- " accent: the hairline takes the drop-shadow tint (espresso in light, black",
686
- " in dark), a 1px halo in the same tone hugs the edge, and the drop shadow",
687
- " deepens. The tray below continues the same hairline, so its three edges",
688
- " follow whenever the card above it holds focus. */",
689
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card]:focus-within {",
690
- " border-color: rgba(20, 20, 19, 0.36);",
691
- " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.13), 0 6px 18px rgba(20, 20, 19, 0.06), 0 2px 6px rgba(20, 20, 19, 0.03);",
799
+ " accent: the hairline takes the drop-shadow tint (espresso in light), a 1px",
800
+ " halo in the same tone hugs the edge, and the drop shadow deepens. Dark sits",
801
+ " on a near-black canvas, where black-on-black carries no cue at all — there",
802
+ " the focus face inverts to a BRIGHT ivory rim and halo, so the field visibly",
803
+ " lights up instead of deepening. The tray below continues the same hairline,",
804
+ " so its three edges follow whenever the card above it holds focus. */",
805
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card]:focus-within {",
806
+ " border-color: rgba(20, 20, 19, 0.18);",
807
+ " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.065), 0 6px 18px rgba(20, 20, 19, 0.03), 0 2px 6px rgba(20, 20, 19, 0.015), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base);",
692
808
  "}",
693
809
  "",
694
- "body[data-dsh-claude-style][data-ds-dark-theme] [data-composer-card]:focus-within {",
695
- " border-color: rgba(0, 0, 0, 0.38);",
696
- " box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 6px 20px rgba(0, 0, 0, 0.27);",
810
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card]:focus-within {",
811
+ " border-color: rgba(250, 249, 245, 0.22);",
812
+ " box-shadow: 0 0 0 1px rgba(250, 249, 245, 0.09), 0 6px 24px rgba(0, 0, 0, 0.22), 0 2px 8px rgba(0, 0, 0, 0.11), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base);",
697
813
  "}",
698
814
  "",
699
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:has([data-composer-card]:focus-within) > [class*=\"heroWorkspaceRow\"] {",
700
- " border-color: rgba(20, 20, 19, 0.36);",
815
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:has([data-composer-card]:focus-within) > [class*=\"heroWorkspaceRow\"] {",
816
+ " border-color: rgba(20, 20, 19, 0.18);",
701
817
  "}",
702
818
  "",
703
- "body[data-dsh-claude-style][data-ds-dark-theme] [class*=\"composerStack\"]:has([data-composer-card]:focus-within) > [class*=\"heroWorkspaceRow\"] {",
704
- " border-color: rgba(0, 0, 0, 0.38);",
819
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [class*=\"composerStack\"]:has([data-composer-card]:focus-within) > [class*=\"heroWorkspaceRow\"] {",
820
+ " border-color: rgba(250, 249, 245, 0.22);",
705
821
  "}",
706
822
  "",
707
823
  "/* The workspace-trigger variant paints its dashed ring through a masked svg",
708
824
  " cut with rx=22; re-cut it so the ring tracks the 18px card. */",
709
- "body[data-dsh-claude-style] [data-composer-card]:after {",
825
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card]:after {",
710
826
  " border-radius: 18px;",
711
827
  " -webkit-mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27%3E%3Crect width=%27100%25%27 height=%27100%25%27 fill=%27none%27 rx=%2718%27 ry=%2718%27 stroke=%27black%27 stroke-width=%272%27 stroke-dasharray=%274 4%27/%3E%3C/svg%3E\");",
712
828
  " mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27%3E%3Crect width=%27100%25%27 height=%27100%25%27 fill=%27none%27 rx=%2718%27 ry=%2718%27 stroke=%27black%27 stroke-width=%272%27 stroke-dasharray=%274 4%27/%3E%3C/svg%3E\");",
@@ -714,21 +830,21 @@ window.__ModuleLoader__.load({
714
830
  "",
715
831
  "/* Commands and attach: 7px corners instead of the shipped full circle, no",
716
832
  " resting fill, and a warm plate on hover. */",
717
- "body[data-dsh-claude-style] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
833
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
718
834
  " border-radius: 7px;",
719
835
  "}",
720
836
  "",
721
837
  "/* Send, and the stop/queue/steer labels that replace it while running: the",
722
838
  " shipped 34px circle becomes a 7px rounded rectangle. */",
723
- "body[data-dsh-claude-style] :is(button[aria-label=\"发送消息\"], button[aria-label=\"Send message\"], button[aria-label=\"排队发送\"], button[aria-label=\"Queue message\"], button[aria-label=\"插话发送\"], button[aria-label=\"Steer message\"], button[aria-label=\"停止生成\"], button[aria-label=\"Stop generating\"]) {",
839
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] :is(button[aria-label=\"发送消息\"], button[aria-label=\"Send message\"], button[aria-label=\"排队发送\"], button[aria-label=\"Queue message\"], button[aria-label=\"插话发送\"], button[aria-label=\"Steer message\"], button[aria-label=\"停止生成\"], button[aria-label=\"Stop generating\"]) {",
724
840
  " border-radius: 7px;",
725
841
  "}",
726
842
  "",
727
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
843
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
728
844
  " background: transparent;",
729
845
  "}",
730
846
  "",
731
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled) {",
847
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled) {",
732
848
  " background: #f6f6f4;",
733
849
  "}",
734
850
  "",
@@ -736,16 +852,16 @@ window.__ModuleLoader__.load({
736
852
  " same 7px corners; its chevron is dropped while the click target and the",
737
853
  " menu it opens stay exactly as shipped. Its shipped hover token is only a",
738
854
  " ~6% tint, so the hover plate matches the composer tool buttons. */",
739
- "body[data-dsh-claude-style] [data-composer-card] [class*=\"trigger\"] {",
855
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"trigger\"] {",
740
856
  " font-size: 14px;",
741
857
  " border-radius: 7px;",
742
858
  "}",
743
859
  "",
744
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card] [class*=\"trigger\"]:hover:not(:disabled) {",
860
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card] [class*=\"trigger\"]:hover:not(:disabled) {",
745
861
  " background: #f6f6f4;",
746
862
  "}",
747
863
  "",
748
- "body[data-dsh-claude-style] [data-composer-card] [class*=\"_chevron\"] {",
864
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"_chevron\"] {",
749
865
  " display: none !important;",
750
866
  "}",
751
867
  "",
@@ -755,23 +871,23 @@ window.__ModuleLoader__.load({
755
871
  " equal-width tray (z-index: 1) attached directly to the bottom of the card,",
756
872
  " with transparent background (inheriting the canvas tone #fcfcfb),",
757
873
  " left/right/bottom border, and 18px rounded bottom corners. */",
758
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) {",
874
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) {",
759
875
  " --dsh-claude-bar-h: 96px;",
760
876
  "}",
761
877
  "",
762
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) *:has([data-composer-card]) {",
878
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) *:has([data-composer-card]) {",
763
879
  " order: 1;",
764
880
  " padding-bottom: 0 !important;",
765
881
  "}",
766
882
  "",
767
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) [data-composer-card] {",
883
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) [data-composer-card] {",
768
884
  " gap: 8px !important;",
769
885
  " padding-bottom: 2px !important;",
770
886
  " min-height: 0 !important;",
771
887
  " height: auto !important;",
772
888
  "}",
773
889
  "",
774
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) > [class*=\"heroWorkspaceRow\"] {",
890
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:has([class*=\"heroWorkspaceRow\"]) > [class*=\"heroWorkspaceRow\"] {",
775
891
  " order: 2;",
776
892
  " position: relative;",
777
893
  " z-index: 1;",
@@ -794,14 +910,14 @@ window.__ModuleLoader__.load({
794
910
  "}",
795
911
  "",
796
912
  "/* Muted typography and 7px corners for footer controls */",
797
- "body[data-dsh-claude-style] [class*=\"heroWorkspaceRow\"] :is(button, [role=\"button\"]) {",
913
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"heroWorkspaceRow\"] :is(button, [role=\"button\"]) {",
798
914
  " font-size: 13px;",
799
915
  " color: var(--dsw-alias-label-secondary);",
800
916
  " border-radius: 7px;",
801
917
  "}",
802
918
  "",
803
919
  "/* Hide chevrons in the footer tray for a clean, minimal Claude Code look */",
804
- "body[data-dsh-claude-style] [class*=\"heroWorkspaceRow\"] :is([class*=\"chevron\"], [class*=\"Chevron\"]) {",
920
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"heroWorkspaceRow\"] :is([class*=\"chevron\"], [class*=\"Chevron\"]) {",
805
921
  " display: none !important;",
806
922
  "}",
807
923
  "",
@@ -813,7 +929,7 @@ window.__ModuleLoader__.load({
813
929
  " border-box keeps the outer 34px so the row does not shift. The stop/queue/",
814
930
  " steer labels are untouched, so a running turn keeps its control even with an",
815
931
  " empty draft. */",
816
- "body[data-dsh-claude-style] [data-composer-card]:has([data-composer-placeholder]) :is(button[aria-label=\"发送消息\"], button[aria-label=\"Send message\"]) {",
932
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card]:not([data-has-attachments=\"true\"]):has([data-composer-placeholder]) :is(button[aria-label=\"发送消息\"], button[aria-label=\"Send message\"]) {",
817
933
  " box-sizing: border-box;",
818
934
  " background: transparent;",
819
935
  " color: var(--dsw-alias-label-caption);",
@@ -826,10 +942,10 @@ window.__ModuleLoader__.load({
826
942
  "/* In an active conversation, compress composer to a single-line input card,",
827
943
  " render send button as an enter symbol ↵ inside the card on the right,",
828
944
  " and display toolbar controls directly underneath on the canvas. */",
829
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"],",
830
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"]:focus-within,",
831
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card],",
832
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within {",
945
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"],",
946
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"]:focus-within,",
947
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card],",
948
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within {",
833
949
  " background: transparent !important;",
834
950
  " border: none !important;",
835
951
  " box-shadow: none !important;",
@@ -853,61 +969,120 @@ window.__ModuleLoader__.load({
853
969
  " composer seat near the TOP of the scroll content — sticky bottom:0",
854
970
  " cannot pull an element down past its normal position, so the composer",
855
971
  " appeared mid-scroll and never followed message growth. */",
856
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) {",
972
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) {",
857
973
  " flex: 0 0 auto !important;",
858
974
  " overflow: visible !important;",
859
975
  " height: auto !important;",
860
976
  " max-height: none !important;",
861
977
  "}",
862
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"]:not([data-has-attachments=\"true\"]) [class*=\"rail\"]:not([class*=\"trailing\"]),",
863
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:not([data-has-attachments=\"true\"]) [class*=\"rail\"]:not([class*=\"trailing\"]) {",
978
+ "/* Message body clearance: 40px placeholder space at the end of the",
979
+ " conversation view so the composer's upward shadow does not obscure",
980
+ " the action buttons (copy, retry, etc.) on the last turn. */",
981
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"viewArea\"] {",
982
+ " padding-bottom: 40px !important;",
983
+ "}",
984
+ "/* The composer is a chat-view affordance. The host keeps the seat mounted on",
985
+ " every conversation tab (轨迹 / 上下文 even reserve room for it), but it",
986
+ " should only show on the chat tab — drop the whole bottom area otherwise.",
987
+ " Hiding the seat also zeroes the host's --dsh-composer-height, so the",
988
+ " trajectory ledger's bottom clearance collapses with it. */",
989
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-dsh-claude-composer-hidden] [data-composer-seat] {",
864
990
  " display: none !important;",
865
991
  "}",
866
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]),",
867
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) {",
992
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"]:not([data-has-attachments=\"true\"]) [class*=\"rail\"]:not([class*=\"trailing\"]),",
993
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:not([data-has-attachments=\"true\"]) [class*=\"rail\"]:not([class*=\"trailing\"]) {",
994
+ " display: none !important;",
995
+ "}",
996
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]),",
997
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) {",
868
998
  " background: var(--dsw-specific-input-major, #ffffff) !important;",
869
999
  " border: 1px solid var(--dsw-alias-border-l1) !important;",
870
1000
  " border-bottom: none !important;",
871
1001
  " border-radius: 14px 14px 0 0 !important;",
872
- " padding: 8px 12px 2px 12px !important;",
1002
+ " padding: 12px 14px 10px 14px !important;",
873
1003
  " margin: 0 !important;",
874
1004
  " width: 100% !important;",
875
1005
  " max-width: 100% !important;",
876
1006
  " box-sizing: border-box !important;",
877
- " box-shadow: 0 1px 3px rgba(20, 20, 19, 0.03) !important;",
1007
+ " min-height: 162px !important;",
1008
+ " height: auto !important;",
1009
+ " overflow: visible !important;",
1010
+ " box-shadow: 0 1px 3px rgba(20, 20, 19, 0.03), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1011
+ " position: relative !important;",
1012
+ " z-index: 4 !important;",
878
1013
  " transition: border-color 0.12s ease, box-shadow 0.12s ease !important;",
879
1014
  "}",
880
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]),",
881
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) {",
1015
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]),",
1016
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) {",
882
1017
  " background: #ffffff !important;",
883
1018
  " border-color: #e8e6dc !important;",
884
1019
  "}",
885
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]),",
886
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]) {",
887
- " border-color: rgba(20, 20, 19, 0.36) !important;",
888
- " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.13), 0 4px 12px rgba(20, 20, 19, 0.05) !important;",
1020
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]),",
1021
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]) {",
1022
+ " border-color: rgba(20, 20, 19, 0.18) !important;",
1023
+ " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.065), 0 4px 12px rgba(20, 20, 19, 0.025), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
889
1024
  "}",
890
- "body[data-dsh-claude-style][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]),",
891
- "body[data-dsh-claude-style][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]) {",
892
- " border-color: rgba(0, 0, 0, 0.38) !important;",
893
- " box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 4px 14px rgba(0, 0, 0, 0.27) !important;",
1025
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]),",
1026
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [class*=\"rail\"]:not([class*=\"trailing\"]) {",
1027
+ " border-color: rgba(250, 249, 245, 0.22) !important;",
1028
+ " box-shadow: 0 0 0 1px rgba(250, 249, 245, 0.09), 0 4px 16px rgba(0, 0, 0, 0.20), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
894
1029
  "}",
895
1030
  "/* The attachment rail nests two levels: ComposerAttachments' outer rail wraps",
896
1031
  " AttachmentRail's scrolling inner rail, and BOTH substring-match",
897
1032
  " `[class*=\"rail\"]`, so the block above would draw the card frame twice —",
898
1033
  " one box inside the other. Only the outer shell carries the frame; the",
899
1034
  " inner scrolling rail stays frameless. */",
900
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) [class*=\"rail\"]:not([class*=\"trailing\"]),",
901
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) [class*=\"rail\"]:not([class*=\"trailing\"]) {",
1035
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) [class*=\"rail\"]:not([class*=\"trailing\"]),",
1036
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [class*=\"rail\"]:not([class*=\"trailing\"]) [class*=\"rail\"]:not([class*=\"trailing\"]) {",
902
1037
  " background: transparent !important;",
903
1038
  " border: none !important;",
904
1039
  " box-shadow: none !important;",
905
1040
  " border-radius: 0 !important;",
906
1041
  " padding: 0 !important;",
907
1042
  " margin: 0 !important;",
1043
+ " min-height: 140px !important;",
1044
+ " height: auto !important;",
1045
+ " display: flex !important;",
1046
+ " align-items: center !important;",
1047
+ " gap: 10px !important;",
1048
+ " overflow-x: auto !important;",
1049
+ " overflow-y: hidden !important;",
1050
+ "}",
1051
+ "/* Attachment thumbnail card: enlarged by 75% (~140px), matching non-focus border without shadow */",
1052
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"rail\"]:not([class*=\"trailing\"]) :is(._54WpYG_imageItem, [class*=\"imageItem\"], [class*=\"thumbnail\"], [class*=\"FileCard\"], [class*=\"item\"]:has(img), [class*=\"card\"]:has(img), [class*=\"attachment\"]:has(img)) {",
1053
+ " width: 140px !important;",
1054
+ " height: 140px !important;",
1055
+ " min-width: 140px !important;",
1056
+ " min-height: 140px !important;",
1057
+ " max-width: 140px !important;",
1058
+ " max-height: 140px !important;",
1059
+ " border-radius: 12px !important;",
1060
+ " border: 1px solid var(--dsw-alias-border-l1) !important;",
1061
+ " box-shadow: none !important;",
1062
+ " overflow: hidden !important;",
1063
+ " position: relative !important;",
1064
+ " z-index: 5 !important;",
1065
+ " flex: 0 0 140px !important;",
1066
+ " box-sizing: border-box !important;",
1067
+ "}",
1068
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card] [class*=\"rail\"]:not([class*=\"trailing\"]) :is(._54WpYG_imageItem, [class*=\"imageItem\"], [class*=\"thumbnail\"], [class*=\"FileCard\"], [class*=\"item\"]:has(img), [class*=\"card\"]:has(img), [class*=\"attachment\"]:has(img)) {",
1069
+ " border-color: #e8e6dc !important;",
908
1070
  "}",
909
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll],",
910
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] {",
1071
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"rail\"]:not([class*=\"trailing\"]) :is(._54WpYG_imageItem, [class*=\"imageItem\"], [class*=\"thumbnail\"], [class*=\"FileCard\"], [class*=\"item\"]:has(img), [class*=\"card\"]:has(img), [class*=\"attachment\"]:has(img)) :is(img, canvas, [class*=\"preview\"], [class*=\"image\"]) {",
1072
+ " width: 100% !important;",
1073
+ " height: 100% !important;",
1074
+ " max-width: 100% !important;",
1075
+ " max-height: 100% !important;",
1076
+ " object-fit: cover !important;",
1077
+ " display: block !important;",
1078
+ " border-radius: 11px !important;",
1079
+ "}",
1080
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"rail\"]:not([class*=\"trailing\"]) :is(._54WpYG_imageItem, [class*=\"imageItem\"], [class*=\"thumbnail\"], [class*=\"FileCard\"], [class*=\"item\"]:has(img), [class*=\"card\"]:has(img), [class*=\"attachment\"]:has(img)) :is(button, [role=\"button\"], [class*=\"close\"], [class*=\"delete\"], [class*=\"remove\"], [class*=\"badge\"], [class*=\"tag\"]) {",
1081
+ " position: absolute !important;",
1082
+ " z-index: 6 !important;",
1083
+ "}",
1084
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll],",
1085
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] {",
911
1086
  " background: var(--dsw-specific-input-major, #ffffff) !important;",
912
1087
  " border: 1px solid var(--dsw-alias-border-l1) !important;",
913
1088
  " border-radius: 14px !important;",
@@ -923,34 +1098,53 @@ window.__ModuleLoader__.load({
923
1098
  " padding: 7px 36px 7px 14px !important;",
924
1099
  " margin: 0 !important;",
925
1100
  " position: relative !important;",
1101
+ " z-index: 2 !important;",
926
1102
  " cursor: text !important;",
1103
+ " box-shadow: 0 1px 3px rgba(20, 20, 19, 0.03), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
927
1104
  " transition: border-color 0.12s ease, box-shadow 0.12s ease !important;",
928
1105
  "}",
929
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [data-input-scroll],",
930
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [data-input-scroll] {",
1106
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] [data-input-scroll],",
1107
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] [data-input-scroll] {",
931
1108
  " border-top: none !important;",
932
1109
  " border-radius: 0 0 14px 14px !important;",
1110
+ " /* Seamless join with attachment rail above: 1px negative margin prevents subpixel seam without clipping thumbnails */",
1111
+ " margin-top: -1px !important;",
933
1112
  " min-height: 32px !important;",
934
- " padding: 2px 36px 6px 14px !important;",
1113
+ " padding: 8px 36px 6px 14px !important;",
935
1114
  "}",
936
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll],",
937
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] {",
1115
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll],",
1116
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] {",
938
1117
  " background: #ffffff !important;",
939
1118
  " border-color: #e8e6dc !important;",
940
- " box-shadow: 0 1px 3px rgba(20, 20, 19, 0.03) !important;",
941
- "}",
942
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"]:focus-within [data-input-scroll],",
943
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [data-input-scroll] {",
944
- " border-color: rgba(20, 20, 19, 0.36) !important;",
945
- " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.13), 0 4px 12px rgba(20, 20, 19, 0.05) !important;",
946
- "}",
947
- "body[data-dsh-claude-style][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"]:focus-within [data-input-scroll],",
948
- "body[data-dsh-claude-style][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [data-input-scroll] {",
949
- " border-color: rgba(0, 0, 0, 0.38) !important;",
950
- " box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 4px 14px rgba(0, 0, 0, 0.27) !important;",
951
- "}",
952
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll] [class*=\"grow\"],",
953
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] [class*=\"grow\"] {",
1119
+ " box-shadow: 0 1px 3px rgba(20, 20, 19, 0.03), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1120
+ "}",
1121
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll],",
1122
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] {",
1123
+ " box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1124
+ "}",
1125
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"]:focus-within [data-input-scroll],",
1126
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [data-input-scroll] {",
1127
+ " border-color: rgba(20, 20, 19, 0.18) !important;",
1128
+ " box-shadow: 0 0 0 1px rgba(20, 20, 19, 0.065), 0 4px 12px rgba(20, 20, 19, 0.025), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1129
+ "}",
1130
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"]:focus-within [data-input-scroll],",
1131
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:focus-within [data-input-scroll] {",
1132
+ " border-color: rgba(250, 249, 245, 0.22) !important;",
1133
+ " box-shadow: 0 0 0 1px rgba(250, 249, 245, 0.09), 0 4px 16px rgba(0, 0, 0, 0.20), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1134
+ "}",
1135
+ "/* With attachments the rail already carries the card's focus ring, so the",
1136
+ " input keeps only the deepened drop — its own 1px ring would paint a second",
1137
+ " line across the seam between the thumbnails and the text. */",
1138
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"]:focus-within [data-input-scroll],",
1139
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"]:focus-within [data-input-scroll] {",
1140
+ " box-shadow: 0 4px 12px rgba(20, 20, 19, 0.025), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1141
+ "}",
1142
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"]:focus-within [data-input-scroll],",
1143
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active][data-ds-dark-theme] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"]:focus-within [data-input-scroll] {",
1144
+ " box-shadow: 0 4px 16px rgba(0, 0, 0, 0.20), 0 0 0 6px var(--dsw-alias-bg-base), 0 0 16px 10px var(--dsw-alias-bg-base), 0 0 48px 16px var(--dsw-alias-bg-base) !important;",
1145
+ "}",
1146
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [data-input-scroll] [class*=\"grow\"],",
1147
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-input-scroll] [class*=\"grow\"] {",
954
1148
  " width: 100% !important;",
955
1149
  " max-width: 100% !important;",
956
1150
  " min-height: 24px !important;",
@@ -959,8 +1153,8 @@ window.__ModuleLoader__.load({
959
1153
  " box-sizing: border-box !important;",
960
1154
  " overflow-x: hidden !important;",
961
1155
  "}",
962
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [data-composer-input],",
963
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-composer-input] {",
1156
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [data-composer-input],",
1157
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-composer-input] {",
964
1158
  " min-height: 24px !important;",
965
1159
  " height: auto !important;",
966
1160
  " line-height: 24px !important;",
@@ -976,8 +1170,8 @@ window.__ModuleLoader__.load({
976
1170
  " overflow-wrap: anywhere !important;",
977
1171
  " overflow-x: hidden !important;",
978
1172
  "}",
979
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [data-composer-placeholder],",
980
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-composer-placeholder] {",
1173
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [data-composer-placeholder],",
1174
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [data-composer-placeholder] {",
981
1175
  " line-height: 24px !important;",
982
1176
  " height: 24px !important;",
983
1177
  " position: absolute !important;",
@@ -995,8 +1189,8 @@ window.__ModuleLoader__.load({
995
1189
  " user-select: none !important;",
996
1190
  "}",
997
1191
  "/* Pinned send button inside input box */",
998
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]),",
999
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]) {",
1192
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]),",
1193
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]) {",
1000
1194
  " position: absolute !important;",
1001
1195
  " bottom: 40px !important;",
1002
1196
  " right: 8px !important;",
@@ -1018,11 +1212,11 @@ window.__ModuleLoader__.load({
1018
1212
  " cursor: pointer !important;",
1019
1213
  " transition: color 0.12s ease, background-color 0.12s ease !important;",
1020
1214
  "}",
1021
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]) :is(svg, [class*=\"chevron\"], span) {",
1215
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"]) :is(svg, [class*=\"chevron\"], span) {",
1022
1216
  " display: none !important;",
1023
1217
  "}",
1024
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"])::after,",
1025
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"])::after {",
1218
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"])::after,",
1219
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"], button[aria-label*=\"排队\"], button[aria-label*=\"Queue\"], button[aria-label*=\"插话\"], button[aria-label*=\"Steer\"], [class*=\"sendBtn\"], [class*=\"sendButton\"])::after {",
1026
1220
  " content: \"↵\" !important;",
1027
1221
  " font-family: var(--dsw-font-code, monospace) !important;",
1028
1222
  " font-size: 16px !important;",
@@ -1030,18 +1224,20 @@ window.__ModuleLoader__.load({
1030
1224
  " line-height: 1 !important;",
1031
1225
  " color: currentColor !important;",
1032
1226
  "}",
1033
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]):not(:disabled):hover,",
1034
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]):not(:disabled):hover {",
1227
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]):not(:disabled):hover,",
1228
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]):not(:disabled):hover {",
1035
1229
  " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.08)) !important;",
1036
1230
  " color: var(--dsw-alias-label-primary) !important;",
1037
1231
  "}",
1038
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"]:not(:has([data-composer-placeholder])) :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]),",
1039
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:not(:has([data-composer-placeholder])) :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]) {",
1232
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"]:not(:has([data-composer-placeholder])) :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]),",
1233
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"][data-has-attachments=\"true\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]),",
1234
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card]:not(:has([data-composer-placeholder])) :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]),",
1235
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card][data-has-attachments=\"true\"] :is(button[aria-label^=\"发送\"], button[aria-label^=\"Send\"], button[aria-label*=\"发送\"], button[aria-label*=\"Send\"]) {",
1040
1236
  " color: var(--dsw-alias-brand-primary, #d97757) !important;",
1041
1237
  "}",
1042
1238
  "/* Pinned stop button inside input box */",
1043
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]),",
1044
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) {",
1239
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]),",
1240
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) {",
1045
1241
  " position: absolute !important;",
1046
1242
  " bottom: 40px !important;",
1047
1243
  " right: 8px !important;",
@@ -1060,22 +1256,22 @@ window.__ModuleLoader__.load({
1060
1256
  " color: var(--dsw-alias-brand-primary, #d97757) !important;",
1061
1257
  " border: none !important;",
1062
1258
  "}",
1063
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) svg,",
1064
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) svg {",
1259
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) svg,",
1260
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"]) svg {",
1065
1261
  " display: block !important;",
1066
1262
  " width: 12px !important;",
1067
1263
  " height: 12px !important;",
1068
1264
  "}",
1069
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"])::after,",
1070
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"])::after {",
1265
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"])::after,",
1266
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label*=\"停止\"], button[aria-label*=\"Stop\"])::after {",
1071
1267
  " display: none !important;",
1072
1268
  "}",
1073
1269
  "/* Toolbar row below input card. `[class*=\"_row\"]` on purpose: a bare",
1074
1270
  " `[class*=\"row\"]` substring-matches the shipped `.p_FcLG_grow` input",
1075
1271
  " wrapper (\"grow\" contains \"row\"), and the fixed 28px height + flex",
1076
1272
  " display here would pin the composer field to one line forever. */",
1077
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_row\"],",
1078
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_row\"] {",
1273
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_row\"],",
1274
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_row\"] {",
1079
1275
  " display: flex !important;",
1080
1276
  " flex-wrap: nowrap !important;",
1081
1277
  " justify-content: space-between !important;",
@@ -1091,6 +1287,8 @@ window.__ModuleLoader__.load({
1091
1287
  " max-width: 100% !important;",
1092
1288
  " box-sizing: border-box !important;",
1093
1289
  " overflow: visible !important;",
1290
+ " position: relative !important;",
1291
+ " z-index: 3 !important;",
1094
1292
  "}",
1095
1293
  "/* The context-occupancy meter renders its click-open panel INSIDE the inline",
1096
1294
  " composer card, and its legend classes (`…_rows` / `…_row`) substring-match",
@@ -1098,8 +1296,8 @@ window.__ModuleLoader__.load({
1098
1296
  " list into one 28px flex line and wrapped every label/value. Restore the",
1099
1297
  " shipped legend layout: the list stacks vertically, each row keeps its",
1100
1298
  " natural height and space-between distribution. */",
1101
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_rows\"],",
1102
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_rows\"] {",
1299
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_rows\"],",
1300
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_rows\"] {",
1103
1301
  " display: block !important;",
1104
1302
  " height: auto !important;",
1105
1303
  " min-height: 0 !important;",
@@ -1107,8 +1305,8 @@ window.__ModuleLoader__.load({
1107
1305
  " max-width: none !important;",
1108
1306
  " padding: 0 !important;",
1109
1307
  "}",
1110
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_rows\"] [class*=\"_row\"],",
1111
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_rows\"] [class*=\"_row\"] {",
1308
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_rows\"] [class*=\"_row\"],",
1309
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_rows\"] [class*=\"_row\"] {",
1112
1310
  " display: flex !important;",
1113
1311
  " height: auto !important;",
1114
1312
  " min-height: 0 !important;",
@@ -1117,23 +1315,23 @@ window.__ModuleLoader__.load({
1117
1315
  " padding: 2px 0 !important;",
1118
1316
  " margin: 0 !important;",
1119
1317
  "}",
1120
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"tools\"],",
1121
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"tools\"] {",
1318
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"tools\"],",
1319
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"tools\"] {",
1122
1320
  " display: flex !important;",
1123
1321
  " align-items: center !important;",
1124
1322
  " gap: 8px !important;",
1125
1323
  " flex: 0 0 auto !important;",
1126
1324
  " overflow: visible !important;",
1127
1325
  "}",
1128
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"modes\"],",
1129
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"modes\"] {",
1326
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"modes\"],",
1327
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"modes\"] {",
1130
1328
  " order: 1 !important;",
1131
1329
  " display: inline-flex !important;",
1132
1330
  " align-items: center !important;",
1133
1331
  " overflow: visible !important;",
1134
1332
  "}",
1135
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"]),",
1136
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"]) {",
1333
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"]),",
1334
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"]) {",
1137
1335
  " order: 2 !important;",
1138
1336
  " width: 24px !important;",
1139
1337
  " height: 24px !important;",
@@ -1144,8 +1342,8 @@ window.__ModuleLoader__.load({
1144
1342
  " align-items: center !important;",
1145
1343
  " justify-content: center !important;",
1146
1344
  "}",
1147
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]),",
1148
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
1345
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]),",
1346
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]) {",
1149
1347
  " order: 3 !important;",
1150
1348
  " width: 24px !important;",
1151
1349
  " height: 24px !important;",
@@ -1156,13 +1354,13 @@ window.__ModuleLoader__.load({
1156
1354
  " align-items: center !important;",
1157
1355
  " justify-content: center !important;",
1158
1356
  "}",
1159
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled),",
1160
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled) {",
1357
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled),",
1358
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] :is(button[aria-label=\"指令\"], button[aria-label=\"Commands\"], button[aria-label=\"添加附件\"], button[aria-label=\"Add attachment\"]):hover:not(:disabled) {",
1161
1359
  " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.08)) !important;",
1162
1360
  " color: var(--dsw-alias-label-primary) !important;",
1163
1361
  "}",
1164
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"],",
1165
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"trailing\"] {",
1362
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"],",
1363
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"trailing\"] {",
1166
1364
  " display: flex !important;",
1167
1365
  " align-items: center !important;",
1168
1366
  " gap: 8px !important;",
@@ -1170,8 +1368,8 @@ window.__ModuleLoader__.load({
1170
1368
  " flex: 0 0 auto !important;",
1171
1369
  "}",
1172
1370
  "/* Model trigger in trailing */",
1173
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] > :first-child,",
1174
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] :is([class*=\"trigger\" i], [class*=\"model\" i], [class*=\"Model\"]) {",
1371
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] > :first-child,",
1372
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] :is([class*=\"trigger\" i], [class*=\"model\" i], [class*=\"Model\"]) {",
1175
1373
  " display: inline-flex !important;",
1176
1374
  " align-items: center !important;",
1177
1375
  " font-size: 13px !important;",
@@ -1181,14 +1379,69 @@ window.__ModuleLoader__.load({
1181
1379
  " visibility: visible !important;",
1182
1380
  " opacity: 1 !important;",
1183
1381
  "}",
1184
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] > :first-child:hover:not(:disabled),",
1185
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] :is([class*=\"trigger\" i], [class*=\"model\" i], [class*=\"Model\"]):hover:not(:disabled) {",
1382
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] > :first-child:hover:not(:disabled),",
1383
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active]:not([data-ds-dark-theme]) [data-composer-card][data-composer-variant=\"inline\"] [class*=\"trailing\"] :is([class*=\"trigger\" i], [class*=\"model\" i], [class*=\"Model\"]):hover:not(:disabled) {",
1186
1384
  " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.06)) !important;",
1187
1385
  " color: var(--dsw-alias-label-primary) !important;",
1188
1386
  "}",
1189
- "/* Separate Token stats row below the composer card */",
1190
- "body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] ~ [data-composer-stats],",
1191
- "body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-stats] {",
1387
+ "/* The skin's own model trigger replaces the host's model seat (the host's",
1388
+ " root is marked and hidden by syncModelControl). One button, one hover",
1389
+ " background — the shipped seat stacks an icon + label + effort + chevron,",
1390
+ " each with its own surface. */",
1391
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-dsh-claude-model-host] {",
1392
+ " display: none !important;",
1393
+ "}",
1394
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn {",
1395
+ " display: inline-flex !important;",
1396
+ " align-items: center !important;",
1397
+ " gap: 2px !important;",
1398
+ " height: 28px !important;",
1399
+ " max-width: 280px !important;",
1400
+ " padding: 0 6px 0 8px !important;",
1401
+ " border: none !important;",
1402
+ " border-radius: 7px !important;",
1403
+ " background: transparent !important;",
1404
+ " color: var(--dsw-alias-label-secondary) !important;",
1405
+ " font-size: 13px !important;",
1406
+ " font-weight: 500 !important;",
1407
+ " line-height: 20px !important;",
1408
+ " cursor: pointer !important;",
1409
+ " box-sizing: border-box !important;",
1410
+ " min-width: 0 !important;",
1411
+ "}",
1412
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn-label.dsh-claude-model-btn-loading {",
1413
+ " color: var(--dsw-alias-label-caption, #a6a094) !important;",
1414
+ "}",
1415
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn:hover {",
1416
+ " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.08)) !important;",
1417
+ " color: var(--dsw-alias-label-primary) !important;",
1418
+ "}",
1419
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn-label {",
1420
+ " text-overflow: ellipsis !important;",
1421
+ " white-space: nowrap !important;",
1422
+ " min-width: 0 !important;",
1423
+ " overflow: hidden !important;",
1424
+ "}",
1425
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn-effort {",
1426
+ " flex: none !important;",
1427
+ " color: var(--dsw-alias-label-caption, #a6a094) !important;",
1428
+ " font-weight: 400 !important;",
1429
+ "}",
1430
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"trailing\"] .dsh-claude-model-btn-chevron {",
1431
+ " flex: none !important;",
1432
+ " display: inline-flex !important;",
1433
+ " align-items: center !important;",
1434
+ " color: var(--dsw-alias-label-caption, #a6a094) !important;",
1435
+ "}",
1436
+ "/* Token stats pills — merged into the toolbar row (one line with the",
1437
+ " controls). The base rule below is the fallback for the host's own",
1438
+ " position (a full-width line under the card); once mergeStatsIntoRow()",
1439
+ " has moved the pills into the row, the override after it resets every",
1440
+ " geometry property the host's full-width line depends on. */",
1441
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] ~ [data-composer-stats],",
1442
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-stats] {",
1443
+ " position: relative !important;",
1444
+ " z-index: 3 !important;",
1192
1445
  " display: flex !important;",
1193
1446
  " align-items: center !important;",
1194
1447
  " justify-content: center !important;",
@@ -1206,9 +1459,42 @@ window.__ModuleLoader__.load({
1206
1459
  " white-space: nowrap !important;",
1207
1460
  " text-overflow: ellipsis !important;",
1208
1461
  "}",
1462
+ "/* In-row: the pills become an inline, shrinkable flex item between the left",
1463
+ " tool cluster and the trailing model/status group (the row's space-between",
1464
+ " centers them). Width, padding and margin come from the host's full-width",
1465
+ " line, so all of them are reset; the pills keep their own hover/click. */",
1466
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] [class*=\"_row\"] [data-composer-stats],",
1467
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-card] [class*=\"_row\"] [data-composer-stats] {",
1468
+ " position: relative !important;",
1469
+ " z-index: 3 !important;",
1470
+ " width: auto !important;",
1471
+ " max-width: none !important;",
1472
+ " margin: 0 8px !important;",
1473
+ " padding: 0 !important;",
1474
+ " height: auto !important;",
1475
+ " line-height: 20px !important;",
1476
+ " justify-content: flex-start !important;",
1477
+ " flex: 0 1 auto !important;",
1478
+ " min-width: 0 !important;",
1479
+ "}",
1480
+ "/* The stats pills are on-demand: hidden unless the chat window (the composer)",
1481
+ " is hovered, so the toolbar stays clean. Space is preserved — no reflow when",
1482
+ " they fade in — and because the pills live inside the card, hovering them",
1483
+ " keeps them visible long enough to click. */",
1484
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card] [class*=\"_row\"] [data-composer-stats] {",
1485
+ " opacity: 0 !important;",
1486
+ " visibility: hidden !important;",
1487
+ " pointer-events: none !important;",
1488
+ " transition: opacity 0.15s ease, visibility 0.15s ease !important;",
1489
+ "}",
1490
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card]:hover [class*=\"_row\"] [data-composer-stats] {",
1491
+ " opacity: 1 !important;",
1492
+ " visibility: visible !important;",
1493
+ " pointer-events: auto !important;",
1494
+ "}",
1209
1495
  "@media (max-width: 820px) {",
1210
- " body[data-dsh-claude-style] [data-composer-card][data-composer-variant=\"inline\"] ~ [data-composer-stats],",
1211
- " body[data-dsh-claude-style] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-stats] {",
1496
+ " body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-composer-card][data-composer-variant=\"inline\"] ~ [data-composer-stats],",
1497
+ " body[data-dsh-claude-style][data-dsh-claude-composer-active] [class*=\"composerStack\"]:not(:has([class*=\"heroWorkspaceRow\"])) [data-composer-stats] {",
1212
1498
  " display: none !important;",
1213
1499
  " }",
1214
1500
  "}",
@@ -1224,11 +1510,11 @@ window.__ModuleLoader__.load({
1224
1510
  " brandName box, and each wordmark takes its natural width from that height",
1225
1511
  " via the artwork aspect ratios (Claude 4.214:1, ANTHROPIC ~8.94:1). The",
1226
1512
  " wordmark keeps a max-width so a longer brand can never clip the row. */",
1227
- "body[data-dsh-claude-style] :is([class*=\"brandMark\"], [class*=\"railMark\"]) > * {",
1513
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) :is([class*=\"brandMark\"], [class*=\"railMark\"]) > * {",
1228
1514
  " display: none !important;",
1229
1515
  "}",
1230
1516
  "",
1231
- "body[data-dsh-claude-style] :is([class*=\"brandMark\"], [class*=\"railMark\"])::before {",
1517
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) :is([class*=\"brandMark\"], [class*=\"railMark\"])::before {",
1232
1518
  " content: \"\";",
1233
1519
  " display: block;",
1234
1520
  " flex: none;",
@@ -1239,18 +1525,18 @@ window.__ModuleLoader__.load({
1239
1525
  "}",
1240
1526
  "",
1241
1527
  "/* Claude (default): starburst mark + the Claude wordmark. */",
1242
- "body[data-dsh-claude-style]:not([data-dsh-claude-brand=\"anthropic\"]) :is([class*=\"brandMark\"], [class*=\"railMark\"])::before {",
1528
+ "body[data-dsh-claude-style][data-dsh-claude-brand=\"claude\"] :is([class*=\"brandMark\"], [class*=\"railMark\"])::before {",
1243
1529
  " width: 18px;",
1244
1530
  " height: 18px;",
1245
1531
  " -webkit-mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%20148.09%20148.18'%3E%3Cg%20transform%3D'translate(-75.96%2C-223.53)'%3E%3Cpath%20d%3D'm%20105.01%2C322.07%2029.14%2C-16.35%200.49%2C-1.42%20-0.49%2C-0.79%20h%20-1.42%20l%20-4.87%2C-0.3%20-16.65%2C-0.45%20-14.44%2C-0.6%20-13.99%2C-0.75%20-3.52%2C-0.75%20-3.3%2C-4.35%200.34%2C-2.17%202.96%2C-1.99%204.24%2C0.37%209.37%2C0.64%2014.06%2C0.97%2010.2%2C0.6%2015.11%2C1.57%20h%202.4%20l%200.34%2C-0.97%20-0.82%2C-0.6%20-0.64%2C-0.6%20-14.55%2C-9.86%20-15.75%2C-10.42%20-8.25%2C-6%20-4.46%2C-3.04%20-2.25%2C-2.85%20-0.97%2C-6.22%204.05%2C-4.46%205.44%2C0.37%201.39%2C0.37%205.51%2C4.24%2011.77%2C9.11%2015.37%2C11.32%202.25%2C1.87%200.9%2C-0.64%200.11%2C-0.45%20-1.01%2C-1.69%20-8.36%2C-15.11%20-8.92%2C-15.37%20-3.97%2C-6.37%20-1.05%2C-3.82%20c%20-0.37%2C-1.57%20-0.64%2C-2.89%20-0.64%2C-4.5%20l%204.61%2C-6.26%202.55%2C-0.82%206.15%2C0.82%202.59%2C2.25%203.82%2C8.74%206.19%2C13.76%209.6%2C18.71%202.81%2C5.55%201.5%2C5.14%200.56%2C1.57%20h%200.97%20v%20-0.9%20l%200.79%2C-10.54%201.46%2C-12.94%201.42%2C-16.65%200.49%2C-4.69%202.32%2C-5.62%204.61%2C-3.04%203.6%2C1.72%202.96%2C4.24%20-0.41%2C2.74%20-1.76%2C11.44%20-3.45%2C17.92%20-2.25%2C12%20h%201.31%20l%201.5%2C-1.5%206.07%2C-8.06%2010.2%2C-12.75%204.5%2C-5.06%205.25%2C-5.59%203.37%2C-2.66%20h%206.37%20l%204.69%2C6.97%20-2.1%2C7.2%20-6.56%2C8.32%20-5.44%2C7.05%20-7.8%2C10.5%20-4.87%2C8.4%200.45%2C0.67%201.16%2C-0.11%2017.62%2C-3.75%209.52%2C-1.72%2011.36%2C-1.95%205.14%2C2.4%200.56%2C2.44%20-2.02%2C4.99%20-12.15%2C3%20-14.25%2C2.85%20-21.22%2C5.02%20-0.26%2C0.19%200.3%2C0.37%209.56%2C0.9%204.09%2C0.22%20h%2010.01%20l%2018.64%2C1.39%204.87%2C3.22%202.92%2C3.94%20-0.49%2C3%20-7.5%2C3.82%20-10.12%2C-2.4%20-23.62%2C-5.62%20-8.1%2C-2.02%20h%20-1.12%20v%200.67%20l%206.75%2C6.6%2012.37%2C11.17%2015.49%2C14.4%200.79%2C3.56%20-1.99%2C2.81%20-2.1%2C-0.3%20-13.61%2C-10.24%20-5.25%2C-4.61%20-11.89%2C-10.01%20h%20-0.79%20v%201.05%20l%202.74%2C4.01%2014.47%2C21.75%200.75%2C6.67%20-1.05%2C2.17%20-3.75%2C1.31%20-4.12%2C-0.75%20-8.47%2C-11.89%20-8.74%2C-13.39%20-7.05%2C-12%20-0.86%2C0.49%20-4.16%2C44.81%20-1.95%2C2.29%20-4.5%2C1.72%20-3.75%2C-2.85%20-1.99%2C-4.61%201.99%2C-9.11%202.4%2C-11.89%201.95%2C-9.45%201.76%2C-11.74%201.05%2C-3.9%20-0.07%2C-0.26%20-0.86%2C0.11%20-8.85%2C12.15%20-13.46%2C18.19%20-10.65%2C11.4%20-2.55%2C1.01%20-4.42%2C-2.29%200.41%2C-4.09%202.47%2C-3.64%2014.74%2C-18.75%208.89%2C-11.62%205.74%2C-6.71%20-0.04%2C-0.97%20h%20-0.34%20l%20-39.15%2C25.42%20-6.97%2C0.9%20-3%2C-2.81%200.37%2C-4.61%201.42%2C-1.5%2011.77%2C-8.1%20-0.04%2C0.04%20z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1246
1532
  " mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%20148.09%20148.18'%3E%3Cg%20transform%3D'translate(-75.96%2C-223.53)'%3E%3Cpath%20d%3D'm%20105.01%2C322.07%2029.14%2C-16.35%200.49%2C-1.42%20-0.49%2C-0.79%20h%20-1.42%20l%20-4.87%2C-0.3%20-16.65%2C-0.45%20-14.44%2C-0.6%20-13.99%2C-0.75%20-3.52%2C-0.75%20-3.3%2C-4.35%200.34%2C-2.17%202.96%2C-1.99%204.24%2C0.37%209.37%2C0.64%2014.06%2C0.97%2010.2%2C0.6%2015.11%2C1.57%20h%202.4%20l%200.34%2C-0.97%20-0.82%2C-0.6%20-0.64%2C-0.6%20-14.55%2C-9.86%20-15.75%2C-10.42%20-8.25%2C-6%20-4.46%2C-3.04%20-2.25%2C-2.85%20-0.97%2C-6.22%204.05%2C-4.46%205.44%2C0.37%201.39%2C0.37%205.51%2C4.24%2011.77%2C9.11%2015.37%2C11.32%202.25%2C1.87%200.9%2C-0.64%200.11%2C-0.45%20-1.01%2C-1.69%20-8.36%2C-15.11%20-8.92%2C-15.37%20-3.97%2C-6.37%20-1.05%2C-3.82%20c%20-0.37%2C-1.57%20-0.64%2C-2.89%20-0.64%2C-4.5%20l%204.61%2C-6.26%202.55%2C-0.82%206.15%2C0.82%202.59%2C2.25%203.82%2C8.74%206.19%2C13.76%209.6%2C18.71%202.81%2C5.55%201.5%2C5.14%200.56%2C1.57%20h%200.97%20v%20-0.9%20l%200.79%2C-10.54%201.46%2C-12.94%201.42%2C-16.65%200.49%2C-4.69%202.32%2C-5.62%204.61%2C-3.04%203.6%2C1.72%202.96%2C4.24%20-0.41%2C2.74%20-1.76%2C11.44%20-3.45%2C17.92%20-2.25%2C12%20h%201.31%20l%201.5%2C-1.5%206.07%2C-8.06%2010.2%2C-12.75%204.5%2C-5.06%205.25%2C-5.59%203.37%2C-2.66%20h%206.37%20l%204.69%2C6.97%20-2.1%2C7.2%20-6.56%2C8.32%20-5.44%2C7.05%20-7.8%2C10.5%20-4.87%2C8.4%200.45%2C0.67%201.16%2C-0.11%2017.62%2C-3.75%209.52%2C-1.72%2011.36%2C-1.95%205.14%2C2.4%200.56%2C2.44%20-2.02%2C4.99%20-12.15%2C3%20-14.25%2C2.85%20-21.22%2C5.02%20-0.26%2C0.19%200.3%2C0.37%209.56%2C0.9%204.09%2C0.22%20h%2010.01%20l%2018.64%2C1.39%204.87%2C3.22%202.92%2C3.94%20-0.49%2C3%20-7.5%2C3.82%20-10.12%2C-2.4%20-23.62%2C-5.62%20-8.1%2C-2.02%20h%20-1.12%20v%200.67%20l%206.75%2C6.6%2012.37%2C11.17%2015.49%2C14.4%200.79%2C3.56%20-1.99%2C2.81%20-2.1%2C-0.3%20-13.61%2C-10.24%20-5.25%2C-4.61%20-11.89%2C-10.01%20h%20-0.79%20v%201.05%20l%202.74%2C4.01%2014.47%2C21.75%200.75%2C6.67%20-1.05%2C2.17%20-3.75%2C1.31%20-4.12%2C-0.75%20-8.47%2C-11.89%20-8.74%2C-13.39%20-7.05%2C-12%20-0.86%2C0.49%20-4.16%2C44.81%20-1.95%2C2.29%20-4.5%2C1.72%20-3.75%2C-2.85%20-1.99%2C-4.61%201.99%2C-9.11%202.4%2C-11.89%201.95%2C-9.45%201.76%2C-11.74%201.05%2C-3.9%20-0.07%2C-0.26%20-0.86%2C0.11%20-8.85%2C12.15%20-13.46%2C18.19%20-10.65%2C11.4%20-2.55%2C1.01%20-4.42%2C-2.29%200.41%2C-4.09%202.47%2C-3.64%2014.74%2C-18.75%208.89%2C-11.62%205.74%2C-6.71%20-0.04%2C-0.97%20h%20-0.34%20l%20-39.15%2C25.42%20-6.97%2C0.9%20-3%2C-2.81%200.37%2C-4.61%201.42%2C-1.5%2011.77%2C-8.1%20-0.04%2C0.04%20z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1247
1533
  "}",
1248
1534
  "",
1249
- "body[data-dsh-claude-style] [class*=\"brandIdentity\"] > [class*=\"brandName\"] > * {",
1535
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) [class*=\"brandIdentity\"] > [class*=\"brandName\"] > * {",
1250
1536
  " display: none !important;",
1251
1537
  "}",
1252
1538
  "",
1253
- "body[data-dsh-claude-style] [class*=\"brandIdentity\"] > [class*=\"brandName\"]::before {",
1539
+ "body[data-dsh-claude-style]:is([data-dsh-claude-brand=\"claude\"], [data-dsh-claude-brand=\"anthropic\"]) [class*=\"brandIdentity\"] > [class*=\"brandName\"]::before {",
1254
1540
  " content: \"\";",
1255
1541
  " display: block;",
1256
1542
  " flex: none;",
@@ -1260,7 +1546,7 @@ window.__ModuleLoader__.load({
1260
1546
  " background-size: contain;",
1261
1547
  "}",
1262
1548
  "",
1263
- "body[data-dsh-claude-style]:not([data-dsh-claude-brand=\"anthropic\"]) [class*=\"brandIdentity\"] > [class*=\"brandName\"]::before {",
1549
+ "body[data-dsh-claude-style][data-dsh-claude-brand=\"claude\"] [class*=\"brandIdentity\"] > [class*=\"brandName\"]::before {",
1264
1550
  " width: 75.9px;",
1265
1551
  " max-width: 100%;",
1266
1552
  " height: 18px;",
@@ -1272,16 +1558,16 @@ window.__ModuleLoader__.load({
1272
1558
  "body[data-dsh-claude-style][data-dsh-claude-brand=\"anthropic\"] :is([class*=\"brandMark\"], [class*=\"railMark\"])::before {",
1273
1559
  " width: 25.9px;",
1274
1560
  " height: 18px;",
1275
- " -webkit-mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 46 32%27%3E%3Cpath d=%27M32.73 0H25.7846L38.4499 32H45.3953L32.73 0Z%27/%3E%3Cpath d=%27M12.6653 0L0 32H7.08167L9.67193 25.28H22.9219L25.5122 32H32.5939L19.9286 0H12.6653ZM11.9626 19.3371L16.2969 8.09143L20.6313 19.3371H11.9626Z%27/%3E%3C/svg%3E\") center / contain no-repeat;",
1276
- " mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 46 32%27%3E%3Cpath d=%27M32.73 0H25.7846L38.4499 32H45.3953L32.73 0Z%27/%3E%3Cpath d=%27M12.6653 0L0 32H7.08167L9.67193 25.28H22.9219L25.5122 32H32.5939L19.9286 0H12.6653ZM11.9626 19.3371L16.2969 8.09143L20.6313 19.3371H11.9626Z%27/%3E%3C/svg%3E\") center / contain no-repeat;",
1561
+ " -webkit-mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2046%2032'%3E%3Cpath%20d%3D'M32.73%200H25.7846L38.4499%2032H45.3953L32.73%200Z'%2F%3E%3Cpath%20d%3D'M12.6653%200L0%2032H7.08167L9.67193%2025.28H22.9219L25.5122%2032H32.5939L19.9286%200H12.6653ZM11.9626%2019.3371L16.2969%208.09143L20.6313%2019.3371H11.9626Z'%2F%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1562
+ " mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2046%2032'%3E%3Cpath%20d%3D'M32.73%200H25.7846L38.4499%2032H45.3953L32.73%200Z'%2F%3E%3Cpath%20d%3D'M12.6653%200L0%2032H7.08167L9.67193%2025.28H22.9219L25.5122%2032H32.5939L19.9286%200H12.6653ZM11.9626%2019.3371L16.2969%208.09143L20.6313%2019.3371H11.9626Z'%2F%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1277
1563
  "}",
1278
1564
  "",
1279
1565
  "body[data-dsh-claude-style][data-dsh-claude-brand=\"anthropic\"] [class*=\"brandIdentity\"] > [class*=\"brandName\"]::before {",
1280
1566
  " width: 160.9px;",
1281
1567
  " max-width: 100%;",
1282
1568
  " height: 18px;",
1283
- " -webkit-mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 143 16%27%3E%3Cpath transform=%27translate(18.299999237060547,0.27000001072883606)%27 d=%27 M10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 3.756195545196533,0 3.756195545196533,0 C3.756195545196533,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.2038140296936035,15.470022201538086 3.2038140296936035,15.470022201538086 C3.2038140296936035,15.470022201538086 3.2038140296936035,4.6410064697265625 3.2038140296936035,4.6410064697265625 C3.2038140296936035,4.6410064697265625 10.163809776306152,15.470022201538086 10.163809776306152,15.470022201538086 C10.163809776306152,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.716191291809082,0 10.716191291809082,0 C10.716191291809082,0 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777z%27/%3E%3Cpath transform=%27translate(34.869998931884766,0.27000001072883606)%27 d=%27 M0,2.983504056930542 C0,2.983504056930542 5.19273567199707,2.983504056930542 5.19273567199707,2.983504056930542 C5.19273567199707,2.983504056930542 5.19273567199707,15.470022201538086 5.19273567199707,15.470022201538086 C5.19273567199707,15.470022201538086 8.507256507873535,15.470022201538086 8.507256507873535,15.470022201538086 C8.507256507873535,15.470022201538086 8.507256507873535,2.983504056930542 8.507256507873535,2.983504056930542 C8.507256507873535,2.983504056930542 13.700006484985352,2.983504056930542 13.700006484985352,2.983504056930542 C13.700006484985352,2.983504056930542 13.700006484985352,0 13.700006484985352,0 C13.700006484985352,0 0,0 0,0 C0,0 0,2.983504056930542 0,2.983504056930542 C0,2.983504056930542 0,2.983504056930542 0,2.983504056930542z%27/%3E%3Cpath transform=%27translate(51.22999954223633,0.27000001072883606)%27 d=%27 M10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 3.3142902851104736,6.165900230407715 3.3142902851104736,6.165900230407715 C3.3142902851104736,6.165900230407715 3.3142902851104736,0 3.3142902851104736,0 C3.3142902851104736,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3142902851104736,15.470022201538086 3.3142902851104736,15.470022201538086 C3.3142902851104736,15.470022201538086 3.3142902851104736,9.149404525756836 3.3142902851104736,9.149404525756836 C3.3142902851104736,9.149404525756836 10.605714797973633,9.149404525756836 10.605714797973633,9.149404525756836 C10.605714797973633,9.149404525756836 10.605714797973633,15.470022201538086 10.605714797973633,15.470022201538086 C10.605714797973633,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.605714797973633,0 10.605714797973633,0 C10.605714797973633,0 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715z%27/%3E%3Cpath transform=%27translate(69.23999786376953,0.27000001072883606)%27 d=%27 M3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 7.403865814208984,2.983504056930542 7.403865814208984,2.983504056930542 C9.03934097290039,2.983504056930542 9.901290893554688,3.5801939964294434 9.901290893554688,4.707304000854492 C9.901290893554688,5.834399700164795 9.03934097290039,6.431103706359863 7.403865814208984,6.431103706359863 C7.403865814208984,6.431103706359863 3.3151700496673584,6.431103706359863 3.3151700496673584,6.431103706359863 C3.3151700496673584,6.431103706359863 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542z M13.216461181640625,4.707304000854492 C13.216461181640625,1.7900969982147217 11.072648048400879,0 7.558576583862305,0 C7.558576583862305,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3151700496673584,15.470022201538086 3.3151700496673584,15.470022201538086 C3.3151700496673584,15.470022201538086 3.3151700496673584,9.414593696594238 3.3151700496673584,9.414593696594238 C3.3151700496673584,9.414593696594238 7.005825519561768,9.414593696594238 7.005825519561768,9.414593696594238 C7.005825519561768,9.414593696594238 10.321218490600586,15.470022201538086 10.321218490600586,15.470022201538086 C10.321218490600586,15.470022201538086 13.990056991577148,15.470022201538086 13.990056991577148,15.470022201538086 C13.990056991577148,15.470022201538086 10.319005966186523,8.953378677368164 10.319005966186523,8.953378677368164 C12.161579132080078,8.245061874389648 13.216461181640625,6.753532409667969 13.216461181640625,4.707304000854492 C13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492z%27/%3E%3Cpath transform=%27translate(84.98999786376953,0)%27 d=%27 M7.622087478637695,12.906073570251465 C5.015110492706299,12.906073570251465 3.4244225025177,11.049725532531738 3.4244225025177,8.022093772888184 C3.4244225025177,4.95027494430542 5.015110492706299,3.0939269065856934 7.622087478637695,3.0939269065856934 C10.206976890563965,3.0939269065856934 11.775577545166016,4.95027494430542 11.775577545166016,8.022093772888184 C11.775577545166016,11.049725532531738 10.206976890563965,12.906073570251465 7.622087478637695,12.906073570251465 C7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465z M7.622087478637695,0 C3.1593029499053955,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1593029499053955,16 7.622087478637695,16 C12.062784194946289,16 15.200028419494629,12.685078620910645 15.200028419494629,8.022093772888184 C15.200028419494629,3.3149218559265137 12.062784194946289,0 7.622087478637695,0 C7.622087478637695,0 7.622087478637695,0 7.622087478637695,0z%27/%3E%3Cpath transform=%27translate(103.29000091552734,0.27000001072883606)%27 d=%27 M7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 3.3160574436187744,6.873104095458984 3.3160574436187744,6.873104095458984 C3.3160574436187744,6.873104095458984 3.3160574436187744,2.983504056930542 3.3160574436187744,2.983504056930542 C3.3160574436187744,2.983504056930542 7.405848026275635,2.983504056930542 7.405848026275635,2.983504056930542 C9.04176139831543,2.983504056930542 9.90394115447998,3.646505117416382 9.90394115447998,4.928304195404053 C9.90394115447998,6.2101030349731445 9.04176139831543,6.873104095458984 7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984z M7.5605998039245605,0 C7.5605998039245605,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3160574436187744,15.470022201538086 3.3160574436187744,15.470022201538086 C3.3160574436187744,15.470022201538086 3.3160574436187744,9.85659408569336 3.3160574436187744,9.85659408569336 C3.3160574436187744,9.85659408569336 7.5605998039245605,9.85659408569336 7.5605998039245605,9.85659408569336 C11.07561206817627,9.85659408569336 13.219999313354492,8.000200271606445 13.219999313354492,4.928304195404053 C13.219999313354492,1.8563942909240723 11.07561206817627,0 7.5605998039245605,0 C7.5605998039245605,0 7.5605998039245605,0 7.5605998039245605,0z%27/%3E%3Cpath transform=%27translate(128.0399932861328,0)%27 d=%27 M10.914844512939453,10.5414400100708 C10.340370178222656,12.044201850891113 9.191434860229492,12.906073570251465 7.622706890106201,12.906073570251465 C5.0155181884765625,12.906073570251465 3.4246866703033447,11.049725532531738 3.4246866703033447,8.022093772888184 C3.4246866703033447,4.95027494430542 5.0155181884765625,3.0939269065856934 7.622706890106201,3.0939269065856934 C9.191434860229492,3.0939269065856934 10.340370178222656,3.9557981491088867 10.914844512939453,5.458559989929199 C10.914844512939453,5.458559989929199 14.427860260009766,5.458559989929199 14.427860260009766,5.458559989929199 C13.566211700439453,2.1436522006988525 10.981111526489258,0 7.622706890106201,0 C3.1595458984375,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1595458984375,16 7.622706890106201,16 C11.003214836120605,16 13.588300704956055,13.834254264831543 14.449976921081543,10.5414400100708 C14.449976921081543,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 C10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708z%27/%3E%3Cpath transform=%27translate(117.83000183105469,0.27000001072883606)%27 d=%27 M0,0 C0,0 6.1677093505859375,15.470022201538086 6.1677093505859375,15.470022201538086 C6.1677093505859375,15.470022201538086 9.550004005432129,15.470022201538086 9.550004005432129,15.470022201538086 C9.550004005432129,15.470022201538086 3.382294178009033,0 3.382294178009033,0 C3.382294178009033,0 0,0 0,0 C0,0 0,0 0,0z%27/%3E%3Cpath transform=%27translate(0,0.27000001072883606)%27 d=%27 M5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 7.93500280380249,3.911694288253784 7.93500280380249,3.911694288253784 C7.93500280380249,3.911694288253784 10.045400619506836,9.348296165466309 10.045400619506836,9.348296165466309 C10.045400619506836,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309z M6.166755199432373,0 C6.166755199432373,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.4480772018432617,15.470022201538086 3.4480772018432617,15.470022201538086 C3.4480772018432617,15.470022201538086 4.709278583526611,12.22130012512207 4.709278583526611,12.22130012512207 C4.709278583526611,12.22130012512207 11.16093635559082,12.22130012512207 11.16093635559082,12.22130012512207 C11.16093635559082,12.22130012512207 12.421928405761719,15.470022201538086 12.421928405761719,15.470022201538086 C12.421928405761719,15.470022201538086 15.87000560760498,15.470022201538086 15.87000560760498,15.470022201538086 C15.87000560760498,15.470022201538086 9.703250885009766,0 9.703250885009766,0 C9.703250885009766,0 6.166755199432373,0 6.166755199432373,0 C6.166755199432373,0 6.166755199432373,0 6.166755199432373,0z%27/%3E%3C/svg%3E\") center / contain no-repeat;",
1284
- " mask: url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 143 16%27%3E%3Cpath transform=%27translate(18.299999237060547,0.27000001072883606)%27 d=%27 M10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 3.756195545196533,0 3.756195545196533,0 C3.756195545196533,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.2038140296936035,15.470022201538086 3.2038140296936035,15.470022201538086 C3.2038140296936035,15.470022201538086 3.2038140296936035,4.6410064697265625 3.2038140296936035,4.6410064697265625 C3.2038140296936035,4.6410064697265625 10.163809776306152,15.470022201538086 10.163809776306152,15.470022201538086 C10.163809776306152,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.716191291809082,0 10.716191291809082,0 C10.716191291809082,0 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 C10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777 10.716191291809082,10.829001426696777z%27/%3E%3Cpath transform=%27translate(34.869998931884766,0.27000001072883606)%27 d=%27 M0,2.983504056930542 C0,2.983504056930542 5.19273567199707,2.983504056930542 5.19273567199707,2.983504056930542 C5.19273567199707,2.983504056930542 5.19273567199707,15.470022201538086 5.19273567199707,15.470022201538086 C5.19273567199707,15.470022201538086 8.507256507873535,15.470022201538086 8.507256507873535,15.470022201538086 C8.507256507873535,15.470022201538086 8.507256507873535,2.983504056930542 8.507256507873535,2.983504056930542 C8.507256507873535,2.983504056930542 13.700006484985352,2.983504056930542 13.700006484985352,2.983504056930542 C13.700006484985352,2.983504056930542 13.700006484985352,0 13.700006484985352,0 C13.700006484985352,0 0,0 0,0 C0,0 0,2.983504056930542 0,2.983504056930542 C0,2.983504056930542 0,2.983504056930542 0,2.983504056930542z%27/%3E%3Cpath transform=%27translate(51.22999954223633,0.27000001072883606)%27 d=%27 M10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 3.3142902851104736,6.165900230407715 3.3142902851104736,6.165900230407715 C3.3142902851104736,6.165900230407715 3.3142902851104736,0 3.3142902851104736,0 C3.3142902851104736,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3142902851104736,15.470022201538086 3.3142902851104736,15.470022201538086 C3.3142902851104736,15.470022201538086 3.3142902851104736,9.149404525756836 3.3142902851104736,9.149404525756836 C3.3142902851104736,9.149404525756836 10.605714797973633,9.149404525756836 10.605714797973633,9.149404525756836 C10.605714797973633,9.149404525756836 10.605714797973633,15.470022201538086 10.605714797973633,15.470022201538086 C10.605714797973633,15.470022201538086 13.919991493225098,15.470022201538086 13.919991493225098,15.470022201538086 C13.919991493225098,15.470022201538086 13.919991493225098,0 13.919991493225098,0 C13.919991493225098,0 10.605714797973633,0 10.605714797973633,0 C10.605714797973633,0 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 C10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715 10.605714797973633,6.165900230407715z%27/%3E%3Cpath transform=%27translate(69.23999786376953,0.27000001072883606)%27 d=%27 M3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 7.403865814208984,2.983504056930542 7.403865814208984,2.983504056930542 C9.03934097290039,2.983504056930542 9.901290893554688,3.5801939964294434 9.901290893554688,4.707304000854492 C9.901290893554688,5.834399700164795 9.03934097290039,6.431103706359863 7.403865814208984,6.431103706359863 C7.403865814208984,6.431103706359863 3.3151700496673584,6.431103706359863 3.3151700496673584,6.431103706359863 C3.3151700496673584,6.431103706359863 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 C3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542 3.3151700496673584,2.983504056930542z M13.216461181640625,4.707304000854492 C13.216461181640625,1.7900969982147217 11.072648048400879,0 7.558576583862305,0 C7.558576583862305,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3151700496673584,15.470022201538086 3.3151700496673584,15.470022201538086 C3.3151700496673584,15.470022201538086 3.3151700496673584,9.414593696594238 3.3151700496673584,9.414593696594238 C3.3151700496673584,9.414593696594238 7.005825519561768,9.414593696594238 7.005825519561768,9.414593696594238 C7.005825519561768,9.414593696594238 10.321218490600586,15.470022201538086 10.321218490600586,15.470022201538086 C10.321218490600586,15.470022201538086 13.990056991577148,15.470022201538086 13.990056991577148,15.470022201538086 C13.990056991577148,15.470022201538086 10.319005966186523,8.953378677368164 10.319005966186523,8.953378677368164 C12.161579132080078,8.245061874389648 13.216461181640625,6.753532409667969 13.216461181640625,4.707304000854492 C13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492 13.216461181640625,4.707304000854492z%27/%3E%3Cpath transform=%27translate(84.98999786376953,0)%27 d=%27 M7.622087478637695,12.906073570251465 C5.015110492706299,12.906073570251465 3.4244225025177,11.049725532531738 3.4244225025177,8.022093772888184 C3.4244225025177,4.95027494430542 5.015110492706299,3.0939269065856934 7.622087478637695,3.0939269065856934 C10.206976890563965,3.0939269065856934 11.775577545166016,4.95027494430542 11.775577545166016,8.022093772888184 C11.775577545166016,11.049725532531738 10.206976890563965,12.906073570251465 7.622087478637695,12.906073570251465 C7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465 7.622087478637695,12.906073570251465z M7.622087478637695,0 C3.1593029499053955,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1593029499053955,16 7.622087478637695,16 C12.062784194946289,16 15.200028419494629,12.685078620910645 15.200028419494629,8.022093772888184 C15.200028419494629,3.3149218559265137 12.062784194946289,0 7.622087478637695,0 C7.622087478637695,0 7.622087478637695,0 7.622087478637695,0z%27/%3E%3Cpath transform=%27translate(103.29000091552734,0.27000001072883606)%27 d=%27 M7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 3.3160574436187744,6.873104095458984 3.3160574436187744,6.873104095458984 C3.3160574436187744,6.873104095458984 3.3160574436187744,2.983504056930542 3.3160574436187744,2.983504056930542 C3.3160574436187744,2.983504056930542 7.405848026275635,2.983504056930542 7.405848026275635,2.983504056930542 C9.04176139831543,2.983504056930542 9.90394115447998,3.646505117416382 9.90394115447998,4.928304195404053 C9.90394115447998,6.2101030349731445 9.04176139831543,6.873104095458984 7.405848026275635,6.873104095458984 C7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984 7.405848026275635,6.873104095458984z M7.5605998039245605,0 C7.5605998039245605,0 0,0 0,0 C0,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.3160574436187744,15.470022201538086 3.3160574436187744,15.470022201538086 C3.3160574436187744,15.470022201538086 3.3160574436187744,9.85659408569336 3.3160574436187744,9.85659408569336 C3.3160574436187744,9.85659408569336 7.5605998039245605,9.85659408569336 7.5605998039245605,9.85659408569336 C11.07561206817627,9.85659408569336 13.219999313354492,8.000200271606445 13.219999313354492,4.928304195404053 C13.219999313354492,1.8563942909240723 11.07561206817627,0 7.5605998039245605,0 C7.5605998039245605,0 7.5605998039245605,0 7.5605998039245605,0z%27/%3E%3Cpath transform=%27translate(128.0399932861328,0)%27 d=%27 M10.914844512939453,10.5414400100708 C10.340370178222656,12.044201850891113 9.191434860229492,12.906073570251465 7.622706890106201,12.906073570251465 C5.0155181884765625,12.906073570251465 3.4246866703033447,11.049725532531738 3.4246866703033447,8.022093772888184 C3.4246866703033447,4.95027494430542 5.0155181884765625,3.0939269065856934 7.622706890106201,3.0939269065856934 C9.191434860229492,3.0939269065856934 10.340370178222656,3.9557981491088867 10.914844512939453,5.458559989929199 C10.914844512939453,5.458559989929199 14.427860260009766,5.458559989929199 14.427860260009766,5.458559989929199 C13.566211700439453,2.1436522006988525 10.981111526489258,0 7.622706890106201,0 C3.1595458984375,0 0,3.3149218559265137 0,8.022093772888184 C0,12.685078620910645 3.1595458984375,16 7.622706890106201,16 C11.003214836120605,16 13.588300704956055,13.834254264831543 14.449976921081543,10.5414400100708 C14.449976921081543,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 C10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708 10.914844512939453,10.5414400100708z%27/%3E%3Cpath transform=%27translate(117.83000183105469,0.27000001072883606)%27 d=%27 M0,0 C0,0 6.1677093505859375,15.470022201538086 6.1677093505859375,15.470022201538086 C6.1677093505859375,15.470022201538086 9.550004005432129,15.470022201538086 9.550004005432129,15.470022201538086 C9.550004005432129,15.470022201538086 3.382294178009033,0 3.382294178009033,0 C3.382294178009033,0 0,0 0,0 C0,0 0,0 0,0z%27/%3E%3Cpath transform=%27translate(0,0.27000001072883606)%27 d=%27 M5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 7.93500280380249,3.911694288253784 7.93500280380249,3.911694288253784 C7.93500280380249,3.911694288253784 10.045400619506836,9.348296165466309 10.045400619506836,9.348296165466309 C10.045400619506836,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309z M6.166755199432373,0 C6.166755199432373,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.4480772018432617,15.470022201538086 3.4480772018432617,15.470022201538086 C3.4480772018432617,15.470022201538086 4.709278583526611,12.22130012512207 4.709278583526611,12.22130012512207 C4.709278583526611,12.22130012512207 11.16093635559082,12.22130012512207 11.16093635559082,12.22130012512207 C11.16093635559082,12.22130012512207 12.421928405761719,15.470022201538086 12.421928405761719,15.470022201538086 C12.421928405761719,15.470022201538086 15.87000560760498,15.470022201538086 15.87000560760498,15.470022201538086 C15.87000560760498,15.470022201538086 9.703250885009766,0 9.703250885009766,0 C9.703250885009766,0 6.166755199432373,0 6.166755199432373,0 C6.166755199432373,0 6.166755199432373,0 6.166755199432373,0z%27/%3E%3C/svg%3E\") center / contain no-repeat;",
1569
+ " -webkit-mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%20143%2016'%3E%3Cpath%20transform%3D'translate(18.299999237060547%2C0.27000001072883606)'%20d%3D'%20M10.716191291809082%2C10.829001426696777%20C10.716191291809082%2C10.829001426696777%203.756195545196533%2C0%203.756195545196533%2C0%20C3.756195545196533%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.2038140296936035%2C15.470022201538086%203.2038140296936035%2C15.470022201538086%20C3.2038140296936035%2C15.470022201538086%203.2038140296936035%2C4.6410064697265625%203.2038140296936035%2C4.6410064697265625%20C3.2038140296936035%2C4.6410064697265625%2010.163809776306152%2C15.470022201538086%2010.163809776306152%2C15.470022201538086%20C10.163809776306152%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%20C13.919991493225098%2C15.470022201538086%2013.919991493225098%2C0%2013.919991493225098%2C0%20C13.919991493225098%2C0%2010.716191291809082%2C0%2010.716191291809082%2C0%20C10.716191291809082%2C0%2010.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777%20C10.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777z'%2F%3E%3Cpath%20transform%3D'translate(34.869998931884766%2C0.27000001072883606)'%20d%3D'%20M0%2C2.983504056930542%20C0%2C2.983504056930542%205.19273567199707%2C2.983504056930542%205.19273567199707%2C2.983504056930542%20C5.19273567199707%2C2.983504056930542%205.19273567199707%2C15.470022201538086%205.19273567199707%2C15.470022201538086%20C5.19273567199707%2C15.470022201538086%208.507256507873535%2C15.470022201538086%208.507256507873535%2C15.470022201538086%20C8.507256507873535%2C15.470022201538086%208.507256507873535%2C2.983504056930542%208.507256507873535%2C2.983504056930542%20C8.507256507873535%2C2.983504056930542%2013.700006484985352%2C2.983504056930542%2013.700006484985352%2C2.983504056930542%20C13.700006484985352%2C2.983504056930542%2013.700006484985352%2C0%2013.700006484985352%2C0%20C13.700006484985352%2C0%200%2C0%200%2C0%20C0%2C0%200%2C2.983504056930542%200%2C2.983504056930542%20C0%2C2.983504056930542%200%2C2.983504056930542%200%2C2.983504056930542z'%2F%3E%3Cpath%20transform%3D'translate(51.22999954223633%2C0.27000001072883606)'%20d%3D'%20M10.605714797973633%2C6.165900230407715%20C10.605714797973633%2C6.165900230407715%203.3142902851104736%2C6.165900230407715%203.3142902851104736%2C6.165900230407715%20C3.3142902851104736%2C6.165900230407715%203.3142902851104736%2C0%203.3142902851104736%2C0%20C3.3142902851104736%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3142902851104736%2C15.470022201538086%203.3142902851104736%2C15.470022201538086%20C3.3142902851104736%2C15.470022201538086%203.3142902851104736%2C9.149404525756836%203.3142902851104736%2C9.149404525756836%20C3.3142902851104736%2C9.149404525756836%2010.605714797973633%2C9.149404525756836%2010.605714797973633%2C9.149404525756836%20C10.605714797973633%2C9.149404525756836%2010.605714797973633%2C15.470022201538086%2010.605714797973633%2C15.470022201538086%20C10.605714797973633%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%20C13.919991493225098%2C15.470022201538086%2013.919991493225098%2C0%2013.919991493225098%2C0%20C13.919991493225098%2C0%2010.605714797973633%2C0%2010.605714797973633%2C0%20C10.605714797973633%2C0%2010.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715%20C10.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715z'%2F%3E%3Cpath%20transform%3D'translate(69.23999786376953%2C0.27000001072883606)'%20d%3D'%20M3.3151700496673584%2C2.983504056930542%20C3.3151700496673584%2C2.983504056930542%207.403865814208984%2C2.983504056930542%207.403865814208984%2C2.983504056930542%20C9.03934097290039%2C2.983504056930542%209.901290893554688%2C3.5801939964294434%209.901290893554688%2C4.707304000854492%20C9.901290893554688%2C5.834399700164795%209.03934097290039%2C6.431103706359863%207.403865814208984%2C6.431103706359863%20C7.403865814208984%2C6.431103706359863%203.3151700496673584%2C6.431103706359863%203.3151700496673584%2C6.431103706359863%20C3.3151700496673584%2C6.431103706359863%203.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542%20C3.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542z%20M13.216461181640625%2C4.707304000854492%20C13.216461181640625%2C1.7900969982147217%2011.072648048400879%2C0%207.558576583862305%2C0%20C7.558576583862305%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3151700496673584%2C15.470022201538086%203.3151700496673584%2C15.470022201538086%20C3.3151700496673584%2C15.470022201538086%203.3151700496673584%2C9.414593696594238%203.3151700496673584%2C9.414593696594238%20C3.3151700496673584%2C9.414593696594238%207.005825519561768%2C9.414593696594238%207.005825519561768%2C9.414593696594238%20C7.005825519561768%2C9.414593696594238%2010.321218490600586%2C15.470022201538086%2010.321218490600586%2C15.470022201538086%20C10.321218490600586%2C15.470022201538086%2013.990056991577148%2C15.470022201538086%2013.990056991577148%2C15.470022201538086%20C13.990056991577148%2C15.470022201538086%2010.319005966186523%2C8.953378677368164%2010.319005966186523%2C8.953378677368164%20C12.161579132080078%2C8.245061874389648%2013.216461181640625%2C6.753532409667969%2013.216461181640625%2C4.707304000854492%20C13.216461181640625%2C4.707304000854492%2013.216461181640625%2C4.707304000854492%2013.216461181640625%2C4.707304000854492z'%2F%3E%3Cpath%20transform%3D'translate(84.98999786376953%2C0)'%20d%3D'%20M7.622087478637695%2C12.906073570251465%20C5.015110492706299%2C12.906073570251465%203.4244225025177%2C11.049725532531738%203.4244225025177%2C8.022093772888184%20C3.4244225025177%2C4.95027494430542%205.015110492706299%2C3.0939269065856934%207.622087478637695%2C3.0939269065856934%20C10.206976890563965%2C3.0939269065856934%2011.775577545166016%2C4.95027494430542%2011.775577545166016%2C8.022093772888184%20C11.775577545166016%2C11.049725532531738%2010.206976890563965%2C12.906073570251465%207.622087478637695%2C12.906073570251465%20C7.622087478637695%2C12.906073570251465%207.622087478637695%2C12.906073570251465%207.622087478637695%2C12.906073570251465z%20M7.622087478637695%2C0%20C3.1593029499053955%2C0%200%2C3.3149218559265137%200%2C8.022093772888184%20C0%2C12.685078620910645%203.1593029499053955%2C16%207.622087478637695%2C16%20C12.062784194946289%2C16%2015.200028419494629%2C12.685078620910645%2015.200028419494629%2C8.022093772888184%20C15.200028419494629%2C3.3149218559265137%2012.062784194946289%2C0%207.622087478637695%2C0%20C7.622087478637695%2C0%207.622087478637695%2C0%207.622087478637695%2C0z'%2F%3E%3Cpath%20transform%3D'translate(103.29000091552734%2C0.27000001072883606)'%20d%3D'%20M7.405848026275635%2C6.873104095458984%20C7.405848026275635%2C6.873104095458984%203.3160574436187744%2C6.873104095458984%203.3160574436187744%2C6.873104095458984%20C3.3160574436187744%2C6.873104095458984%203.3160574436187744%2C2.983504056930542%203.3160574436187744%2C2.983504056930542%20C3.3160574436187744%2C2.983504056930542%207.405848026275635%2C2.983504056930542%207.405848026275635%2C2.983504056930542%20C9.04176139831543%2C2.983504056930542%209.90394115447998%2C3.646505117416382%209.90394115447998%2C4.928304195404053%20C9.90394115447998%2C6.2101030349731445%209.04176139831543%2C6.873104095458984%207.405848026275635%2C6.873104095458984%20C7.405848026275635%2C6.873104095458984%207.405848026275635%2C6.873104095458984%207.405848026275635%2C6.873104095458984z%20M7.5605998039245605%2C0%20C7.5605998039245605%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3160574436187744%2C15.470022201538086%203.3160574436187744%2C15.470022201538086%20C3.3160574436187744%2C15.470022201538086%203.3160574436187744%2C9.85659408569336%203.3160574436187744%2C9.85659408569336%20C3.3160574436187744%2C9.85659408569336%207.5605998039245605%2C9.85659408569336%207.5605998039245605%2C9.85659408569336%20C11.07561206817627%2C9.85659408569336%2013.219999313354492%2C8.000200271606445%2013.219999313354492%2C4.928304195404053%20C13.219999313354492%2C1.8563942909240723%2011.07561206817627%2C0%207.5605998039245605%2C0%20C7.5605998039245605%2C0%207.5605998039245605%2C0%207.5605998039245605%2C0z'%2F%3E%3Cpath%20transform%3D'translate(128.0399932861328%2C0)'%20d%3D'%20M10.914844512939453%2C10.5414400100708%20C10.340370178222656%2C12.044201850891113%209.191434860229492%2C12.906073570251465%207.622706890106201%2C12.906073570251465%20C5.0155181884765625%2C12.906073570251465%203.4246866703033447%2C11.049725532531738%203.4246866703033447%2C8.022093772888184%20C3.4246866703033447%2C4.95027494430542%205.0155181884765625%2C3.0939269065856934%207.622706890106201%2C3.0939269065856934%20C9.191434860229492%2C3.0939269065856934%2010.340370178222656%2C3.9557981491088867%2010.914844512939453%2C5.458559989929199%20C10.914844512939453%2C5.458559989929199%2014.427860260009766%2C5.458559989929199%2014.427860260009766%2C5.458559989929199%20C13.566211700439453%2C2.1436522006988525%2010.981111526489258%2C0%207.622706890106201%2C0%20C3.1595458984375%2C0%200%2C3.3149218559265137%200%2C8.022093772888184%20C0%2C12.685078620910645%203.1595458984375%2C16%207.622706890106201%2C16%20C11.003214836120605%2C16%2013.588300704956055%2C13.834254264831543%2014.449976921081543%2C10.5414400100708%20C14.449976921081543%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%20C10.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708z'%2F%3E%3Cpath%20transform%3D'translate(117.83000183105469%2C0.27000001072883606)'%20d%3D'%20M0%2C0%20C0%2C0%206.1677093505859375%2C15.470022201538086%206.1677093505859375%2C15.470022201538086%20C6.1677093505859375%2C15.470022201538086%209.550004005432129%2C15.470022201538086%209.550004005432129%2C15.470022201538086%20C9.550004005432129%2C15.470022201538086%203.382294178009033%2C0%203.382294178009033%2C0%20C3.382294178009033%2C0%200%2C0%200%2C0%20C0%2C0%200%2C0%200%2C0z'%2F%3E%3Cpath%20transform%3D'translate(0%2C0.27000001072883606)'%20d%3D'%20M5.824605464935303%2C9.348296165466309%20C5.824605464935303%2C9.348296165466309%207.93500280380249%2C3.911694288253784%207.93500280380249%2C3.911694288253784%20C7.93500280380249%2C3.911694288253784%2010.045400619506836%2C9.348296165466309%2010.045400619506836%2C9.348296165466309%20C10.045400619506836%2C9.348296165466309%205.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309%20C5.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309z%20M6.166755199432373%2C0%20C6.166755199432373%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.4480772018432617%2C15.470022201538086%203.4480772018432617%2C15.470022201538086%20C3.4480772018432617%2C15.470022201538086%204.709278583526611%2C12.22130012512207%204.709278583526611%2C12.22130012512207%20C4.709278583526611%2C12.22130012512207%2011.16093635559082%2C12.22130012512207%2011.16093635559082%2C12.22130012512207%20C11.16093635559082%2C12.22130012512207%2012.421928405761719%2C15.470022201538086%2012.421928405761719%2C15.470022201538086%20C12.421928405761719%2C15.470022201538086%2015.87000560760498%2C15.470022201538086%2015.87000560760498%2C15.470022201538086%20C15.87000560760498%2C15.470022201538086%209.703250885009766%2C0%209.703250885009766%2C0%20C9.703250885009766%2C0%206.166755199432373%2C0%206.166755199432373%2C0%20C6.166755199432373%2C0%206.166755199432373%2C0%206.166755199432373%2C0z'%2F%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1570
+ " mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%20143%2016'%3E%3Cpath%20transform%3D'translate(18.299999237060547%2C0.27000001072883606)'%20d%3D'%20M10.716191291809082%2C10.829001426696777%20C10.716191291809082%2C10.829001426696777%203.756195545196533%2C0%203.756195545196533%2C0%20C3.756195545196533%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.2038140296936035%2C15.470022201538086%203.2038140296936035%2C15.470022201538086%20C3.2038140296936035%2C15.470022201538086%203.2038140296936035%2C4.6410064697265625%203.2038140296936035%2C4.6410064697265625%20C3.2038140296936035%2C4.6410064697265625%2010.163809776306152%2C15.470022201538086%2010.163809776306152%2C15.470022201538086%20C10.163809776306152%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%20C13.919991493225098%2C15.470022201538086%2013.919991493225098%2C0%2013.919991493225098%2C0%20C13.919991493225098%2C0%2010.716191291809082%2C0%2010.716191291809082%2C0%20C10.716191291809082%2C0%2010.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777%20C10.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777%2010.716191291809082%2C10.829001426696777z'%2F%3E%3Cpath%20transform%3D'translate(34.869998931884766%2C0.27000001072883606)'%20d%3D'%20M0%2C2.983504056930542%20C0%2C2.983504056930542%205.19273567199707%2C2.983504056930542%205.19273567199707%2C2.983504056930542%20C5.19273567199707%2C2.983504056930542%205.19273567199707%2C15.470022201538086%205.19273567199707%2C15.470022201538086%20C5.19273567199707%2C15.470022201538086%208.507256507873535%2C15.470022201538086%208.507256507873535%2C15.470022201538086%20C8.507256507873535%2C15.470022201538086%208.507256507873535%2C2.983504056930542%208.507256507873535%2C2.983504056930542%20C8.507256507873535%2C2.983504056930542%2013.700006484985352%2C2.983504056930542%2013.700006484985352%2C2.983504056930542%20C13.700006484985352%2C2.983504056930542%2013.700006484985352%2C0%2013.700006484985352%2C0%20C13.700006484985352%2C0%200%2C0%200%2C0%20C0%2C0%200%2C2.983504056930542%200%2C2.983504056930542%20C0%2C2.983504056930542%200%2C2.983504056930542%200%2C2.983504056930542z'%2F%3E%3Cpath%20transform%3D'translate(51.22999954223633%2C0.27000001072883606)'%20d%3D'%20M10.605714797973633%2C6.165900230407715%20C10.605714797973633%2C6.165900230407715%203.3142902851104736%2C6.165900230407715%203.3142902851104736%2C6.165900230407715%20C3.3142902851104736%2C6.165900230407715%203.3142902851104736%2C0%203.3142902851104736%2C0%20C3.3142902851104736%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3142902851104736%2C15.470022201538086%203.3142902851104736%2C15.470022201538086%20C3.3142902851104736%2C15.470022201538086%203.3142902851104736%2C9.149404525756836%203.3142902851104736%2C9.149404525756836%20C3.3142902851104736%2C9.149404525756836%2010.605714797973633%2C9.149404525756836%2010.605714797973633%2C9.149404525756836%20C10.605714797973633%2C9.149404525756836%2010.605714797973633%2C15.470022201538086%2010.605714797973633%2C15.470022201538086%20C10.605714797973633%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%2013.919991493225098%2C15.470022201538086%20C13.919991493225098%2C15.470022201538086%2013.919991493225098%2C0%2013.919991493225098%2C0%20C13.919991493225098%2C0%2010.605714797973633%2C0%2010.605714797973633%2C0%20C10.605714797973633%2C0%2010.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715%20C10.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715%2010.605714797973633%2C6.165900230407715z'%2F%3E%3Cpath%20transform%3D'translate(69.23999786376953%2C0.27000001072883606)'%20d%3D'%20M3.3151700496673584%2C2.983504056930542%20C3.3151700496673584%2C2.983504056930542%207.403865814208984%2C2.983504056930542%207.403865814208984%2C2.983504056930542%20C9.03934097290039%2C2.983504056930542%209.901290893554688%2C3.5801939964294434%209.901290893554688%2C4.707304000854492%20C9.901290893554688%2C5.834399700164795%209.03934097290039%2C6.431103706359863%207.403865814208984%2C6.431103706359863%20C7.403865814208984%2C6.431103706359863%203.3151700496673584%2C6.431103706359863%203.3151700496673584%2C6.431103706359863%20C3.3151700496673584%2C6.431103706359863%203.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542%20C3.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542%203.3151700496673584%2C2.983504056930542z%20M13.216461181640625%2C4.707304000854492%20C13.216461181640625%2C1.7900969982147217%2011.072648048400879%2C0%207.558576583862305%2C0%20C7.558576583862305%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3151700496673584%2C15.470022201538086%203.3151700496673584%2C15.470022201538086%20C3.3151700496673584%2C15.470022201538086%203.3151700496673584%2C9.414593696594238%203.3151700496673584%2C9.414593696594238%20C3.3151700496673584%2C9.414593696594238%207.005825519561768%2C9.414593696594238%207.005825519561768%2C9.414593696594238%20C7.005825519561768%2C9.414593696594238%2010.321218490600586%2C15.470022201538086%2010.321218490600586%2C15.470022201538086%20C10.321218490600586%2C15.470022201538086%2013.990056991577148%2C15.470022201538086%2013.990056991577148%2C15.470022201538086%20C13.990056991577148%2C15.470022201538086%2010.319005966186523%2C8.953378677368164%2010.319005966186523%2C8.953378677368164%20C12.161579132080078%2C8.245061874389648%2013.216461181640625%2C6.753532409667969%2013.216461181640625%2C4.707304000854492%20C13.216461181640625%2C4.707304000854492%2013.216461181640625%2C4.707304000854492%2013.216461181640625%2C4.707304000854492z'%2F%3E%3Cpath%20transform%3D'translate(84.98999786376953%2C0)'%20d%3D'%20M7.622087478637695%2C12.906073570251465%20C5.015110492706299%2C12.906073570251465%203.4244225025177%2C11.049725532531738%203.4244225025177%2C8.022093772888184%20C3.4244225025177%2C4.95027494430542%205.015110492706299%2C3.0939269065856934%207.622087478637695%2C3.0939269065856934%20C10.206976890563965%2C3.0939269065856934%2011.775577545166016%2C4.95027494430542%2011.775577545166016%2C8.022093772888184%20C11.775577545166016%2C11.049725532531738%2010.206976890563965%2C12.906073570251465%207.622087478637695%2C12.906073570251465%20C7.622087478637695%2C12.906073570251465%207.622087478637695%2C12.906073570251465%207.622087478637695%2C12.906073570251465z%20M7.622087478637695%2C0%20C3.1593029499053955%2C0%200%2C3.3149218559265137%200%2C8.022093772888184%20C0%2C12.685078620910645%203.1593029499053955%2C16%207.622087478637695%2C16%20C12.062784194946289%2C16%2015.200028419494629%2C12.685078620910645%2015.200028419494629%2C8.022093772888184%20C15.200028419494629%2C3.3149218559265137%2012.062784194946289%2C0%207.622087478637695%2C0%20C7.622087478637695%2C0%207.622087478637695%2C0%207.622087478637695%2C0z'%2F%3E%3Cpath%20transform%3D'translate(103.29000091552734%2C0.27000001072883606)'%20d%3D'%20M7.405848026275635%2C6.873104095458984%20C7.405848026275635%2C6.873104095458984%203.3160574436187744%2C6.873104095458984%203.3160574436187744%2C6.873104095458984%20C3.3160574436187744%2C6.873104095458984%203.3160574436187744%2C2.983504056930542%203.3160574436187744%2C2.983504056930542%20C3.3160574436187744%2C2.983504056930542%207.405848026275635%2C2.983504056930542%207.405848026275635%2C2.983504056930542%20C9.04176139831543%2C2.983504056930542%209.90394115447998%2C3.646505117416382%209.90394115447998%2C4.928304195404053%20C9.90394115447998%2C6.2101030349731445%209.04176139831543%2C6.873104095458984%207.405848026275635%2C6.873104095458984%20C7.405848026275635%2C6.873104095458984%207.405848026275635%2C6.873104095458984%207.405848026275635%2C6.873104095458984z%20M7.5605998039245605%2C0%20C7.5605998039245605%2C0%200%2C0%200%2C0%20C0%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.3160574436187744%2C15.470022201538086%203.3160574436187744%2C15.470022201538086%20C3.3160574436187744%2C15.470022201538086%203.3160574436187744%2C9.85659408569336%203.3160574436187744%2C9.85659408569336%20C3.3160574436187744%2C9.85659408569336%207.5605998039245605%2C9.85659408569336%207.5605998039245605%2C9.85659408569336%20C11.07561206817627%2C9.85659408569336%2013.219999313354492%2C8.000200271606445%2013.219999313354492%2C4.928304195404053%20C13.219999313354492%2C1.8563942909240723%2011.07561206817627%2C0%207.5605998039245605%2C0%20C7.5605998039245605%2C0%207.5605998039245605%2C0%207.5605998039245605%2C0z'%2F%3E%3Cpath%20transform%3D'translate(128.0399932861328%2C0)'%20d%3D'%20M10.914844512939453%2C10.5414400100708%20C10.340370178222656%2C12.044201850891113%209.191434860229492%2C12.906073570251465%207.622706890106201%2C12.906073570251465%20C5.0155181884765625%2C12.906073570251465%203.4246866703033447%2C11.049725532531738%203.4246866703033447%2C8.022093772888184%20C3.4246866703033447%2C4.95027494430542%205.0155181884765625%2C3.0939269065856934%207.622706890106201%2C3.0939269065856934%20C9.191434860229492%2C3.0939269065856934%2010.340370178222656%2C3.9557981491088867%2010.914844512939453%2C5.458559989929199%20C10.914844512939453%2C5.458559989929199%2014.427860260009766%2C5.458559989929199%2014.427860260009766%2C5.458559989929199%20C13.566211700439453%2C2.1436522006988525%2010.981111526489258%2C0%207.622706890106201%2C0%20C3.1595458984375%2C0%200%2C3.3149218559265137%200%2C8.022093772888184%20C0%2C12.685078620910645%203.1595458984375%2C16%207.622706890106201%2C16%20C11.003214836120605%2C16%2013.588300704956055%2C13.834254264831543%2014.449976921081543%2C10.5414400100708%20C14.449976921081543%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%20C10.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708%2010.914844512939453%2C10.5414400100708z'%2F%3E%3Cpath%20transform%3D'translate(117.83000183105469%2C0.27000001072883606)'%20d%3D'%20M0%2C0%20C0%2C0%206.1677093505859375%2C15.470022201538086%206.1677093505859375%2C15.470022201538086%20C6.1677093505859375%2C15.470022201538086%209.550004005432129%2C15.470022201538086%209.550004005432129%2C15.470022201538086%20C9.550004005432129%2C15.470022201538086%203.382294178009033%2C0%203.382294178009033%2C0%20C3.382294178009033%2C0%200%2C0%200%2C0%20C0%2C0%200%2C0%200%2C0z'%2F%3E%3Cpath%20transform%3D'translate(0%2C0.27000001072883606)'%20d%3D'%20M5.824605464935303%2C9.348296165466309%20C5.824605464935303%2C9.348296165466309%207.93500280380249%2C3.911694288253784%207.93500280380249%2C3.911694288253784%20C7.93500280380249%2C3.911694288253784%2010.045400619506836%2C9.348296165466309%2010.045400619506836%2C9.348296165466309%20C10.045400619506836%2C9.348296165466309%205.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309%20C5.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309%205.824605464935303%2C9.348296165466309z%20M6.166755199432373%2C0%20C6.166755199432373%2C0%200%2C15.470022201538086%200%2C15.470022201538086%20C0%2C15.470022201538086%203.4480772018432617%2C15.470022201538086%203.4480772018432617%2C15.470022201538086%20C3.4480772018432617%2C15.470022201538086%204.709278583526611%2C12.22130012512207%204.709278583526611%2C12.22130012512207%20C4.709278583526611%2C12.22130012512207%2011.16093635559082%2C12.22130012512207%2011.16093635559082%2C12.22130012512207%20C11.16093635559082%2C12.22130012512207%2012.421928405761719%2C15.470022201538086%2012.421928405761719%2C15.470022201538086%20C12.421928405761719%2C15.470022201538086%2015.87000560760498%2C15.470022201538086%2015.87000560760498%2C15.470022201538086%20C15.87000560760498%2C15.470022201538086%209.703250885009766%2C0%209.703250885009766%2C0%20C9.703250885009766%2C0%206.166755199432373%2C0%206.166755199432373%2C0%20C6.166755199432373%2C0%206.166755199432373%2C0%206.166755199432373%2C0z'%2F%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1285
1571
  "}",
1286
1572
  "",
1287
1573
  "/* ---------- Claude Code layout: new session button ---------- */",
@@ -1557,8 +1843,8 @@ window.__ModuleLoader__.load({
1557
1843
  "/* ---------- Claude Code layout: permission segments ---------- */",
1558
1844
  "/* The shipped access control is one popup-select button; it is replaced by",
1559
1845
  " a Read | Edit | Auto segmented control over the same three presets. */",
1560
- "body[data-dsh-claude-style] button[aria-label^=\"访问模式\"],",
1561
- "body[data-dsh-claude-style] button[aria-label^=\"Access mode\"] {",
1846
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] button[aria-label^=\"访问模式\"],",
1847
+ "body[data-dsh-claude-style][data-dsh-claude-composer-active] button[aria-label^=\"Access mode\"] {",
1562
1848
  " display: none !important;",
1563
1849
  "}",
1564
1850
  "",
@@ -1669,7 +1955,9 @@ window.__ModuleLoader__.load({
1669
1955
  " z-index: 99999 !important;",
1670
1956
  " display: flex !important;",
1671
1957
  " flex-direction: column !important;",
1672
- " gap: 2px !important;",
1958
+ " /* Two-line preset rows (label + description) need air between them: the",
1959
+ " 2px gap read as one solid block, so each row is separated by 6px. */",
1960
+ " gap: 6px !important;",
1673
1961
  " opacity: 0 !important;",
1674
1962
  " pointer-events: none !important;",
1675
1963
  " transform: translateY(4px) scale(0.98) !important;",
@@ -1724,7 +2012,7 @@ window.__ModuleLoader__.load({
1724
2012
  "body[data-dsh-claude-style] .dsh-claude-account-avatar {",
1725
2013
  " width: 18px;",
1726
2014
  " height: 18px;",
1727
- " background: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z' fill='%23D97757'/%3E%3C/svg%3E\") center / contain no-repeat;",
2015
+ " background: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2024%2024'%3E%3Cpath%20d%3D'M4.709%2015.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0%2011.784l.055-.352.48-.321.686.06%201.52.103%202.278.158%201.652.097%202.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686%201.908%201.476%202.491%201.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97%202.97%200%2001-.104-.729L6.283.134%206.696%200l.996.134.42.364.62%201.414%201.002%202.229%201.555%203.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286%201.851-.559%202.903-.364%201.942h.212l.243-.242.985-1.306%201.652-2.064.73-.82.85-.904.547-.431h1.033l.76%201.129-.34%201.166-1.064%201.347-.881%201.142-1.264%201.7-.79%201.36.073.11.188-.02%202.856-.606%201.543-.28%201.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061%201.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093%201.068%202.006%201.81%202.509%202.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649%202.345%203.521.122%201.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674%207.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434%201.967-2.18%202.945-1.726%201.845-.414.164-.717-.37.067-.662.401-.589%202.388-3.036%201.44-1.882.93-1.086-.006-.158h-.055L4.132%2018.56l-1.13.146-.487-.456.061-.746.231-.243%201.908-1.312-.006.006z'%20fill%3D'%23D97757'%2F%3E%3C%2Fsvg%3E\") center / contain no-repeat;",
1728
2016
  " flex: none;",
1729
2017
  " margin-right: 8px;",
1730
2018
  "}",
@@ -1812,6 +2100,149 @@ window.__ModuleLoader__.load({
1812
2100
  " background: transparent;",
1813
2101
  "}",
1814
2102
  "",
2103
+ "/* ---------- Claude Code layout: model picker ---------- */",
2104
+ "/* Replaces the host's two-pane model menu: level 1 carries the current",
2105
+ " provider's models, a divider, the effort row and a More models row; both",
2106
+ " rows open their level 2 beside this popover. Container metrics mirror the",
2107
+ " permission popover so the two read as one design. */",
2108
+ "body[data-dsh-claude-style] .dsh-claude-model-popover {",
2109
+ " position: fixed !important;",
2110
+ " min-width: 248px !important;",
2111
+ " max-width: min(360px, calc(100vw - 16px)) !important;",
2112
+ " max-height: min(440px, calc(100vh - 96px)) !important;",
2113
+ " overflow-y: auto !important;",
2114
+ " background: var(--dsw-alias-bg-overlay, #ffffff) !important;",
2115
+ " border: 1px solid var(--dsw-alias-border-l1, #e8e6dc) !important;",
2116
+ " border-radius: 12px !important;",
2117
+ " box-shadow: 0 8px 30px rgba(20, 20, 19, 0.12), 0 2px 8px rgba(20, 20, 19, 0.06) !important;",
2118
+ " padding: 6px !important;",
2119
+ " box-sizing: border-box !important;",
2120
+ " z-index: 99999 !important;",
2121
+ " display: flex !important;",
2122
+ " flex-direction: column !important;",
2123
+ " gap: 6px !important;",
2124
+ " opacity: 0 !important;",
2125
+ " pointer-events: none !important;",
2126
+ " transform: translateY(4px) scale(0.98) !important;",
2127
+ " transform-origin: bottom right !important;",
2128
+ " transition: opacity 0.15s ease, transform 0.15s ease !important;",
2129
+ "}",
2130
+ "body[data-dsh-claude-style] .dsh-claude-model-popover[data-open=\"true\"] {",
2131
+ " opacity: 1 !important;",
2132
+ " pointer-events: auto !important;",
2133
+ " transform: translateY(0) scale(1) !important;",
2134
+ "}",
2135
+ "body[data-dsh-claude-style][data-ds-dark-theme] .dsh-claude-model-popover {",
2136
+ " background: #1e1e1d !important;",
2137
+ " border-color: #2e2c29 !important;",
2138
+ " box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3) !important;",
2139
+ "}",
2140
+ "body[data-dsh-claude-style] .dsh-claude-model-popover-body {",
2141
+ " display: flex !important;",
2142
+ " flex-direction: column !important;",
2143
+ " gap: 6px !important;",
2144
+ " min-width: 0 !important;",
2145
+ "}",
2146
+ "body[data-dsh-claude-style] .dsh-claude-model-status {",
2147
+ " color: var(--dsw-alias-label-tertiary, #8f8d84) !important;",
2148
+ " font-size: 12px !important;",
2149
+ " line-height: 20px !important;",
2150
+ " padding: 4px 8px !important;",
2151
+ "}",
2152
+ "body[data-dsh-claude-style] .dsh-claude-model-group {",
2153
+ " color: var(--dsw-alias-label-tertiary, #8f8d84) !important;",
2154
+ " font-size: 11px !important;",
2155
+ " line-height: 16px !important;",
2156
+ " padding: 2px 8px 0 8px !important;",
2157
+ "}",
2158
+ "/* Model / effort option: same row metrics and hover as the drawer items. */",
2159
+ "body[data-dsh-claude-style] .dsh-claude-model-option {",
2160
+ " display: flex !important;",
2161
+ " align-items: center !important;",
2162
+ " gap: 8px !important;",
2163
+ " width: 100% !important;",
2164
+ " min-height: 32px !important;",
2165
+ " padding: 4px 8px !important;",
2166
+ " border: none !important;",
2167
+ " border-radius: 6px !important;",
2168
+ " background: transparent !important;",
2169
+ " color: var(--dsw-alias-label-primary, #141413) !important;",
2170
+ " font-size: 13px !important;",
2171
+ " text-align: left !important;",
2172
+ " cursor: pointer !important;",
2173
+ " box-sizing: border-box !important;",
2174
+ "}",
2175
+ "body[data-dsh-claude-style] .dsh-claude-model-option:hover {",
2176
+ " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.08)) !important;",
2177
+ "}",
2178
+ "body[data-dsh-claude-style] .dsh-claude-model-copy {",
2179
+ " display: flex !important;",
2180
+ " flex-direction: column !important;",
2181
+ " gap: 2px !important;",
2182
+ " flex: 1 !important;",
2183
+ " min-width: 0 !important;",
2184
+ "}",
2185
+ "body[data-dsh-claude-style] .dsh-claude-model-name {",
2186
+ " font-size: 13px !important;",
2187
+ " font-weight: 500 !important;",
2188
+ " line-height: 16px !important;",
2189
+ "}",
2190
+ "/* The row carries one description line, in the shell's language: the copy",
2191
+ " document is localized rather than stacked, so there is no second-language",
2192
+ " rule to style. */",
2193
+ "body[data-dsh-claude-style] .dsh-claude-model-desc {",
2194
+ " font-size: 11px !important;",
2195
+ " line-height: 14px !important;",
2196
+ " color: var(--dsw-alias-label-tertiary, #8f8d84) !important;",
2197
+ "}",
2198
+ "body[data-dsh-claude-style] .dsh-claude-model-check {",
2199
+ " flex: none !important;",
2200
+ " display: inline-flex !important;",
2201
+ " align-items: center !important;",
2202
+ " color: var(--dsw-alias-brand-primary, #d97757) !important;",
2203
+ "}",
2204
+ "body[data-dsh-claude-style] .dsh-claude-model-divider {",
2205
+ " height: 1px !important;",
2206
+ " background: var(--dsw-alias-border-l1, #e8e6dc) !important;",
2207
+ " margin: 2px 4px !important;",
2208
+ " flex: none !important;",
2209
+ "}",
2210
+ "/* Level-2 row: label + current value + chevron; hover opens its own level. */",
2211
+ "body[data-dsh-claude-style] .dsh-claude-model-cell {",
2212
+ " display: flex !important;",
2213
+ " align-items: center !important;",
2214
+ " gap: 8px !important;",
2215
+ " width: 100% !important;",
2216
+ " min-height: 32px !important;",
2217
+ " padding: 4px 8px !important;",
2218
+ " border: none !important;",
2219
+ " border-radius: 6px !important;",
2220
+ " background: transparent !important;",
2221
+ " color: var(--dsw-alias-label-primary, #141413) !important;",
2222
+ " font-size: 13px !important;",
2223
+ " text-align: left !important;",
2224
+ " cursor: pointer !important;",
2225
+ " box-sizing: border-box !important;",
2226
+ "}",
2227
+ "body[data-dsh-claude-style] .dsh-claude-model-cell:hover {",
2228
+ " background: var(--dsh-claude-hover-bg, rgba(0, 0, 0, 0.08)) !important;",
2229
+ "}",
2230
+ "body[data-dsh-claude-style] .dsh-claude-model-cell-label {",
2231
+ " flex: 1 !important;",
2232
+ " min-width: 0 !important;",
2233
+ "}",
2234
+ "body[data-dsh-claude-style] .dsh-claude-model-cell-value {",
2235
+ " flex: none !important;",
2236
+ " color: var(--dsw-alias-label-tertiary, #8f8d84) !important;",
2237
+ " font-size: 12px !important;",
2238
+ "}",
2239
+ "body[data-dsh-claude-style] .dsh-claude-model-cell-chevron {",
2240
+ " flex: none !important;",
2241
+ " display: inline-flex !important;",
2242
+ " align-items: center !important;",
2243
+ " color: var(--dsw-alias-label-caption, #a6a094) !important;",
2244
+ "}",
2245
+ "",
1815
2246
  "/* Popover Header */",
1816
2247
  "body[data-dsh-claude-style] .dsh-claude-account-popover-header {",
1817
2248
  " padding: 6px 8px 6px 8px !important;",
@@ -1909,13 +2340,39 @@ window.__ModuleLoader__.load({
1909
2340
  " display: none !important;",
1910
2341
  "}",
1911
2342
  "",
2343
+ "/* ---------- Footer takeover ----------",
2344
+ " Everything in this block modifies the HOST's own footer (it hides entries and",
2345
+ " zeroes the containers that host them) and exists only because the skin",
2346
+ " replaces that footer with its account row. The \"Collapse the sidebar settings",
2347
+ " area\" preference turns the whole takeover off, so each rule below carries",
2348
+ " data-dsh-claude-footer-takeover — the skin sets it on <body> only while the takeover is on,",
2349
+ " and with it absent the host footer renders exactly as shipped. */",
1912
2350
  "/* Hide original trigger buttons in footArea while keeping containers intact for modals */",
1913
- "body[data-dsh-claude-style] [class*=\"footArea\"] > [class*=\"settingsArea\"] > [class*=\"triggerRow\"],",
1914
- "body[data-dsh-claude-style] [class*=\"footArea\"] > [class*=\"footerActions\"] :is([class*=\"footerButtons\"], > button) {",
2351
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] > [class*=\"settingsArea\"] > [class*=\"triggerRow\"],",
2352
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] > [class*=\"footerActions\"] :is([class*=\"footerButtons\"], > button) {",
1915
2353
  " display: none !important;",
1916
2354
  "}",
1917
- "body[data-dsh-claude-style] [class*=\"footArea\"] > [class*=\"settingsArea\"],",
1918
- "body[data-dsh-claude-style] [class*=\"footArea\"] > [class*=\"footerActions\"] {",
2355
+ "/* Both containers stay mounted at zero size so the overlays they host keep",
2356
+ " painting, but the collapse must stay geometric. font-size and line-height",
2357
+ " inherit, and the settings dialog mounts IN PLACE inside settingsArea (the",
2358
+ " host renders its overlay as a sibling of the trigger row — no portal): the",
2359
+ " dialog inherited font-size: 0 with line-height: 0px, so every text line",
2360
+ " that sets an explicit font-size without its own line-height (the SubAgent",
2361
+ " page's rows, the onboarding overlay) collapsed to a 0px line box and",
2362
+ " vanished. settingsArea hosts nothing besides its display:none'd trigger row",
2363
+ " and those in-place overlays, so it keeps only the geometric collapse and",
2364
+ " hands real inherited metrics down; footerActions still hosts plain plugin",
2365
+ " entries whose stray in-flow text only the zeroing keeps invisible, so the",
2366
+ " full collapse stays there. */",
2367
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] > [class*=\"settingsArea\"] {",
2368
+ " position: static !important;",
2369
+ " width: 0 !important;",
2370
+ " height: 0 !important;",
2371
+ " margin: 0 !important;",
2372
+ " padding: 0 !important;",
2373
+ " overflow: visible !important;",
2374
+ "}",
2375
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] > [class*=\"footerActions\"] {",
1919
2376
  " position: static !important;",
1920
2377
  " width: 0 !important;",
1921
2378
  " height: 0 !important;",
@@ -1934,10 +2391,10 @@ window.__ModuleLoader__.load({
1934
2391
  " keep their subtree visible — the overlay must stay reachable after the",
1935
2392
  " mirrored popover item opens it — but the entry box itself collapses so it",
1936
2393
  " never paints inside the zero-sized footerActions container. */",
1937
- "body[data-dsh-claude-style] [class*=\"footArea\"] [data-dsh-claude-footer-hidden] {",
2394
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] [data-dsh-claude-footer-hidden] {",
1938
2395
  " display: none !important;",
1939
2396
  "}",
1940
- "body[data-dsh-claude-style] [class*=\"footArea\"] [data-dsh-claude-footer-entry] {",
2397
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"footArea\"] [data-dsh-claude-footer-entry] {",
1941
2398
  " width: 0 !important;",
1942
2399
  " height: 0 !important;",
1943
2400
  " min-width: 0 !important;",
@@ -1963,13 +2420,47 @@ window.__ModuleLoader__.load({
1963
2420
  "body[data-dsh-claude-style] [class*=\"root\"][class*=\"collapsed\"] :is(.dsh-claude-account-label, .dsh-claude-account-chevron) {",
1964
2421
  " display: none !important;",
1965
2422
  "}",
2423
+ "/* The rail's popover cannot stay an absolutely positioned child of the footer.",
2424
+ " The sidebar column is 56px wide with `overflow: hidden`, so a panel anchored",
2425
+ " past the rail edge is cut off the moment it crosses it — and the base rule's",
2426
+ " percentage max-width, measured against the 59px footer, squashed it to 43px.",
2427
+ " Fixed positioning lifts it out of that clip (no ancestor is a containing block",
2428
+ " for it), and overrides.js anchors it to the trigger from there. left/right/",
2429
+ " bottom are reset so the base rule's own `!important` anchors cannot fight the",
2430
+ " resolved coordinates. */",
1966
2431
  "body[data-dsh-claude-style] [class*=\"root\"][class*=\"collapsed\"] .dsh-claude-account-popover {",
1967
- " left: calc(100% + 8px) !important;",
1968
- " bottom: 0 !important;",
2432
+ " position: fixed !important;",
2433
+ " left: auto !important;",
1969
2434
  " right: auto !important;",
2435
+ " bottom: auto !important;",
2436
+ " top: auto !important;",
1970
2437
  " width: 220px !important;",
2438
+ " max-width: min(220px, calc(100vw - 16px)) !important;",
1971
2439
  " transform-origin: bottom left !important;",
1972
2440
  "}",
2441
+ "/* The rail opens the panel beside the trigger, not above it, so the hover bridge",
2442
+ " has to span the horizontal gap: the base rule's downward strip would sit under",
2443
+ " the panel and leave the pointer's 8px crossing uncovered. */",
2444
+ "body[data-dsh-claude-style] [class*=\"root\"][class*=\"collapsed\"] .dsh-claude-account-popover::after {",
2445
+ " top: 0 !important;",
2446
+ " bottom: 0 !important;",
2447
+ " left: auto !important;",
2448
+ " right: 100% !important;",
2449
+ " width: 12px !important;",
2450
+ " height: auto !important;",
2451
+ "}",
2452
+ "/* In the rail the account button is the only control; the settings entry lives",
2453
+ " in the popover. The settings container is zero-sized rather than hidden (its",
2454
+ " dialog must stay reachable), which is enough while the sidebar is wide — the",
2455
+ " entry is squeezed to a 4px sliver. A plugin that ships its own rail variant",
2456
+ " escapes that box instead: the settings plugin's `…_rail` trigger keeps its",
2457
+ " full 36px square and lands straight on top of the Claude mark. Hide the entry",
2458
+ " in the rail. Reachability is unaffected — the popover's settings item opens",
2459
+ " the real trigger programmatically (`realTrigger.click()`), which",
2460
+ " display:none does not block. */",
2461
+ "body[data-dsh-claude-style][data-dsh-claude-footer-takeover] [class*=\"root\"][class*=\"collapsed\"] [class*=\"footArea\"] [class*=\"settingsArea\"] :is(button, [class*=\"triggerRow\"]) {",
2462
+ " display: none !important;",
2463
+ "}",
1973
2464
  "",
1974
2465
  "/* Embedded footer widgets: display-only plugin entries (progress bars,",
1975
2466
  " status panels — the cost-meter balance/quota stack is the known case)",
@@ -2031,10 +2522,12 @@ window.__ModuleLoader__.load({
2031
2522
  " overflow-x: auto;",
2032
2523
  "}",
2033
2524
  "",
2034
- "/* ---------- Claude Code layout: settings section (brand) ---------- */",
2035
- "/* The skin's own page in the settings dialog. It borrows the composer's",
2036
- " segment language so the two controls read as one design. */",
2037
- "body[data-dsh-claude-style] .dsh-claude-brand-section {",
2525
+ "/* ---------- Claude Code layout: settings page ---------- */",
2526
+ "/* The skin's own page in the settings dialog. Its segmented controls reuse the",
2527
+ " composer permission picker's classes (`.dsh-claude-segments` /",
2528
+ " `.dsh-claude-segment`), so the two are literally one control rather than two",
2529
+ " lookalikes; only the row shell and the switch are new here. */",
2530
+ "body[data-dsh-claude-style] .dsh-claude-settings {",
2038
2531
  " display: flex;",
2039
2532
  " flex-direction: column;",
2040
2533
  " gap: 16px;",
@@ -2044,13 +2537,13 @@ window.__ModuleLoader__.load({
2044
2537
  " font-family: var(--dsw-font-family);",
2045
2538
  "}",
2046
2539
  "",
2047
- "body[data-dsh-claude-style] .dsh-claude-brand-title {",
2540
+ "body[data-dsh-claude-style] .dsh-claude-settings-title {",
2048
2541
  " font-size: 15px;",
2049
2542
  " font-weight: 600;",
2050
2543
  " color: var(--dsw-alias-label-primary);",
2051
2544
  "}",
2052
2545
  "",
2053
- "body[data-dsh-claude-style] .dsh-claude-brand-card {",
2546
+ "body[data-dsh-claude-style] .dsh-claude-settings-row {",
2054
2547
  " display: flex;",
2055
2548
  " align-items: center;",
2056
2549
  " gap: 12px;",
@@ -2059,72 +2552,73 @@ window.__ModuleLoader__.load({
2059
2552
  " border-radius: 12px;",
2060
2553
  "}",
2061
2554
  "",
2062
- "body[data-dsh-claude-style] .dsh-claude-brand-card-text {",
2555
+ "body[data-dsh-claude-style] .dsh-claude-settings-row-text {",
2063
2556
  " flex: 1;",
2064
2557
  " min-width: 0;",
2065
2558
  "}",
2066
2559
  "",
2067
- "body[data-dsh-claude-style] .dsh-claude-brand-card-title {",
2560
+ "body[data-dsh-claude-style] .dsh-claude-settings-row-title {",
2068
2561
  " font-size: 13px;",
2069
2562
  " font-weight: 600;",
2070
2563
  " line-height: 1.5;",
2071
2564
  " color: var(--dsw-alias-label-primary);",
2072
2565
  "}",
2073
2566
  "",
2074
- "body[data-dsh-claude-style] .dsh-claude-brand-card-desc {",
2567
+ "body[data-dsh-claude-style] .dsh-claude-settings-row-desc {",
2075
2568
  " margin-top: 4px;",
2076
2569
  " font-size: 12px;",
2077
2570
  " line-height: 1.5;",
2078
2571
  " color: var(--dsw-alias-label-tertiary);",
2079
2572
  "}",
2080
2573
  "",
2081
- "body[data-dsh-claude-style] .dsh-claude-brand-segments {",
2574
+ "body[data-dsh-claude-style] .dsh-claude-settings-error {",
2575
+ " font-size: 12px;",
2576
+ " line-height: 1.5;",
2577
+ " color: var(--dsw-alias-state-error-primary, #c0392b);",
2578
+ "}",
2579
+ "",
2580
+ "/* The switch borrows the segment track's palette and radius so a page of rows",
2581
+ " reads as one control set rather than two. */",
2582
+ "body[data-dsh-claude-style] .dsh-claude-settings-switch {",
2082
2583
  " flex: none;",
2083
- " display: inline-flex;",
2084
- " align-items: center;",
2085
- " gap: 2px;",
2584
+ " appearance: none;",
2585
+ " margin: 0;",
2586
+ " border: 0;",
2587
+ " cursor: pointer;",
2588
+ " width: 36px;",
2589
+ " height: 20px;",
2086
2590
  " padding: 2px;",
2087
- " border-radius: 7px;",
2591
+ " box-sizing: border-box;",
2592
+ " border-radius: 10px;",
2088
2593
  " background: var(--dsw-specific-selector);",
2594
+ " transition: background-color .12s ease;",
2089
2595
  "}",
2090
2596
  "",
2091
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) .dsh-claude-brand-segments {",
2597
+ "body[data-dsh-claude-style]:not([data-ds-dark-theme]) .dsh-claude-settings-switch {",
2092
2598
  " background: #f6f6f4;",
2093
2599
  "}",
2094
2600
  "",
2095
- "body[data-dsh-claude-style] .dsh-claude-brand-option {",
2096
- " appearance: none;",
2097
- " margin: 0;",
2098
- " border: 0;",
2099
- " cursor: pointer;",
2100
- " background: transparent;",
2101
- " color: var(--dsw-alias-label-secondary);",
2102
- " font: inherit;",
2103
- " font-size: 13px;",
2104
- " font-weight: 500;",
2105
- " line-height: 18px;",
2106
- " padding: 3px 12px;",
2107
- " border-radius: 7px;",
2108
- " transition: background-color .1s, color .1s;",
2109
- "}",
2110
- "",
2111
- "body[data-dsh-claude-style] .dsh-claude-brand-option:hover:not([data-active=\"true\"]) {",
2112
- " color: var(--dsw-alias-label-primary);",
2601
+ "body[data-dsh-claude-style] .dsh-claude-settings-switch[data-on] {",
2602
+ " background: var(--dsw-alias-brand-primary, #d97757);",
2113
2603
  "}",
2114
2604
  "",
2115
- "body[data-dsh-claude-style] .dsh-claude-brand-option[data-active=\"true\"] {",
2116
- " color: var(--dsw-alias-label-primary);",
2117
- " background: var(--dsw-alias-bg-layer-3);",
2605
+ "body[data-dsh-claude-style] .dsh-claude-settings-switch-knob {",
2606
+ " display: block;",
2607
+ " width: 16px;",
2608
+ " height: 16px;",
2609
+ " border-radius: 50%;",
2610
+ " background: var(--dsw-alias-bg-overlay, #ffffff);",
2611
+ " box-shadow: 0 1px 2px rgba(20, 20, 19, 0.18);",
2612
+ " transition: transform .12s ease;",
2118
2613
  "}",
2119
2614
  "",
2120
- "body[data-dsh-claude-style]:not([data-ds-dark-theme]) .dsh-claude-brand-option[data-active=\"true\"] {",
2121
- " background: var(--dsw-alias-bg-overlay);",
2122
- " box-shadow: 0 1px 2px rgba(20, 20, 19, 0.08);",
2615
+ "body[data-dsh-claude-style] .dsh-claude-settings-switch[data-on] .dsh-claude-settings-switch-knob {",
2616
+ " transform: translateX(16px);",
2123
2617
  "}",
2124
2618
  ].join('\n')
2125
2619
 
2126
2620
  // ============================================================================
2127
- // Zone 3: 宿主上下文与通用辅助 (DSH Context & Helpers)
2621
+ // 宿主上下文访问器与辅助 (Host Context & Helpers)
2128
2622
  // ============================================================================
2129
2623
  function findAccessTrigger() {
2130
2624
  var prefixes = ['访问模式', 'Access mode']
@@ -2138,11 +2632,29 @@ window.__ModuleLoader__.load({
2138
2632
  return null
2139
2633
  }
2140
2634
 
2635
+ /**
2636
+ * The current-session selection left the Session Controller in dsh 0.2:
2637
+ * the list snapshot no longer carries `current`, and the main-view
2638
+ * selection is projected by the `uiSession` service as a binding source
2639
+ * whose `value.key` is the selected session id (`undefined` when no
2640
+ * session is materialized). Read the new source first and fall back to
2641
+ * the legacy `list.current` so older hosts keep working.
2642
+ */
2643
+ function currentSessionId(ctx, sessions) {
2644
+ try {
2645
+ var uiSession = ctx.get('uiSession')
2646
+ var current = uiSession === void 0 || uiSession === null ? null : uiSession.current
2647
+ var value = current === void 0 || current === null ? null : current.value
2648
+ if (value !== void 0 && value !== null && typeof value.key === 'string') return value.key
2649
+ } catch (error) { /* fall through to the legacy snapshot field */ }
2650
+ return sessions.list.getSnapshot().current
2651
+ }
2652
+
2141
2653
  function currentSession(ctx) {
2142
2654
  var sessions = ctx.get('sessions')
2143
2655
  if (sessions === void 0 || sessions === null) return null
2144
- var id = sessions.list.getSnapshot().current
2145
- if (id === void 0) return null
2656
+ var id = currentSessionId(ctx, sessions)
2657
+ if (id === void 0 || id === null) return null
2146
2658
  var binding = sessions.binding(id)
2147
2659
  if (binding === void 0 || binding === null) return null
2148
2660
  return binding.session === void 0 ? null : binding.session
@@ -2151,56 +2663,16 @@ window.__ModuleLoader__.load({
2151
2663
  function currentPreset(session) {
2152
2664
  try {
2153
2665
  var snapshot = session.projections.faceOf('permissions').getSnapshot()
2154
- return snapshot === void 0 ? null : snapshot.currentValue
2666
+ if (snapshot === void 0 || snapshot === null) return null
2667
+ // dsh 0.2+ projection faces hand back the bare value (e.g. the preset
2668
+ // id string); older hosts wrapped it as `{ currentValue }`.
2669
+ if (typeof snapshot === 'object' && 'currentValue' in snapshot) return snapshot.currentValue
2670
+ return snapshot
2155
2671
  } catch (error) {
2156
2672
  return null
2157
2673
  }
2158
2674
  }
2159
2675
 
2160
- /**
2161
- * Read the persisted brand choice.
2162
- *
2163
- * Storage is the renderer's own localStorage, which DSH backs with the
2164
- * `persist:dsh-desktop-renderer` partition, so the value survives an app
2165
- * restart. Every access is guarded: a locked-down or full store must not
2166
- * break the theme, so an unreadable value simply falls back to the default.
2167
- *
2168
- * @returns one of BRAND_CLAUDE / BRAND_ANTHROPIC.
2169
- */
2170
- function readStoredBrand() {
2171
- try {
2172
- var raw = window.localStorage.getItem(BRAND_STORAGE_KEY)
2173
- if (raw === BRAND_ANTHROPIC) return BRAND_ANTHROPIC
2174
- if (raw === BRAND_CLAUDE) return BRAND_CLAUDE
2175
- } catch (error) {
2176
- /* storage unavailable — fall through to the default */
2177
- }
2178
- return DEFAULT_BRAND
2179
- }
2180
-
2181
- /** Persist the brand choice, ignoring a store that refuses writes. */
2182
- function writeStoredBrand(brand) {
2183
- try {
2184
- window.localStorage.setItem(BRAND_STORAGE_KEY, brand)
2185
- } catch (error) {
2186
- /* storage unavailable — the session still shows the chosen brand */
2187
- }
2188
- }
2189
-
2190
- /**
2191
- * Apply a brand to the document. The stylesheet keys off the attribute, so
2192
- * this is the single mutation that repaints the sidebar brand; keeping it to
2193
- * one attribute write is what makes the switch cheap and idempotent.
2194
- *
2195
- * @param brand - the brand to show; unknown values fall back to the default.
2196
- * @returns the brand actually applied.
2197
- */
2198
- function applyBrand(brand) {
2199
- var next = brand === BRAND_ANTHROPIC ? BRAND_ANTHROPIC : BRAND_CLAUDE
2200
- document.body.setAttribute(BRAND_ATTR, next)
2201
- return next
2202
- }
2203
-
2204
2676
  /**
2205
2677
  * The client context exposes no user or account service, so the account
2206
2678
  * name is inferred from the home-directory segment of a workspace path or
@@ -2230,21 +2702,388 @@ window.__ModuleLoader__.load({
2230
2702
  return 'User'
2231
2703
  }
2232
2704
 
2705
+ /**
2706
+ * Host context reference for services that need to read host state
2707
+ * (e.g. locale) outside of apply(ctx)'s direct call stack.
2708
+ */
2709
+ var hostCtx = null
2710
+ function setHostContext(ctx) {
2711
+ hostCtx = ctx
2712
+ }
2713
+
2714
+ /**
2715
+ * Skin preferences.
2716
+ *
2717
+ * The authoritative store is the host settings namespace `claude-style`,
2718
+ * reached through this plugin's own route: the configuration client
2719
+ * (`settingsScope`) only reaches namespaces the api-proxy exposes to it, and
2720
+ * a plugin's own namespace is not on that list. `src/../lib/index.js` owns
2721
+ * the namespace and the route; this side only reads and writes it.
2722
+ *
2723
+ * Every value is mirrored onto the document as an attribute, so the
2724
+ * stylesheet — not this module — decides what a preference means visually.
2725
+ * Until the first read settles (and if it fails) the defaults below hold,
2726
+ * which is exactly the shipped behaviour.
2727
+ */
2728
+ var prefs = {
2729
+ brand: DEFAULT_BRAND,
2730
+ collapseFooter: true,
2731
+ autoPopover: true,
2732
+ composerScope: 'all',
2733
+ }
2734
+ var prefsRevision
2735
+ var prefsAvailable = false
2736
+ var prefsListeners = []
2737
+
2738
+ /** The current preferences (live object; treat as read-only). */
2739
+ function readPrefs() {
2740
+ return prefs
2741
+ }
2742
+
2743
+ /** Observe preference changes; returns the unsubscriber. */
2744
+ function subscribePrefs(listener) {
2745
+ prefsListeners.push(listener)
2746
+ return function () {
2747
+ var index = prefsListeners.indexOf(listener)
2748
+ if (index !== -1) prefsListeners.splice(index, 1)
2749
+ }
2750
+ }
2751
+
2752
+ /**
2753
+ * Adopt a preference set: mirror it onto the document, then notify.
2754
+ * @param next - resolved preferences from the host.
2755
+ */
2756
+ function adoptPrefs(next) {
2757
+ prefs = next
2758
+ // The brand is one attribute write; the other preferences gate rules the
2759
+ // stylesheet and the scheduler read directly.
2760
+ document.body.setAttribute(BRAND_ATTR, next.brand)
2761
+ if (next.collapseFooter) document.body.setAttribute(FOOTER_ATTR, '')
2762
+ else document.body.removeAttribute(FOOTER_ATTR)
2763
+ var listeners = prefsListeners.slice()
2764
+ for (var i = 0; i < listeners.length; i++) {
2765
+ try {
2766
+ listeners[i](next)
2767
+ } catch (error) { /* one bad listener must not stop the rest */ }
2768
+ }
2769
+ }
2770
+
2771
+ /**
2772
+ * Read the preferences once. A failure keeps the defaults and leaves the
2773
+ * settings page to report that the store is unavailable.
2774
+ */
2775
+ function loadPrefs() {
2776
+ if (typeof fetch !== 'function') return
2777
+ try {
2778
+ fetch(PREFS_ROUTE, {
2779
+ method: 'POST',
2780
+ headers: { 'Content-Type': 'application/json' },
2781
+ credentials: 'same-origin',
2782
+ body: '{}',
2783
+ })
2784
+ .then(function (response) {
2785
+ return response.json()
2786
+ })
2787
+ .then(function (data) {
2788
+ if (!data || data.ok !== true) return
2789
+ prefsRevision = data.revision
2790
+ prefsAvailable = data.available === true
2791
+ adoptPrefs(normalizePrefs(data.value))
2792
+ })
2793
+ .catch(function () { /* defaults stay */ })
2794
+ } catch (error) { /* no fetch: defaults stay */ }
2795
+ }
2796
+
2797
+ /** Clamp one host value into the preference shape (the host already did this). */
2798
+ function normalizePrefs(value) {
2799
+ var section = value && typeof value === 'object' ? value : {}
2800
+ return {
2801
+ brand: section.brand === BRAND_ANTHROPIC || section.brand === BRAND_OFF ? section.brand : BRAND_CLAUDE,
2802
+ collapseFooter: section.collapseFooter !== false,
2803
+ autoPopover: section.autoPopover !== false,
2804
+ composerScope: COMPOSER_SCOPES.indexOf(section.composerScope) === -1 ? 'all' : section.composerScope,
2805
+ }
2806
+ }
2807
+
2808
+ /**
2809
+ * Write a partial preference change.
2810
+ *
2811
+ * The revision travels with the write so a concurrent move of the namespace
2812
+ * is rejected rather than silently overwritten; on that rejection the
2813
+ * authoritative value is re-read.
2814
+ *
2815
+ * @param patch - preference keys to change.
2816
+ * @returns a promise for the resolved preferences, or null when unavailable.
2817
+ */
2818
+ function savePrefs(patch) {
2819
+ if (typeof fetch !== 'function') return Promise.resolve(null)
2820
+ var body = { revision: prefsRevision }
2821
+ for (var key in patch) body[key] = patch[key]
2822
+ return fetch(PREFS_ROUTE, {
2823
+ method: 'POST',
2824
+ headers: { 'Content-Type': 'application/json' },
2825
+ credentials: 'same-origin',
2826
+ body: JSON.stringify(body),
2827
+ })
2828
+ .then(function (response) {
2829
+ return response.json().then(function (data) {
2830
+ return { status: response.status, data: data }
2831
+ })
2832
+ })
2833
+ .then(function (result) {
2834
+ var data = result.data
2835
+ if (data && data.ok === true) {
2836
+ prefsRevision = data.revision
2837
+ prefsAvailable = data.available === true
2838
+ adoptPrefs(normalizePrefs(data.value))
2839
+ return prefs
2840
+ }
2841
+ // Conflict or refusal: re-read rather than guess.
2842
+ loadPrefs()
2843
+ return null
2844
+ })
2845
+ .catch(function () {
2846
+ return null
2847
+ })
2848
+ }
2849
+
2850
+ /**
2851
+ * The brand to show. `off` leaves the brand area entirely to the host, so
2852
+ * the stylesheet matches neither brand variant for it.
2853
+ *
2854
+ * @param brand - the stored choice.
2855
+ * @returns the brand actually applied.
2856
+ */
2857
+ function applyBrand(brand) {
2858
+ var next = brand === BRAND_ANTHROPIC || brand === BRAND_OFF ? brand : BRAND_CLAUDE
2859
+ document.body.setAttribute(BRAND_ATTR, next)
2860
+ return next
2861
+ }
2862
+
2863
+ /**
2864
+ * Model & settings localized copy.
2865
+ *
2866
+ * The copy document ships as `model-descriptions.json` beside the bundle.
2867
+ * Both the model picker (src/overrides/model-picker.js) and the settings section
2868
+ * (src/settings.js) consume this copy, so the state lives in the shared context.
2869
+ * where both zones can reach it.
2870
+ */
2871
+ var modelCopy = null
2872
+ var modelCopyRequested = false
2873
+ var modelCopyListeners = []
2874
+
2875
+ function onModelCopyLoaded(listener) {
2876
+ modelCopyListeners.push(listener)
2877
+ return function () {
2878
+ var index = modelCopyListeners.indexOf(listener)
2879
+ if (index !== -1) modelCopyListeners.splice(index, 1)
2880
+ }
2881
+ }
2882
+
2883
+ /**
2884
+ * Fetch the model copy document the host half serves.
2885
+ */
2886
+ function loadModelCopy() {
2887
+ if (modelCopyRequested) return
2888
+ modelCopyRequested = true
2889
+ if (typeof fetch !== 'function') return
2890
+ try {
2891
+ fetch(MODEL_COPY_ROUTE, { credentials: 'same-origin' })
2892
+ .then(function (response) {
2893
+ if (!response.ok) throw new Error('HTTP ' + response.status)
2894
+ return response.json()
2895
+ })
2896
+ .then(function (doc) {
2897
+ modelCopy = indexModelCopy(doc)
2898
+ if (modelCopy === null) return
2899
+ var listeners = modelCopyListeners.slice()
2900
+ for (var i = 0; i < listeners.length; i++) {
2901
+ try {
2902
+ listeners[i](modelCopy)
2903
+ } catch (error) { /* listener error */ }
2904
+ }
2905
+ })
2906
+ .catch(function () { /* fallback copy stays */ })
2907
+ } catch (error) { /* no fetch: fallback copy stays */ }
2908
+ }
2909
+
2910
+ /**
2911
+ * Compile a copy document into the shape lookups want: a folded id index,
2912
+ * the alias table, and the rule lists with their regexps built once.
2913
+ * @param doc - parsed document; anything malformed is dropped, not fatal.
2914
+ * @returns the index, or null when the document is unusable.
2915
+ */
2916
+ function indexModelCopy(doc) {
2917
+ if (!doc || typeof doc !== 'object') return null
2918
+ var exact = doc.exact && typeof doc.exact === 'object' ? doc.exact : {}
2919
+ var index = {
2920
+ ui: doc.ui && typeof doc.ui === 'object' ? doc.ui : {},
2921
+ settings: doc.settings && typeof doc.settings === 'object' ? doc.settings : {},
2922
+ exact: exact,
2923
+ aliases: doc.aliases && typeof doc.aliases === 'object' ? doc.aliases : {},
2924
+ fallback: typeof doc.fallback === 'string' && doc.fallback ? doc.fallback : MODEL_COPY_FALLBACK_LOCALE,
2925
+ folded: {},
2926
+ foldedAliases: {},
2927
+ families: [],
2928
+ tiers: [],
2929
+ }
2930
+ for (var id in exact) index.folded[normalizeModelId(id)] = exact[id]
2931
+ for (var a in index.aliases) {
2932
+ index.foldedAliases[normalizeModelId(a)] = index.aliases[a]
2933
+ index.foldedAliases[a.toLowerCase()] = index.aliases[a]
2934
+ }
2935
+ var compile = function (rules) {
2936
+ var out = []
2937
+ for (var i = 0; i < (rules || []).length; i++) {
2938
+ var rule = rules[i]
2939
+ if (!rule || typeof rule.match !== 'string') continue
2940
+ try {
2941
+ out.push({ re: new RegExp(rule.match, 'i'), key: rule.key, text: rule.text })
2942
+ } catch (error) { /* a malformed rule is skipped, not fatal */ }
2943
+ }
2944
+ return out
2945
+ }
2946
+ index.families = compile(doc.families)
2947
+ index.tiers = compile(doc.tiers)
2948
+ return index
2949
+ }
2950
+
2951
+ /** Fold case and separators so `glm-5.3-flash` and `glm-5-3-flash` agree. */
2952
+ function normalizeModelId(id) {
2953
+ return String(id === void 0 || id === null ? '' : id).toLowerCase().replace(/[^a-z0-9]/g, '')
2954
+ }
2955
+
2956
+ /** The shell's active locale id, or the document fallback when it cannot be read. */
2957
+ function activeLocale(ctx) {
2958
+ var c = ctx || hostCtx
2959
+ try {
2960
+ if (c && typeof c.get === 'function') {
2961
+ var locale = c.get('locale')
2962
+ if (locale && typeof locale.getSnapshot === 'function') {
2963
+ var active = locale.getSnapshot().active
2964
+ if (typeof active === 'string' && active) return active
2965
+ }
2966
+ }
2967
+ } catch (error) { /* no locale service: keep the fallback language */ }
2968
+ return modelCopy === null ? MODEL_COPY_FALLBACK_LOCALE : modelCopy.fallback
2969
+ }
2970
+
2971
+ /** One localized string out of a `{ locale: text }` pair, fallback locale last. */
2972
+ function localized(pair, ctx) {
2973
+ if (!pair || typeof pair !== 'object') return ''
2974
+ var loc = activeLocale(ctx)
2975
+ var text = pair[loc]
2976
+ if (typeof text === 'string' && text) return text
2977
+ var prefix = typeof loc === 'string' && loc.indexOf('-') !== -1 ? loc.split('-')[0] : (typeof loc === 'string' && loc.indexOf('_') !== -1 ? loc.split('_')[0] : '')
2978
+ if (prefix && typeof pair[prefix] === 'string' && pair[prefix]) return pair[prefix]
2979
+ var fallback = modelCopy === null ? MODEL_COPY_FALLBACK_LOCALE : modelCopy.fallback
2980
+ var backstop = pair[fallback]
2981
+ if (typeof backstop === 'string' && backstop) return backstop
2982
+ var fallbackPrefix = typeof fallback === 'string' && fallback.indexOf('-') !== -1 ? fallback.split('-')[0] : ''
2983
+ if (fallbackPrefix && typeof pair[fallbackPrefix] === 'string' && pair[fallbackPrefix]) return pair[fallbackPrefix]
2984
+ return ''
2985
+ }
2986
+
2987
+ /**
2988
+ * One picker label: the document's localized string, else the neutral
2989
+ * English constant the bundle carries. `{name}` placeholders are filled
2990
+ * from `params`, so a label with a slot stays translatable.
2991
+ */
2992
+ function copyLabel(key, fallback, params) {
2993
+ var text = modelCopy === null || !modelCopy.ui ? '' : localized(modelCopy.ui[key])
2994
+ if (!text) text = fallback
2995
+ if (!params) return text
2996
+ return text.replace(/\{(\w+)\}/g, function (match, name) {
2997
+ return Object.prototype.hasOwnProperty.call(params, name) ? String(params[name]) : match
2998
+ })
2999
+ }
3000
+
3001
+ /**
3002
+ * One settings-page string. The settings copy rides the same document as
3003
+ * the picker copy, so the page follows the shell language too — and the
3004
+ * English constants stay as the fallback for a failed fetch.
3005
+ */
3006
+ function settingsCopy(key, fallback) {
3007
+ var text = modelCopy === null || !modelCopy.settings ? '' : localized(modelCopy.settings[key])
3008
+ return text || fallback
3009
+ }
3010
+
2233
3011
  // ============================================================================
2234
- // Zone 4: Claude Code UI 重塑与交互增强 (UI Overrides)
3012
+ // 弹层共享辅助 (Shared Popover Helpers)
2235
3013
  // ============================================================================
3014
+ var POPOVER_MARGIN = 8
3015
+
2236
3016
  /**
2237
- * Install the Claude Code surface rewrites: the copy slots (hero headline,
2238
- * composer hint), the permission segmented control, and the account footer.
2239
- * All of them sit in React-rendered trees — the headline and hint re-render
2240
- * on locale switches, the hint unmounts while a draft exists, and the
2241
- * composer re-renders the access trigger on every preset change — so one
2242
- * MutationObserver re-applies them after each render. Every rewrite is
2243
- * idempotent (a node already in the target state is left alone, and the
2244
- * controls are only inserted when absent), so the observer cannot feed
2245
- * itself.
3017
+ * Position a fixed-position popover relative to its trigger.
3018
+ *
3019
+ * `side: 'right'` opens to the trigger's right and bottom-aligns it (the
3020
+ * account popover in the rail). The default `side: 'above'` right-aligns
3021
+ * the popover with the trigger and opens above it with `gap` spacing (the
3022
+ * model picker). `important` switches to `style.setProperty(..., 'important')`
3023
+ * and rounds the coordinates, as the account popover requires.
3024
+ *
3025
+ * @param trigger - element the popover is anchored to.
3026
+ * @param pop - the fixed-position popover element.
3027
+ * @param opts - `{ side, gap, important }`.
3028
+ * @returns the chosen `{ x, y }` in viewport coordinates.
2246
3029
  */
2247
- function installOverrides(ctx) {
3030
+ function positionAnchoredPopover(trigger, pop, opts) {
3031
+ opts = opts || {}
3032
+ var rect = trigger.getBoundingClientRect()
3033
+ var width = pop.offsetWidth
3034
+ var height = pop.offsetHeight
3035
+ var margin = opts.margin || POPOVER_MARGIN
3036
+ var x
3037
+ var y
3038
+ if (opts.side === 'right') {
3039
+ x = rect.right + margin
3040
+ if (x + width > window.innerWidth - margin) {
3041
+ x = Math.max(margin, rect.left - margin - width)
3042
+ }
3043
+ y = Math.min(Math.max(margin, rect.bottom - height), Math.max(margin, window.innerHeight - height - margin))
3044
+ } else {
3045
+ x = Math.max(margin, Math.min(rect.right - width, window.innerWidth - width - margin))
3046
+ y = rect.top - (opts.gap || 0) - height
3047
+ if (y < margin) y = Math.min(rect.bottom + (opts.gap || 0), Math.max(margin, window.innerHeight - height - margin))
3048
+ }
3049
+ if (opts.important) {
3050
+ pop.style.setProperty('left', Math.round(x) + 'px', 'important')
3051
+ pop.style.setProperty('top', Math.round(y) + 'px', 'important')
3052
+ } else {
3053
+ pop.style.left = x + 'px'
3054
+ pop.style.top = y + 'px'
3055
+ }
3056
+ return { x: x, y: y }
3057
+ }
3058
+
3059
+ /**
3060
+ * Hover-intent helper shared by the model picker and account popover.
3061
+ *
3062
+ * The `open` callback is part of the shared signature but the original
3063
+ * hover behaviour only schedules the close side (mouseenter calls the
3064
+ * feature's open function directly); keeping the parameter makes the two
3065
+ * call sites symmetrical.
3066
+ */
3067
+ function createHoverIntent(open, close, delay) {
3068
+ var timer = null
3069
+ return {
3070
+ cancel: function () {
3071
+ if (timer) {
3072
+ clearTimeout(timer)
3073
+ timer = null
3074
+ }
3075
+ },
3076
+ scheduleClose: function () {
3077
+ if (timer) clearTimeout(timer)
3078
+ timer = setTimeout(close, delay)
3079
+ },
3080
+ }
3081
+ }
3082
+
3083
+ // ============================================================================
3084
+ // 4.1: 文案改写 (Copy Rewrites)
3085
+ // ============================================================================
3086
+ function installCopy(ctx, ui) {
2248
3087
  // --- 4.1 Copy Overrides ---
2249
3088
  /** Shipped idle composer hints (zh / en, hero / default) this skin replaces. */
2250
3089
  var HINT_SOURCES = [
@@ -2271,7 +3110,19 @@ window.__ModuleLoader__.load({
2271
3110
  }
2272
3111
  }
2273
3112
 
3113
+ function isHeroView() {
3114
+ var hasTurns = document.querySelector('[class*="turn"], [class*="message"], [data-turn], [data-message-id]') !== null
3115
+ return !hasTurns && (document.querySelector('[class*="composerHero"], [data-phase="hero"]') !== null)
3116
+ }
3117
+
3118
+ function isComposerActive() {
3119
+ var isHero = isHeroView()
3120
+ var scope = readPrefs().composerScope
3121
+ return scope === 'all' || (isHero ? scope === 'hero' : scope === 'conversation')
3122
+ }
3123
+
2274
3124
  function rewriteHint() {
3125
+ if (!isComposerActive()) return
2275
3126
  var isHero = document.querySelector('[class*="heroWorkspaceRow"], [class*="titleGroup"]') !== null
2276
3127
  var targetHint = isHero ? COMPOSER_HINT : 'Type / for commands'
2277
3128
  var hints = document.querySelectorAll('[data-composer-placeholder]')
@@ -2287,6 +3138,54 @@ window.__ModuleLoader__.load({
2287
3138
  }
2288
3139
  if (idle && text !== targetHint) node.textContent = targetHint
2289
3140
  }
3141
+ syncAttachmentPlaceholder()
3142
+ }
3143
+
3144
+ function syncAttachmentPlaceholder() {
3145
+ if (!isComposerActive()) {
3146
+ var synths = document.querySelectorAll('[data-dsh-synthetic-placeholder]')
3147
+ for (var si = 0; si < synths.length; si++) {
3148
+ if (synths[si].parentElement) synths[si].parentElement.removeChild(synths[si])
3149
+ }
3150
+ return
3151
+ }
3152
+ var isHero = document.querySelector('[class*="heroWorkspaceRow"], [class*="titleGroup"]') !== null
3153
+ var targetHint = isHero ? COMPOSER_HINT : 'Type / for commands'
3154
+ var cards = document.querySelectorAll('[data-composer-card]')
3155
+ for (var ci = 0; ci < cards.length; ci++) {
3156
+ var card = cards[ci]
3157
+ var input = card.querySelector('[data-composer-input]')
3158
+ if (!input) continue
3159
+ var text = (input.textContent || '').replace(/[\u200B-\u200D\uFEFF]/g, '').trim()
3160
+ var isEmpty = text.length === 0
3161
+ var placeholder = card.querySelector('[data-composer-placeholder]')
3162
+ var grow = input.closest ? input.closest('[class*="grow"]') : input.parentElement
3163
+
3164
+ if (isEmpty) {
3165
+ if (!placeholder && grow) {
3166
+ placeholder = document.createElement('div')
3167
+ placeholder.setAttribute('data-composer-placeholder', '')
3168
+ placeholder.setAttribute('data-dsh-synthetic-placeholder', 'true')
3169
+ placeholder.textContent = targetHint
3170
+ grow.appendChild(placeholder)
3171
+ } else if (placeholder) {
3172
+ if (placeholder.style.display === 'none') placeholder.style.display = ''
3173
+ var curText = placeholder.textContent || ''
3174
+ var idle = false
3175
+ for (var j = 0; j < HINT_SOURCES.length; j++) {
3176
+ if (curText.indexOf(HINT_SOURCES[j]) === 0) {
3177
+ idle = true
3178
+ break
3179
+ }
3180
+ }
3181
+ if (idle && curText !== targetHint) placeholder.textContent = targetHint
3182
+ }
3183
+ } else {
3184
+ if (placeholder && placeholder.hasAttribute('data-dsh-synthetic-placeholder')) {
3185
+ if (placeholder.parentElement) placeholder.parentElement.removeChild(placeholder)
3186
+ }
3187
+ }
3188
+ }
2290
3189
  }
2291
3190
 
2292
3191
  /**
@@ -2320,6 +3219,28 @@ window.__ModuleLoader__.load({
2320
3219
  }
2321
3220
  }
2322
3221
 
3222
+
3223
+ ui.copy = {
3224
+ sync: function () {
3225
+ rewriteHeadline()
3226
+ rewriteHint()
3227
+ rewriteTurnStatus()
3228
+ },
3229
+ syncGreeting: function () {
3230
+ rewriteHeadline()
3231
+ },
3232
+ syncAttachmentPlaceholder: syncAttachmentPlaceholder,
3233
+ isHeroView: isHeroView,
3234
+ isComposerActive: isComposerActive
3235
+ }
3236
+
3237
+ return function () {}
3238
+ }
3239
+
3240
+ // ============================================================================
3241
+ // 4.2: 权限段控件与会话内弹层 (Permission Segments & Popover)
3242
+ // ============================================================================
3243
+ function installPermissions(ctx, ui) {
2323
3244
  // --- 4.2 Permission Segments & In-Conversation Popover ---
2324
3245
  var segments = null
2325
3246
  var permContainer = null
@@ -2332,6 +3253,7 @@ window.__ModuleLoader__.load({
2332
3253
  group.className = SEGMENTS_CLASS
2333
3254
  group.setAttribute('role', 'radiogroup')
2334
3255
  group.setAttribute('aria-label', 'Permission')
3256
+ group.setAttribute('data-composer-segments', '')
2335
3257
  for (var i = 0; i < PERMISSION_SEGMENTS.length; i++) {
2336
3258
  var spec = PERMISSION_SEGMENTS[i]
2337
3259
  var item = document.createElement('button')
@@ -2505,7 +3427,7 @@ window.__ModuleLoader__.load({
2505
3427
  var session = currentSession(ctx)
2506
3428
  if (session === null) return
2507
3429
  var settled = session.command('/permission ' + preset)
2508
- if (settled !== void 0 && typeof settled.then === 'function') settled.then(schedule, schedule)
3430
+ if (settled !== void 0 && typeof settled.then === 'function') settled.then(ui.schedule, ui.schedule)
2509
3431
  }
2510
3432
 
2511
3433
  /**
@@ -2559,9 +3481,16 @@ window.__ModuleLoader__.load({
2559
3481
  }
2560
3482
 
2561
3483
  function syncAttachmentState() {
3484
+ var active = ui.copy.isComposerActive()
2562
3485
  var cards = document.querySelectorAll('[data-composer-card]')
2563
3486
  for (var ci = 0; ci < cards.length; ci++) {
2564
3487
  var card = cards[ci]
3488
+ if (!active) {
3489
+ if (card.hasAttribute('data-has-attachments')) {
3490
+ card.removeAttribute('data-has-attachments')
3491
+ }
3492
+ continue
3493
+ }
2565
3494
  var hasAtt = card.querySelector('._54WpYG_imageItem, [class*="imageItem"], [class*="thumbnail"], [class*="FileCard"], [class*="rail"]:not([class*="trailing"]) [class*="item"], [class*="rail"]:not([class*="trailing"]) img, [class*="rail"]:not([class*="trailing"]) [class*="card"]') !== null
2566
3495
  if (hasAtt) {
2567
3496
  if (card.getAttribute('data-has-attachments') !== 'true') {
@@ -2573,113 +3502,846 @@ window.__ModuleLoader__.load({
2573
3502
  }
2574
3503
  }
2575
3504
  }
3505
+ if (ui.copy && ui.copy.syncAttachmentPlaceholder) ui.copy.syncAttachmentPlaceholder()
3506
+ }
3507
+
3508
+ /**
3509
+ * Merge the session-stats pills into the composer toolbar row so the
3510
+ * controls and the stats share ONE line. The host renders the pills
3511
+ * (the `conversation.composer.dock` slot) as the card's sibling — a
3512
+ * full-width line of their own below the input box; the skin moves
3513
+ * them into the row, right before the trailing model/status group.
3514
+ * A host re-render can put them back, so the move is re-applied on
3515
+ * every pass and is a no-op once they are in place.
3516
+ */
3517
+ function mergeStatsIntoRow() {
3518
+ var stats = document.querySelector('[data-composer-stats]')
3519
+ if (!stats) return
3520
+ var active = ui.copy.isComposerActive()
3521
+ if (!active) {
3522
+ if (stats.parentElement && stats.parentElement.matches && stats.parentElement.matches('[class*="_row"]')) {
3523
+ var card = stats.closest('[data-composer-card]')
3524
+ if (card && card.parentElement) {
3525
+ card.parentElement.insertBefore(stats, card.nextSibling)
3526
+ }
3527
+ }
3528
+ return
3529
+ }
3530
+ // `[class*="_row"]`, not `[class*="row"]`: the bare substring also
3531
+ // matches the input growth wrapper (`grow` contains `row`).
3532
+ var row = null
3533
+ if (stats.parentElement && stats.parentElement.matches && stats.parentElement.matches('[class*="_row"]')) {
3534
+ row = stats.parentElement
3535
+ } else {
3536
+ // Host default: the pills sit in a slot anchor beside the card.
3537
+ // Walk up to the nearest ancestor that also holds a composer card.
3538
+ var node = stats.parentElement
3539
+ while (node && node !== document.body && row === null) {
3540
+ var card = node.querySelector('[data-composer-card]')
3541
+ if (card) {
3542
+ var r = card.querySelector('[class*="_row"]')
3543
+ if (r) row = r
3544
+ }
3545
+ node = node.parentElement
3546
+ }
3547
+ }
3548
+ if (row === null) return
3549
+ var trailing = row.querySelector('[class*="trailing"]')
3550
+ var inPlace = stats.parentElement === row &&
3551
+ (trailing !== null ? stats.nextElementSibling === trailing : row.lastElementChild === stats)
3552
+ if (inPlace) return
3553
+ if (trailing !== null) row.insertBefore(stats, trailing)
3554
+ else row.appendChild(stats)
3555
+ }
3556
+
3557
+ // Re-insert when a re-render swapped the host row, then mirror the running preset.
3558
+ function syncSegments() {
3559
+ var isHero = ui.copy.isHeroView()
3560
+ var allCards = document.querySelectorAll('[data-composer-card]')
3561
+ for (var c = 0; c < allCards.length; c++) {
3562
+ allCards[c].setAttribute('data-composer-variant', isHero ? 'hero' : 'inline')
3563
+ }
3564
+
3565
+ var composerOn = ui.copy.isComposerActive()
3566
+ if (composerOn) document.body.setAttribute(COMPOSER_ATTR, '')
3567
+ else document.body.removeAttribute(COMPOSER_ATTR)
3568
+
3569
+ var existingPermContainers = document.querySelectorAll('.dsh-claude-perm-container')
3570
+ var existingSegments = document.querySelectorAll('.' + SEGMENTS_CLASS + '[data-composer-segments]')
3571
+
3572
+ if (!composerOn) {
3573
+ for (var ep = 0; ep < existingPermContainers.length; ep++) {
3574
+ existingPermContainers[ep].remove()
3575
+ }
3576
+ if (permPopover && permPopover.parentElement) {
3577
+ permPopover.parentElement.removeChild(permPopover)
3578
+ }
3579
+ permContainer = null
3580
+ permBtn = null
3581
+ permLabel = null
3582
+ permPopover = null
3583
+
3584
+ for (var es0 = 0; es0 < existingSegments.length; es0++) {
3585
+ existingSegments[es0].remove()
3586
+ }
3587
+ segments = null
3588
+ return
3589
+ }
3590
+
3591
+ var trigger = findAccessTrigger()
3592
+ if (trigger === null) return
3593
+ var host = trigger.parentElement
3594
+ if (host === null) return
3595
+
3596
+ var session = currentSession(ctx)
3597
+ var preset = session === null ? null : currentPreset(session)
3598
+
3599
+ if (isHero) {
3600
+ for (var i = 0; i < existingPermContainers.length; i++) {
3601
+ existingPermContainers[i].remove()
3602
+ }
3603
+ if (permPopover && permPopover.parentElement) {
3604
+ permPopover.parentElement.removeChild(permPopover)
3605
+ }
3606
+ permContainer = null
3607
+ permBtn = null
3608
+ permLabel = null
3609
+ permPopover = null
3610
+
3611
+ if (existingSegments.length > 1) {
3612
+ for (var s = 1; s < existingSegments.length; s++) existingSegments[s].remove()
3613
+ }
3614
+ if (existingSegments.length === 1 && host.contains(existingSegments[0])) {
3615
+ segments = existingSegments[0]
3616
+ } else {
3617
+ for (var s2 = 0; s2 < existingSegments.length; s2++) existingSegments[s2].remove()
3618
+ segments = buildSegments(pick)
3619
+ host.insertBefore(segments, host.firstChild)
3620
+ }
3621
+ for (var j = 0; j < segments.children.length; j++) {
3622
+ var item = segments.children[j]
3623
+ if (item.getAttribute('data-preset') === preset) {
3624
+ item.setAttribute('data-active', '')
3625
+ item.setAttribute('aria-checked', 'true')
3626
+ } else {
3627
+ item.removeAttribute('data-active')
3628
+ item.setAttribute('aria-checked', 'false')
3629
+ }
3630
+ }
3631
+ } else {
3632
+ for (var es = 0; es < existingSegments.length; es++) {
3633
+ existingSegments[es].remove()
3634
+ }
3635
+ segments = null
3636
+
3637
+ var allExisting = document.querySelectorAll('.dsh-claude-perm-container')
3638
+ if (allExisting.length > 0) {
3639
+ permContainer = allExisting[0]
3640
+ for (var p = 1; p < allExisting.length; p++) {
3641
+ allExisting[p].remove()
3642
+ }
3643
+ if (permContainer.parentElement !== host) {
3644
+ host.insertBefore(permContainer, host.firstChild)
3645
+ }
3646
+ permBtn = permContainer.querySelector('.dsh-claude-perm-btn')
3647
+ permLabel = permContainer.querySelector('.dsh-claude-perm-label')
3648
+ } else {
3649
+ var res = buildPermTriggerAndPopover(pick)
3650
+ permContainer = res.container
3651
+ permBtn = res.btn
3652
+ permLabel = res.label
3653
+ permPopover = res.popover
3654
+ host.insertBefore(permContainer, host.firstChild)
3655
+ }
3656
+ updatePermState(preset)
3657
+ }
3658
+ }
3659
+
3660
+ /**
3661
+ * The composer is chat-view-only. The host mounts the seat inside the
3662
+ * conversation root on every tab (轨迹 / 上下文 even reserve room for
3663
+ * it), so the skin reflects the active view on <body> and CSS drops the
3664
+ * whole bottom area unless the chat tab is selected.
3665
+ *
3666
+ * Scope: the conversation tablist lives in the panel header, which is
3667
+ * the root's first child — any other tablist (the trajectory detail
3668
+ * panel, say) renders later inside the ledger. The chat view registers
3669
+ * at order 0, so it is always the tablist's FIRST tab; reading that
3670
+ * tab's aria-selected is locale-independent. No tab bar at all (hero /
3671
+ * single view) means the chat surface is all there is.
3672
+ */
3673
+ function syncChatTabComposer() {
3674
+ if (!ui.copy.isComposerActive()) {
3675
+ document.body.removeAttribute('data-dsh-claude-composer-hidden')
3676
+ return
3677
+ }
3678
+ var chatActive = true
3679
+ var seat = document.querySelector('[data-composer-seat]')
3680
+ var root = seat && seat.closest ? seat.closest('[data-phase]') : null
3681
+ if (root) {
3682
+ var list = root.querySelector('[role="tablist"]')
3683
+ if (list) {
3684
+ var first = list.querySelector('[role="tab"]')
3685
+ if (first) chatActive = first.getAttribute('aria-selected') === 'true'
3686
+ }
3687
+ }
3688
+ if (chatActive) document.body.removeAttribute('data-dsh-claude-composer-hidden')
3689
+ else document.body.setAttribute('data-dsh-claude-composer-hidden', '')
3690
+ }
3691
+
3692
+
3693
+ ui.permissions = {
3694
+ sync: function () {
3695
+ syncAttachmentState()
3696
+ mergeStatsIntoRow()
3697
+ syncSegments()
3698
+ syncChatTabComposer()
3699
+ },
3700
+ closeMenu: closePermMenu
3701
+ }
3702
+
3703
+ return function () {
3704
+ if (permDocPointerListener) {
3705
+ document.removeEventListener('pointerdown', permDocPointerListener)
3706
+ permDocPointerListener = null
3707
+ }
3708
+ if (permResizeListener) {
3709
+ window.removeEventListener('resize', permResizeListener)
3710
+ window.removeEventListener('scroll', permResizeListener, true)
3711
+ permResizeListener = null
3712
+ }
3713
+ if (segments !== null && segments.parentElement !== null) segments.parentElement.removeChild(segments)
3714
+ segments = null
3715
+ if (permPopover !== null && permPopover.parentElement !== null) permPopover.parentElement.removeChild(permPopover)
3716
+ permPopover = null
3717
+ permBtn = null
3718
+ permLabel = null
3719
+ permContainer = null
3720
+ }
3721
+ }
3722
+
3723
+ // ============================================================================
3724
+ // 4.4: 模型选择器 (Model Picker)
3725
+ // ============================================================================
3726
+ function installModelPicker(ctx, ui) {
3727
+ // --- 4.4 Model picker: replaces the host's model seat ---
3728
+ /**
3729
+ * The host's model seat is a click-triggered two-pane menu (Model /
3730
+ * Effort rows drilling into their own lists). The skin replaces it with
3731
+ * a Claude-style picker: hovering the trigger opens the first level —
3732
+ * the DeepSeek official provider's models, a divider, then the
3733
+ * reasoning-effort row (when the current model offers one) and a More
3734
+ * models row; both open their second level BESIDE the first level.
3735
+ *
3736
+ * Data and submission ride the host's own per-session ModelDirectory
3737
+ * (`ctx.modelDirectories`), the same store the host's menu and the
3738
+ * /model command read — so the current selection, catalog and errors
3739
+ * stay in sync without scraping the DOM. The host's seat is hidden and
3740
+ * marked; a React swap re-marks it on the next pass.
3741
+ */
3742
+ var modelBtn = null
3743
+ var modelPop = null
3744
+ var modelSubPop = null
3745
+ var modelBody = null
3746
+ var modelSubBody = null
3747
+ var modelHoverIntent = createHoverIntent(openModelPopover, closeModelPopovers, 180)
3748
+ var modelDir = null
3749
+ var modelSub = null
3750
+ var modelSessionId = null
3751
+ var modelSubKind = null
3752
+ var modelBodySig = ''
3753
+ var modelSubSig = ''
3754
+
3755
+ /** Exact entry: `provider/model`, bare id, folded id, then the alias table. */
3756
+ function exactModelCopy(groupId, modelId) {
3757
+ if (modelCopy === null) return null
3758
+ var gid = String(groupId === void 0 || groupId === null ? '' : groupId).toLowerCase()
3759
+ var mid = String(modelId === void 0 || modelId === null ? '' : modelId)
3760
+ var midLower = mid.toLowerCase()
3761
+ var byProvider = modelCopy.exact[groupId + '/' + mid] || modelCopy.exact[gid + '/' + midLower]
3762
+ if (byProvider) return byProvider
3763
+ if (modelCopy.exact[mid]) return modelCopy.exact[mid]
3764
+ if (modelCopy.exact[midLower]) return modelCopy.exact[midLower]
3765
+ var folded = normalizeModelId(mid)
3766
+ if (modelCopy.folded[folded]) return modelCopy.folded[folded]
3767
+ var alias = modelCopy.aliases[mid] || modelCopy.aliases[midLower] || modelCopy.aliases[folded] || (modelCopy.foldedAliases && modelCopy.foldedAliases[folded])
3768
+ if (alias) {
3769
+ if (modelCopy.exact[alias]) return modelCopy.exact[alias]
3770
+ var foldedAlias = normalizeModelId(alias)
3771
+ if (modelCopy.folded[foldedAlias]) return modelCopy.folded[foldedAlias]
3772
+ }
3773
+ return null
3774
+ }
3775
+
3776
+ /**
3777
+ * Family entry. The model id is tried alone first because it is the
3778
+ * stronger signal, then `provider/id` for ids that carry no brand of their
3779
+ * own (`abab6.5s-chat` under a provider called `minimax`).
3780
+ */
3781
+ function familyModelCopy(groupId, modelId) {
3782
+ if (modelCopy === null) return null
3783
+ var id = String(modelId === void 0 || modelId === null ? '' : modelId).toLowerCase()
3784
+ var haystacks = [id, String(groupId === void 0 || groupId === null ? '' : groupId).toLowerCase() + '/' + id]
3785
+ for (var h = 0; h < haystacks.length; h++) {
3786
+ for (var i = 0; i < modelCopy.families.length; i++) {
3787
+ var rule = modelCopy.families[i]
3788
+ if (!rule.re.test(haystacks[h])) continue
3789
+ if (rule.key) return modelCopy.exact[rule.key] || null
3790
+ return rule.text
3791
+ }
3792
+ }
3793
+ return null
3794
+ }
3795
+
3796
+ /** Last-resort tier rule, read out of the id itself. */
3797
+ function tierModelCopy(modelId) {
3798
+ if (modelCopy === null) return null
3799
+ var id = String(modelId === void 0 || modelId === null ? '' : modelId).toLowerCase()
3800
+ for (var i = 0; i < modelCopy.tiers.length; i++) {
3801
+ if (modelCopy.tiers[i].re.test(id)) return modelCopy.tiers[i].text
3802
+ }
3803
+ return null
3804
+ }
3805
+
3806
+ function cancelCloseModel() {
3807
+ modelHoverIntent.cancel()
3808
+ }
3809
+
3810
+ function scheduleCloseModel() {
3811
+ modelHoverIntent.scheduleClose()
3812
+ }
3813
+
3814
+ function closeModelPopovers() {
3815
+ cancelCloseModel()
3816
+ if (modelPop) modelPop.setAttribute('data-open', 'false')
3817
+ if (modelSubPop) modelSubPop.setAttribute('data-open', 'false')
3818
+ modelSubKind = null
3819
+ }
3820
+
3821
+ function openModelPopover() {
3822
+ cancelCloseModel()
3823
+ modelDirectory()
3824
+ // load() is async — the host itself guards with .catch(() => {}); a bare
3825
+ // try/catch cannot see its rejection.
3826
+ if (modelDir && typeof modelDir.load === 'function') {
3827
+ try {
3828
+ var pending = modelDir.load()
3829
+ if (pending && typeof pending.catch === 'function') {
3830
+ pending.catch(function () { /* the store's error surface covers a failure */ })
3831
+ }
3832
+ } catch (error) { /* synchronous failure — the store's error surface covers it */ }
3833
+ }
3834
+ modelSubKind = null
3835
+ if (modelSubPop) modelSubPop.setAttribute('data-open', 'false')
3836
+ renderModelBody()
3837
+ positionModelPopovers()
3838
+ if (modelPop) modelPop.setAttribute('data-open', 'true')
3839
+ }
3840
+
3841
+ function openModelSub(kind) {
3842
+ cancelCloseModel()
3843
+ modelSubKind = kind
3844
+ renderModelSub()
3845
+ positionModelPopovers()
3846
+ if (modelSubPop) modelSubPop.setAttribute('data-open', 'true')
3847
+ }
3848
+
3849
+ /**
3850
+ * The current session id. The Session Controller dropped
3851
+ * `list.current` in dsh 0.2 (the main-view selection now comes from the
3852
+ * `uiSession` projection), so this MUST go through the shared
3853
+ * currentSessionId() in context.js — reading the legacy field directly
3854
+ * resolves to null on current hosts and the picker never loads.
3855
+ */
3856
+ function currentModelSessionId() {
3857
+ try {
3858
+ var sessions = ctx.get('sessions')
3859
+ if (sessions === void 0 || sessions === null) return null
3860
+ var id = currentSessionId(ctx, sessions)
3861
+ return id === void 0 || id === null ? null : id
3862
+ } catch (error) {
3863
+ return null
3864
+ }
3865
+ }
3866
+
3867
+ function dropModelSubscription() {
3868
+ if (modelSub) {
3869
+ try { modelSub() } catch (error) { /* already disposed */ }
3870
+ }
3871
+ modelSub = null
3872
+ }
3873
+
3874
+ /** Resolve the session's directory (and observe it) once per session. */
3875
+ function modelDirectory() {
3876
+ var id = currentModelSessionId()
3877
+ if (id === null) {
3878
+ dropModelSubscription()
3879
+ modelDir = null
3880
+ modelSessionId = null
3881
+ return null
3882
+ }
3883
+ if (modelSessionId === id && modelDir !== null) return modelDir
3884
+ dropModelSubscription()
3885
+ modelDir = null
3886
+ modelSessionId = null
3887
+ try {
3888
+ var dirs = ctx.get('modelDirectories')
3889
+ if (dirs && typeof dirs.directoryFor === 'function') {
3890
+ modelDir = dirs.directoryFor(id)
3891
+ }
3892
+ } catch (error) {
3893
+ modelDir = null
3894
+ }
3895
+ modelSessionId = id
3896
+ // The directory INSTANCE only carries load/select — its reactive state
3897
+ // hangs off the `.store` snapshot store (the host hands that same store
3898
+ // to its own menu as `directory`). Subscribe to the store, never to the
3899
+ // instance, and never let a subscribe failure discard the directory.
3900
+ if (modelDir !== null) {
3901
+ var store = modelDir.store
3902
+ if (store && typeof store.subscribe === 'function') {
3903
+ try {
3904
+ modelSub = store.subscribe(function () { if (ui.schedule) ui.schedule() })
3905
+ } catch (error) {
3906
+ modelSub = null
3907
+ }
3908
+ }
3909
+ }
3910
+ return modelDir
2576
3911
  }
2577
3912
 
2578
- function restoreStatsPosition() {
2579
- var stats = document.querySelector('[data-composer-stats]')
2580
- // `[class*="_row"]`, not `[class*="row"]`: the bare substring also
2581
- // matches the input growth wrapper (`grow` contains `row`).
2582
- if (stats && stats.parentElement && (stats.parentElement.matches && stats.parentElement.matches('[class*="_row"]') || stats.parentElement.querySelector('[class*="tools"]'))) {
2583
- var card = stats.closest('[data-composer-card]')
2584
- if (card && card.parentNode) {
2585
- card.parentNode.insertBefore(stats, card.nextSibling)
3913
+ function modelSnapshot() {
3914
+ if (modelDir === null || !modelDir.store) return null
3915
+ try { return modelDir.store.getSnapshot() } catch (error) { return null }
3916
+ }
3917
+
3918
+ /** The current selection resolved to its group + model entries. */
3919
+ function modelCurrent(snap) {
3920
+ if (!snap || snap.current === null) return null
3921
+ for (var g = 0; g < snap.groups.length; g++) {
3922
+ var group = snap.groups[g]
3923
+ if (group.id !== snap.current.provider) continue
3924
+ for (var m = 0; m < group.models.length; m++) {
3925
+ if (group.models[m].id === snap.current.model) return { group: group, model: group.models[m] }
2586
3926
  }
2587
3927
  }
3928
+ return null
2588
3929
  }
2589
3930
 
2590
- // Re-insert when a re-render swapped the host row, then mirror the running preset.
2591
- function syncSegments() {
2592
- var hasTurns = document.querySelector('[class*="turn"], [class*="message"], [data-turn], [data-message-id]') !== null
2593
- var isHero = !hasTurns && (document.querySelector('[class*="composerHero"], [data-phase="hero"]') !== null)
2594
- var allCards = document.querySelectorAll('[data-composer-card]')
2595
- for (var c = 0; c < allCards.length; c++) {
2596
- allCards[c].setAttribute('data-composer-variant', isHero ? 'hero' : 'inline')
3931
+ /** Reasoning metadata + the effective effort for the current model. */
3932
+ function modelEffort(snap) {
3933
+ var current = modelCurrent(snap)
3934
+ if (current === null || !current.model.reasoning) return null
3935
+ var reasoning = current.model.reasoning
3936
+ var effective = snap.current.reasoningEffort !== void 0 ? snap.current.reasoningEffort : reasoning.defaultEffort
3937
+ var label = MODEL_EFFORT_DEFAULT
3938
+ if (effective !== void 0) {
3939
+ label = effective
3940
+ for (var i = 0; i < reasoning.efforts.length; i++) {
3941
+ if (reasoning.efforts[i].id === effective) {
3942
+ label = reasoning.efforts[i].name
3943
+ break
3944
+ }
3945
+ }
2597
3946
  }
3947
+ return { reasoning: reasoning, effective: effective, label: label }
3948
+ }
2598
3949
 
2599
- var trigger = findAccessTrigger()
2600
- if (trigger === null) return
2601
- var host = trigger.parentElement
2602
- if (host === null) return
3950
+ /**
3951
+ * The description line for one catalog model, in the shell's language.
3952
+ *
3953
+ * Resolution descends: exact entry (one model resold by several providers
3954
+ * folds to a single key) → family rule → tier rule → the catalog's own
3955
+ * text. Family rules are ordered and anchored (see
3956
+ * src/model-descriptions.json) so another vendor's flash tier never
3957
+ * borrows DeepSeek's copy. A model this table has never seen and the
3958
+ * catalog does not describe resolves to an empty string on purpose: a
3959
+ * name-only row beats an invented line.
3960
+ */
3961
+ function modelDescription(groupId, model) {
3962
+ var id = typeof model.id === 'string' ? model.id : ''
3963
+ var pair = exactModelCopy(groupId, id) || familyModelCopy(groupId, id) || tierModelCopy(id)
3964
+ var text = localized(pair, ctx)
3965
+ if (text) return text
3966
+ return typeof model.description === 'string' ? model.description : ''
3967
+ }
2603
3968
 
2604
- var session = currentSession(ctx)
2605
- var preset = session === null ? null : currentPreset(session)
3969
+ function modelEl(tag, cls, text) {
3970
+ var el = document.createElement(tag)
3971
+ if (cls) el.className = cls
3972
+ if (text !== void 0 && text !== null) el.textContent = text
3973
+ return el
3974
+ }
2606
3975
 
2607
- var existingPermContainers = document.querySelectorAll('.dsh-claude-perm-container')
2608
- var existingSegments = document.querySelectorAll('.' + SEGMENTS_CLASS)
3976
+ var MODEL_CHECK_SVG = '<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5l3.2 3.2L13 5"/></svg>'
3977
+ var MODEL_CHEVRON_SVG = '<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4l4 4-4 4"/></svg>'
3978
+ var MODEL_CHEVRON_DOWN_SVG = '<svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6l4 4 4-4"/></svg>'
3979
+
3980
+ /** One selectable model row: name, description line and a check when current. */
3981
+ function buildModelOption(group, model, selected) {
3982
+ var item = modelEl('button', 'dsh-claude-model-option')
3983
+ item.type = 'button'
3984
+ item.setAttribute('role', 'menuitemradio')
3985
+ item.setAttribute('aria-checked', selected ? 'true' : 'false')
3986
+ var copy = modelEl('span', 'dsh-claude-model-copy')
3987
+ copy.appendChild(modelEl('span', 'dsh-claude-model-name', model.name))
3988
+ // One line, in the shell's language: the copy document is localized, so
3989
+ // the row never stacks two languages.
3990
+ var desc = modelDescription(group.id, model)
3991
+ if (desc) copy.appendChild(modelEl('span', 'dsh-claude-model-desc', desc))
3992
+ item.appendChild(copy)
3993
+ var check = modelEl('span', 'dsh-claude-model-check')
3994
+ check.innerHTML = selected ? MODEL_CHECK_SVG : ''
3995
+ item.appendChild(check)
3996
+ item.addEventListener('click', (function (g, m) {
3997
+ return function (e) {
3998
+ e.stopPropagation()
3999
+ pickModel(g, m)
4000
+ }
4001
+ })(group.id, model.id))
4002
+ return item
4003
+ }
2609
4004
 
2610
- if (isHero) {
2611
- for (var i = 0; i < existingPermContainers.length; i++) {
2612
- existingPermContainers[i].remove()
4005
+ /** One level-2 row: label + current value + chevron, hover opens its level. */
4006
+ function buildModelCell(label, value, kind) {
4007
+ var cell = modelEl('button', 'dsh-claude-model-cell')
4008
+ cell.type = 'button'
4009
+ cell.setAttribute('role', 'menuitem')
4010
+ cell.appendChild(modelEl('span', 'dsh-claude-model-cell-label', label))
4011
+ if (value) cell.appendChild(modelEl('span', 'dsh-claude-model-cell-value', value))
4012
+ var chevron = modelEl('span', 'dsh-claude-model-cell-chevron')
4013
+ chevron.innerHTML = MODEL_CHEVRON_SVG
4014
+ cell.appendChild(chevron)
4015
+ cell.addEventListener('mouseenter', (function (k) {
4016
+ return function () {
4017
+ if (readPrefs().autoPopover) openModelSub(k)
2613
4018
  }
2614
- if (permPopover && permPopover.parentElement) {
2615
- permPopover.parentElement.removeChild(permPopover)
4019
+ })(kind))
4020
+ cell.addEventListener('click', (function (k) {
4021
+ return function (e) {
4022
+ e.stopPropagation()
4023
+ if (modelSubKind === k) closeModelPopovers()
4024
+ else openModelSub(k)
2616
4025
  }
2617
- permContainer = null
2618
- permBtn = null
2619
- permLabel = null
2620
- permPopover = null
4026
+ })(kind))
4027
+ return cell
4028
+ }
2621
4029
 
2622
- if (existingSegments.length > 1) {
2623
- for (var s = 1; s < existingSegments.length; s++) existingSegments[s].remove()
4030
+ function pickModel(provider, modelId) {
4031
+ var dir = modelDirectory()
4032
+ if (dir === null) return
4033
+ try {
4034
+ // select() is async and rejects on a failed selection; swallow the
4035
+ // rejection the way the host's own seat wrapper does.
4036
+ var pending = dir.select({ provider: provider, model: modelId })
4037
+ if (pending && typeof pending.catch === 'function') pending.catch(function () {})
4038
+ } catch (error) { /* rejected selections surface on the host's toast */ }
4039
+ closeModelPopovers()
4040
+ }
4041
+
4042
+ function pickEffort(effort) {
4043
+ var dir = modelDirectory()
4044
+ var snap = modelSnapshot()
4045
+ if (dir === null || !snap || snap.current === null) return
4046
+ var selection = { provider: snap.current.provider, model: snap.current.model }
4047
+ if (effort !== void 0) selection.reasoningEffort = effort
4048
+ try {
4049
+ var pending = dir.select(selection)
4050
+ if (pending && typeof pending.catch === 'function') pending.catch(function () {})
4051
+ } catch (error) { /* rejected selections surface on the host's toast */ }
4052
+ closeModelPopovers()
4053
+ }
4054
+
4055
+ /** Level 1: the official provider's models, divider, effort + more rows. */
4056
+ function renderModelBody() {
4057
+ if (!modelBody) return
4058
+ var snap = modelSnapshot()
4059
+ var status = snap ? snap.status : 'idle'
4060
+ var groups = (snap && snap.groups) || []
4061
+ var current = modelCurrent(snap)
4062
+ var effort = modelEffort(snap)
4063
+ var sig = [status, activeLocale(), current ? current.group.id + '/' + current.model.id : '', effort ? String(effort.effective) : ''].join('|')
4064
+ for (var g = 0; g < groups.length; g++) sig += ';' + groups[g].id + ':' + groups[g].models.length
4065
+ if (sig === modelBodySig) return
4066
+ modelBodySig = sig
4067
+ while (modelBody.firstChild) modelBody.removeChild(modelBody.firstChild)
4068
+
4069
+ if (status === 'idle' || status === 'loading' || status === 'selecting') {
4070
+ modelBody.appendChild(modelEl('div', 'dsh-claude-model-status', copyLabel('loading', MODEL_LOADING_LABEL)))
4071
+ } else {
4072
+ var official = null
4073
+ for (var g2 = 0; g2 < groups.length; g2++) {
4074
+ if (groups[g2].id === MODEL_OFFICIAL_GROUP) { official = groups[g2]; break }
2624
4075
  }
2625
- if (existingSegments.length === 1 && host.contains(existingSegments[0])) {
2626
- segments = existingSegments[0]
4076
+ var rows = []
4077
+ if (official) {
4078
+ for (var m = 0; m < official.models.length; m++) rows.push({ group: official, model: official.models[m] })
2627
4079
  } else {
2628
- for (var s2 = 0; s2 < existingSegments.length; s2++) existingSegments[s2].remove()
2629
- segments = buildSegments(pick)
2630
- host.insertBefore(segments, host.firstChild)
4080
+ for (var g3 = 0; g3 < groups.length; g3++) {
4081
+ for (var m2 = 0; m2 < groups[g3].models.length; m2++) rows.push({ group: groups[g3], model: groups[g3].models[m2] })
4082
+ }
2631
4083
  }
2632
- for (var j = 0; j < segments.children.length; j++) {
2633
- var item = segments.children[j]
2634
- if (item.getAttribute('data-preset') === preset) {
2635
- item.setAttribute('data-active', '')
2636
- item.setAttribute('aria-checked', 'true')
2637
- } else {
2638
- item.removeAttribute('data-active')
2639
- item.setAttribute('aria-checked', 'false')
4084
+ if (rows.length === 0) {
4085
+ modelBody.appendChild(modelEl('div', 'dsh-claude-model-status', copyLabel('empty', MODEL_EMPTY_LABEL)))
4086
+ } else {
4087
+ for (var r = 0; r < rows.length; r++) {
4088
+ var selected = current !== null && current.group.id === rows[r].group.id && current.model.id === rows[r].model.id
4089
+ modelBody.appendChild(buildModelOption(rows[r].group, rows[r].model, selected))
2640
4090
  }
2641
4091
  }
2642
- } else {
2643
- for (var es = 0; es < existingSegments.length; es++) {
2644
- existingSegments[es].remove()
4092
+ modelBody.appendChild(modelEl('div', 'dsh-claude-model-divider'))
4093
+ if (effort) modelBody.appendChild(buildModelCell(copyLabel('effortLabel', MODEL_EFFORT_LABEL), effort.label, 'effort'))
4094
+ modelBody.appendChild(buildModelCell(copyLabel('moreLabel', MODEL_MORE_LABEL), '', 'more'))
4095
+ }
4096
+ }
4097
+
4098
+ /** Level 2: the effort ladder, or every provider group's models. */
4099
+ function renderModelSub() {
4100
+ if (!modelSubBody) return
4101
+ var snap = modelSnapshot()
4102
+ if (modelSubKind === 'effort') {
4103
+ var effort = modelEffort(snap)
4104
+ var sig = 'effort:' + (effort ? String(effort.effective) : 'none')
4105
+ if (sig === modelSubSig) return
4106
+ modelSubSig = sig
4107
+ while (modelSubBody.firstChild) modelSubBody.removeChild(modelSubBody.firstChild)
4108
+ if (effort === null) {
4109
+ modelSubBody.appendChild(modelEl('div', 'dsh-claude-model-status', copyLabel('noEffort', MODEL_NO_EFFORT_LABEL)))
4110
+ return
2645
4111
  }
2646
- segments = null
4112
+ var levels = []
4113
+ if (effort.reasoning.defaultEffort === void 0) levels.push({ effort: void 0, label: MODEL_EFFORT_DEFAULT })
4114
+ for (var i = 0; i < effort.reasoning.efforts.length; i++) {
4115
+ levels.push({ effort: effort.reasoning.efforts[i].id, label: effort.reasoning.efforts[i].name })
4116
+ }
4117
+ for (var l = 0; l < levels.length; l++) {
4118
+ (function (level, active) {
4119
+ var item = modelEl('button', 'dsh-claude-model-option')
4120
+ item.type = 'button'
4121
+ item.setAttribute('role', 'menuitemradio')
4122
+ item.setAttribute('aria-checked', active ? 'true' : 'false')
4123
+ item.appendChild(modelEl('span', 'dsh-claude-model-copy', level.label))
4124
+ var check = modelEl('span', 'dsh-claude-model-check')
4125
+ check.innerHTML = active ? MODEL_CHECK_SVG : ''
4126
+ item.appendChild(check)
4127
+ item.addEventListener('click', function (e) {
4128
+ e.stopPropagation()
4129
+ pickEffort(level.effort)
4130
+ })
4131
+ modelSubBody.appendChild(item)
4132
+ })(levels[l], effort.effective === levels[l].effort)
4133
+ }
4134
+ return
4135
+ }
4136
+ // 'more': every provider group, headed by its name.
4137
+ var groups = (snap && snap.groups) || []
4138
+ var current = modelCurrent(snap)
4139
+ var sig2 = 'more'
4140
+ for (var g = 0; g < groups.length; g++) sig2 += ';' + groups[g].id + ':' + groups[g].models.length
4141
+ if (current) sig2 += '#' + current.group.id + '/' + current.model.id
4142
+ if (sig2 === modelSubSig) return
4143
+ modelSubSig = sig2
4144
+ while (modelSubBody.firstChild) modelSubBody.removeChild(modelSubBody.firstChild)
4145
+ for (var g2 = 0; g2 < groups.length; g2++) {
4146
+ var group = groups[g2]
4147
+ if (group.models.length === 0) continue
4148
+ modelSubBody.appendChild(modelEl('div', 'dsh-claude-model-group', group.name))
4149
+ for (var m = 0; m < group.models.length; m++) {
4150
+ var selected = current !== null && current.group.id === group.id && current.model.id === group.models[m].id
4151
+ modelSubBody.appendChild(buildModelOption(group, group.models[m], selected))
4152
+ }
4153
+ }
4154
+ if (modelSubBody.firstChild === null) {
4155
+ modelSubBody.appendChild(modelEl('div', 'dsh-claude-model-status', copyLabel('empty', MODEL_EMPTY_LABEL)))
4156
+ }
4157
+ }
2647
4158
 
2648
- var allExisting = document.querySelectorAll('.dsh-claude-perm-container')
2649
- if (allExisting.length > 0) {
2650
- permContainer = allExisting[0]
2651
- for (var p = 1; p < allExisting.length; p++) {
2652
- allExisting[p].remove()
2653
- }
2654
- if (permContainer.parentElement !== host) {
2655
- host.insertBefore(permContainer, host.firstChild)
2656
- }
2657
- permBtn = permContainer.querySelector('.dsh-claude-perm-btn')
2658
- permLabel = permContainer.querySelector('.dsh-claude-perm-label')
2659
- } else {
2660
- var res = buildPermTriggerAndPopover(pick)
2661
- permContainer = res.container
2662
- permBtn = res.btn
2663
- permLabel = res.label
2664
- permPopover = res.popover
2665
- host.insertBefore(permContainer, host.firstChild)
4159
+ function positionModelPopovers() {
4160
+ if (!modelBtn || !modelPop) return
4161
+ var pos = positionAnchoredPopover(modelBtn, modelPop, { side: 'above', gap: 6 })
4162
+ if (modelSubPop && modelSubPop.getAttribute('data-open') === 'true') {
4163
+ var w2 = modelSubPop.offsetWidth
4164
+ var h2 = modelSubPop.offsetHeight
4165
+ // Beside the first level; flip to its left when the viewport is tight.
4166
+ var x2 = pos.x + modelPop.offsetWidth + 4
4167
+ if (x2 + w2 > window.innerWidth - POPOVER_MARGIN) x2 = Math.max(POPOVER_MARGIN, pos.x - 4 - w2)
4168
+ var y2 = Math.max(POPOVER_MARGIN, Math.min(pos.y, window.innerHeight - h2 - POPOVER_MARGIN))
4169
+ modelSubPop.style.left = x2 + 'px'
4170
+ modelSubPop.style.top = y2 + 'px'
4171
+ }
4172
+ }
4173
+
4174
+ function ensureModelChrome() {
4175
+ if (modelPop === null) {
4176
+ modelPop = document.createElement('div')
4177
+ modelPop.className = 'dsh-claude-model-popover'
4178
+ modelPop.setAttribute('role', 'menu')
4179
+ modelPop.setAttribute('data-open', 'false')
4180
+ modelBody = document.createElement('div')
4181
+ modelBody.className = 'dsh-claude-model-popover-body'
4182
+ modelPop.appendChild(modelBody)
4183
+ modelPop.addEventListener('mouseenter', cancelCloseModel)
4184
+ modelPop.addEventListener('mouseleave', scheduleCloseModel)
4185
+ document.body.appendChild(modelPop)
4186
+ }
4187
+ if (modelSubPop === null) {
4188
+ modelSubPop = document.createElement('div')
4189
+ modelSubPop.className = 'dsh-claude-model-popover dsh-claude-model-popover-sub'
4190
+ modelSubPop.setAttribute('role', 'menu')
4191
+ modelSubPop.setAttribute('data-open', 'false')
4192
+ modelSubBody = document.createElement('div')
4193
+ modelSubBody.className = 'dsh-claude-model-popover-body'
4194
+ modelSubPop.appendChild(modelSubBody)
4195
+ modelSubPop.addEventListener('mouseenter', cancelCloseModel)
4196
+ modelSubPop.addEventListener('mouseleave', scheduleCloseModel)
4197
+ document.body.appendChild(modelSubPop)
4198
+ }
4199
+ }
4200
+
4201
+ /** Build/refresh the trigger, its label and the popover rows. */
4202
+ function syncModelControl() {
4203
+ if (!ui.copy.isComposerActive()) {
4204
+ var allHosts = document.querySelectorAll('[data-dsh-claude-model-host]')
4205
+ for (var h = 0; h < allHosts.length; h++) {
4206
+ allHosts[h].removeAttribute('data-dsh-claude-model-host')
2666
4207
  }
2667
- updatePermState(preset)
4208
+ var allModelBtns = document.querySelectorAll('.dsh-claude-model-btn')
4209
+ for (var mb = 0; mb < allModelBtns.length; mb++) {
4210
+ allModelBtns[mb].remove()
4211
+ }
4212
+ modelBtn = null
4213
+ var allModelPops = document.querySelectorAll('.dsh-claude-model-popover')
4214
+ for (var mp = 0; mp < allModelPops.length; mp++) {
4215
+ allModelPops[mp].remove()
4216
+ }
4217
+ modelPop = null
4218
+ modelSubPop = null
4219
+ modelBody = null
4220
+ modelSubBody = null
4221
+ modelSubKind = null
4222
+ modelBodySig = ''
4223
+ modelSubSig = ''
4224
+ cancelCloseModel()
4225
+ dropModelSubscription()
4226
+ modelDir = null
4227
+ modelSessionId = null
4228
+ return
4229
+ }
4230
+
4231
+ // The copy document is fetched on first paint of the picker rather than
4232
+ // at install, so a session that never opens it never pays for it.
4233
+ loadModelCopy()
4234
+ modelDirectory()
4235
+ var slot = document.querySelector('[data-slot="conversation.input.model"]')
4236
+ if (slot === null) return
4237
+ // Hide the host's own seat (React owns the node; re-mark on swap).
4238
+ var hostRoot = slot.firstElementChild
4239
+ if (hostRoot !== null && !hostRoot.hasAttribute('data-dsh-claude-model-host')) {
4240
+ hostRoot.setAttribute('data-dsh-claude-model-host', '')
4241
+ }
4242
+ if (modelBtn === null || modelBtn.parentElement !== slot) {
4243
+ if (modelBtn !== null && modelBtn.parentElement !== null) modelBtn.parentElement.removeChild(modelBtn)
4244
+ modelBtn = document.createElement('button')
4245
+ modelBtn.type = 'button'
4246
+ modelBtn.className = 'dsh-claude-model-btn'
4247
+ modelBtn.setAttribute('aria-haspopup', 'menu')
4248
+ modelBtn.innerHTML =
4249
+ '<span class="dsh-claude-model-btn-label"></span>' +
4250
+ '<span class="dsh-claude-model-btn-chevron">' + MODEL_CHEVRON_DOWN_SVG + '</span>'
4251
+ // Same contract as the account trigger: hover unless the preference
4252
+ // says click-only.
4253
+ modelBtn.addEventListener('mouseenter', function () {
4254
+ if (readPrefs().autoPopover) openModelPopover()
4255
+ })
4256
+ modelBtn.addEventListener('mouseleave', function () {
4257
+ if (readPrefs().autoPopover) scheduleCloseModel()
4258
+ })
4259
+ modelBtn.addEventListener('click', function (e) {
4260
+ e.stopPropagation()
4261
+ if (modelPop && modelPop.getAttribute('data-open') === 'true') closeModelPopovers()
4262
+ else openModelPopover()
4263
+ })
4264
+ slot.appendChild(modelBtn)
4265
+ }
4266
+ ensureModelChrome()
4267
+
4268
+ var snap = modelSnapshot()
4269
+ var current = modelCurrent(snap)
4270
+ var effort = modelEffort(snap)
4271
+ var label = current ? current.model.name : copyLabel('fallbackLabel', MODEL_FALLBACK_LABEL)
4272
+ var labelEl = modelBtn.querySelector('.dsh-claude-model-btn-label')
4273
+ if (labelEl) {
4274
+ labelEl.textContent = label
4275
+ labelEl.classList.toggle('dsh-claude-model-btn-loading', !!(snap && (snap.status === 'loading' || snap.status === 'idle' || snap.status === 'selecting')))
4276
+ }
4277
+ var effortEl = modelBtn.querySelector('.dsh-claude-model-btn-effort')
4278
+ if (effort) {
4279
+ if (effortEl === null) {
4280
+ effortEl = modelEl('span', 'dsh-claude-model-btn-effort')
4281
+ modelBtn.insertBefore(effortEl, modelBtn.firstChild ? labelEl.nextSibling : null)
4282
+ }
4283
+ effortEl.textContent = '· ' + effort.label
4284
+ } else if (effortEl !== null && effortEl.parentElement) {
4285
+ effortEl.parentElement.removeChild(effortEl)
4286
+ }
4287
+ modelBtn.setAttribute('aria-label', copyLabel('triggerLabel', MODEL_TRIGGER_LABEL, { model: label }))
4288
+ modelBtn.disabled = false
4289
+
4290
+ renderModelBody()
4291
+ if (modelSubKind !== null) {
4292
+ renderModelSub()
4293
+ if (modelSubPop && modelSubPop.getAttribute('data-open') === 'true') positionModelPopovers()
4294
+ }
4295
+ if (modelPop && modelPop.getAttribute('data-open') === 'true') positionModelPopovers()
4296
+ }
4297
+
4298
+
4299
+ ui.model = {
4300
+ sync: syncModelControl,
4301
+ close: closeModelPopovers,
4302
+ owns: function (target) {
4303
+ if (!target) return false
4304
+ return (modelBtn !== null && modelBtn.contains(target)) ||
4305
+ (modelPop !== null && modelPop.contains(target)) ||
4306
+ (modelSubPop !== null && modelSubPop.contains(target))
4307
+ },
4308
+ reposition: positionModelPopovers,
4309
+ invalidateCopy: function () {
4310
+ modelBodySig = ''
4311
+ modelSubSig = ''
4312
+ },
4313
+ teardown: function () {
4314
+ cancelCloseModel()
4315
+ dropModelSubscription()
4316
+ modelDir = null
4317
+ modelSessionId = null
4318
+ modelBtn = null
4319
+ modelPop = null
4320
+ modelSubPop = null
4321
+ modelBody = null
4322
+ modelSubBody = null
4323
+ modelSubKind = null
4324
+ modelBodySig = ''
4325
+ modelSubSig = ''
2668
4326
  }
2669
4327
  }
2670
4328
 
4329
+ return ui.model.teardown
4330
+ }
4331
+
4332
+ // ============================================================================
4333
+ // 4.3: 账户页脚与弹层 (Account Footer & Popover)
4334
+ // ============================================================================
4335
+ function installAccountFooter(ctx, ui) {
2671
4336
  // --- 4.3 Account Footer & Popover ---
2672
4337
  var accountBtn = null
2673
4338
  var accountPopover = null
2674
4339
  var popoverBody = null
2675
- var popoverTimer = null
4340
+ var popoverHoverIntent = createHoverIntent(openPopover, closePopover, 150)
2676
4341
 
2677
4342
  function openPopover() {
2678
4343
  if (!accountPopover || !accountBtn) return
2679
- if (popoverTimer) {
2680
- clearTimeout(popoverTimer)
2681
- popoverTimer = null
2682
- }
4344
+ cancelClosePopover()
2683
4345
  // Mirrors are frozen while the popover is open (syncPopoverItems
2684
4346
  // bails), so reconcile them here — before the reveal — to show fresh
2685
4347
  // content/order and bind click targets for the upcoming interaction.
@@ -2687,6 +4349,9 @@ window.__ModuleLoader__.load({
2687
4349
  var footArea = document.querySelector('[class*="footArea"]')
2688
4350
  if (footArea) syncPopoverItems(footArea)
2689
4351
  } catch (error) { /* opening must never fail because of a mirror sync */ }
4352
+ // Resolve the rail anchor before the reveal so the panel never paints at
4353
+ // its stale coordinates for a frame.
4354
+ positionAccountPopover()
2690
4355
  accountPopover.setAttribute('data-open', 'true')
2691
4356
  accountBtn.setAttribute('data-open', 'true')
2692
4357
  accountBtn.setAttribute('aria-expanded', 'true')
@@ -2694,10 +4359,7 @@ window.__ModuleLoader__.load({
2694
4359
 
2695
4360
  function closePopover() {
2696
4361
  if (!accountPopover || !accountBtn) return
2697
- if (popoverTimer) {
2698
- clearTimeout(popoverTimer)
2699
- popoverTimer = null
2700
- }
4362
+ cancelClosePopover()
2701
4363
  accountPopover.setAttribute('data-open', 'false')
2702
4364
  accountBtn.setAttribute('data-open', 'false')
2703
4365
  accountBtn.setAttribute('aria-expanded', 'false')
@@ -2713,18 +4375,36 @@ window.__ModuleLoader__.load({
2713
4375
  }
2714
4376
  }
2715
4377
 
4378
+ function cancelClosePopover() {
4379
+ popoverHoverIntent.cancel()
4380
+ }
4381
+
2716
4382
  function scheduleClosePopover() {
2717
- if (popoverTimer) clearTimeout(popoverTimer)
2718
- popoverTimer = setTimeout(function () {
2719
- closePopover()
2720
- }, 150)
4383
+ popoverHoverIntent.scheduleClose()
2721
4384
  }
2722
4385
 
2723
- function cancelClosePopover() {
2724
- if (popoverTimer) {
2725
- clearTimeout(popoverTimer)
2726
- popoverTimer = null
4386
+ /**
4387
+ * Anchor the account popover to its trigger while the sidebar is a rail.
4388
+ *
4389
+ * In the rail the popover is `position: fixed` (components/account-footer.css): the sidebar
4390
+ * column clips its overflow, so an absolutely positioned panel would be cut
4391
+ * off at the 56px rail edge and never seen. Its coordinates therefore have
4392
+ * to be resolved here — the same contract the model picker's popovers use.
4393
+ * The declarations are written `important` because the stylesheet anchors
4394
+ * the wide-sidebar popover with `!important` as well, and an author
4395
+ * `!important` beats a plain inline declaration.
4396
+ *
4397
+ * With the sidebar wide the CSS anchor is the right one, so the inline
4398
+ * overrides are dropped again and the footer rule takes over.
4399
+ */
4400
+ function positionAccountPopover() {
4401
+ if (!accountPopover || !accountBtn) return
4402
+ if (accountBtn.closest('[class*="collapsed"]') === null) {
4403
+ accountPopover.style.removeProperty('left')
4404
+ accountPopover.style.removeProperty('top')
4405
+ return
2727
4406
  }
4407
+ positionAnchoredPopover(accountBtn, accountPopover, { side: 'right', important: true })
2728
4408
  }
2729
4409
 
2730
4410
  var settingsItem = null
@@ -3194,10 +4874,41 @@ window.__ModuleLoader__.load({
3194
4874
  return null
3195
4875
  }
3196
4876
 
4877
+ /**
4878
+ * Hand the sidebar footer back to the host.
4879
+ *
4880
+ * The "Collapse the sidebar settings area" preference turns the whole
4881
+ * takeover off, so the skin's own nodes go and every marker it put on the
4882
+ * host's entries is removed — with the stylesheet's takeover rules gated
4883
+ * on the same attribute, the footer then renders exactly as shipped.
4884
+ */
4885
+ function dropAccountFooter(footArea) {
4886
+ cancelClosePopover()
4887
+ if (accountBtn !== null && accountBtn.parentElement !== null) accountBtn.parentElement.removeChild(accountBtn)
4888
+ if (accountPopover !== null && accountPopover.parentElement !== null) {
4889
+ accountPopover.parentElement.removeChild(accountPopover)
4890
+ }
4891
+ accountBtn = null
4892
+ accountPopover = null
4893
+ popoverBody = null
4894
+ settingsItem = null
4895
+ var marked = footArea.querySelectorAll(
4896
+ '[data-dsh-claude-footer-entry], [data-dsh-claude-footer-hidden], [data-dsh-claude-footer-overlay]',
4897
+ )
4898
+ for (var i = 0; i < marked.length; i++) {
4899
+ marked[i].removeAttribute('data-dsh-claude-footer-entry')
4900
+ marked[i].removeAttribute('data-dsh-claude-footer-hidden')
4901
+ marked[i].removeAttribute('data-dsh-claude-footer-overlay')
4902
+ }
4903
+ }
3197
4904
  function syncAccountFooter() {
3198
4905
  var footArea = document.querySelector('[class*="footArea"]')
3199
4906
  if (footArea === null) return
3200
4907
 
4908
+ if (!readPrefs().collapseFooter) {
4909
+ dropAccountFooter(footArea)
4910
+ return
4911
+ }
3201
4912
  var username = getUsername(ctx)
3202
4913
 
3203
4914
  if (accountBtn === null || !footArea.contains(accountBtn)) {
@@ -3215,11 +4926,15 @@ window.__ModuleLoader__.load({
3215
4926
  '</span>' +
3216
4927
  '<span class="dsh-claude-account-chevron"></span>'
3217
4928
 
4929
+ // Hover is the default way in; the "Open popovers on hover"
4930
+ // preference turns it off, leaving the click handler below as the only
4931
+ // way in (and the only way out, so a click-opened popover does not
4932
+ // vanish when the pointer leaves).
3218
4933
  accountBtn.addEventListener('mouseenter', function () {
3219
- openPopover()
4934
+ if (readPrefs().autoPopover) openPopover()
3220
4935
  })
3221
4936
  accountBtn.addEventListener('mouseleave', function () {
3222
- scheduleClosePopover()
4937
+ if (readPrefs().autoPopover) scheduleClosePopover()
3223
4938
  })
3224
4939
  accountBtn.addEventListener('click', function (e) {
3225
4940
  e.stopPropagation()
@@ -3272,20 +4987,58 @@ window.__ModuleLoader__.load({
3272
4987
  syncPopoverItems(footArea)
3273
4988
  }
3274
4989
 
3275
- // ============================================================================
3276
- // Zone 5: 响应式调度与生命周期清理 (Scheduler & Teardown)
3277
- // ============================================================================
4990
+
4991
+ ui.footer = {
4992
+ sync: syncAccountFooter,
4993
+ close: closePopover,
4994
+ owns: function (target) {
4995
+ if (!target) return false
4996
+ return (accountBtn !== null && accountBtn.contains(target)) ||
4997
+ (accountPopover !== null && accountPopover.contains(target))
4998
+ },
4999
+ isOpen: function () {
5000
+ return !!(accountPopover && accountPopover.getAttribute('data-open') === 'true')
5001
+ },
5002
+ reposition: positionAccountPopover
5003
+ }
5004
+
5005
+ return function () {
5006
+ cancelClosePopover()
5007
+ var footArea = document.querySelector('[class*="footArea"]')
5008
+ if (footArea) {
5009
+ dropAccountFooter(footArea)
5010
+ } else {
5011
+ if (accountBtn !== null && accountBtn.parentElement !== null) accountBtn.parentElement.removeChild(accountBtn)
5012
+ if (accountPopover !== null && accountPopover.parentElement !== null) accountPopover.parentElement.removeChild(accountPopover)
5013
+ accountBtn = null
5014
+ accountPopover = null
5015
+ popoverBody = null
5016
+ settingsItem = null
5017
+ }
5018
+ }
5019
+ }
5020
+
5021
+ // ============================================================================
5022
+ // 响应式调度与生命周期清理 (Scheduler & Teardown)
5023
+ // ============================================================================
5024
+ function installScheduler(ctx, ui) {
3278
5025
  function onGlobalPointerDown(e) {
3279
- if (!accountPopover || !accountBtn) return
3280
5026
  var target = e.target
3281
- if (target && (accountBtn.contains(target) || accountPopover.contains(target))) return
3282
- closePopover()
5027
+ // The model picker is hover-driven; a press anywhere outside its
5028
+ // trigger and both levels closes it (same discipline as the perm menu).
5029
+ if (target && ui.model && !ui.model.owns(target)) {
5030
+ ui.model.close()
5031
+ }
5032
+ if (!ui.footer || !ui.footer.isOpen()) return
5033
+ if (target && ui.footer.owns(target)) return
5034
+ ui.footer.close()
3283
5035
  }
3284
5036
 
3285
5037
  function onGlobalKeyDown(e) {
3286
5038
  if (e.key === 'Escape') {
3287
- closePopover()
3288
- closePermMenu()
5039
+ if (ui.footer) ui.footer.close()
5040
+ if (ui.permissions) ui.permissions.closeMenu()
5041
+ if (ui.model) ui.model.close()
3289
5042
  }
3290
5043
  if ((e.ctrlKey || e.metaKey) && e.key === ',') {
3291
5044
  e.preventDefault()
@@ -3323,9 +5076,63 @@ window.__ModuleLoader__.load({
3323
5076
  }
3324
5077
  }
3325
5078
 
5079
+ function onComposerInput(e) {
5080
+ var target = e.target
5081
+ if (!target) return
5082
+ if (target.hasAttribute && (target.hasAttribute('data-composer-input') || (target.closest && target.closest('[data-composer-input]')))) {
5083
+ if (ui.copy && ui.copy.syncAttachmentPlaceholder) ui.copy.syncAttachmentPlaceholder()
5084
+ }
5085
+ }
5086
+
3326
5087
  document.addEventListener('pointerdown', onGlobalPointerDown)
3327
5088
  document.addEventListener('pointerdown', onCardPointerDown)
3328
5089
  document.addEventListener('keydown', onGlobalKeyDown, true)
5090
+ document.addEventListener('input', onComposerInput, true)
5091
+ document.addEventListener('compositionend', onComposerInput, true)
5092
+
5093
+ // Both fixed popovers are anchored to their trigger; scroll of the page
5094
+ // (not the conversation's own auto-stick) and resizes move the anchor, so
5095
+ // whichever is open must re-resolve it.
5096
+ function onFixedPopoverViewportChange() {
5097
+ if (ui.model) ui.model.reposition()
5098
+ if (ui.footer && ui.footer.isOpen()) ui.footer.reposition()
5099
+ }
5100
+ window.addEventListener('resize', onFixedPopoverViewportChange)
5101
+ window.addEventListener('scroll', onFixedPopoverViewportChange, true)
5102
+
5103
+ // The picker's copy follows the shell language, so a locale switch has to
5104
+ // rebuild the rows it already painted. Subscribing here (rather than
5105
+ // reading the locale at render time only) is what makes the change land
5106
+ // while a popover is open.
5107
+ var localeUnsubscribe = null
5108
+ function onLocaleChange() {
5109
+ if (ui.model) ui.model.invalidateCopy()
5110
+ schedule()
5111
+ }
5112
+ try {
5113
+ var localeService = ctx.get('locale')
5114
+ if (localeService && typeof localeService.subscribe === 'function') {
5115
+ localeUnsubscribe = localeService.subscribe(onLocaleChange)
5116
+ }
5117
+ } catch (error) { /* no locale service: the picker keeps the fallback language */ }
5118
+
5119
+ // Preferences gate the stylesheet and this scheduler both — the footer
5120
+ // takeover adds or removes the account row, and the composer scope flips
5121
+ // an attribute the stylesheet reads — so a change re-runs the pass. The
5122
+ // first read also arrives through here, which is what replaces the
5123
+ // defaults with the stored values.
5124
+ var prefsUnsubscribe = null
5125
+ prefsUnsubscribe = subscribePrefs(function () {
5126
+ if (ui.model) ui.model.invalidateCopy()
5127
+ schedule()
5128
+ })
5129
+ loadPrefs()
5130
+
5131
+ var modelCopyUnsubscribe = null
5132
+ modelCopyUnsubscribe = onModelCopyLoaded(function () {
5133
+ if (ui.model) ui.model.invalidateCopy()
5134
+ schedule()
5135
+ })
3329
5136
 
3330
5137
  // Chat streaming mutates the tree constantly; coalesce to one pass a frame.
3331
5138
  var scheduled = false
@@ -3348,13 +5155,13 @@ window.__ModuleLoader__.load({
3348
5155
  scheduled = true
3349
5156
  requestAnimationFrame(function () {
3350
5157
  scheduled = false
3351
- rewriteHeadline()
3352
- rewriteHint()
3353
- rewriteTurnStatus()
3354
- syncAttachmentState()
3355
- restoreStatsPosition()
3356
- syncSegments()
3357
- syncAccountFooter()
5158
+ if (ui.copy) ui.copy.sync()
5159
+ if (ui.permissions) ui.permissions.sync()
5160
+ if (ui.model) ui.model.sync()
5161
+ if (ui.footer) ui.footer.sync()
5162
+ // Covers the rail toggle (and any reflow) while the popover is open:
5163
+ // its anchor moved without a window resize or a page scroll.
5164
+ if (ui.footer && ui.footer.isOpen()) ui.footer.reposition()
3358
5165
  if (composerCardObserver) {
3359
5166
  var currentCard = document.querySelector('[data-composer-card]')
3360
5167
  if (currentCard !== observedCard) {
@@ -3365,6 +5172,7 @@ window.__ModuleLoader__.load({
3365
5172
  }
3366
5173
  })
3367
5174
  }
5175
+ ui.schedule = schedule
3368
5176
 
3369
5177
  var observer = new MutationObserver(schedule)
3370
5178
  observer.observe(document.body, {
@@ -3372,8 +5180,9 @@ window.__ModuleLoader__.load({
3372
5180
  characterData: true,
3373
5181
  subtree: true,
3374
5182
  attributes: true,
3375
- // The shipped trigger carries the current preset in its aria-label.
3376
- attributeFilter: ['aria-label'],
5183
+ // The shipped trigger carries the current preset in its aria-label;
5184
+ // the conversation tabs carry the active view in aria-selected.
5185
+ attributeFilter: ['aria-label', 'aria-selected'],
3377
5186
  })
3378
5187
  schedule()
3379
5188
 
@@ -3381,53 +5190,40 @@ window.__ModuleLoader__.load({
3381
5190
  // line rolls over on the hour while the app stays open. rewriteHeadline
3382
5191
  // skips identical text, so this cannot feed the observer.
3383
5192
  var greetingTimer = setInterval(function () {
3384
- rewriteHeadline()
5193
+ if (ui.copy) ui.copy.syncGreeting()
3385
5194
  }, 60000)
3386
5195
 
3387
5196
  return function () {
3388
5197
  clearInterval(greetingTimer)
3389
5198
  greetingTimer = null
5199
+ window.removeEventListener('resize', onFixedPopoverViewportChange)
5200
+ window.removeEventListener('scroll', onFixedPopoverViewportChange, true)
5201
+ if (localeUnsubscribe !== null) {
5202
+ try { localeUnsubscribe() } catch (error) { /* already disposed */ }
5203
+ localeUnsubscribe = null
5204
+ }
5205
+ if (prefsUnsubscribe !== null) {
5206
+ try { prefsUnsubscribe() } catch (error) { /* already disposed */ }
5207
+ prefsUnsubscribe = null
5208
+ }
5209
+ if (modelCopyUnsubscribe !== null) {
5210
+ try { modelCopyUnsubscribe() } catch (error) { /* already disposed */ }
5211
+ modelCopyUnsubscribe = null
5212
+ }
3390
5213
  observer.disconnect()
3391
5214
  if (composerCardObserver) {
3392
5215
  composerCardObserver.disconnect()
3393
5216
  composerCardObserver = null
3394
5217
  observedCard = null
3395
5218
  }
3396
- if (popoverTimer) {
3397
- clearTimeout(popoverTimer)
3398
- popoverTimer = null
3399
- }
3400
5219
  document.removeEventListener('pointerdown', onGlobalPointerDown)
3401
5220
  document.removeEventListener('pointerdown', onCardPointerDown)
3402
5221
  document.removeEventListener('keydown', onGlobalKeyDown, true)
3403
- if (permDocPointerListener) {
3404
- document.removeEventListener('pointerdown', permDocPointerListener)
3405
- permDocPointerListener = null
3406
- }
3407
- if (permResizeListener) {
3408
- window.removeEventListener('resize', permResizeListener)
3409
- window.removeEventListener('scroll', permResizeListener, true)
3410
- permResizeListener = null
3411
- }
3412
- if (segments !== null && segments.parentElement !== null) segments.parentElement.removeChild(segments)
3413
- segments = null
3414
- if (permPopover !== null && permPopover.parentElement !== null) {
3415
- permPopover.parentElement.removeChild(permPopover)
3416
- }
3417
- permPopover = null
3418
- permBtn = null
3419
- permLabel = null
3420
- permContainer = null
3421
- if (accountPopover !== null && accountPopover.parentElement !== null) {
3422
- accountPopover.parentElement.removeChild(accountPopover)
3423
- }
3424
- accountPopover = null
3425
- popoverBody = null
3426
- if (accountBtn !== null && accountBtn.parentElement !== null) {
3427
- accountBtn.parentElement.removeChild(accountBtn)
3428
- }
3429
- accountBtn = null
3430
- var leftoverItems = document.querySelectorAll('.dsh-claude-popover-item, .dsh-claude-popover-embed, .dsh-claude-account-popover, .dsh-claude-account-btn, .dsh-claude-perm-container, .dsh-claude-perm-popover, .dsh-claude-segments')
5222
+ document.removeEventListener('input', onComposerInput, true)
5223
+ document.removeEventListener('compositionend', onComposerInput, true)
5224
+ // Safety-net DOM sweep. Feature teardowns run after this and tolerate
5225
+ // nodes already being detached.
5226
+ var leftoverItems = document.querySelectorAll('.dsh-claude-popover-item, .dsh-claude-popover-embed, .dsh-claude-account-popover, .dsh-claude-account-btn, .dsh-claude-perm-container, .dsh-claude-perm-popover, .dsh-claude-segments[data-composer-segments], .dsh-claude-model-btn, .dsh-claude-model-popover, [data-dsh-synthetic-placeholder]')
3431
5227
  for (var li = 0; li < leftoverItems.length; li++) {
3432
5228
  if (leftoverItems[li].parentElement) {
3433
5229
  leftoverItems[li].parentElement.removeChild(leftoverItems[li])
@@ -3444,74 +5240,160 @@ window.__ModuleLoader__.load({
3444
5240
  }
3445
5241
 
3446
5242
  // ============================================================================
3447
- // Zone 4.4: 设置页品牌分区 (Settings Section: Brand)
5243
+ // 设置页 (Settings Section)
3448
5244
  // ============================================================================
3449
5245
  /**
3450
5246
  * The settings page section, mounted by the host into the `settings.section`
3451
- * slot. That slot hands a section only `{ close }` plus the standard hooks, so
3452
- * this component owns its state and persistence rather than reading a store.
5247
+ * slot. That slot hands a section only `{ close }` plus the standard hooks,
5248
+ * so this component owns no store of its own: it reads and writes the skin
5249
+ * preferences through src/context/prefs.js, which owns the host round trip, and
5250
+ * follows changes the same way the rest of the skin does.
5251
+ *
5252
+ * Copy comes from the model copy document's `settings` block, so the page
5253
+ * follows the shell language like every other string the skin paints. The
5254
+ * English literals here are the fallback for a failed fetch.
3453
5255
  *
3454
- * It renders a segmented control in the same visual language as the composer's
3455
- * permission control: a single hairline track with the active segment plated.
5256
+ * Both segmented controls reuse the shared `.dsh-claude-segments` /
5257
+ * `.dsh-claude-segment` classes — the same control the composer's permission
5258
+ * picker uses — so the two read as one design instead of two lookalikes.
3456
5259
  */
3457
- function BrandSettingsSection() {
3458
- var state = React.useState(readStoredBrand())
3459
- var brand = state[0]
3460
- var setBrand = state[1]
5260
+ function ClaudeStyleSettingsSection() {
5261
+ var state = React.useState(readPrefs())
5262
+ var prefs = state[0]
5263
+ var setPrefs = state[1]
5264
+ var errorState = React.useState(null)
5265
+ var error = errorState[0]
5266
+ var setError = errorState[1]
5267
+
5268
+ // The skin's own apply-side writes land here too (a reload, a conflict
5269
+ // re-read), so the page never drifts from what the document says.
5270
+ React.useEffect(function () {
5271
+ var alive = true
5272
+ var unsubscribe = subscribePrefs(function (next) {
5273
+ if (alive) setPrefs(next)
5274
+ })
5275
+ var unsubscribeCopy = onModelCopyLoaded(function () {
5276
+ if (alive) setPrefs(function (p) { return Object.assign({}, p) })
5277
+ })
5278
+ return function () {
5279
+ alive = false
5280
+ unsubscribe()
5281
+ if (unsubscribeCopy) unsubscribeCopy()
5282
+ }
5283
+ }, [])
3461
5284
 
3462
- var choose = function (next) {
3463
- if (next === brand) return
3464
- writeStoredBrand(next)
3465
- applyBrand(next)
3466
- setBrand(next)
5285
+ /**
5286
+ * Apply one change. The control flips immediately and the host write
5287
+ * follows; a refusal re-reads the authoritative value and says so.
5288
+ */
5289
+ var write = function (patch) {
5290
+ setError(null)
5291
+ setPrefs(Object.assign({}, prefs, patch))
5292
+ savePrefs(patch).then(function (result) {
5293
+ if (result === null) setError(settingsCopy('unavailable', 'The settings store is unavailable, so changes will not be saved.'))
5294
+ })
3467
5295
  }
3468
5296
 
3469
- var options = [
3470
- { value: BRAND_CLAUDE, label: 'Claude' },
3471
- { value: BRAND_ANTHROPIC, label: 'Anthropic' },
3472
- ]
3473
-
3474
- var segments = []
3475
- for (var i = 0; i < options.length; i++) {
3476
- segments.push(
3477
- React.createElement(
5297
+ var segment = function (options, active, onPick) {
5298
+ var buttons = []
5299
+ for (var i = 0; i < options.length; i++) {
5300
+ buttons.push(React.createElement(
3478
5301
  'button',
3479
5302
  {
3480
5303
  key: options[i].value,
3481
5304
  type: 'button',
3482
- className: 'dsh-claude-brand-option',
3483
- 'data-active': options[i].value === brand ? 'true' : 'false',
3484
- 'aria-pressed': options[i].value === brand ? 'true' : 'false',
5305
+ className: SEGMENT_CLASS,
5306
+ 'data-active': options[i].value === active ? '' : undefined,
5307
+ 'aria-pressed': options[i].value === active ? 'true' : 'false',
3485
5308
  onClick: (function (value) {
3486
5309
  return function () {
3487
- choose(value)
5310
+ if (value !== active) onPick(value)
3488
5311
  }
3489
5312
  })(options[i].value),
3490
5313
  },
3491
5314
  options[i].label,
3492
- ),
5315
+ ))
5316
+ }
5317
+ return React.createElement('div', { className: SEGMENTS_CLASS, role: 'group' }, buttons)
5318
+ }
5319
+
5320
+ var toggle = function (on, onPick) {
5321
+ return React.createElement(
5322
+ 'button',
5323
+ {
5324
+ type: 'button',
5325
+ className: 'dsh-claude-settings-switch',
5326
+ role: 'switch',
5327
+ 'aria-checked': on ? 'true' : 'false',
5328
+ 'data-on': on ? '' : undefined,
5329
+ onClick: function () { onPick(!on) },
5330
+ },
5331
+ React.createElement('span', { className: 'dsh-claude-settings-switch-knob' }),
3493
5332
  )
3494
5333
  }
3495
5334
 
3496
- return React.createElement(
3497
- 'div',
3498
- { className: 'dsh-claude-brand-section' },
3499
- React.createElement('div', { className: 'dsh-claude-brand-title' }, 'Claude Style'),
3500
- React.createElement(
5335
+ var row = function (key, title, description, control) {
5336
+ return React.createElement(
3501
5337
  'div',
3502
- { className: 'dsh-claude-brand-card' },
5338
+ { className: 'dsh-claude-settings-row', key: key },
3503
5339
  React.createElement(
3504
5340
  'div',
3505
- { className: 'dsh-claude-brand-card-text' },
3506
- React.createElement('div', { className: 'dsh-claude-brand-card-title' }, 'Sidebar brand'),
3507
- React.createElement(
3508
- 'div',
3509
- { className: 'dsh-claude-brand-card-desc' },
3510
- 'Which brand mark the sidebar shows. Claude is the default.',
3511
- ),
5341
+ { className: 'dsh-claude-settings-row-text' },
5342
+ React.createElement('div', { className: 'dsh-claude-settings-row-title' }, title),
5343
+ React.createElement('div', { className: 'dsh-claude-settings-row-desc' }, description),
3512
5344
  ),
3513
- React.createElement('div', { className: 'dsh-claude-brand-segments', role: 'group' }, segments),
5345
+ control,
5346
+ )
5347
+ }
5348
+
5349
+ var brandOptions = [
5350
+ { value: BRAND_OFF, label: settingsCopy('brandOff', 'Off') },
5351
+ { value: BRAND_CLAUDE, label: settingsCopy('brandClaude', 'Claude') },
5352
+ { value: BRAND_ANTHROPIC, label: settingsCopy('brandAnthropic', 'Anthropic') },
5353
+ ]
5354
+ var scopeOptions = [
5355
+ { value: 'off', label: settingsCopy('scopeOff', 'Off') },
5356
+ { value: 'hero', label: settingsCopy('scopeHero', 'Home only') },
5357
+ { value: 'conversation', label: settingsCopy('scopeConversation', 'Conversation only') },
5358
+ { value: 'all', label: settingsCopy('scopeAll', 'All') },
5359
+ ]
5360
+
5361
+ var rows = [
5362
+ row(
5363
+ 'brand',
5364
+ settingsCopy('brandTitle', 'Brand mark'),
5365
+ settingsCopy('brandDesc', 'Which brand mark the sidebar shows. "Off" leaves the host\'s own brand area untouched.'),
5366
+ segment(brandOptions, prefs.brand, function (value) { write({ brand: value }) }),
5367
+ ),
5368
+ row(
5369
+ 'collapseFooter',
5370
+ settingsCopy('collapseTitle', 'Collapse the sidebar settings area'),
5371
+ settingsCopy('collapseDesc', 'Fold the sidebar footer\'s settings entry into the account popover. Off hands the footer back to the host entirely.'),
5372
+ toggle(prefs.collapseFooter, function (value) { write({ collapseFooter: value }) }),
5373
+ ),
5374
+ row(
5375
+ 'autoPopover',
5376
+ settingsCopy('autoPopoverTitle', 'Open popovers on hover'),
5377
+ settingsCopy('autoPopoverDesc', 'Hover opens the account and model popovers. Off switches them to click-to-open.'),
5378
+ toggle(prefs.autoPopover, function (value) { write({ autoPopover: value }) }),
3514
5379
  ),
5380
+ row(
5381
+ 'composerScope',
5382
+ settingsCopy('composerTitle', 'Composer restyle'),
5383
+ settingsCopy('composerDesc', 'Which input area the skin restyles: the new-conversation page, the conversation, or both.'),
5384
+ segment(scopeOptions, prefs.composerScope, function (value) { write({ composerScope: value }) }),
5385
+ ),
5386
+ ]
5387
+
5388
+ if (error !== null) {
5389
+ rows.push(React.createElement('div', { className: 'dsh-claude-settings-error', key: 'error' }, error))
5390
+ }
5391
+
5392
+ return React.createElement(
5393
+ 'div',
5394
+ { className: 'dsh-claude-settings' },
5395
+ React.createElement('div', { className: 'dsh-claude-settings-title' }, settingsCopy('title', 'Claude Style')),
5396
+ rows,
3515
5397
  )
3516
5398
  }
3517
5399
 
@@ -3535,6 +5417,7 @@ window.__ModuleLoader__.load({
3535
5417
  * @returns a disposer that tears the registration down.
3536
5418
  */
3537
5419
  function installSettingsSection(ctx) {
5420
+ loadModelCopy()
3538
5421
  if (typeof ctx.inject !== 'function') return function () {}
3539
5422
  var fiber = ctx.inject(['slots'], function (scope) {
3540
5423
  var slots = scope.get('slots')
@@ -3542,8 +5425,15 @@ window.__ModuleLoader__.load({
3542
5425
  scope.effect(function () {
3543
5426
  return slots.inject('settings.section', function () {
3544
5427
  return slots.register(
3545
- { name: 'settings.section', id: 'claude-style', order: 22, label: function () { return 'Claude Style' } },
3546
- BrandSettingsSection,
5428
+ {
5429
+ name: 'settings.section',
5430
+ id: 'claude-style',
5431
+ order: 22,
5432
+ // A function, so the navigation entry localizes once the copy
5433
+ // document has arrived; the literal is the pre-fetch fallback.
5434
+ label: function () { return settingsCopy('title', 'Claude Style') },
5435
+ },
5436
+ ClaudeStyleSettingsSection,
3547
5437
  )
3548
5438
  })
3549
5439
  }, 'dsh-claude-style: settings section')
@@ -3558,12 +5448,18 @@ window.__ModuleLoader__.load({
3558
5448
  }
3559
5449
 
3560
5450
  // ============================================================================
3561
- // Zone 6: 插件入口与导出 (Plugin Entry & Export)
5451
+ // 插件入口与导出 (Plugin Entry & Export)
3562
5452
  // ============================================================================
3563
5453
  function apply(ctx) {
3564
5454
  var body = document.body
3565
5455
  body.setAttribute('data-dsh-claude-style', '')
3566
- applyBrand(readStoredBrand())
5456
+ setHostContext(ctx)
5457
+ loadModelCopy()
5458
+ // Preferences are read asynchronously from the host settings namespace;
5459
+ // applying the defaults first keeps every gated rule in a defined state
5460
+ // for the frames before that read settles, and is exactly the shipped
5461
+ // behaviour when it never does.
5462
+ adoptPrefs(prefs)
3567
5463
 
3568
5464
  var old = document.getElementById(STYLE_ID)
3569
5465
  if (old && old.parentElement) old.parentElement.removeChild(old)
@@ -3574,19 +5470,30 @@ window.__ModuleLoader__.load({
3574
5470
  style.textContent = CSS
3575
5471
  document.head.appendChild(style)
3576
5472
 
3577
- var stopOverrides = installOverrides(ctx)
5473
+ var ui = {}
5474
+ var teardowns = []
5475
+ teardowns.push(installCopy(ctx, ui))
5476
+ teardowns.push(installPermissions(ctx, ui))
5477
+ teardowns.push(installModelPicker(ctx, ui))
5478
+ teardowns.push(installAccountFooter(ctx, ui))
5479
+ teardowns.push(installScheduler(ctx, ui)) // 最后装,回调中惰性读 ui 句柄
3578
5480
  var stopSettings = installSettingsSection(ctx)
3579
5481
 
3580
5482
  ctx.effect(function () {
3581
5483
  return function () {
3582
- stopOverrides()
5484
+ for (var i = teardowns.length - 1; i >= 0; i--) {
5485
+ try { teardowns[i]() } catch (error) { /* one teardown must not block the rest */ }
5486
+ }
3583
5487
  stopSettings()
5488
+ setHostContext(null)
3584
5489
  body.removeAttribute('data-dsh-claude-style')
3585
5490
  body.removeAttribute(BRAND_ATTR)
5491
+ body.removeAttribute(FOOTER_ATTR)
5492
+ body.removeAttribute(COMPOSER_ATTR)
3586
5493
  var el = document.getElementById(STYLE_ID)
3587
5494
  if (el) el.remove()
3588
5495
  }
3589
- }, 'dsh-claude-style: Claude Code Desktop theme')
5496
+ }, 'dsh-claude-style: Claude Code desktop theme')
3590
5497
  }
3591
5498
 
3592
5499
  exports.apply = apply