@dickpy/dsh-imagegen 1.2.3 → 1.4.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 (45) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +203 -181
  3. package/cordis.patch.yml +8 -8
  4. package/docs/images/multi-model-comparison.png +0 -0
  5. package/lib/client.js +2711 -1318
  6. package/lib/client.js.map +1 -1
  7. package/lib/index.js +830 -155
  8. package/package.json +70 -68
  9. package/src/agent-image-tools.ts +418 -316
  10. package/src/client/ImageGenPanel.tsx +1703 -1476
  11. package/src/client/SettingsCard.tsx +936 -648
  12. package/src/client/TemplateLibrary.tsx +336 -336
  13. package/src/client/api.ts +193 -193
  14. package/src/client/channels-form.ts +263 -0
  15. package/src/client/controller.ts +46 -46
  16. package/src/client/conversation-sync.ts +14 -0
  17. package/src/client/css-modules.d.ts +5 -5
  18. package/src/client/helpers.ts +33 -33
  19. package/src/client/image-toolview.module.css +73 -73
  20. package/src/client/image-toolview.tsx +170 -152
  21. package/src/client/index.ts +32 -22
  22. package/src/client/locales.ts +610 -484
  23. package/src/client/mount.tsx +185 -96
  24. package/src/client/panel.module.css +1713 -1445
  25. package/src/client/settings-card.module.css +1023 -536
  26. package/src/client/settings-form.ts +336 -336
  27. package/src/client/settings-scope.ts +298 -250
  28. package/src/client/sidebar-entry.ts +148 -102
  29. package/src/client/templates.module.css +453 -453
  30. package/src/engine.ts +520 -464
  31. package/src/gallery-store.ts +286 -280
  32. package/src/generation-runtime.ts +79 -48
  33. package/src/history-store.ts +250 -238
  34. package/src/image-format.ts +11 -0
  35. package/src/image-models.ts +19 -19
  36. package/src/index.ts +318 -212
  37. package/src/model-catalog.ts +115 -0
  38. package/src/presets.ts +71 -0
  39. package/src/prompt-enhancer.ts +137 -79
  40. package/src/protocol.ts +338 -253
  41. package/src/routes.ts +916 -738
  42. package/src/task-queue.ts +113 -103
  43. package/src/templates/cases.json +10196 -10196
  44. package/src/templates-store.ts +278 -278
  45. package/src/updater.ts +117 -117
