@dickpy/dsh-imagegen 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +270 -124
  3. package/cordis.patch.yml +8 -8
  4. package/docs/images/ecommerce-mode.png +0 -0
  5. package/docs/images/image-generation-studio-three-column.png +0 -0
  6. package/docs/images/imagegen-overview.png +0 -0
  7. package/docs/videos/agent-chat-edit.gif +0 -0
  8. package/docs/videos/agent-chat-edit.mp4 +0 -0
  9. package/lib/client.js +1859 -420
  10. package/lib/client.js.map +1 -1
  11. package/lib/index.js +327 -112
  12. package/package.json +69 -68
  13. package/src/agent-image-tools.ts +447 -418
  14. package/src/client/ImageGenPanel.tsx +1242 -348
  15. package/src/client/SettingsCard.tsx +936 -936
  16. package/src/client/TemplateLibrary.tsx +336 -336
  17. package/src/client/api.ts +203 -193
  18. package/src/client/channels-form.ts +263 -263
  19. package/src/client/controller.ts +46 -46
  20. package/src/client/conversation-sync.ts +14 -14
  21. package/src/client/css-modules.d.ts +5 -5
  22. package/src/client/helpers.ts +33 -33
  23. package/src/client/image-toolview.module.css +73 -73
  24. package/src/client/image-toolview.tsx +18 -18
  25. package/src/client/index.ts +22 -22
  26. package/src/client/locales.ts +156 -28
  27. package/src/client/mount.tsx +117 -117
  28. package/src/client/panel.module.css +1243 -455
  29. package/src/client/settings-card.module.css +1023 -1023
  30. package/src/client/settings-form.ts +336 -336
  31. package/src/client/settings-scope.ts +298 -298
  32. package/src/client/sidebar-entry.ts +190 -190
  33. package/src/client/templates.module.css +453 -453
  34. package/src/edit-image-command.ts +110 -0
  35. package/src/engine.ts +520 -520
  36. package/src/gallery-store.ts +306 -286
  37. package/src/generation-runtime.ts +84 -79
  38. package/src/history-store.ts +270 -250
  39. package/src/image-format.ts +11 -11
  40. package/src/image-models.ts +19 -19
  41. package/src/index.ts +337 -318
  42. package/src/model-catalog.ts +115 -115
  43. package/src/presets.ts +71 -71
  44. package/src/prompt-enhancer.ts +137 -137
  45. package/src/protocol.ts +380 -338
  46. package/src/routes.ts +964 -916
  47. package/src/task-queue.ts +113 -113
  48. package/src/templates/cases.json +10196 -10196
  49. package/src/templates-store.ts +278 -278
  50. package/src/updater.ts +117 -117
  51. package/docs/images/agent-chat-edit.png +0 -0
  52. package/docs/images/agent-chat-generate.png +0 -0
  53. package/docs/images/agent-chat-poster-workflow.png +0 -0
@@ -15,140 +15,140 @@
15
15
  both shells: the legacy `[data-pane="conversation"]` and the rc.6+
16
16
  AppFrame class-based column ([class*="centerCol"]) — without a positioned
17
17
  ancestor the absolutely-positioned view resolves against the frame. */
18
- [data-pane='conversation'],
19
- [class*='centerCol'] {
20
- position: relative;
21
- min-width: 0;
22
- min-height: 0;
23
- }
18
+ [data-pane='conversation'],
19
+ [class*='centerCol'] {
20
+ position: relative;
21
+ min-width: 0;
22
+ min-height: 0;
23
+ }
24
24
 
25
25
  /* The panel container rides inside the conversation grid item as an extra
26
26
  trailing child; hidden unless the panel is active. */
27
- [data-dsh-imagegen-view] {
28
- position: relative;
29
- grid-column: 1;
30
- grid-row: 1;
31
- display: none;
32
- z-index: 60;
33
- min-width: 0;
34
- min-height: 0;
35
- background: var(--dsw-alias-bg-base);
36
- }
27
+ [data-dsh-imagegen-view] {
28
+ position: relative;
29
+ grid-column: 1;
30
+ grid-row: 1;
31
+ display: none;
32
+ z-index: 60;
33
+ min-width: 0;
34
+ min-height: 0;
35
+ background: var(--dsw-alias-bg-base);
36
+ }
37
37
 
38
38
  /* The center column is single-occupant; the :not() guards keep the sibling
39
39
  panels (task board / ssh) from fighting over visibility if both activation
40
40
  attributes ever coexist. */
41
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'],
42
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] {
43
- display: grid !important;
44
- grid-template-columns: minmax(0, 1fr) 8px minmax(320px, clamp(320px, var(--dsh-imagegen-chat-width, 36%), 70%));
45
- grid-template-rows: minmax(0, 1fr);
46
- gap: 1px;
47
- overflow: hidden;
48
- background: var(--dsw-alias-border-l1);
49
- }
50
-
51
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-view] {
52
- display: block;
53
- }
54
-
55
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-slot='conversation'] {
56
- grid-column: 3;
57
- grid-row: 1;
58
- align-items: stretch;
59
- display: flex !important;
60
- width: auto;
61
- min-width: 0;
62
- min-height: 0;
63
- overflow: hidden;
64
- background: var(--dsw-alias-bg-base);
65
- }
66
-
67
- /* DSH's native conversation root is a flex item with an intrinsic width.
68
- Stretch that direct child to the complete chat column so its hero composer
69
- can center itself inside the resized pane instead of leaving a blank rail
70
- on the right. */
71
- html[data-dsh-imagegen-active] [data-slot='conversation'] > [data-phase] {
72
- align-self: stretch;
73
- flex: 1 1 auto;
74
- width: 100%;
75
- max-width: none;
76
- min-width: 0;
77
- }
78
-
79
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-chat-resizer] {
80
- grid-column: 2;
81
- grid-row: 1;
82
- }
83
-
84
- .chatResizer {
85
- position: relative;
86
- z-index: 70;
87
- display: none;
88
- width: 8px;
89
- min-width: 8px;
90
- align-items: center;
91
- justify-content: center;
92
- color: var(--dsw-alias-label-tertiary);
93
- background: var(--dsw-alias-border-l1);
94
- cursor: col-resize;
95
- touch-action: none;
96
- }
97
-
98
- .chatResizer::before {
99
- width: 3px;
100
- height: 36px;
101
- border-radius: 3px;
102
- background: currentColor;
103
- content: '';
104
- opacity: .55;
105
- }
106
-
107
- .chatResizer:hover,
108
- .chatResizer:focus-visible {
109
- color: var(--dsw-alias-brand-primary);
110
- outline: none;
111
- background: var(--dsw-alias-bg-layer-2);
112
- }
113
-
114
- /* Keep the handle above shell defaults: some skins set display:none on
115
- unrecognised children of the conversation frame. */
116
- html[data-dsh-imagegen-active] [data-dsh-imagegen-chat-resizer] {
117
- display: flex !important;
118
- }
119
-
120
- /* Hide only unrelated center-column plugin children. */
121
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'] > :not([data-dsh-imagegen-view]):not([data-slot='conversation']):not([data-dsh-imagegen-chat-resizer]),
122
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] > :not([data-dsh-imagegen-view]):not([data-slot='conversation']):not([data-dsh-imagegen-chat-resizer]) {
123
- display: none !important;
124
- }
125
-
126
- /* The shell can have any number of plugin entries between the New Session
127
- tabs and its workspace region. Hide the whole middle run while image
128
- generation owns the frame, without relying on a plugin allow-list. */
129
- html[data-dsh-imagegen-active] [data-dsh-imagegen-sidebar-root] > :not([data-dsh-imagegen-session-tabs]):not([class*='logoRow']):not([class*='regionArea']):not([class*='footArea']) {
130
- display: none !important;
131
- }
132
-
133
- @media (max-width: 760px) {
134
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'],
135
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] {
136
- grid-template-columns: minmax(0, 1fr);
137
- grid-template-rows: minmax(0, 1fr) minmax(340px, 0.9fr);
138
- overflow-y: auto;
139
- }
140
-
141
- html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-slot='conversation'] {
142
- grid-column: 1;
143
- grid-row: 2;
144
- }
145
-
146
- html[data-dsh-imagegen-active] [data-dsh-imagegen-chat-resizer] {
147
- display: none !important;
148
- }
149
- }
150
-
151
- /* --- sidebar entry row ------------------------------------------------------- */
41
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'],
42
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] {
43
+ display: grid !important;
44
+ grid-template-columns: minmax(0, 1fr) 8px minmax(320px, clamp(320px, var(--dsh-imagegen-chat-width, 36%), 70%));
45
+ grid-template-rows: minmax(0, 1fr);
46
+ gap: 1px;
47
+ overflow: hidden;
48
+ background: var(--dsw-alias-border-l1);
49
+ }
50
+
51
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-view] {
52
+ display: block;
53
+ }
54
+
55
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-slot='conversation'] {
56
+ grid-column: 3;
57
+ grid-row: 1;
58
+ align-items: stretch;
59
+ display: flex !important;
60
+ width: auto;
61
+ min-width: 0;
62
+ min-height: 0;
63
+ overflow: hidden;
64
+ background: var(--dsw-alias-bg-base);
65
+ }
66
+
67
+ /* DSH's native conversation root is a flex item with an intrinsic width.
68
+ Stretch that direct child to the complete chat column so its hero composer
69
+ can center itself inside the resized pane instead of leaving a blank rail
70
+ on the right. */
71
+ html[data-dsh-imagegen-active] [data-slot='conversation'] > [data-phase] {
72
+ align-self: stretch;
73
+ flex: 1 1 auto;
74
+ width: 100%;
75
+ max-width: none;
76
+ min-width: 0;
77
+ }
78
+
79
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-dsh-imagegen-chat-resizer] {
80
+ grid-column: 2;
81
+ grid-row: 1;
82
+ }
83
+
84
+ .chatResizer {
85
+ position: relative;
86
+ z-index: 70;
87
+ display: none;
88
+ width: 8px;
89
+ min-width: 8px;
90
+ align-items: center;
91
+ justify-content: center;
92
+ color: var(--dsw-alias-label-tertiary);
93
+ background: var(--dsw-alias-border-l1);
94
+ cursor: col-resize;
95
+ touch-action: none;
96
+ }
97
+
98
+ .chatResizer::before {
99
+ width: 3px;
100
+ height: 36px;
101
+ border-radius: 3px;
102
+ background: currentColor;
103
+ content: '';
104
+ opacity: .55;
105
+ }
106
+
107
+ .chatResizer:hover,
108
+ .chatResizer:focus-visible {
109
+ color: var(--dsw-alias-brand-primary);
110
+ outline: none;
111
+ background: var(--dsw-alias-bg-layer-2);
112
+ }
113
+
114
+ /* Keep the handle above shell defaults: some skins set display:none on
115
+ unrecognised children of the conversation frame. */
116
+ html[data-dsh-imagegen-active] [data-dsh-imagegen-chat-resizer] {
117
+ display: flex !important;
118
+ }
119
+
120
+ /* Hide only unrelated center-column plugin children. */
121
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'] > :not([data-dsh-imagegen-view]):not([data-slot='conversation']):not([data-dsh-imagegen-chat-resizer]),
122
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] > :not([data-dsh-imagegen-view]):not([data-slot='conversation']):not([data-dsh-imagegen-chat-resizer]) {
123
+ display: none !important;
124
+ }
125
+
126
+ /* The shell can have any number of plugin entries between the New Session
127
+ tabs and its workspace region. Hide the whole middle run while image
128
+ generation owns the frame, without relying on a plugin allow-list. */
129
+ html[data-dsh-imagegen-active] [data-dsh-imagegen-sidebar-root] > :not([data-dsh-imagegen-session-tabs]):not([class*='logoRow']):not([class*='regionArea']):not([class*='footArea']) {
130
+ display: none !important;
131
+ }
132
+
133
+ @media (max-width: 760px) {
134
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'],
135
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] {
136
+ grid-template-columns: minmax(0, 1fr);
137
+ grid-template-rows: minmax(0, 1fr) minmax(340px, 0.9fr);
138
+ overflow-y: auto;
139
+ }
140
+
141
+ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-slot='conversation'] {
142
+ grid-column: 1;
143
+ grid-row: 2;
144
+ }
145
+
146
+ html[data-dsh-imagegen-active] [data-dsh-imagegen-chat-resizer] {
147
+ display: none !important;
148
+ }
149
+ }
150
+
151
+ /* --- sidebar entry row ------------------------------------------------------- */
152
152
 