@@ -1,453 +1,453 @@
1
- /**
2
- * Prompt-template library styles. Same conventions as panel.module.css:
3
- * scoped box-sizing, dsh --dsw-* tokens, no leakage outside the overlay
4
- * subtree.
5
- */
6
-
7
- .overlay,
8
- .overlay *,
9
- .overlay *::before,
10
- .overlay *::after {
11
- box-sizing: border-box;
12
- }
13
-
14
- .overlay {
15
- position: fixed;
16
- inset: 0;
17
- z-index: 130;
18
- display: flex;
19
- align-items: center;
20
- justify-content: center;
21
- padding: 28px;
22
- background: var(--dsw-alias-bg-mask-1);
23
- color: var(--dsw-alias-label-primary);
24
- font-family: var(--dsw-font-family);
25
- }
26
-
27
- .shell {
28
- display: flex;
29
- flex-direction: column;
30
- width: min(1180px, 100%);
31
- height: 100%;
32
- max-height: 100%;
33
- overflow: hidden;
34
- border: 1px solid var(--dsw-alias-border-l1);
35
- border-radius: 14px;
36
- background: var(--dsw-alias-bg-base);
37
- box-shadow: 0 18px 60px rgba(0, 0, 0, 0.28);
38
- }
39
-
40
- /* --- header ------------------------------------------------------------ */
41
-
42
- .header {
43
- display: flex;
44
- align-items: center;
45
- justify-content: space-between;
46
- gap: 12px;
47
- padding: 14px 18px 10px;
48
- flex: none;
49
- }
50
-
51
- .heading {
52
- display: flex;
53
- align-items: baseline;
54
- gap: 10px;
55
- min-width: 0;
56
- }
57
-
58
- .title {
59
- margin: 0;
60
- font-size: 15px;
61
- font-weight: 650;
62
- }
63
-
64
- .meta {
65
- font-size: 12px;
66
- color: var(--dsw-alias-label-tertiary);
67
- white-space: nowrap;
68
- }
69
-
70
- .headerActions {
71
- display: inline-flex;
72
- align-items: center;
73
- gap: 8px;
74
- flex: none;
75
- }
76
-
77
- .close {
78
- display: inline-flex;
79
- align-items: center;
80
- justify-content: center;
81
- width: 28px;
82
- height: 28px;
83
- border: none;
84
- border-radius: 8px;
85
- background: transparent;
86
- color: var(--dsw-alias-label-secondary);
87
- cursor: pointer;
88
- }
89
-
90
- .close:hover {
91
- background: var(--dsw-alias-interactive-bg-hover);
92
- color: var(--dsw-alias-label-primary);
93
- }
94
-
95
- /* --- toolbar ----------------------------------------------------------- */
96
-
97
- .toolbar {
98
- display: flex;
99
- flex-direction: column;
100
- gap: 10px;
101
- padding: 0 18px 12px;
102
- flex: none;
103
- }
104
-
105
- .search {
106
- width: 100%;
107
- height: 34px;
108
- padding: 0 12px;
109
- border: 1px solid var(--dsw-alias-border-l1);
110
- border-radius: 9px;
111
- background: var(--dsw-alias-bg-layer-1);
112
- color: var(--dsw-alias-label-primary);
113
- font-size: 13px;
114
- font-family: inherit;
115
- outline: none;
116
- }
117
-
118
- .search:focus {
119
- border-color: var(--dsw-alias-brand-primary);
120
- }
121
-
122
- .search::placeholder {
123
- color: var(--dsw-alias-label-dimmed);
124
- }
125
-
126
- .categoryRow {
127
- display: flex;
128
- flex-wrap: wrap;
129
- gap: 6px;
130
- max-height: 64px;
131
- overflow-y: auto;
132
- }
133
-
134
- .categoryPill {
135
- height: 26px;
136
- padding: 0 11px;
137
- border: 1px solid var(--dsw-alias-border-l1);
138
- border-radius: 999px;
139
- background: var(--dsw-alias-bg-layer-1);
140
- color: var(--dsw-alias-label-secondary);
141
- font-size: 12px;
142
- font-family: inherit;
143
- cursor: pointer;
144
- white-space: nowrap;
145
- }
146
-
147
- .categoryPill:hover {
148
- color: var(--dsw-alias-label-primary);
149
- background: var(--dsw-alias-interactive-bg-hover);
150
- }
151
-
152
- .categoryPill[data-active] {
153
- border-color: var(--dsw-alias-brand-primary);
154
- background: var(--dsw-alias-brand-primary);
155
- color: var(--dsw-alias-bg-base);
156
- }
157
-
158
- .notice {
159
- margin: 0 18px 10px;
160
- padding: 8px 12px;
161
- border: 1px solid var(--dsw-alias-border-l1);
162
- border-radius: 9px;
163
- background: var(--dsw-alias-bg-layer-1);
164
- color: var(--dsw-alias-label-secondary);
165
- font-size: 12px;
166
- flex: none;
167
- }
168
-
169
- /* --- body / grid -------------------------------------------------------- */
170
-
171
- .body {
172
- flex: 1;
173
- min-height: 0;
174
- overflow-y: auto;
175
- padding: 2px 18px 14px;
176
- }
177
-
178
- .state {
179
- display: flex;
180
- flex-direction: column;
181
- align-items: center;
182
- justify-content: center;
183
- gap: 12px;
184
- height: 100%;
185
- min-height: 220px;
186
- color: var(--dsw-alias-label-tertiary);
187
- font-size: 13px;
188
- }
189
-
190
- .spinner {
191
- width: 26px;
192
- height: 26px;
193
- border: 2px solid var(--dsw-alias-border-l2);
194
- border-top-color: var(--dsw-alias-brand-primary);
195
- border-radius: 50%;
196
- animation: dsh-imagegen-templates-spin 0.9s linear infinite;
197
- }
198
-
199
- @keyframes dsh-imagegen-templates-spin {
200
- to { transform: rotate(360deg); }
201
- }
202
-
203
- .grid {
204
- display: grid;
205
- grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
206
- gap: 12px;
207
- }
208
-
209
- .card {
210
- display: flex;
211
- flex-direction: column;
212
- gap: 0;
213
- padding: 0;
214
- overflow: hidden;
215
- border: 1px solid var(--dsw-alias-border-l1);
216
- border-radius: 11px;
217
- background: var(--dsw-alias-bg-layer-1);
218
- cursor: pointer;
219
- text-align: left;
220
- font-family: inherit;
221
- color: var(--dsw-alias-label-primary);
222
- transition: border-color 0.15s ease, transform 0.15s ease;
223
- }
224
-
225
- .card:hover {
226
- border-color: var(--dsw-alias-brand-primary);
227
- transform: translateY(-1px);
228
- }
229
-
230
- .thumbWrap {
231
- position: relative;
232
- display: block;
233
- width: 100%;
234
- aspect-ratio: 1 / 1;
235
- background: var(--dsw-alias-bg-layer-2);
236
- }
237
-
238
- .thumb {
239
- display: block;
240
- width: 100%;
241
- height: 100%;
242
- object-fit: cover;
243
- }
244
-
245
- .thumbPlaceholder {
246
- display: flex;
247
- align-items: center;
248
- justify-content: center;
249
- width: 100%;
250
- height: 100%;
251
- color: var(--dsw-alias-label-dimmed);
252
- }
253
-
254
- .featuredBadge {
255
- position: absolute;
256
- top: 8px;
257
- left: 8px;
258
- padding: 2px 8px;
259
- border-radius: 999px;
260
- background: var(--dsw-alias-brand-primary);
261
- color: var(--dsw-alias-bg-base);
262
- font-size: 11px;
263
- font-weight: 600;
264
- }
265
-
266
- .cardBody {
267
- display: flex;
268
- flex-direction: column;
269
- gap: 4px;
270
- padding: 9px 11px 10px;
271
- min-width: 0;
272
- }
273
-
274
- .cardTitle {
275
- font-size: 12.5px;
276
- font-weight: 600;
277
- line-height: 1.35;
278
- display: -webkit-box;
279
- -webkit-line-clamp: 2;
280
- -webkit-box-orient: vertical;
281
- overflow: hidden;
282
- }
283
-
284
- .cardMeta {
285
- display: flex;
286
- align-items: center;
287
- gap: 6px;
288
- min-width: 0;
289
- font-size: 11px;
290
- color: var(--dsw-alias-label-tertiary);
291
- }
292
-
293
- .cardCategory {
294
- flex: none;
295
- padding: 1px 7px;
296
- border-radius: 999px;
297
- background: var(--dsw-alias-bg-layer-2);
298
- color: var(--dsw-alias-label-secondary);
299
- }
300
-
301
- .cardSource {
302
- overflow: hidden;
303
- text-overflow: ellipsis;
304
- white-space: nowrap;
305
- }
306
-
307
- /* --- footer ------------------------------------------------------------- */
308
-
309
- .footer {
310
- flex: none;
311
- display: flex;
312
- align-items: center;
313
- justify-content: space-between;
314
- gap: 10px;
315
- padding: 9px 18px;
316
- border-top: 1px solid var(--dsw-alias-border-l1);
317
- }
318
-
319
- .attribution {
320
- font-size: 11.5px;
321
- color: var(--dsw-alias-label-dimmed);
322
- min-width: 0;
323
- }
324
-
325
- .sourceLink {
326
- flex: none;
327
- font-size: 11.5px;
328
- font-weight: 600;
329
- color: var(--dsw-alias-brand-primary);
330
- text-decoration: none;
331
- white-space: nowrap;
332
- }
333
-
334
- .sourceLink:hover {
335
- text-decoration: underline;
336
- }
337
-
338
- /* --- detail overlay ----------------------------------------------------- */
339
-
340
- .detailOverlay {
341
- position: absolute;
342
- inset: 0;
343
- display: flex;
344
- align-items: center;
345
- justify-content: center;
346
- padding: 34px;
347
- background: var(--dsw-alias-bg-mask-1);
348
- }
349
-
350
- .detail {
351
- display: grid;
352
- grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
353
- grid-template-rows: minmax(0, 1fr);
354
- gap: 0;
355
- width: min(980px, 100%);
356
- max-height: 100%;
357
- overflow: hidden;
358
- border: 1px solid var(--dsw-alias-border-l1);
359
- border-radius: 14px;
360
- background: var(--dsw-alias-bg-base);
361
- box-shadow: 0 18px 60px rgba(0, 0, 0, 0.32);
362
- }
363
-
364
- .detailMedia {
365
- display: flex;
366
- align-items: center;
367
- justify-content: center;
368
- min-height: 0;
369
- overflow: hidden;
370
- background: var(--dsw-alias-bg-layer-2);
371
- }
372
-
373
- .detailImage {
374
- display: block;
375
- width: 100%;
376
- height: 100%;
377
- object-fit: contain;
378
- }
379
-
380
- .detailInfo {
381
- display: flex;
382
- flex-direction: column;
383
- gap: 10px;
384
- min-height: 0;
385
- overflow-y: auto;
386
- padding: 18px;
387
- }
388
-
389
- .detailTitle {
390
- margin: 0;
391
- font-size: 15px;
392
- font-weight: 650;
393
- line-height: 1.4;
394
- }
395
-
396
- .detailMeta {
397
- display: flex;
398
- align-items: center;
399
- flex-wrap: wrap;
400
- gap: 8px;
401
- font-size: 12px;
402
- color: var(--dsw-alias-label-tertiary);
403
- }
404
-
405
- .detailLink {
406
- color: var(--dsw-alias-brand-primary);
407
- text-decoration: none;
408
- overflow: hidden;
409
- text-overflow: ellipsis;
410
- white-space: nowrap;
411
- }
412
-
413
- .detailLink:hover {
414
- text-decoration: underline;
415
- }
416
-
417
- .detailPrompt {
418
- flex: 1;
419
- min-height: 0;
420
- margin: 0;
421
- padding: 12px;
422
- overflow-y: auto;
423
- border: 1px solid var(--dsw-alias-border-l1);
424
- border-radius: 10px;
425
- background: var(--dsw-alias-bg-layer-1);
426
- color: var(--dsw-alias-label-primary);
427
- font-size: 12.5px;
428
- line-height: 1.6;
429
- font-family: inherit;
430
- white-space: pre-wrap;
431
- word-break: break-word;
432
- user-select: text;
433
- }
434
-
435
- .detailActions {
436
- display: flex;
437
- gap: 8px;
438
- flex: none;
439
- position: sticky;
440
- bottom: 0;
441
- margin: 0 -18px -18px;
442
- padding: 12px 18px;
443
- background: var(--dsw-alias-bg-base);
444
- border-top: 1px solid var(--dsw-alias-border-l1);
445
- }
446
-
447
- /* Narrow shells: stack the detail pane. */
448
- @media (max-width: 760px) {
449
- .detail {
450
- grid-template-columns: 1fr;
451
- grid-template-rows: minmax(0, 3fr) minmax(0, 4fr);
452
- }
453
- }
1
+ /**
2
+ * Prompt-template library styles. Same conventions as panel.module.css:
3
+ * scoped box-sizing, dsh --dsw-* tokens, no leakage outside the overlay
4
+ * subtree.
5
+ */
6
+
7
+ .overlay,
8
+ .overlay *,
9
+ .overlay *::before,
10
+ .overlay *::after {
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ .overlay {
15
+ position: fixed;
16
+ inset: 0;
17
+ z-index: 130;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ padding: 28px;
22
+ background: var(--dsw-alias-bg-mask-1);
23
+ color: var(--dsw-alias-label-primary);
24
+ font-family: var(--dsw-font-family);
25
+ }
26
+
27
+ .shell {
28
+ display: flex;
29
+ flex-direction: column;
30
+ width: min(1180px, 100%);
31
+ height: 100%;
32
+ max-height: 100%;
33
+ overflow: hidden;
34
+ border: 1px solid var(--dsw-alias-border-l1);
35
+ border-radius: 14px;
36
+ background: var(--dsw-alias-bg-base);
37
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.28);
38
+ }
39
+
40
+ /* --- header ------------------------------------------------------------ */
41
+
42
+ .header {
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: space-between;
46
+ gap: 12px;
47
+ padding: 14px 18px 10px;
48
+ flex: none;
49
+ }
50
+
51
+ .heading {
52
+ display: flex;
53
+ align-items: baseline;
54
+ gap: 10px;
55
+ min-width: 0;
56
+ }
57
+
58
+ .title {
59
+ margin: 0;
60
+ font-size: 15px;
61
+ font-weight: 650;
62
+ }
63
+
64
+ .meta {
65
+ font-size: 12px;
66
+ color: var(--dsw-alias-label-tertiary);
67
+ white-space: nowrap;
68
+ }
69
+
70
+ .headerActions {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ gap: 8px;
74
+ flex: none;
75
+ }
76
+
77
+ .close {
78
+ display: inline-flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ width: 28px;
82
+ height: 28px;
83
+ border: none;
84
+ border-radius: 8px;
85
+ background: transparent;
86
+ color: var(--dsw-alias-label-secondary);
87
+ cursor: pointer;
88
+ }
89
+
90
+ .close:hover {
91
+ background: var(--dsw-alias-interactive-bg-hover);
92
+ color: var(--dsw-alias-label-primary);
93
+ }
94
+
95
+ /* --- toolbar ----------------------------------------------------------- */
96
+
97
+ .toolbar {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 10px;
101
+ padding: 0 18px 12px;
102
+ flex: none;
103
+ }
104
+
105
+ .search {
106
+ width: 100%;
107
+ height: 34px;
108
+ padding: 0 12px;
109
+ border: 1px solid var(--dsw-alias-border-l1);
110
+ border-radius: 9px;
111
+ background: var(--dsw-alias-bg-layer-1);
112
+ color: var(--dsw-alias-label-primary);
113
+ font-size: 13px;
114
+ font-family: inherit;
115
+ outline: none;
116
+ }
117
+
118
+ .search:focus {
119
+ border-color: var(--dsw-alias-brand-primary);
120
+ }
121
+
122
+ .search::placeholder {
123
+ color: var(--dsw-alias-label-dimmed);
124
+ }
125
+
126
+ .categoryRow {
127
+ display: flex;
128
+ flex-wrap: wrap;
129
+ gap: 6px;
130
+ max-height: 64px;
131
+ overflow-y: auto;
132
+ }
133
+
134
+ .categoryPill {
135
+ height: 26px;
136
+ padding: 0 11px;
137
+ border: 1px solid var(--dsw-alias-border-l1);
138
+ border-radius: 999px;
139
+ background: var(--dsw-alias-bg-layer-1);
140
+ color: var(--dsw-alias-label-secondary);
141
+ font-size: 12px;
142
+ font-family: inherit;
143
+ cursor: pointer;
144
+ white-space: nowrap;
145
+ }
146
+
147
+ .categoryPill:hover {
148
+ color: var(--dsw-alias-label-primary);
149
+ background: var(--dsw-alias-interactive-bg-hover);
150
+ }
151
+
152
+ .categoryPill[data-active] {
153
+ border-color: var(--dsw-alias-brand-primary);
154
+ background: var(--dsw-alias-brand-primary);
155
+ color: var(--dsw-alias-bg-base);
156
+ }
157
+
158
+ .notice {
159
+ margin: 0 18px 10px;
160
+ padding: 8px 12px;
161
+ border: 1px solid var(--dsw-alias-border-l1);
162
+ border-radius: 9px;
163
+ background: var(--dsw-alias-bg-layer-1);
164
+ color: var(--dsw-alias-label-secondary);
165
+ font-size: 12px;
166
+ flex: none;
167
+ }
168
+
169
+ /* --- body / grid -------------------------------------------------------- */
170
+
171
+ .body {
172
+ flex: 1;
173
+ min-height: 0;
174
+ overflow-y: auto;
175
+ padding: 2px 18px 14px;
176
+ }
177
+
178
+ .state {
179
+ display: flex;
180
+ flex-direction: column;
181
+ align-items: center;
182
+ justify-content: center;
183
+ gap: 12px;
184
+ height: 100%;
185
+ min-height: 220px;
186
+ color: var(--dsw-alias-label-tertiary);
187
+ font-size: 13px;
188
+ }
189
+
190
+ .spinner {
191
+ width: 26px;
192
+ height: 26px;
193
+ border: 2px solid var(--dsw-alias-border-l2);
194
+ border-top-color: var(--dsw-alias-brand-primary);
195
+ border-radius: 50%;
196
+ animation: dsh-imagegen-templates-spin 0.9s linear infinite;
197
+ }
198
+
199
+ @keyframes dsh-imagegen-templates-spin {
200
+ to { transform: rotate(360deg); }
201
+ }
202
+
203
+ .grid {
204
+ display: grid;
205
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
206
+ gap: 12px;
207
+ }
208
+
209
+ .card {
210
+ display: flex;
211
+ flex-direction: column;
212
+ gap: 0;
213
+ padding: 0;
214
+ overflow: hidden;
215
+ border: 1px solid var(--dsw-alias-border-l1);
216
+ border-radius: 11px;
217
+ background: var(--dsw-alias-bg-layer-1);
218
+ cursor: pointer;
219
+ text-align: left;
220
+ font-family: inherit;
221
+ color: var(--dsw-alias-label-primary);
222
+ transition: border-color 0.15s ease, transform 0.15s ease;
223
+ }
224
+
225
+ .card:hover {
226
+ border-color: var(--dsw-alias-brand-primary);
227
+ transform: translateY(-1px);
228
+ }
229
+
230
+ .thumbWrap {
231
+ position: relative;
232
+ display: block;
233
+ width: 100%;
234
+ aspect-ratio: 1 / 1;
235
+ background: var(--dsw-alias-bg-layer-2);
236
+ }
237
+
238
+ .thumb {
239
+ display: block;
240
+ width: 100%;
241
+ height: 100%;
242
+ object-fit: cover;
243
+ }
244
+
245
+ .thumbPlaceholder {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ width: 100%;
250
+ height: 100%;
251
+ color: var(--dsw-alias-label-dimmed);
252
+ }
253
+
254
+ .featuredBadge {
255
+ position: absolute;
256
+ top: 8px;
257
+ left: 8px;
258
+ padding: 2px 8px;
259
+ border-radius: 999px;
260
+ background: var(--dsw-alias-brand-primary);
261
+ color: var(--dsw-alias-bg-base);
262
+ font-size: 11px;
263
+ font-weight: 600;
264
+ }
265
+
266
+ .cardBody {
267
+ display: flex;
268
+ flex-direction: column;
269
+ gap: 4px;
270
+ padding: 9px 11px 10px;
271
+ min-width: 0;
272
+ }
273
+
274
+ .cardTitle {
275
+ font-size: 12.5px;
276
+ font-weight: 600;
277
+ line-height: 1.35;
278
+ display: -webkit-box;
279
+ -webkit-line-clamp: 2;
280
+ -webkit-box-orient: vertical;
281
+ overflow: hidden;
282
+ }
283
+
284
+ .cardMeta {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 6px;
288
+ min-width: 0;
289
+ font-size: 11px;
290
+ color: var(--dsw-alias-label-tertiary);
291
+ }
292
+
293
+ .cardCategory {
294
+ flex: none;
295
+ padding: 1px 7px;
296
+ border-radius: 999px;
297
+ background: var(--dsw-alias-bg-layer-2);
298
+ color: var(--dsw-alias-label-secondary);
299
+ }
300
+
301
+ .cardSource {
302
+ overflow: hidden;
303
+ text-overflow: ellipsis;
304
+ white-space: nowrap;
305
+ }
306
+
307
+ /* --- footer ------------------------------------------------------------- */
308
+
309
+ .footer {
310
+ flex: none;
311
+ display: flex;
312
+ align-items: center;
313
+ justify-content: space-between;
314
+ gap: 10px;
315
+ padding: 9px 18px;
316
+ border-top: 1px solid var(--dsw-alias-border-l1);
317
+ }
318
+
319
+ .attribution {
320
+ font-size: 11.5px;
321
+ color: var(--dsw-alias-label-dimmed);
322
+ min-width: 0;
323
+ }
324
+
325
+ .sourceLink {
326
+ flex: none;
327
+ font-size: 11.5px;
328
+ font-weight: 600;
329
+ color: var(--dsw-alias-brand-primary);
330
+ text-decoration: none;
331
+ white-space: nowrap;
332
+ }
333
+
334
+ .sourceLink:hover {
335
+ text-decoration: underline;
336
+ }
337
+
338
+ /* --- detail overlay ----------------------------------------------------- */
339
+
340
+ .detailOverlay {
341
+ position: absolute;
342
+ inset: 0;
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ padding: 34px;
347
+ background: var(--dsw-alias-bg-mask-1);
348
+ }
349
+
350
+ .detail {
351
+ display: grid;
352
+ grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
353
+ grid-template-rows: minmax(0, 1fr);
354
+ gap: 0;
355
+ width: min(980px, 100%);
356
+ max-height: 100%;
357
+ overflow: hidden;
358
+ border: 1px solid var(--dsw-alias-border-l1);
359
+ border-radius: 14px;
360
+ background: var(--dsw-alias-bg-base);
361
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.32);
362
+ }
363
+
364
+ .detailMedia {
365
+ display: flex;
366
+ align-items: center;
367
+ justify-content: center;
368
+ min-height: 0;
369
+ overflow: hidden;
370
+ background: var(--dsw-alias-bg-layer-2);
371
+ }
372
+
373
+ .detailImage {
374
+ display: block;
375
+ width: 100%;
376
+ height: 100%;
377
+ object-fit: contain;
378
+ }
379
+
380
+ .detailInfo {
381
+ display: flex;
382
+ flex-direction: column;
383
+ gap: 10px;
384
+ min-height: 0;
385
+ overflow-y: auto;
386
+ padding: 18px;
387
+ }
388
+
389
+ .detailTitle {
390
+ margin: 0;
391
+ font-size: 15px;
392
+ font-weight: 650;
393
+ line-height: 1.4;
394
+ }
395
+
396
+ .detailMeta {
397
+ display: flex;
398
+ align-items: center;
399
+ flex-wrap: wrap;
400
+ gap: 8px;
401
+ font-size: 12px;
402
+ color: var(--dsw-alias-label-tertiary);
403
+ }
404
+
405
+ .detailLink {
406
+ color: var(--dsw-alias-brand-primary);
407
+ text-decoration: none;
408
+ overflow: hidden;
409
+ text-overflow: ellipsis;
410
+ white-space: nowrap;
411
+ }
412
+
413
+ .detailLink:hover {
414
+ text-decoration: underline;
415
+ }
416
+
417
+ .detailPrompt {
418
+ flex: 1;
419
+ min-height: 0;
420
+ margin: 0;
421
+ padding: 12px;
422
+ overflow-y: auto;
423
+ border: 1px solid var(--dsw-alias-border-l1);
424
+ border-radius: 10px;
425
+ background: var(--dsw-alias-bg-layer-1);
426
+ color: var(--dsw-alias-label-primary);
427
+ font-size: 12.5px;
428
+ line-height: 1.6;
429
+ font-family: inherit;
430
+ white-space: pre-wrap;
431
+ word-break: break-word;
432
+ user-select: text;
433
+ }
434
+
435
+ .detailActions {
436
+ display: flex;
437
+ gap: 8px;
438
+ flex: none;
439
+ position: sticky;
440
+ bottom: 0;
441
+ margin: 0 -18px -18px;
442
+ padding: 12px 18px;
443
+ background: var(--dsw-alias-bg-base);
444
+ border-top: 1px solid var(--dsw-alias-border-l1);
445
+ }
446
+
447
+ /* Narrow shells: stack the detail pane. */
448
+ @media (max-width: 760px) {
449
+ .detail {
450
+ grid-template-columns: 1fr;
451
+ grid-template-rows: minmax(0, 3fr) minmax(0, 4fr);
452
+ }
453
+ }