153
153
  .entry {
154
154
  display: flex;
@@ -184,96 +184,121 @@ html[data-dsh-imagegen-active] [data-dsh-imagegen-sidebar-root] > :not([data-dsh
184
184
  flex: none;
185
185
  }
186
186
 
187
- .entryLabel {
188
- overflow: hidden;
189
- text-overflow: ellipsis;
190
- }
191
-
192
- /* New Session + Image Generation tabs share the shell's top action row. */
193
- .sessionTabs {
194
- display: grid;
195
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
196
- gap: 2px;
197
- width: 100%;
198
- min-width: 0;
199
- padding: 3px;
200
- border: 1px solid var(--dsw-alias-border-l1);
201
- border-radius: 9px;
202
- background: var(--dsw-alias-bg-layer-1);
203
- }
204
-
205
- .sessionTab {
206
- display: inline-flex;
207
- align-items: center;
208
- justify-content: center;
209
- gap: 6px;
210
- min-width: 0;
211
- height: 30px;
212
- padding: 0 8px;
213
- border: 0;
214
- border-radius: 7px;
215
- color: var(--dsw-alias-label-secondary);
216
- background: transparent;
217
- cursor: pointer;
218
- font: inherit;
219
- font-size: 12px;
220
- white-space: nowrap;
221
- }
222
-
223
- .sessionTab:hover,
224
- .sessionTab[data-active] {
225
- color: var(--dsw-alias-label-primary);
226
- background: var(--dsw-specific-sidebar-nav-item-active);
227
- }
228
-
229
- .sessionTabIcon {
230
- display: inline-flex;
231
- flex: none;
232
- align-items: center;
233
- justify-content: center;
234
- }
235
-
236
- .sessionTabLabel {
237
- min-width: 0;
238
- overflow: hidden;
239
- text-overflow: ellipsis;
240
- }
241
-
242
- /* The history surface occupies the shell's workspace/session region while
243
- image generation is active. The shell's own tree stays mounted underneath
244
- so closing the tab restores it without a React remount. */
245
- [class*='regionArea'] {
246
- position: relative;
247
- min-height: 0;
248
- }
249
-
250
- .sidebarHistoryHost {
251
- position: absolute;
252
- z-index: 30;
253
- inset: 0;
254
- display: none;
255
- min-width: 0;
256
- min-height: 0;
257
- padding: 6px 4px;
258
- overflow: hidden;
259
- background: var(--dsw-alias-bg-base);
260
- }
261
-
262
- html[data-dsh-imagegen-active] .sidebarHistoryHost {
263
- display: flex;
264
- }
265
-
266
- .sidebarHistoryHost .history {
267
- width: 100%;
268
- height: 100%;
269
- border: 0;
270
- border-radius: 8px;
271
- background: transparent;
272
- }
273
-
274
- [data-dsh-frame][data-sidebar-collapsed] .sidebarHistoryHost {
275
- display: none;
276
- }
187
+ .entryLabel {
188
+ overflow: hidden;
189
+ text-overflow: ellipsis;
190
+ }
191
+
192
+ /* New Session + Image Generation tabs share the shell's top action row. */
193
+ .sessionTabs {
194
+ display: grid;
195
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
196
+ gap: 2px;
197
+ width: 100%;
198
+ min-width: 0;
199
+ padding: 3px;
200
+ border: 1px solid var(--dsw-alias-border-l1);
201
+ border-radius: 9px;
202
+ background: var(--dsw-alias-bg-layer-1);
203
+ }
204
+
205
+ .sessionTab {
206
+ display: inline-flex;
207
+ align-items: center;
208
+ justify-content: center;
209
+ gap: 6px;
210
+ min-width: 0;
211
+ height: 30px;
212
+ padding: 0 8px;
213
+ border: 0;
214
+ border-radius: 7px;
215
+ color: var(--dsw-alias-label-secondary);
216
+ background: transparent;
217
+ cursor: pointer;
218
+ font: inherit;
219
+ font-size: 12px;
220
+ white-space: nowrap;
221
+ }
222
+
223
+ /* Collapsed sidebar rail: the injected tabs become plain stacked icon
224
+ * buttons that match the shell's native rail entries. */
225
+ [data-sidebar-collapsed] .sessionTabs {
226
+ display: flex;
227
+ flex-direction: column;
228
+ gap: 6px;
229
+ width: auto;
230
+ padding: 0;
231
+ border: none;
232
+ border-radius: 0;
233
+ background: transparent;
234
+ }
235
+
236
+ [data-sidebar-collapsed] .sessionTab {
237
+ width: 34px;
238
+ height: 34px;
239
+ padding: 0;
240
+ border-radius: 9px;
241
+ font-size: 0;
242
+ }
243
+
244
+ [data-sidebar-collapsed] .sessionTabLabel {
245
+ display: none;
246
+ }
247
+
248
+ .sessionTab:hover,
249
+ .sessionTab[data-active] {
250
+ color: var(--dsw-alias-label-primary);
251
+ background: var(--dsw-specific-sidebar-nav-item-active);
252
+ }
253
+
254
+ .sessionTabIcon {
255
+ display: inline-flex;
256
+ flex: none;
257
+ align-items: center;
258
+ justify-content: center;
259
+ }
260
+
261
+ .sessionTabLabel {
262
+ min-width: 0;
263
+ overflow: hidden;
264
+ text-overflow: ellipsis;
265
+ }
266
+
267
+ /* The history surface occupies the shell's workspace/session region while
268
+ image generation is active. The shell's own tree stays mounted underneath
269
+ so closing the tab restores it without a React remount. */
270
+ [class*='regionArea'] {
271
+ position: relative;
272
+ min-height: 0;
273
+ }
274
+
275
+ .sidebarHistoryHost {
276
+ position: absolute;
277
+ z-index: 30;
278
+ inset: 0;
279
+ display: none;
280
+ min-width: 0;
281
+ min-height: 0;
282
+ padding: 6px 4px;
283
+ overflow: hidden;
284
+ background: var(--dsw-alias-bg-base);
285
+ }
286
+
287
+ html[data-dsh-imagegen-active] .sidebarHistoryHost {
288
+ display: flex;
289
+ }
290
+
291
+ .sidebarHistoryHost .history {
292
+ width: 100%;
293
+ height: 100%;
294
+ border: 0;
295
+ border-radius: 8px;
296
+ background: transparent;
297
+ }
298
+
299
+ [data-dsh-frame][data-sidebar-collapsed] .sidebarHistoryHost {
300
+ display: none;
301
+ }
277
302
 
278
303
  /* Collapsed rail: icon-only, centered, matching the shell's 56px rail. */
279
304
  [data-dsh-frame][data-sidebar-collapsed] .entry {
@@ -288,12 +313,12 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
288
313
 
289
314
  /* --- panel frame -------------------------------------------------------------- */
290
315
 
291
- .view {
292
- width: 100%;
293
- min-width: 0;
294
- min-height: 0;
295
- overflow: hidden;
296
- }
316
+ .view {
317
+ width: 100%;
318
+ min-width: 0;
319
+ min-height: 0;
320
+ overflow: hidden;
321
+ }
297
322
 
298
323
  /* The shell does not ship a global `box-sizing: border-box` reset, so scope
299
324
  one to the panel subtree: without it, `height: 100%` + padding grows past
@@ -321,6 +346,7 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
321
346
  }
322
347
 
323
348
  .panelHeader {
349
+ position: relative;
324
350
  display: flex;
325
351
  align-items: center;
326
352
  justify-content: space-between;
@@ -453,36 +479,80 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
453
479
  }
454
480
  }
455
481
 
456
- /* --- studio split: left history + middle generation workspace ----------------- */
457
-
458
- .studio {
459
- display: flex;
460
- min-width: 0;
461
- min-height: 0;
462
- flex: 1;
463
- }
464
-
465
- .generation {
466
- display: flex;
467
- width: 100%;
468
- gap: 14px;
469
- min-width: 0;
470
- min-height: 0;
471
- }
482
+ /* --- studio split: left history + middle generation workspace ----------------- */
483
+
484
+ .studio {
485
+ display: flex;
486
+ min-width: 0;
487
+ min-height: 0;
488
+ flex: 1;
489
+ }
490
+
491
+ .generation {
492
+ display: flex;
493
+ width: 100%;
494
+ gap: 14px;
495
+ min-width: 0;
496
+ min-height: 0;
497
+ }
472
498
 
473
499
  .config {
474
500
  display: flex;
475
501
  flex-direction: column;
476
502
  gap: 12px;
477
503
  flex: none;
478
- width: min(300px, 42%);
479
- min-width: 220px;
480
- max-width: 300px;
504
+ position: relative;
505
+ width: clamp(240px, var(--dsh-imagegen-config-width, 300px), 480px);
506
+ min-width: 240px;
507
+ max-width: 480px;
481
508
  height: 100%;
482
509
  min-height: 0;
483
510
  overflow: hidden;
484
511
  }
485
512
 
513
+ .configHeader {
514
+ display: flex;
515
+ justify-content: flex-end;
516
+ flex: none;
517
+ min-height: 28px;
518
+ }
519
+
520
+ .configToggle {
521
+ display: inline-flex;
522
+ align-items: center;
523
+ justify-content: center;
524
+ width: 28px;
525
+ height: 28px;
526
+ padding: 0;
527
+ border: 1px solid var(--dsw-alias-border-l1);
528
+ border-radius: 7px;
529
+ color: var(--dsw-alias-label-secondary);
530
+ background: var(--dsw-alias-bg-layer-1);
531
+ cursor: pointer;
532
+ }
533
+
534
+ .configToggle:hover,
535
+ .configToggle:focus-visible {
536
+ border-color: var(--dsw-alias-brand-primary);
537
+ color: var(--dsw-alias-brand-primary);
538
+ outline: none;
539
+ }
540
+
541
+ .config[data-collapsed='true'] {
542
+ width: 38px;
543
+ min-width: 38px;
544
+ max-width: 38px;
545
+ gap: 0;
546
+ }
547
+
548
+ .config[data-collapsed='true'] .configHeader {
549
+ justify-content: center;
550
+ }
551
+
552
+ .config[data-collapsed='true'] > :not(.configHeader) {
553
+ display: none;
554
+ }
555
+
486
556
  /* The cards scroll in their own scrollport; the footer stays a fixed sibling
487
557
  below, so nothing ever hides underneath it (text and edit modes alike). */
488
558
  .configScroll {
@@ -562,14 +632,14 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
562
632
  .configGuideBody span { color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 1.55; }
563
633
  .configGuideBody button { align-self: flex-end; min-height: 30px; padding: 0 12px; border: 0; border-radius: 7px; color: var(--dsw-alias-bg-layer-1); background: var(--dsw-alias-brand-primary); cursor: pointer; font: inherit; font-size: 12px; }
564
634
 
565
- /* --- history surface (rendered into the shell sidebar) ----------------------- */
566
-
567
- .history {
568
- display: flex;
569
- flex-direction: column;
570
- width: auto;
571
- min-width: 0;
572
- max-width: none;
635
+ /* --- history surface (rendered into the shell sidebar) ----------------------- */
636
+
637
+ .history {
638
+ display: flex;
639
+ flex-direction: column;
640
+ width: auto;
641
+ min-width: 0;
642
+ max-width: none;
573
643
  min-height: 0;
574
644
  border: 1px solid var(--dsw-alias-border-l1);
575
645
  border-radius: 12px;
@@ -587,6 +657,13 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
587
657
  flex: none;
588
658
  }
589
659
 
660
+ .historyHeaderActions {
661
+ display: flex;
662
+ align-items: center;
663
+ gap: 6px;
664
+ flex: none;
665
+ }
666
+
590
667
  .historyFilters {
591
668
  display: grid;
592
669
  grid-template-columns: 1fr 1fr;
@@ -623,172 +700,851 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
623
700
  color: var(--dsw-alias-label-primary);
624
701
  }
625
702
 
626
- .historyClear {
627
- padding: 2px 8px;
628
- font: inherit;
629
- font-size: 11.5px;
630
- color: var(--dsw-alias-label-tertiary);
631
- background: transparent;
632
- border: 1px solid var(--dsw-alias-border-l2);
633
- border-radius: 999px;
703
+ .historyNew {
704
+ display: inline-flex;
705
+ align-items: center;
706
+ justify-content: center;
707
+ width: 26px;
708
+ height: 26px;
709
+ padding: 0;
710
+ color: var(--dsw-alias-label-secondary);
711
+ background: transparent;
712
+ border: 1px solid var(--dsw-alias-border-l2);
713
+ border-radius: 7px;
714
+ cursor: pointer;
715
+ }
716
+
717
+ .historyNew:hover {
718
+ color: var(--dsw-alias-brand-primary);
719
+ border-color: var(--dsw-alias-brand-primary);
720
+ }
721
+
722
+ .historyClear {
723
+ padding: 2px 8px;
724
+ font: inherit;
725
+ font-size: 11.5px;
726
+ color: var(--dsw-alias-label-tertiary);
727
+ background: transparent;
728
+ border: 1px solid var(--dsw-alias-border-l2);
729
+ border-radius: 999px;
730
+ cursor: pointer;
731
+ }
732
+
733
+ .historyClear:hover {
734
+ color: var(--dsw-alias-label-error);
735
+ border-color: var(--dsw-alias-label-error);
736
+ }
737
+
738
+ .historyList {
739
+ flex: 1;
740
+ min-height: 0;
741
+ overflow-y: auto;
742
+ display: flex;
743
+ flex-direction: column;
744
+ gap: 8px;
745
+ padding: 10px;
746
+ scrollbar-width: thin;
747
+ scrollbar-color: var(--dsw-alias-border-l2) transparent;
748
+ }
749
+
750
+ .historyList::-webkit-scrollbar {
751
+ width: 8px;
752
+ }
753
+
754
+ .historyList::-webkit-scrollbar-thumb {
755
+ background: var(--dsw-alias-border-l2);
756
+ border-radius: 999px;
757
+ }
758
+
759
+ .historyEmpty {
760
+ flex: 1;
761
+ display: flex;
762
+ align-items: center;
763
+ justify-content: center;
764
+ padding: 20px;
765
+ font-size: 12px;
766
+ line-height: 1.6;
767
+ text-align: center;
768
+ color: var(--dsw-alias-label-tertiary);
769
+ }
770
+
771
+ .historyItem {
772
+ display: flex;
773
+ flex-direction: column;
774
+ gap: 6px;
775
+ padding: 8px;
776
+ border: 1px solid var(--dsw-alias-border-l1);
777
+ border-radius: 10px;
778
+ background: var(--dsw-alias-bg-layer-2);
779
+ flex: none;
780
+ }
781
+
782
+ .historyItem:hover {
783
+ border-color: var(--dsw-alias-border-l2);
784
+ }
785
+
786
+ .historyItem[data-active] {
787
+ border-color: var(--dsw-alias-brand-primary);
788
+ }
789
+
790
+ .historyMain {
791
+ display: flex;
792
+ gap: 8px;
793
+ align-items: flex-start;
794
+ padding: 0;
795
+ background: transparent;
796
+ border: none;
797
+ font: inherit;
798
+ color: inherit;
799
+ text-align: left;
800
+ cursor: pointer;
801
+ min-width: 0;
802
+ }
803
+
804
+ .historyThumb {
805
+ width: 52px;
806
+ height: 52px;
807
+ border-radius: 8px;
808
+ object-fit: cover;
809
+ background: var(--dsw-alias-bg-base);
810
+ flex: none;
811
+ }
812
+
813
+ .historyThumbPlaceholder {
814
+ width: 52px;
815
+ height: 52px;
816
+ border-radius: 8px;
817
+ background: var(--dsw-alias-bg-layer-3);
818
+ flex: none;
819
+ }
820
+
821
+ .historyInfo {
822
+ flex: 1;
823
+ min-width: 0;
824
+ display: flex;
825
+ flex-direction: column;
826
+ gap: 4px;
827
+ }
828
+
829
+ .historyPrompt {
830
+ font-size: 12px;
831
+ line-height: 1.4;
832
+ color: var(--dsw-alias-label-primary);
833
+ display: -webkit-box;
834
+ -webkit-line-clamp: 2;
835
+ -webkit-box-orient: vertical;
836
+ overflow: hidden;
837
+ }
838
+
839
+ .historyMeta {
840
+ font-size: 11px;
841
+ color: var(--dsw-alias-label-tertiary);
842
+ white-space: nowrap;
843
+ overflow: hidden;
844
+ text-overflow: ellipsis;
845
+ }
846
+
847
+ .historyActions {
848
+ display: flex;
849
+ gap: 6px;
850
+ justify-content: flex-end;
851
+ }
852
+
853
+ .historyAction {
854
+ padding: 2px 8px;
855
+ font: inherit;
856
+ font-size: 11.5px;
857
+ color: var(--dsw-alias-label-secondary);
858
+ background: transparent;
859
+ border: 1px solid var(--dsw-alias-border-l2);
860
+ border-radius: 999px;
861
+ cursor: pointer;
862
+ }
863
+
864
+ .historyAction:hover {
865
+ color: var(--dsw-alias-label-primary);
866
+ border-color: var(--dsw-alias-label-dimmed);
867
+ }
868
+
869
+ .historyAction[data-danger]:hover {
870
+ color: var(--dsw-alias-label-error);
871
+ border-color: var(--dsw-alias-label-error);
872
+ }
873
+
874
+ /* --- cards (system-aligned rounded group chrome) ------------------------------ */
875
+
876
+ .card {
877
+ display: flex;
878
+ flex-direction: column;
879
+ gap: 10px;
880
+ padding: 12px;
881
+ background: var(--dsw-alias-bg-layer-2);
882
+ border: 1px solid var(--dsw-alias-border-l1);
883
+ border-radius: 12px;
884
+ flex: none;
885
+ }
886
+
887
+ .ecommerceWorkspace {
888
+ display: flex;
889
+ flex-direction: column;
890
+ gap: 16px;
891
+ max-width: 720px;
892
+ margin: 0 auto;
893
+ padding: 6px 2px 12px;
894
+ }
895
+
896
+ /* Flat sections in the CapyAI style: plain headings, no card boxes. */
897
+ .ecommerceSection {
898
+ display: flex;
899
+ flex-direction: column;
900
+ gap: 8px;
901
+ padding: 0;
902
+ border: none;
903
+ border-radius: 0;
904
+ background: transparent;
905
+ }
906
+
907
+ .ecommerceSection h3 {
908
+ margin: 0;
909
+ font-size: 13.5px;
910
+ font-weight: 600;
911
+ display: flex;
912
+ align-items: baseline;
913
+ gap: 6px;
914
+ }
915
+
916
+ .ecommerceSectionHint {
917
+ font-size: 11px;
918
+ font-weight: 400;
919
+ color: var(--dsw-alias-label-tertiary);
920
+ }
921
+
922
+ .ecommerceSection input:not([type="checkbox"]), .ecommerceSection select, .ecommerceSection textarea { box-sizing: border-box; width: 100%; padding: 8px 10px; color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-3); border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; font: inherit; }
923
+ .ecommerceSection textarea { min-height: 60px; resize: vertical; }
924
+
925
+ .ecommerceField {
926
+ display: flex;
927
+ flex-direction: column;
928
+ gap: 4px;
929
+ min-width: 0;
930
+ }
931
+
932
+ .ecommerceFieldLabel {
933
+ font-size: 11.5px;
934
+ color: var(--dsw-alias-label-secondary);
935
+ }
936
+
937
+ .ecommerceParamGrid {
938
+ display: grid;
939
+ grid-template-columns: 1fr 1fr;
940
+ gap: 10px 8px;
941
+ }
942
+
943
+ .ecommerceUploadHero {
944
+ display: flex;
945
+ flex-direction: column;
946
+ align-items: center;
947
+ justify-content: center;
948
+ gap: 4px;
949
+ min-height: 78px;
950
+ padding: 12px;
951
+ border: 1.5px dashed var(--dsw-alias-border-l2);
952
+ border-radius: 10px;
953
+ background: transparent;
954
+ color: var(--dsw-alias-label-secondary);
955
+ cursor: pointer;
956
+ font: inherit;
957
+ text-align: center;
958
+ }
959
+
960
+ .ecommerceUploadHero:hover {
961
+ color: var(--dsw-alias-label-primary);
962
+ border-color: var(--dsw-alias-label-dimmed);
963
+ background: var(--dsw-alias-interactive-bg-hover);
964
+ }
965
+
966
+ .ecommerceUploadHero span {
967
+ font-size: 12px;
968
+ }
969
+
970
+ .ecommerceUploadHero small {
971
+ font-size: 10.5px;
972
+ color: var(--dsw-alias-label-tertiary);
973
+ }
974
+
975
+ .ecommerceStructureGrid {
976
+ display: grid;
977
+ grid-template-columns: repeat(3, 1fr);
978
+ gap: 6px;
979
+ }
980
+
981
+ .ecommerceSlotCard {
982
+ position: relative;
983
+ display: flex;
984
+ align-items: center;
985
+ justify-content: center;
986
+ height: 34px;
987
+ border: 1px solid var(--dsw-alias-border-l2);
988
+ border-radius: 8px;
989
+ background: var(--dsw-alias-bg-layer-2);
990
+ color: var(--dsw-alias-label-primary);
991
+ cursor: pointer;
992
+ font: inherit;
993
+ font-size: 12px;
994
+ white-space: nowrap;
995
+ }
996
+
997
+ .ecommerceSlotCard:hover {
998
+ border-color: var(--dsw-alias-label-dimmed);
999
+ }
1000
+
1001
+ .ecommerceSlotCard[data-active] {
1002
+ background: var(--dsw-alias-label-primary);
1003
+ border-color: var(--dsw-alias-label-primary);
1004
+ color: var(--dsw-alias-bg-base);
1005
+ font-weight: 600;
1006
+ }
1007
+
1008
+ .ecommerceSlotCount {
1009
+ position: absolute;
1010
+ top: -6px;
1011
+ right: -6px;
1012
+ min-width: 16px;
1013
+ height: 16px;
1014
+ padding: 0 4px;
1015
+ border-radius: 8px;
1016
+ background: var(--dsw-alias-brand-primary);
1017
+ color: #fff;
1018
+ font-size: 10px;
1019
+ font-weight: 600;
1020
+ line-height: 16px;
1021
+ text-align: center;
1022
+ }
1023
+
1024
+ .ecommerceRefRow {
1025
+ display: grid;
1026
+ grid-template-columns: 64px 1fr;
1027
+ align-items: center;
1028
+ gap: 8px;
1029
+ }
1030
+
1031
+ .ecommerceRefRow > span {
1032
+ font-size: 12px;
1033
+ color: var(--dsw-alias-label-secondary);
1034
+ }
1035
+
1036
+ .ecommercePrimaryAction {
1037
+ width: 100%;
1038
+ height: 38px;
1039
+ border-radius: 999px;
1040
+ font-size: 13.5px;
1041
+ }
1042
+
1043
+ .previewBadge {
1044
+ margin-left: 5px;
1045
+ padding: 0 4px;
1046
+ border-radius: 4px;
1047
+ background: var(--dsw-alias-brand-primary);
1048
+ color: #fff;
1049
+ font-size: 9px;
1050
+ font-weight: 700;
1051
+ line-height: 13px;
1052
+ letter-spacing: 0.02em;
1053
+ }
1054
+
1055
+ .ecommercePlanNote {
1056
+ color: var(--dsw-alias-label-secondary);
1057
+ font-size: 11.5px;
1058
+ line-height: 1.5;
1059
+ }
1060
+
1061
+ .ecommercePlanWarn {
1062
+ padding: 6px 8px;
1063
+ border: 1px solid var(--dsw-alias-border-l2);
1064
+ border-radius: 6px;
1065
+ background: var(--dsw-alias-bg-layer-2);
1066
+ color: var(--dsw-alias-label-secondary);
1067
+ font-size: 11.5px;
1068
+ line-height: 1.5;
1069
+ }
1070
+
1071
+ .ecommerceAssets {
1072
+ display: grid;
1073
+ grid-template-columns: repeat(3, 1fr);
1074
+ gap: 6px;
1075
+ }
1076
+
1077
+ .ecommerceAsset {
1078
+ position: relative;
1079
+ display: flex;
1080
+ flex-direction: column;
1081
+ gap: 3px;
1082
+ padding: 4px;
1083
+ border: 1px solid var(--dsw-alias-border-l1);
1084
+ border-radius: 8px;
1085
+ background: var(--dsw-alias-bg-layer-3);
1086
+ }
1087
+
1088
+ .ecommerceAsset img {
1089
+ width: 100%;
1090
+ height: 44px;
1091
+ object-fit: cover;
1092
+ border-radius: 5px;
1093
+ }
1094
+
1095
+ .ecommerceAsset select {
1096
+ width: 100%;
1097
+ min-width: 0;
1098
+ padding: 2px;
1099
+ font-size: 10px;
1100
+ }
1101
+
1102
+ .ecommerceAsset button {
1103
+ position: absolute;
1104
+ top: 7px;
1105
+ right: 7px;
1106
+ width: 16px;
1107
+ height: 16px;
1108
+ padding: 0;
1109
+ border: none;
1110
+ border-radius: 50%;
1111
+ background: rgba(0, 0, 0, 0.55);
1112
+ color: #fff;
1113
+ cursor: pointer;
1114
+ font-size: 11px;
1115
+ line-height: 15px;
1116
+ text-align: center;
1117
+ }
1118
+
1119
+ .ecommerceAsset button:hover {
1120
+ background: rgba(0, 0, 0, 0.8);
1121
+ }
1122
+
1123
+ .ecommerceAssetAdd {
1124
+ display: flex;
1125
+ flex-direction: column;
1126
+ align-items: center;
1127
+ justify-content: center;
1128
+ gap: 2px;
1129
+ min-height: 78px;
1130
+ border: 1.5px dashed var(--dsw-alias-border-l2);
1131
+ border-radius: 8px;
1132
+ background: transparent;
1133
+ color: var(--dsw-alias-label-secondary);
1134
+ cursor: pointer;
1135
+ font: inherit;
1136
+ }
1137
+
1138
+ .ecommerceAssetAdd:hover {
1139
+ color: var(--dsw-alias-label-primary);
1140
+ border-color: var(--dsw-alias-label-dimmed);
1141
+ }
1142
+
1143
+ .ecommerceAssetAdd span {
1144
+ font-size: 16px;
1145
+ line-height: 1;
1146
+ }
1147
+
1148
+ .ecommerceAssetAdd small {
1149
+ font-size: 10px;
1150
+ }
1151
+
1152
+ .ecommerceAdvancedToggle {
1153
+ display: flex;
1154
+ align-items: center;
1155
+ justify-content: space-between;
1156
+ width: 100%;
1157
+ padding: 0;
1158
+ border: none;
1159
+ background: transparent;
1160
+ color: var(--dsw-alias-label-secondary);
1161
+ cursor: pointer;
1162
+ font: inherit;
1163
+ font-size: 12.5px;
1164
+ }
1165
+
1166
+ .ecommerceAdvancedToggle:hover {
1167
+ color: var(--dsw-alias-label-primary);
1168
+ }
1169
+
1170
+ .ecommerceAdvancedChevron {
1171
+ font-size: 11px;
1172
+ }
1173
+
1174
+ .ecommerceAdvancedBody {
1175
+ display: flex;
1176
+ flex-direction: column;
1177
+ gap: 8px;
1178
+ margin-top: 8px;
1179
+ }
1180
+
1181
+ .ecommerceFooterBody {
1182
+ display: flex;
1183
+ flex-direction: column;
1184
+ gap: 8px;
1185
+ }
1186
+
1187
+ .ecommercePlanMini {
1188
+ display: flex;
1189
+ flex-direction: column;
1190
+ gap: 6px;
1191
+ padding: 10px;
1192
+ border: 1px solid var(--dsw-alias-brand-primary);
1193
+ border-radius: 10px;
1194
+ }
1195
+
1196
+ .ecommercePlanMini > strong {
1197
+ font-size: 12.5px;
1198
+ }
1199
+
1200
+ .ecommercePlanList {
1201
+ display: flex;
1202
+ flex-direction: column;
1203
+ gap: 3px;
1204
+ max-height: 116px;
1205
+ overflow-y: auto;
1206
+ }
1207
+
1208
+ .ecommercePlanList > div {
1209
+ display: flex;
1210
+ justify-content: space-between;
1211
+ gap: 12px;
1212
+ color: var(--dsw-alias-label-secondary);
1213
+ font-size: 11.5px;
1214
+ }
1215
+
1216
+ .ecommercePlanBack {
1217
+ padding: 0;
1218
+ border: none;
1219
+ background: transparent;
1220
+ color: var(--dsw-alias-label-tertiary);
1221
+ cursor: pointer;
1222
+ font: inherit;
1223
+ font-size: 12px;
1224
+ }
1225
+
1226
+ .ecommercePlanBack:hover {
1227
+ color: var(--dsw-alias-label-primary);
1228
+ }
1229
+
1230
+ .ecommerceFooterHint { color: var(--dsw-alias-label-secondary); font-size: 12px; }
1231
+
1232
+ .ecommerceResults {
1233
+ display: flex;
1234
+ flex-direction: column;
1235
+ gap: 14px;
1236
+ width: 100%;
1237
+ margin: 0 auto;
1238
+ padding: 16px 18px;
1239
+ overflow-y: auto;
1240
+ }
1241
+
1242
+ .ecommerceResultsHeader {
1243
+ display: flex;
1244
+ align-items: center;
1245
+ justify-content: space-between;
1246
+ gap: 12px;
1247
+ }
1248
+
1249
+ .ecommerceResultsHeader h3 {
1250
+ margin: 0;
1251
+ font-size: 15px;
1252
+ }
1253
+
1254
+ .ecommerceResultsHeader > div:first-child {
1255
+ display: flex;
1256
+ align-items: baseline;
1257
+ gap: 10px;
1258
+ }
1259
+
1260
+ .ecommerceResultsHeader span {
1261
+ font-size: 12px;
1262
+ color: var(--dsw-alias-label-secondary);
1263
+ }
1264
+
1265
+ .ecommerceResultsActions {
1266
+ display: flex;
1267
+ gap: 8px;
1268
+ }
1269
+
1270
+ .ecommerceResultsEmpty {
1271
+ padding: 32px 16px;
1272
+ color: var(--dsw-alias-label-tertiary);
1273
+ font-size: 13px;
1274
+ text-align: center;
1275
+ border: 1.5px dashed var(--dsw-alias-border-l2);
1276
+ border-radius: 12px;
1277
+ }
1278
+
1279
+ .ecommerceGroups {
1280
+ display: flex;
1281
+ flex-direction: column;
1282
+ gap: 16px;
1283
+ }
1284
+
1285
+ .ecommerceGroup {
1286
+ display: flex;
1287
+ flex-direction: column;
1288
+ gap: 8px;
1289
+ padding: 0;
1290
+ border: none;
1291
+ border-radius: 0;
1292
+ background: transparent;
1293
+ }
1294
+
1295
+ .ecommerceGroup > header {
1296
+ display: flex;
1297
+ align-items: center;
1298
+ gap: 10px;
1299
+ font-size: 13px;
1300
+ }
1301
+
1302
+ .ecommerceGroup > header strong {
1303
+ font-size: 13px;
1304
+ }
1305
+
1306
+ .ecommerceGroup > header span {
1307
+ color: var(--dsw-alias-label-secondary);
1308
+ font-size: 12px;
1309
+ }
1310
+
1311
+ .ecommerceGroup > header button {
1312
+ margin-left: auto;
1313
+ }
1314
+
1315
+ .ecommerceGroupGrid {
1316
+ display: grid;
1317
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1318
+ gap: 12px;
1319
+ }
1320
+
1321
+ .ecommerceTaskCard {
1322
+ position: relative;
1323
+ display: flex;
1324
+ align-items: center;
1325
+ justify-content: center;
1326
+ width: 100%;
1327
+ aspect-ratio: 1;
1328
+ min-height: 0;
1329
+ padding: 0;
1330
+ border: 1px solid var(--dsw-alias-border-l1);
1331
+ border-radius: 10px;
1332
+ background: var(--dsw-alias-bg-layer-3);
1333
+ overflow: hidden;
1334
+ }
1335
+
1336
+ .ecommerceTaskCard[data-status="failed"],
1337
+ .ecommerceTaskCard[data-status="cancelled"] {
1338
+ color: var(--dsw-alias-label-tertiary);
1339
+ font-size: 12px;
1340
+ }
1341
+
1342
+ .ecommerceTaskCard .imageCard {
1343
+ width: 100%;
1344
+ height: 100%;
1345
+ margin: 0;
1346
+ border: none;
1347
+ border-radius: 0;
1348
+ }
1349
+
1350
+ .ecommerceTaskCard .image {
1351
+ width: 100%;
1352
+ height: 100%;
1353
+ object-fit: cover;
1354
+ }
1355
+
1356
+ .ecommerceResultBadge {
1357
+ position: absolute;
1358
+ top: 6px;
1359
+ left: 6px;
1360
+ padding: 0 7px;
1361
+ border-radius: 999px;
1362
+ background: rgb(0 0 0 / 55%);
1363
+ color: #fff;
1364
+ font-size: 10px;
1365
+ line-height: 16px;
1366
+ pointer-events: none;
1367
+ }
1368
+
1369
+ .ecommerceTaskActions {
1370
+ position: absolute;
1371
+ left: 0;
1372
+ right: 0;
1373
+ bottom: 0;
1374
+ display: flex;
1375
+ gap: 4px;
1376
+ justify-content: center;
1377
+ padding: 10px 4px 5px;
1378
+ background: linear-gradient(transparent, rgb(0 0 0 / 55%));
1379
+ opacity: 0;
1380
+ transition: opacity 0.12s ease;
1381
+ }
1382
+
1383
+ .ecommerceTaskCard:hover .ecommerceTaskActions {
1384
+ opacity: 1;
1385
+ }
1386
+
1387
+ .ecommerceActionChip {
1388
+ border: none;
1389
+ border-radius: 6px;
1390
+ background: rgb(255 255 255 / 92%);
1391
+ color: #111;
1392
+ font-size: 10px;
1393
+ font-weight: 500;
1394
+ line-height: 18px;
1395
+ padding: 0 6px;
634
1396
  cursor: pointer;
1397
+ text-decoration: none;
1398
+ white-space: nowrap;
635
1399
  }
636
1400
 
637
- .historyClear:hover {
638
- color: var(--dsw-alias-label-error);
639
- border-color: var(--dsw-alias-label-error);
1401
+ .ecommerceActionChip:hover {
1402
+ background: #fff;
640
1403
  }
641
1404
 
642
- .historyList {
643
- flex: 1;
644
- min-height: 0;
645
- overflow-y: auto;
1405
+ .ecommerceActionChip:disabled {
1406
+ opacity: 0.5;
1407
+ cursor: default;
1408
+ }
1409
+
1410
+ .ecommerceTaskState {
646
1411
  display: flex;
647
1412
  flex-direction: column;
648
- gap: 8px;
649
- padding: 10px;
650
- scrollbar-width: thin;
651
- scrollbar-color: var(--dsw-alias-border-l2) transparent;
1413
+ gap: 3px;
1414
+ padding: 10px 8px;
1415
+ color: var(--dsw-alias-label-secondary);
1416
+ font-size: 11px;
1417
+ text-align: center;
1418
+ word-break: break-all;
652
1419
  }
653
1420
 
654
- .historyList::-webkit-scrollbar {
655
- width: 8px;
1421
+ .ecommerceTaskState b {
1422
+ font-size: 12px;
1423
+ color: var(--dsw-alias-label-primary);
656
1424
  }
657
1425
 
658
- .historyList::-webkit-scrollbar-thumb {
659
- background: var(--dsw-alias-border-l2);
660
- border-radius: 999px;
661
- }
662
1426
 
663
- .historyEmpty {
664
- flex: 1;
1427
+
1428
+ /* --- top navigation (mode tabs live in the panel header row) -------------------- */
1429
+
1430
+ .topNav {
1431
+ position: absolute;
1432
+ left: 50%;
1433
+ transform: translateX(-50%);
665
1434
  display: flex;
666
1435
  align-items: center;
667
1436
  justify-content: center;
668
- padding: 20px;
669
- font-size: 12px;
670
- line-height: 1.6;
671
- text-align: center;
672
- color: var(--dsw-alias-label-tertiary);
673
- }
674
-
675
- .historyItem {
676
- display: flex;
677
- flex-direction: column;
678
- gap: 6px;
679
- padding: 8px;
680
- border: 1px solid var(--dsw-alias-border-l1);
681
- border-radius: 10px;
682
- background: var(--dsw-alias-bg-layer-2);
1437
+ gap: 2px;
683
1438
  flex: none;
684
1439
  }
685
1440
 
686
- .historyItem:hover {
687
- border-color: var(--dsw-alias-border-l2);
1441
+ .topNavItem {
1442
+ display: inline-flex;
1443
+ align-items: center;
1444
+ gap: 4px;
1445
+ height: 30px;
1446
+ padding: 0 14px;
1447
+ border: none;
1448
+ border-radius: 999px;
1449
+ background: transparent;
1450
+ color: var(--dsw-alias-label-secondary);
1451
+ cursor: pointer;
1452
+ font: inherit;
1453
+ font-size: 13px;
688
1454
  }
689
1455
 
690
- .historyItem[data-active] {
691
- border-color: var(--dsw-alias-brand-primary);
1456
+ .topNavItem,
1457
+ .topNavItem span {
1458
+ white-space: nowrap;
692
1459
  }
693
1460
 
694
- .historyMain {
695
- display: flex;
696
- gap: 8px;
697
- align-items: flex-start;
698
- padding: 0;
699
- background: transparent;
700
- border: none;
701
- font: inherit;
702
- color: inherit;
703
- text-align: left;
704
- cursor: pointer;
705
- min-width: 0;
1461
+ .topNavItem:hover {
1462
+ color: var(--dsw-alias-label-primary);
1463
+ background: var(--dsw-alias-interactive-bg-hover);
706
1464
  }
707
1465
 
708
- .historyThumb {
709
- width: 52px;
710
- height: 52px;
711
- border-radius: 8px;
712
- object-fit: cover;
713
- background: var(--dsw-alias-bg-base);
714
- flex: none;
1466
+ .topNavItem[data-active] {
1467
+ background: var(--dsw-alias-label-primary);
1468
+ color: var(--dsw-alias-bg-base);
1469
+ font-weight: 600;
715
1470
  }
716
1471
 
717
- .historyThumbPlaceholder {
718
- width: 52px;
719
- height: 52px;
720
- border-radius: 8px;
721
- background: var(--dsw-alias-bg-layer-3);
722
- flex: none;
1472
+ .topNavDivider {
1473
+ width: 1px;
1474
+ height: 16px;
1475
+ margin: 0 8px;
1476
+ background: var(--dsw-alias-border-l2);
723
1477
  }
724
1478
 
725
- .historyInfo {
726
- flex: 1;
727
- min-width: 0;
728
- display: flex;
729
- flex-direction: column;
730
- gap: 4px;
1479
+ /* chat pane toggle + collapse */
1480
+
1481
+ .panelHeaderActions {
1482
+ display: inline-flex;
1483
+ align-items: center;
1484
+ gap: 10px;
731
1485
  }
732
1486
 
733
- .historyPrompt {
1487
+ .chatToggle {
1488
+ display: inline-flex;
1489
+ align-items: center;
1490
+ gap: 5px;
1491
+ height: 26px;
1492
+ padding: 0 10px;
1493
+ border: 1px solid var(--dsw-alias-border-l2);
1494
+ border-radius: 999px;
1495
+ background: var(--dsw-alias-bg-layer-2);
1496
+ color: var(--dsw-alias-label-secondary);
1497
+ cursor: pointer;
1498
+ font: inherit;
734
1499
  font-size: 12px;
735
- line-height: 1.4;
1500
+ }
1501
+
1502
+ .chatToggle:hover {
736
1503
  color: var(--dsw-alias-label-primary);
737
- display: -webkit-box;
738
- -webkit-line-clamp: 2;
739
- -webkit-box-orient: vertical;
740
- overflow: hidden;
741
1504
  }
742
1505
 
743
- .historyMeta {
744
- font-size: 11px;
745
- color: var(--dsw-alias-label-tertiary);
746
- white-space: nowrap;
747
- overflow: hidden;
748
- text-overflow: ellipsis;
1506
+ .chatToggle[data-open='true'] {
1507
+ color: var(--dsw-alias-brand-primary);
1508
+ border-color: var(--dsw-alias-brand-primary);
749
1509
  }
750
1510
 
751
- .historyActions {
752
- display: flex;
753
- gap: 6px;
754
- justify-content: flex-end;
1511
+ /* Drop the conversation column entirely while the chat toggle is collapsed. */
1512
+ html[data-dsh-imagegen-chat-collapsed][data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-pane='conversation'],
1513
+ html[data-dsh-imagegen-chat-collapsed][data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [class*='centerCol'] {
1514
+ grid-template-columns: minmax(0, 1fr);
755
1515
  }
756
1516
 
757
- .historyAction {
758
- padding: 2px 8px;
759
- font: inherit;
760
- font-size: 11.5px;
761
- color: var(--dsw-alias-label-secondary);
762
- background: transparent;
763
- border: 1px solid var(--dsw-alias-border-l2);
764
- border-radius: 999px;
765
- cursor: pointer;
1517
+ /* Drop the conversation column entirely while the chat toggle is collapsed.
1518
+ The hide rule must out-specify the base `display: flex !important`. */
1519
+ html[data-dsh-imagegen-chat-collapsed][data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) [data-slot='conversation'] {
1520
+ display: none !important;
766
1521
  }
767
1522
 
768
- .historyAction:hover {
769
- color: var(--dsw-alias-label-primary);
770
- border-color: var(--dsw-alias-label-dimmed);
1523
+ html[data-dsh-imagegen-chat-collapsed] [data-dsh-imagegen-chat-resizer] {
1524
+ display: none !important;
771
1525
  }
772
1526
 
773
- .historyAction[data-danger]:hover {
774
- color: var(--dsw-alias-label-error);
775
- border-color: var(--dsw-alias-label-error);
1527
+ /* config panel drag handle */
1528
+
1529
+ .configResizer {
1530
+ position: absolute;
1531
+ top: 0;
1532
+ right: 0;
1533
+ width: 6px;
1534
+ height: 100%;
1535
+ cursor: col-resize;
1536
+ z-index: 6;
776
1537
  }
777
1538
 
778
- /* --- cards (system-aligned rounded group chrome) ------------------------------ */
1539
+ .configResizer:hover {
1540
+ background: linear-gradient(90deg, transparent, var(--dsw-alias-border-l2));
1541
+ }
779
1542
 
780
- .card {
781
- display: flex;
782
- flex-direction: column;
783
- gap: 10px;
784
- padding: 12px;
785
- background: var(--dsw-alias-bg-layer-2);
786
- border: 1px solid var(--dsw-alias-border-l1);
787
- border-radius: 12px;
788
- flex: none;
1543
+ .config[data-collapsed='true'] .configResizer {
1544
+ display: none;
789
1545
  }
790
1546
 
791
- /* --- mode tabs (system Pill switcher) ------------------------------------------ */
1547
+ /* --- generation sub-modes (inside the normal workspace) ------------------------ */
792
1548
 
793
1549
  .modeRow {
794
1550
  display: flex;
@@ -800,7 +1556,14 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
800
1556
  flex: 1;
801
1557
  justify-content: center;
802
1558
  height: 28px;
803
- font-size: 13px;
1559
+ font-size: 12.5px;
1560
+ }
1561
+
1562
+ .modePill,
1563
+ .modePill span,
1564
+ .modePill div {
1565
+ white-space: nowrap;
1566
+ min-width: 0;
804
1567
  }
805
1568
 
806
1569
  /* --- reference image upload (edit mode) ---------------------------------------- */
@@ -1258,14 +2021,15 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1258
2021
  font-size: 12px;
1259
2022
  line-height: 20px;
1260
2023
  font-weight: 500;
1261
- color: var(--dsw-alias-label-primary);
1262
- background: var(--dsw-alias-bg-mask-1);
1263
- border: 1px solid var(--dsw-alias-border-l2);
2024
+ color: #fff;
2025
+ background: rgb(15 18 24 / 82%);
2026
+ border: 1px solid rgb(255 255 255 / 62%);
1264
2027
  border-radius: 999px;
1265
2028
  text-decoration: none;
1266
2029
  opacity: 0;
1267
2030
  transition: opacity 0.12s;
1268
2031
  backdrop-filter: blur(4px);
2032
+ box-shadow: 0 2px 8px rgb(0 0 0 / 28%);
1269
2033
  }
1270
2034
 
1271
2035
  .imageCard:hover .download {
@@ -1273,7 +2037,13 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1273
2037
  }
1274
2038
 
1275
2039
  .download:hover {
1276
- background: var(--dsw-alias-bg-base);
2040
+ background: rgb(15 18 24 / 94%);
2041
+ }
2042
+
2043
+ .download:focus-visible {
2044
+ opacity: 1;
2045
+ outline: 2px solid #fff;
2046
+ outline-offset: 2px;
1277
2047
  }
1278
2048
 
1279
2049
  /* Add-to-gallery pill (top-left, mirrors .download; shows on card hover). */
@@ -1289,14 +2059,15 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1289
2059
  font-size: 12px;
1290
2060
  line-height: 20px;
1291
2061
  font-weight: 500;
1292
- color: var(--dsw-alias-label-primary);
1293
- background: var(--dsw-alias-bg-mask-1);
1294
- border: 1px solid var(--dsw-alias-border-l2);
2062
+ color: #fff;
2063
+ background: rgb(15 18 24 / 82%);
2064
+ border: 1px solid rgb(255 255 255 / 62%);
1295
2065
  border-radius: 999px;
1296
2066
  cursor: pointer;
1297
2067
  opacity: 0;
1298
2068
  transition: opacity 0.12s;
1299
2069
  backdrop-filter: blur(4px);
2070
+ box-shadow: 0 2px 8px rgb(0 0 0 / 28%);
1300
2071
  }
1301
2072
 
1302
2073
  .imageCard:hover .galleryAdd {
@@ -1304,50 +2075,63 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1304
2075
  }
1305
2076
 
1306
2077
  .galleryAdd:hover {
1307
- background: var(--dsw-alias-bg-base);
2078
+ background: rgb(15 18 24 / 94%);
2079
+ }
2080
+
2081
+ .galleryAdd:focus-visible {
2082
+ opacity: 1;
2083
+ outline: 2px solid #fff;
2084
+ outline-offset: 2px;
2085
+ }
2086
+
2087
+ .galleryAdd:disabled {
2088
+ opacity: 0.4;
2089
+ cursor: default;
2090
+ }
2091
+
2092
+ /* Add-to-conversation action sits below the gallery action on hover. */
2093
+ .conversationAdd {
2094
+ position: absolute;
2095
+ top: 38px;
2096
+ left: 8px;
2097
+ display: inline-flex;
2098
+ align-items: center;
2099
+ gap: 5px;
2100
+ padding: 2px 10px;
2101
+ border: 1px solid rgb(255 255 255 / 62%);
2102
+ border-radius: 999px;
2103
+ color: #fff;
2104
+ background: rgb(15 18 24 / 82%);
2105
+ cursor: pointer;
2106
+ font: inherit;
2107
+ font-size: 12px;
2108
+ line-height: 20px;
2109
+ font-weight: 500;
2110
+ opacity: 0;
2111
+ transition: opacity 0.12s;
2112
+ backdrop-filter: blur(4px);
2113
+ box-shadow: 0 2px 8px rgb(0 0 0 / 28%);
1308
2114
  }
1309
2115
 
1310
- .galleryAdd:disabled {
1311
- opacity: 0.4;
1312
- cursor: default;
1313
- }
1314
-
1315
- /* Add-to-conversation action sits below the gallery action on hover. */
1316
- .conversationAdd {
1317
- position: absolute;
1318
- top: 38px;
1319
- left: 8px;
1320
- display: inline-flex;
1321
- align-items: center;
1322
- gap: 5px;
1323
- padding: 2px 10px;
1324
- border: 1px solid var(--dsw-alias-border-l2);
1325
- border-radius: 999px;
1326
- color: var(--dsw-alias-label-primary);
1327
- background: var(--dsw-alias-bg-mask-1);
1328
- cursor: pointer;
1329
- font: inherit;
1330
- font-size: 12px;
1331
- line-height: 20px;
1332
- font-weight: 500;
1333
- opacity: 0;
1334
- transition: opacity 0.12s;
1335
- backdrop-filter: blur(4px);
1336
- }
1337
-
1338
- .imageCard:hover .conversationAdd,
1339
- .conversationAdd:focus-visible {
1340
- opacity: 1;
1341
- }
1342
-
1343
- .conversationAdd:hover {
1344
- background: var(--dsw-alias-bg-base);
1345
- }
1346
-
1347
- .conversationAdd:disabled {
1348
- opacity: 0.4;
1349
- cursor: default;
1350
- }
2116
+ .imageCard:hover .conversationAdd,
2117
+ .conversationAdd:focus-visible {
2118
+ opacity: 1;
2119
+ }
2120
+
2121
+ .conversationAdd:hover {
2122
+ background: rgb(15 18 24 / 94%);
2123
+ }
2124
+
2125
+ .conversationAdd:focus-visible {
2126
+ opacity: 1;
2127
+ outline: 2px solid #fff;
2128
+ outline-offset: 2px;
2129
+ }
2130
+
2131
+ .conversationAdd:disabled {
2132
+ opacity: 0.4;
2133
+ cursor: default;
2134
+ }
1351
2135
 
1352
2136
  /* Hover hint for the click-to-zoom behavior. */
1353
2137
  .zoomHint {
@@ -1675,33 +2459,33 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1675
2459
  animation: dshImageGenToastIn 160ms ease-out;
1676
2460
  }
1677
2461
 
1678
- @keyframes dshImageGenToastIn {
2462
+ @keyframes dshImageGenToastIn {
1679
2463
  from { opacity: 0; transform: translate(-50%, 6px); }
1680
2464
  to { opacity: 1; transform: translate(-50%, 0); }
1681
- }
1682
-
1683
- .conversationToast {
1684
- position: absolute;
1685
- left: 50%;
1686
- bottom: 24px;
1687
- z-index: 30;
1688
- display: inline-flex;
1689
- align-items: center;
1690
- gap: 7px;
1691
- max-width: calc(100% - 32px);
1692
- padding: 6px 16px;
1693
- border: 1px solid var(--dsw-alias-border-l2);
1694
- border-radius: 999px;
1695
- color: var(--dsw-alias-label-primary);
1696
- background: var(--dsw-alias-bg-mask-1);
1697
- box-shadow: 0 8px 24px rgb(0 0 0 / 22%);
1698
- font-size: 13px;
1699
- font-weight: 500;
1700
- pointer-events: none;
1701
- transform: translateX(-50%);
1702
- animation: dshImageGenToastIn 160ms ease-out;
1703
- backdrop-filter: blur(6px);
1704
- }
2465
+ }
2466
+
2467
+ .conversationToast {
2468
+ position: absolute;
2469
+ left: 50%;
2470
+ bottom: 24px;
2471
+ z-index: 30;
2472
+ display: inline-flex;
2473
+ align-items: center;
2474
+ gap: 7px;
2475
+ max-width: calc(100% - 32px);
2476
+ padding: 6px 16px;
2477
+ border: 1px solid var(--dsw-alias-border-l2);
2478
+ border-radius: 999px;
2479
+ color: var(--dsw-alias-label-primary);
2480
+ background: var(--dsw-alias-bg-mask-1);
2481
+ box-shadow: 0 8px 24px rgb(0 0 0 / 22%);
2482
+ font-size: 13px;
2483
+ font-weight: 500;
2484
+ pointer-events: none;
2485
+ transform: translateX(-50%);
2486
+ animation: dshImageGenToastIn 160ms ease-out;
2487
+ backdrop-filter: blur(6px);
2488
+ }
1705
2489
 
1706
2490
  @media (prefers-reduced-motion: reduce) {
1707
2491
  .download, .spinner, .bigSpinner {
@@ -1792,6 +2576,10 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1792
2576
  .galleryMasonry[data-view='masonry'] .galleryCard:nth-child(3n + 2) .galleryImage { aspect-ratio: 4 / 3; }
1793
2577
  .galleryMasonry[data-view='masonry'] .galleryCard:nth-child(3n) .galleryImage { aspect-ratio: 3 / 4; }
1794
2578
  .galleryBadge { position: absolute; top: 10px; left: 10px; padding: 4px 9px; border-radius: 999px; color: #fff; background: rgb(18 23 36 / 76%); font-size: 11px; backdrop-filter: blur(4px); }
2579
+ .galleryCardActions { display: flex; padding: 8px 12px 0; }
2580
+ .galleryCardAction { display: inline-flex; align-items: center; justify-content: center; width: 100%; min-width: 0; gap: 4px; min-height: 28px; padding: 0 4px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 7px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-bg-layer-2); cursor: pointer; font: inherit; font-size: 10px; font-weight: 500; white-space: nowrap; }
2581
+ .galleryCardAction:hover, .galleryCardAction:focus-visible { border-color: var(--dsw-alias-brand-primary); color: var(--dsw-alias-brand-primary); outline: none; }
2582
+ .galleryCardAction:disabled { cursor: wait; opacity: .55; }
1795
2583
  .galleryCardFooter { display: flex; align-items: center; gap: 9px; min-width: 0; padding: 10px 12px; }
1796
2584
  .galleryAvatar { display: grid; flex: none; width: 27px; height: 27px; place-items: center; border-radius: 50%; color: #fff; background: var(--dsw-alias-brand-primary); font-size: 12px; font-weight: 700; }
1797
2585
  .galleryCardInfo { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 2px; }
@@ -1814,17 +2602,17 @@ html[data-dsh-imagegen-active] .sidebarHistoryHost {
1814
2602
  .galleryMasonry { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1815
2603
  }
1816
2604
 
1817
- @media (max-width: 760px) {
1818
- .studio {
1819
- grid-template-columns: minmax(0, 1fr);
1820
- grid-template-rows: minmax(220px, 36%) minmax(0, 1fr);
1821
- overflow-y: auto;
1822
- }
1823
- .history { grid-column: 1; grid-row: 1; min-height: 220px; }
1824
- .generation { grid-column: 1; grid-row: 2; flex-direction: column; min-height: 0; }
1825
- .config { width: auto; max-width: none; height: auto; min-height: 0; }
1826
- .config[data-gallery='true'] { flex: none; }
1827
- .canvas { min-height: 560px; }
2605
+ @media (max-width: 760px) {
2606
+ .studio {
2607
+ grid-template-columns: minmax(0, 1fr);
2608
+ grid-template-rows: minmax(220px, 36%) minmax(0, 1fr);
2609
+ overflow-y: auto;
2610
+ }
2611
+ .history { grid-column: 1; grid-row: 1; min-height: 220px; }
2612
+ .generation { grid-column: 1; grid-row: 2; flex-direction: column; min-height: 0; }
2613
+ .config { width: auto; max-width: none; height: auto; min-height: 0; }
2614
+ .config[data-gallery='true'] { flex: none; }
2615
+ .canvas { min-height: 560px; }
1828
2616
  .galleryToolbar { align-items: flex-start; flex-direction: column; }
1829
2617
  .galleryToolbarActions { width: 100%; flex-wrap: wrap; }
1830
2618
  .galleryMasonry { grid-template-columns: 1fr; }