dsh-cool-theme 0.1.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.
package/lib/client.js ADDED
@@ -0,0 +1,1585 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-cool-theme",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ //#region \0rolldown/runtime.js
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
+ key = keys[i];
17
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+ //#endregion
29
+ let react = require("react");
30
+ react = __toESM(react, 1);
31
+ //#region src/contract.ts
32
+ /**
33
+ * Shared contract for dsh-cool-theme.
34
+ */
35
+ const THEME_STORAGE_KEY = "cool-theme-preset";
36
+ const THEME_STORAGE_KEY_LEGACY = "cooltea-theme-preset";
37
+ //#endregion
38
+ //#region src/client/presets.ts
39
+ /**
40
+ * Theme presets: 12 popular color schemes, each with a light and a dark palette.
41
+ * Pure data + shared types only; token projection lives in tokens.ts.
42
+ */
43
+ const PRESETS = {
44
+ nord: {
45
+ label: "Nord",
46
+ light: {
47
+ base: "#ffffff",
48
+ l1: "#eceff4",
49
+ l2: "#e5e9f0",
50
+ l3: "#d8dee9",
51
+ overlay: "#e5e9f0",
52
+ b1: "#d8dee9",
53
+ b2: "#b8c4d8",
54
+ brand: "#5e81ac",
55
+ lp: "#2e3440",
56
+ ls: "#4c566a",
57
+ err: "#bf616a",
58
+ ok: "#a3be8c",
59
+ warn: "#ebcb8b",
60
+ side: "#eceff4"
61
+ },
62
+ dark: {
63
+ base: "#242933",
64
+ l1: "#2e3440",
65
+ l2: "#3b4252",
66
+ l3: "#434c5e",
67
+ overlay: "#3b4252",
68
+ b1: "#434c5e",
69
+ b2: "#4c566a",
70
+ brand: "#88c0d0",
71
+ lp: "#eceff4",
72
+ ls: "#d8dee9",
73
+ err: "#bf616a",
74
+ ok: "#a3be8c",
75
+ warn: "#ebcb8b",
76
+ side: "#242933"
77
+ }
78
+ },
79
+ onedark: {
80
+ label: "One Dark",
81
+ light: {
82
+ base: "#ffffff",
83
+ l1: "#f8f9fb",
84
+ l2: "#eef1f5",
85
+ l3: "#e4e8ef",
86
+ overlay: "#ffffff",
87
+ b1: "#e4e8ef",
88
+ b2: "#d1d7e0",
89
+ brand: "#4078f2",
90
+ lp: "#383a42",
91
+ ls: "#6c7086",
92
+ err: "#e45649",
93
+ ok: "#50a14f",
94
+ warn: "#c18401",
95
+ side: "#f8f9fb"
96
+ },
97
+ dark: {
98
+ base: "#1e2127",
99
+ l1: "#282c34",
100
+ l2: "#2c313a",
101
+ l3: "#353b48",
102
+ overlay: "#1d2026",
103
+ b1: "#3e4451",
104
+ b2: "#4b5263",
105
+ brand: "#61afef",
106
+ lp: "#abb2bf",
107
+ ls: "#7f848e",
108
+ err: "#e06c75",
109
+ ok: "#98c379",
110
+ warn: "#e5c07b",
111
+ side: "#1e2127"
112
+ }
113
+ },
114
+ github: {
115
+ label: "GitHub",
116
+ light: {
117
+ base: "#ffffff",
118
+ l1: "#f6f8fa",
119
+ l2: "#eef1f4",
120
+ l3: "#e6eaf0",
121
+ overlay: "#ffffff",
122
+ b1: "#d0d7de",
123
+ b2: "#b7c0cc",
124
+ brand: "#0969da",
125
+ lp: "#24292f",
126
+ ls: "#656d76",
127
+ err: "#cf222e",
128
+ ok: "#1a7f37",
129
+ warn: "#9a6700",
130
+ side: "#f6f8fa"
131
+ },
132
+ dark: {
133
+ base: "#010409",
134
+ l1: "#0d1117",
135
+ l2: "#161b22",
136
+ l3: "#21262d",
137
+ overlay: "#161b22",
138
+ b1: "#30363d",
139
+ b2: "#3d444d",
140
+ brand: "#58a6ff",
141
+ lp: "#e6edf3",
142
+ ls: "#9198a1",
143
+ err: "#f85149",
144
+ ok: "#3fb950",
145
+ warn: "#d29922",
146
+ side: "#010409"
147
+ }
148
+ },
149
+ catppuccin: {
150
+ label: "Catppuccin",
151
+ light: {
152
+ base: "#ffffff",
153
+ l1: "#eff1f5",
154
+ l2: "#e6e9ef",
155
+ l3: "#dce0e8",
156
+ overlay: "#eff1f5",
157
+ b1: "#ccd0da",
158
+ b2: "#bcc0cc",
159
+ brand: "#1e66f5",
160
+ lp: "#4c4f69",
161
+ ls: "#5c5f77",
162
+ err: "#d20f39",
163
+ ok: "#40a02b",
164
+ warn: "#df8e1d",
165
+ side: "#eff1f5"
166
+ },
167
+ dark: {
168
+ base: "#1e1e2e",
169
+ l1: "#313244",
170
+ l2: "#414558",
171
+ l3: "#45475a",
172
+ overlay: "#313244",
173
+ b1: "#45475a",
174
+ b2: "#585b70",
175
+ brand: "#89b4fa",
176
+ lp: "#cdd6f4",
177
+ ls: "#a6adc8",
178
+ err: "#f38ba8",
179
+ ok: "#a6e3a1",
180
+ warn: "#f9e2af",
181
+ side: "#1e1e2e"
182
+ }
183
+ },
184
+ dracula: {
185
+ label: "Dracula",
186
+ light: {
187
+ base: "#ffffff",
188
+ l1: "#f8f8f2",
189
+ l2: "#f1f2f8",
190
+ l3: "#e9eaf3",
191
+ overlay: "#ffffff",
192
+ b1: "#d0d3e6",
193
+ b2: "#b8bccc",
194
+ brand: "#7c3aed",
195
+ lp: "#282a36",
196
+ ls: "#6272a4",
197
+ err: "#e63c3c",
198
+ ok: "#2a9d4a",
199
+ warn: "#b78100",
200
+ side: "#f8f8f2"
201
+ },
202
+ dark: {
203
+ base: "#282a36",
204
+ l1: "#343746",
205
+ l2: "#44475a",
206
+ l3: "#52556c",
207
+ overlay: "#343746",
208
+ b1: "#6272a4",
209
+ b2: "#7a86b8",
210
+ brand: "#bd93f9",
211
+ lp: "#f8f8f2",
212
+ ls: "#bfc0d6",
213
+ err: "#ff5555",
214
+ ok: "#50fa7b",
215
+ warn: "#f1fa8c",
216
+ side: "#282a36"
217
+ }
218
+ },
219
+ tokyonight: {
220
+ label: "Tokyo Night",
221
+ light: {
222
+ base: "#ffffff",
223
+ l1: "#f7f8fb",
224
+ l2: "#e9eaf2",
225
+ l3: "#dfe2f0",
226
+ overlay: "#ffffff",
227
+ b1: "#cbd0e3",
228
+ b2: "#b4b9cc",
229
+ brand: "#34548a",
230
+ lp: "#1a1b26",
231
+ ls: "#5a638c",
232
+ err: "#c53b53",
233
+ ok: "#33635c",
234
+ warn: "#8f5e15",
235
+ side: "#f7f8fb"
236
+ },
237
+ dark: {
238
+ base: "#1a1b26",
239
+ l1: "#24283b",
240
+ l2: "#2f354e",
241
+ l3: "#414868",
242
+ overlay: "#24283b",
243
+ b1: "#414868",
244
+ b2: "#5a638c",
245
+ brand: "#7aa2f7",
246
+ lp: "#c0caf5",
247
+ ls: "#9aa1bf",
248
+ err: "#f7768e",
249
+ ok: "#9ece6a",
250
+ warn: "#e0af68",
251
+ side: "#1a1b26"
252
+ }
253
+ },
254
+ solarized: {
255
+ label: "Solarized",
256
+ light: {
257
+ base: "#fdf6e3",
258
+ l1: "#eee8d5",
259
+ l2: "#e7dfc8",
260
+ l3: "#d9d2b8",
261
+ overlay: "#eee8d5",
262
+ b1: "#93a1a1",
263
+ b2: "#839496",
264
+ brand: "#268bd2",
265
+ lp: "#586e75",
266
+ ls: "#657b83",
267
+ err: "#dc322f",
268
+ ok: "#859900",
269
+ warn: "#b58900",
270
+ side: "#fdf6e3"
271
+ },
272
+ dark: {
273
+ base: "#002b36",
274
+ l1: "#073642",
275
+ l2: "#0e4654",
276
+ l3: "#204e5b",
277
+ overlay: "#073642",
278
+ b1: "#586e75",
279
+ b2: "#657b83",
280
+ brand: "#268bd2",
281
+ lp: "#fdf6e3",
282
+ ls: "#93a1a1",
283
+ err: "#dc322f",
284
+ ok: "#859900",
285
+ warn: "#b58900",
286
+ side: "#002b36"
287
+ }
288
+ },
289
+ gruvbox: {
290
+ label: "Gruvbox",
291
+ light: {
292
+ base: "#fbf1c7",
293
+ l1: "#ebdbb2",
294
+ l2: "#d5c4a1",
295
+ l3: "#bdae93",
296
+ overlay: "#ebdbb2",
297
+ b1: "#a89984",
298
+ b2: "#928374",
299
+ brand: "#076678",
300
+ lp: "#3c3836",
301
+ ls: "#504945",
302
+ err: "#cc241d",
303
+ ok: "#98971a",
304
+ warn: "#d79921",
305
+ side: "#fbf1c7"
306
+ },
307
+ dark: {
308
+ base: "#282828",
309
+ l1: "#3c3836",
310
+ l2: "#504945",
311
+ l3: "#665c54",
312
+ overlay: "#3c3836",
313
+ b1: "#7c6f64",
314
+ b2: "#928374",
315
+ brand: "#83a598",
316
+ lp: "#ebdbb2",
317
+ ls: "#d5c4a1",
318
+ err: "#fb4934",
319
+ ok: "#b8bb26",
320
+ warn: "#fabd2f",
321
+ side: "#282828"
322
+ }
323
+ },
324
+ monokai: {
325
+ label: "Monokai",
326
+ light: {
327
+ base: "#ffffff",
328
+ l1: "#f9f8f5",
329
+ l2: "#ebe8e3",
330
+ l3: "#ddd8d0",
331
+ overlay: "#f9f8f5",
332
+ b1: "#c7c0b3",
333
+ b2: "#a8a194",
334
+ brand: "#6b42a0",
335
+ lp: "#2d2a2e",
336
+ ls: "#5b5956",
337
+ err: "#ff6188",
338
+ ok: "#5a8a2a",
339
+ warn: "#b87a00",
340
+ side: "#f9f8f5"
341
+ },
342
+ dark: {
343
+ base: "#2d2a2e",
344
+ l1: "#403e41",
345
+ l2: "#5b5956",
346
+ l3: "#69676c",
347
+ overlay: "#403e41",
348
+ b1: "#7a7978",
349
+ b2: "#948d8a",
350
+ brand: "#ab9df2",
351
+ lp: "#fcfcfa",
352
+ ls: "#c1c0c0",
353
+ err: "#ff6188",
354
+ ok: "#a9dc76",
355
+ warn: "#ffd866",
356
+ side: "#2d2a2e"
357
+ }
358
+ },
359
+ rosepine: {
360
+ label: "Rosé Pine",
361
+ light: {
362
+ base: "#faf4ed",
363
+ l1: "#fffaf3",
364
+ l2: "#f2e9e1",
365
+ l3: "#e8ddd3",
366
+ overlay: "#fffaf3",
367
+ b1: "#cecacd",
368
+ b2: "#9893a5",
369
+ brand: "#907aa9",
370
+ lp: "#575279",
371
+ ls: "#6e6a86",
372
+ err: "#b4637a",
373
+ ok: "#286983",
374
+ warn: "#ea9d34",
375
+ side: "#faf4ed"
376
+ },
377
+ dark: {
378
+ base: "#191724",
379
+ l1: "#1f1d2e",
380
+ l2: "#26233a",
381
+ l3: "#353142",
382
+ overlay: "#1f1d2e",
383
+ b1: "#6e6a86",
384
+ b2: "#908caa",
385
+ brand: "#c4a7e7",
386
+ lp: "#e0def4",
387
+ ls: "#908caa",
388
+ err: "#eb6f92",
389
+ ok: "#9ccfd8",
390
+ warn: "#f6c177",
391
+ side: "#191724"
392
+ }
393
+ },
394
+ ayu: {
395
+ label: "Ayu",
396
+ light: {
397
+ base: "#fafafa",
398
+ l1: "#f3f4f5",
399
+ l2: "#eaecee",
400
+ l3: "#e1e4e8",
401
+ overlay: "#f3f4f5",
402
+ b1: "#c4c9d0",
403
+ b2: "#a8b0bb",
404
+ brand: "#55b4d4",
405
+ lp: "#5c6773",
406
+ ls: "#5c6773",
407
+ err: "#e65050",
408
+ ok: "#86b300",
409
+ warn: "#fa8d3e",
410
+ side: "#fafafa"
411
+ },
412
+ dark: {
413
+ base: "#0a0e14",
414
+ l1: "#1f2430",
415
+ l2: "#242a38",
416
+ l3: "#3e4b5c",
417
+ overlay: "#1f2430",
418
+ b1: "#5c6773",
419
+ b2: "#7a8a9b",
420
+ brand: "#39bae6",
421
+ lp: "#c5cddb",
422
+ ls: "#95a0b0",
423
+ err: "#ff3333",
424
+ ok: "#7fd962",
425
+ warn: "#ffb454",
426
+ side: "#0a0e14"
427
+ }
428
+ },
429
+ zenburn: {
430
+ label: "Zenburn",
431
+ light: {
432
+ base: "#ffffef",
433
+ l1: "#f6f1e1",
434
+ l2: "#ebe3c8",
435
+ l3: "#ddd6b8",
436
+ overlay: "#f6f1e1",
437
+ b1: "#c2b8a3",
438
+ b2: "#a8a090",
439
+ brand: "#2b6f6f",
440
+ lp: "#3f3f3f",
441
+ ls: "#5f6f5f",
442
+ err: "#8c3333",
443
+ ok: "#4a6f4a",
444
+ warn: "#8f7a3a",
445
+ side: "#ffffef"
446
+ },
447
+ dark: {
448
+ base: "#3f3f3f",
449
+ l1: "#4f4f4f",
450
+ l2: "#5f5f5f",
451
+ l3: "#6f6f6f",
452
+ overlay: "#4f4f4f",
453
+ b1: "#7f7f7f",
454
+ b2: "#9a9a9a",
455
+ brand: "#8cd0d3",
456
+ lp: "#dcdccc",
457
+ ls: "#9ab0a0",
458
+ err: "#cc9393",
459
+ ok: "#7f9f7f",
460
+ warn: "#d0bf8f",
461
+ side: "#3f3f3f"
462
+ }
463
+ }
464
+ };
465
+ const presetOptions = [
466
+ {
467
+ value: "native",
468
+ label: "DeepSeek Harness"
469
+ },
470
+ {
471
+ value: "ayu",
472
+ label: "Ayu"
473
+ },
474
+ {
475
+ value: "catppuccin",
476
+ label: "Catppuccin"
477
+ },
478
+ {
479
+ value: "dracula",
480
+ label: "Dracula"
481
+ },
482
+ {
483
+ value: "github",
484
+ label: "GitHub"
485
+ },
486
+ {
487
+ value: "gruvbox",
488
+ label: "Gruvbox"
489
+ },
490
+ {
491
+ value: "monokai",
492
+ label: "Monokai"
493
+ },
494
+ {
495
+ value: "nord",
496
+ label: "Nord"
497
+ },
498
+ {
499
+ value: "onedark",
500
+ label: "One Dark"
501
+ },
502
+ {
503
+ value: "rosepine",
504
+ label: "Rosé Pine"
505
+ },
506
+ {
507
+ value: "solarized",
508
+ label: "Solarized"
509
+ },
510
+ {
511
+ value: "tokyonight",
512
+ label: "Tokyo Night"
513
+ },
514
+ {
515
+ value: "zenburn",
516
+ label: "Zenburn"
517
+ }
518
+ ];
519
+ //#endregion
520
+ //#region src/client/colors.ts
521
+ function hexLum(hex) {
522
+ const h = hex.replace("#", "");
523
+ const r = parseInt(h.slice(0, 2), 16);
524
+ const g = parseInt(h.slice(2, 4), 16);
525
+ const b = parseInt(h.slice(4, 6), 16);
526
+ return r * .299 + g * .587 + b * .114;
527
+ }
528
+ function pickCodeBlockColors(p) {
529
+ const page = p.base ?? p.l1;
530
+ const isLight = hexLum(page) > 128;
531
+ const brightest = (colors) => {
532
+ let best = colors[0];
533
+ let max = -1;
534
+ for (const c of colors) {
535
+ const l = hexLum(c);
536
+ if (l > max) {
537
+ max = l;
538
+ best = c;
539
+ }
540
+ }
541
+ return best;
542
+ };
543
+ if (isLight) {
544
+ const banner = brightest([
545
+ p.l1,
546
+ p.l2,
547
+ p.l3
548
+ ].filter((c) => c !== page));
549
+ const bannerLum = hexLum(banner);
550
+ let block;
551
+ let bestL = -1;
552
+ for (const c of [
553
+ p.l2,
554
+ p.l3,
555
+ p.b1
556
+ ]) {
557
+ if (c === page || c === banner) continue;
558
+ const l = hexLum(c);
559
+ if (l < bannerLum && l > bestL) {
560
+ bestL = l;
561
+ block = c;
562
+ }
563
+ }
564
+ const resolved = block ?? [
565
+ p.l2,
566
+ p.l3,
567
+ p.b1
568
+ ].find((c) => c !== page && c !== banner) ?? p.l2;
569
+ if (hexLum(banner) < hexLum(resolved)) return {
570
+ banner: resolved,
571
+ block: banner
572
+ };
573
+ if (banner === resolved) return {
574
+ banner,
575
+ block: p.l3 !== banner ? p.l3 : p.b1
576
+ };
577
+ return {
578
+ banner,
579
+ block: resolved
580
+ };
581
+ }
582
+ const banner = brightest([
583
+ p.l3,
584
+ p.b1,
585
+ p.b2,
586
+ p.l2
587
+ ].filter((c) => c !== page));
588
+ let block = [
589
+ p.l2,
590
+ p.l3,
591
+ p.b1,
592
+ p.b2
593
+ ].find((c) => c !== page && c !== banner) ?? p.l2;
594
+ {
595
+ let min = Infinity;
596
+ for (const c of [
597
+ p.l2,
598
+ p.b1,
599
+ p.l3,
600
+ p.b2
601
+ ]) {
602
+ if (c === page || c === banner) continue;
603
+ const l = hexLum(c);
604
+ if (l < min) {
605
+ min = l;
606
+ block = c;
607
+ }
608
+ }
609
+ }
610
+ if (hexLum(banner) < hexLum(block)) return {
611
+ banner: block,
612
+ block: banner
613
+ };
614
+ if (block === page) block = p.l2 !== banner ? p.l2 : p.b1;
615
+ if (banner === block) block = p.b2 !== banner ? p.b2 : p.b1;
616
+ return {
617
+ banner,
618
+ block
619
+ };
620
+ }
621
+ //#endregion
622
+ //#region src/client/tokens.ts
623
+ /**
624
+ * Token projection: preset palette -> DSH theme-token overrides.
625
+ */
626
+ function brightest(...colors) {
627
+ let best = colors[0];
628
+ let max = -1;
629
+ for (const c of colors) {
630
+ const l = hexLum(c);
631
+ if (l > max) {
632
+ max = l;
633
+ best = c;
634
+ }
635
+ }
636
+ return best;
637
+ }
638
+ function aliasCss(p) {
639
+ const m = {};
640
+ const base = p.base ?? p.l1;
641
+ const isLight = hexLum(base) > 128;
642
+ m["--dsw-alias-bg-base"] = base;
643
+ m["--dsw-alias-bg-layer-1"] = p.l1;
644
+ m["--dsw-alias-bg-layer-2"] = p.l2;
645
+ m["--dsw-alias-bg-layer-3"] = p.l3;
646
+ m["--dsw-alias-bg-mask-1"] = base + "3d";
647
+ m["--dsw-alias-bg-mask-2"] = base + "1f";
648
+ m["--dsw-alias-bg-mask-3"] = base + "7a";
649
+ m["--dsw-alias-bg-mask-photo"] = "#000000e0";
650
+ m["--dsw-alias-bg-mask-drop"] = base + "b3";
651
+ m["--dsw-alias-bg-module-platform"] = isLight ? p.l1 : p.l3;
652
+ m["--dsw-alias-bg-multi-select"] = isLight ? p.l1 : p.l3;
653
+ m["--dsw-alias-bg-overlay"] = p.l2;
654
+ m["--dsw-alias-bg-skeleton"] = p.b1 + "0a";
655
+ m["--dsw-alias-border-inverted2"] = "#0000";
656
+ m["--dsw-alias-border-inverted"] = "#0000";
657
+ m["--dsw-alias-border-l1"] = p.b1;
658
+ m["--dsw-alias-border-l2-darkmode-thin"] = p.b2;
659
+ m["--dsw-alias-border-l2"] = p.b2;
660
+ m["--dsw-alias-border-l3"] = p.b2;
661
+ m["--dsw-alias-border-l4"] = p.b2;
662
+ m["--dsw-alias-brand-primary-invert"] = p.lp;
663
+ m["--dsw-alias-brand-primary-new-colorprimary-new-color"] = p.brand;
664
+ m["--dsw-alias-brand-primary"] = p.brand;
665
+ m["--dsw-alias-brand-text"] = p.brand;
666
+ m["--dsw-alias-button-contrast-fill"] = p.lp;
667
+ m["--dsw-alias-button-elevated-fill"] = isLight ? base : p.l2;
668
+ m["--dsw-alias-button-floating-fill"] = isLight ? base : p.l2;
669
+ m["--dsw-alias-button-floating-hover"] = isLight ? p.l2 : p.l3;
670
+ m["--dsw-alias-button-ghost-active-border"] = p.b1;
671
+ m["--dsw-alias-button-ghost-active-fill"] = p.l2;
672
+ m["--dsw-alias-button-ghost-active-hover"] = p.l3;
673
+ m["--dsw-alias-button-info-fill"] = p.brand;
674
+ m["--dsw-alias-button-info-hover"] = p.brand;
675
+ m["--dsw-alias-button-primary-dimmed"] = p.l2;
676
+ m["--dsw-alias-button-primary-fill"] = p.brand;
677
+ m["--dsw-alias-button-primary-hover"] = p.lp;
678
+ m["--dsw-alias-button-tool-bar-fill-invisible"] = p.l2 + "5c";
679
+ m["--dsw-alias-button-tool-bar-fill"] = p.b1 + "80";
680
+ m["--dsw-alias-button-tool-bar-hover"] = p.b1 + "99";
681
+ const interactiveHover = isLight ? p.l3 : p.b2;
682
+ m["--dsw-alias-interactive-bg-active"] = isLight ? p.b2 : p.l3;
683
+ m["--dsw-alias-interactive-bg-hover-accent"] = p.brand + "14";
684
+ m["--dsw-alias-interactive-bg-hover-danger"] = p.err + "14";
685
+ m["--dsw-alias-interactive-bg-hover-solid"] = interactiveHover;
686
+ m["--dsw-alias-interactive-bg-hover"] = interactiveHover;
687
+ m["--dsw-alias-label-caption"] = p.lp + "99";
688
+ m["--dsw-alias-label-dimmed"] = p.b1;
689
+ m["--dsw-alias-label-primary-bluish"] = p.brand;
690
+ m["--dsw-alias-label-primary-dimmed"] = p.lp;
691
+ m["--dsw-alias-label-primary-foreground"] = base;
692
+ m["--dsw-alias-label-primary-inverted"] = base;
693
+ m["--dsw-alias-label-primary"] = p.lp;
694
+ m["--dsw-alias-label-secondary"] = p.ls;
695
+ m["--dsw-alias-label-tertiary"] = p.ls;
696
+ m["--dsw-alias-markdown-citation"] = p.l3;
697
+ const code = pickCodeBlockColors(p);
698
+ m["--dsw-alias-markdown-code-block-banner"] = code.banner;
699
+ m["--dsw-alias-markdown-code-block"] = code.block;
700
+ m["--dsw-alias-markdown-code-segment-selected"] = p.l2;
701
+ m["--dsw-alias-markdown-code-segment-unselected"] = p.l3;
702
+ m["--dsw-alias-markdown-inline-code"] = p.l3;
703
+ m["--dsw-alias-markdown-placeholder"] = p.b1;
704
+ m["--dsw-alias-markdown-tag"] = p.l3;
705
+ m["--dsw-alias-scrollbar-bg-l1"] = p.b1;
706
+ m["--dsw-alias-scrollbar-bg-l2"] = p.b2;
707
+ m["--dsw-alias-scrollbar-hover-l1"] = p.b2;
708
+ m["--dsw-alias-scrollbar-hover-l2"] = p.b2;
709
+ m["--dsw-alias-state-business-primary"] = p.brand;
710
+ m["--dsw-alias-state-business-tertiary"] = p.brand + "20";
711
+ m["--dsw-alias-state-error-primary"] = p.err;
712
+ m["--dsw-alias-state-error-secondary"] = p.err;
713
+ m["--dsw-alias-state-success-primary"] = p.ok;
714
+ m["--dsw-alias-state-success-secondary"] = p.ok;
715
+ m["--dsw-alias-state-success-tertiary"] = p.ok + "20";
716
+ m["--dsw-alias-state-warn-label"] = p.warn;
717
+ m["--dsw-alias-state-warn-primary"] = p.warn;
718
+ m["--dsw-alias-state-warn-secondary"] = p.warn;
719
+ m["--dsw-alias-state-warn-tertiary"] = p.warn + "20";
720
+ m["--dsw-alias-toast-bg"] = isLight ? base : p.l3;
721
+ m["--dsw-cool-theme-toast-bg"] = isLight ? base : p.l3;
722
+ m["--dsw-cool-theme-toast-fg"] = p.lp;
723
+ m["--dsw-cool-theme-toast-border"] = p.b1;
724
+ m["--dsw-alias-tooltip-bg"] = isLight ? p.l3 : brightest(p.l3, p.b2);
725
+ m["--dsw-specific-bubble-highlight"] = p.brand + "30";
726
+ m["--dsw-specific-bubble"] = p.brand + "15";
727
+ m["--dsw-specific-input-major"] = isLight ? base : p.l1;
728
+ m["--dsw-specific-login-input"] = p.l1;
729
+ m["--dsw-specific-menu"] = p.l2;
730
+ m["--dsw-specific-selector"] = isLight ? p.l1 : p.l3;
731
+ m["--dsw-specific-sidebar-fill"] = p.l1;
732
+ m["--dsw-specific-sidebar-nav-item-hover"] = p.l3;
733
+ m["--dsw-specific-sidebar-nav-item-active"] = p.l3;
734
+ m["--dsw-specific-sidebar-nav-item-active-accent"] = p.brand + "20";
735
+ m["--dsw-specific-tip"] = p.l1;
736
+ return m;
737
+ }
738
+ function staticCss(p) {
739
+ const m = {};
740
+ const base = p.base ?? p.l1;
741
+ m["--dsw-static-neutral-bluish-00"] = p.lp;
742
+ m["--dsw-static-neutral-bluish-50"] = p.lp;
743
+ m["--dsw-static-neutral-bluish-60"] = p.l3;
744
+ m["--dsw-static-neutral-bluish-75"] = p.l3;
745
+ m["--dsw-static-neutral-bluish-100"] = p.ls;
746
+ m["--dsw-static-neutral-bluish-150"] = p.ls;
747
+ m["--dsw-static-neutral-bluish-200"] = p.b1;
748
+ m["--dsw-static-neutral-bluish-300"] = p.b1;
749
+ m["--dsw-static-neutral-bluish-400"] = p.b1;
750
+ m["--dsw-static-neutral-bluish-500"] = p.b2;
751
+ m["--dsw-static-neutral-bluish-600"] = p.b2;
752
+ m["--dsw-static-neutral-bluish-700"] = p.l2;
753
+ m["--dsw-static-neutral-bluish-750"] = p.l2;
754
+ m["--dsw-static-neutral-bluish-800"] = p.l2;
755
+ m["--dsw-static-neutral-bluish-850"] = p.l1;
756
+ m["--dsw-static-neutral-bluish-875"] = p.l1;
757
+ m["--dsw-static-neutral-bluish-900"] = p.l1;
758
+ m["--dsw-static-neutral-bluish-950"] = base;
759
+ m["--dsw-static-neutral-bluish-1000"] = base;
760
+ for (const k of [
761
+ "100",
762
+ "200",
763
+ "300",
764
+ "400",
765
+ "450",
766
+ "500",
767
+ "600",
768
+ "800",
769
+ "900"
770
+ ]) {
771
+ m[`--dsw-static-deepseek-${k}`] = p.brand;
772
+ m[`--dsw-static-blue-${k}`] = p.brand;
773
+ }
774
+ m["--dsw-static-deepseek-50"] = p.brand + "15";
775
+ m["--dsw-static-blue-50"] = p.brand + "15";
776
+ m["--dsw-static-blue-50p"] = p.brand + "15";
777
+ m["--dsw-static-blue-75"] = p.brand + "20";
778
+ m["--dsw-static-green-100"] = p.ok + "20";
779
+ m["--dsw-static-green-400"] = p.ok;
780
+ m["--dsw-static-green-500"] = p.ok;
781
+ m["--dsw-static-green-900"] = p.ok + "30";
782
+ m["--dsw-static-amber-100"] = p.warn + "20";
783
+ m["--dsw-static-amber-400"] = p.warn;
784
+ m["--dsw-static-amber-500"] = p.warn;
785
+ m["--dsw-static-amber-600"] = p.warn;
786
+ m["--dsw-static-amber-900"] = p.warn + "30";
787
+ m["--dsw-static-red-50"] = p.err + "15";
788
+ m["--dsw-static-red-100"] = p.err + "20";
789
+ m["--dsw-static-red-400"] = p.err;
790
+ m["--dsw-static-red-500"] = p.err;
791
+ m["--dsw-static-red-600"] = p.err;
792
+ m["--dsw-static-red-900"] = p.err + "30";
793
+ m["--dsw-static-neutral-00"] = p.lp;
794
+ m["--dsw-static-neutral-50"] = p.lp;
795
+ m["--dsw-static-neutral-100"] = p.ls;
796
+ m["--dsw-static-neutral-150"] = p.ls;
797
+ m["--dsw-static-neutral-200"] = p.b1;
798
+ m["--dsw-static-neutral-250"] = p.b1;
799
+ m["--dsw-static-neutral-300"] = p.b1;
800
+ m["--dsw-static-neutral-400"] = p.b1;
801
+ m["--dsw-static-neutral-500"] = p.b2;
802
+ m["--dsw-static-neutral-550"] = p.b2;
803
+ m["--dsw-static-neutral-600"] = p.b2;
804
+ m["--dsw-static-neutral-700"] = p.l2;
805
+ m["--dsw-static-neutral-800"] = p.l2;
806
+ m["--dsw-static-neutral-850"] = p.l1;
807
+ m["--dsw-static-neutral-900"] = base;
808
+ m["--dsw-static-neutral-1000"] = base;
809
+ return m;
810
+ }
811
+ const SHIKI_TABLE = /* @__PURE__ */ new Map([
812
+ [PRESETS.nord.light, {
813
+ constant: "#2e6ea6",
814
+ string: "#3d7a1f",
815
+ comment: "#6c7a8e",
816
+ keyword: "#8b4a9a",
817
+ parameter: "#9a5d2e",
818
+ function: "#2f6f8a",
819
+ stringExpression: "#3d7a1f",
820
+ punctuation: "#4c566a",
821
+ link: "#5e81ac"
822
+ }],
823
+ [PRESETS.nord.dark, {
824
+ constant: "#8be9fd",
825
+ string: "#a3be8c",
826
+ comment: "#6272a4",
827
+ keyword: "#ff79c6",
828
+ parameter: "#d08770",
829
+ function: "#88c0d0",
830
+ stringExpression: "#a3be8c",
831
+ punctuation: "#8ca0b8",
832
+ link: "#88c0d0"
833
+ }],
834
+ [PRESETS.onedark.light, {
835
+ constant: "#0b7ea4",
836
+ string: "#1f7a3a",
837
+ comment: "#76808f",
838
+ keyword: "#a626a4",
839
+ parameter: "#986801",
840
+ function: "#4078f2",
841
+ stringExpression: "#1f7a3a",
842
+ punctuation: "#5c6370",
843
+ link: "#4078f2"
844
+ }],
845
+ [PRESETS.onedark.dark, {
846
+ constant: "#56b6c2",
847
+ string: "#98c379",
848
+ comment: "#7f848e",
849
+ keyword: "#c678dd",
850
+ parameter: "#d19a66",
851
+ function: "#61afef",
852
+ stringExpression: "#98c379",
853
+ punctuation: "#abb2bf",
854
+ link: "#61afef"
855
+ }],
856
+ [PRESETS.github.light, {
857
+ constant: "#0550ae",
858
+ string: "#0a3069",
859
+ comment: "#6e7781",
860
+ keyword: "#cf222e",
861
+ parameter: "#953800",
862
+ function: "#8250df",
863
+ stringExpression: "#1a7f37",
864
+ punctuation: "#656d76",
865
+ link: "#0969da"
866
+ }],
867
+ [PRESETS.github.dark, {
868
+ constant: "#79c0ff",
869
+ string: "#a5d6ff",
870
+ comment: "#8b949e",
871
+ keyword: "#ff7b72",
872
+ parameter: "#ffa657",
873
+ function: "#d2a8ff",
874
+ stringExpression: "#7ee787",
875
+ punctuation: "#8b949e",
876
+ link: "#58a6ff"
877
+ }],
878
+ [PRESETS.catppuccin.light, {
879
+ constant: "#0b7ec8",
880
+ string: "#1a7a3a",
881
+ comment: "#7a7f8e",
882
+ keyword: "#8839ef",
883
+ parameter: "#fe640b",
884
+ function: "#1e66f5",
885
+ stringExpression: "#1a7a3a",
886
+ punctuation: "#5c5f77",
887
+ link: "#1e66f5"
888
+ }],
889
+ [PRESETS.catppuccin.dark, {
890
+ constant: "#89dceb",
891
+ string: "#a6e3a1",
892
+ comment: "#6c7086",
893
+ keyword: "#cba6f7",
894
+ parameter: "#fab387",
895
+ function: "#89b4fa",
896
+ stringExpression: "#a6e3a1",
897
+ punctuation: "#bac2de",
898
+ link: "#89b4fa"
899
+ }],
900
+ [PRESETS.dracula.light, {
901
+ constant: "#6a3fb5",
902
+ string: "#1a7a3a",
903
+ comment: "#6d7a9e",
904
+ keyword: "#a21caf",
905
+ parameter: "#b45309",
906
+ function: "#7c3aed",
907
+ stringExpression: "#1a7a3a",
908
+ punctuation: "#44475a",
909
+ link: "#7c3aed"
910
+ }],
911
+ [PRESETS.dracula.dark, {
912
+ constant: "#8be9fd",
913
+ string: "#50fa7b",
914
+ comment: "#6272a4",
915
+ keyword: "#ff79c6",
916
+ parameter: "#ffb86c",
917
+ function: "#bd93f9",
918
+ stringExpression: "#50fa7b",
919
+ punctuation: "#f8f8f2",
920
+ link: "#bd93f9"
921
+ }],
922
+ [PRESETS.tokyonight.light, {
923
+ constant: "#0f4b6e",
924
+ string: "#1a7a3a",
925
+ comment: "#6e7a9e",
926
+ keyword: "#8c4351",
927
+ parameter: "#965027",
928
+ function: "#34548a",
929
+ stringExpression: "#1a7a3a",
930
+ punctuation: "#5a638c",
931
+ link: "#34548a"
932
+ }],
933
+ [PRESETS.tokyonight.dark, {
934
+ constant: "#7dcfff",
935
+ string: "#9ece6a",
936
+ comment: "#565f89",
937
+ keyword: "#bb9af7",
938
+ parameter: "#ff9e64",
939
+ function: "#7aa2f7",
940
+ stringExpression: "#9ece6a",
941
+ punctuation: "#c0caf5",
942
+ link: "#7aa2f7"
943
+ }],
944
+ [PRESETS.solarized.light, {
945
+ constant: "#2aa198",
946
+ string: "#586e75",
947
+ comment: "#93a1a1",
948
+ keyword: "#859900",
949
+ parameter: "#cb4b16",
950
+ function: "#268bd2",
951
+ stringExpression: "#2aa198",
952
+ punctuation: "#657b83",
953
+ link: "#268bd2"
954
+ }],
955
+ [PRESETS.solarized.dark, {
956
+ constant: "#2aa198",
957
+ string: "#859900",
958
+ comment: "#586e75",
959
+ keyword: "#268bd2",
960
+ parameter: "#cb4b16",
961
+ function: "#b58900",
962
+ stringExpression: "#2aa198",
963
+ punctuation: "#93a1a1",
964
+ link: "#268bd2"
965
+ }],
966
+ [PRESETS.gruvbox.light, {
967
+ constant: "#076678",
968
+ string: "#79740e",
969
+ comment: "#928374",
970
+ keyword: "#9d0006",
971
+ parameter: "#af3a03",
972
+ function: "#076678",
973
+ stringExpression: "#79740e",
974
+ punctuation: "#504945",
975
+ link: "#076678"
976
+ }],
977
+ [PRESETS.gruvbox.dark, {
978
+ constant: "#83a598",
979
+ string: "#b8bb26",
980
+ comment: "#928374",
981
+ keyword: "#fb4934",
982
+ parameter: "#fe8019",
983
+ function: "#fabd2f",
984
+ stringExpression: "#b8bb26",
985
+ punctuation: "#ebdbb2",
986
+ link: "#83a598"
987
+ }],
988
+ [PRESETS.monokai.light, {
989
+ constant: "#6b42a0",
990
+ string: "#2a7a2a",
991
+ comment: "#8a8a8a",
992
+ keyword: "#c4265e",
993
+ parameter: "#b45a00",
994
+ function: "#6b42a0",
995
+ stringExpression: "#2a7a2a",
996
+ punctuation: "#5b5956",
997
+ link: "#6b42a0"
998
+ }],
999
+ [PRESETS.monokai.dark, {
1000
+ constant: "#ab9df2",
1001
+ string: "#a9dc76",
1002
+ comment: "#7a7978",
1003
+ keyword: "#ff6188",
1004
+ parameter: "#fc9867",
1005
+ function: "#78dce8",
1006
+ stringExpression: "#a9dc76",
1007
+ punctuation: "#fcfcfa",
1008
+ link: "#ab9df2"
1009
+ }],
1010
+ [PRESETS.rosepine.light, {
1011
+ constant: "#56949f",
1012
+ string: "#286983",
1013
+ comment: "#9893a5",
1014
+ keyword: "#907aa9",
1015
+ parameter: "#b4637a",
1016
+ function: "#907aa9",
1017
+ stringExpression: "#286983",
1018
+ punctuation: "#575279",
1019
+ link: "#907aa9"
1020
+ }],
1021
+ [PRESETS.rosepine.dark, {
1022
+ constant: "#9ccfd8",
1023
+ string: "#ebbcba",
1024
+ comment: "#6e6a86",
1025
+ keyword: "#c4a7e7",
1026
+ parameter: "#eb6f92",
1027
+ function: "#e0def4",
1028
+ stringExpression: "#ebbcba",
1029
+ punctuation: "#e0def4",
1030
+ link: "#c4a7e7"
1031
+ }],
1032
+ [PRESETS.ayu.light, {
1033
+ constant: "#55b4d4",
1034
+ string: "#86b300",
1035
+ comment: "#a8b0bb",
1036
+ keyword: "#fa8d3e",
1037
+ parameter: "#f07171",
1038
+ function: "#55b4d4",
1039
+ stringExpression: "#86b300",
1040
+ punctuation: "#5c6773",
1041
+ link: "#55b4d4"
1042
+ }],
1043
+ [PRESETS.ayu.dark, {
1044
+ constant: "#39bae6",
1045
+ string: "#7fd962",
1046
+ comment: "#5c6773",
1047
+ keyword: "#ffb454",
1048
+ parameter: "#ff8f40",
1049
+ function: "#59e1ff",
1050
+ stringExpression: "#7fd962",
1051
+ punctuation: "#c5cddb",
1052
+ link: "#39bae6"
1053
+ }],
1054
+ [PRESETS.zenburn.light, {
1055
+ constant: "#2b6f6f",
1056
+ string: "#8c3333",
1057
+ comment: "#7a8a7a",
1058
+ keyword: "#705040",
1059
+ parameter: "#8f5a00",
1060
+ function: "#2b6f6f",
1061
+ stringExpression: "#8c3333",
1062
+ punctuation: "#5f6f5f",
1063
+ link: "#2b6f6f"
1064
+ }],
1065
+ [PRESETS.zenburn.dark, {
1066
+ constant: "#8cd0d3",
1067
+ string: "#cc9393",
1068
+ comment: "#7f9f7f",
1069
+ keyword: "#f0dfaf",
1070
+ parameter: "#d0bf8f",
1071
+ function: "#8cd0d3",
1072
+ stringExpression: "#cc9393",
1073
+ punctuation: "#dcdccc",
1074
+ link: "#8cd0d3"
1075
+ }]
1076
+ ]);
1077
+ const SHIKI_FALLBACK = {
1078
+ constant: "#0550ae",
1079
+ string: "#1a7f37",
1080
+ comment: "#6e7781",
1081
+ keyword: "#cf222e",
1082
+ parameter: "#953800",
1083
+ function: "#8250df",
1084
+ stringExpression: "#1a7f37",
1085
+ punctuation: "#656d76",
1086
+ link: "#0969da"
1087
+ };
1088
+ function shikiCss(p) {
1089
+ const m = {};
1090
+ m["--shiki-foreground"] = p.lp;
1091
+ m["--shiki-background"] = pickCodeBlockColors(p).block;
1092
+ const t = SHIKI_TABLE.get(p) ?? SHIKI_FALLBACK;
1093
+ m["--shiki-token-constant"] = t.constant;
1094
+ m["--shiki-token-string"] = t.string;
1095
+ m["--shiki-token-comment"] = t.comment;
1096
+ m["--shiki-token-keyword"] = t.keyword;
1097
+ m["--shiki-token-parameter"] = t.parameter;
1098
+ m["--shiki-token-function"] = t.function;
1099
+ m["--shiki-token-string-expression"] = t.stringExpression;
1100
+ m["--shiki-token-punctuation"] = t.punctuation;
1101
+ m["--shiki-token-link"] = t.link;
1102
+ return m;
1103
+ }
1104
+ function getTokenMaps(id) {
1105
+ const preset = PRESETS[id];
1106
+ return {
1107
+ lightAlias: aliasCss(preset.light),
1108
+ darkAlias: aliasCss(preset.dark),
1109
+ lightStat: staticCss(preset.light),
1110
+ darkStat: staticCss(preset.dark),
1111
+ lightShiki: shikiCss(preset.light),
1112
+ darkShiki: shikiCss(preset.dark)
1113
+ };
1114
+ }
1115
+ function buildOverrides(id) {
1116
+ if (id === "native") return {};
1117
+ const { lightAlias, darkAlias, lightStat, darkStat, lightShiki, darkShiki } = getTokenMaps(id);
1118
+ const overrides = {};
1119
+ const add = (a, b) => {
1120
+ for (const k of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])) overrides[k] = {
1121
+ light: a[k] ?? b[k],
1122
+ dark: b[k] ?? a[k]
1123
+ };
1124
+ };
1125
+ add(lightAlias, darkAlias);
1126
+ add(lightStat, darkStat);
1127
+ add(lightShiki, darkShiki);
1128
+ return overrides;
1129
+ }
1130
+ function buildFullCssFallback(id) {
1131
+ if (id === "native") return "";
1132
+ const { lightAlias, darkAlias, lightStat, darkStat, lightShiki, darkShiki } = getTokenMaps(id);
1133
+ const block = (map) => Object.entries(map).map(([k, v]) => ` ${k}: ${v};`).join("\n");
1134
+ return `:root{\n${block(lightStat)}\n${block(lightAlias)}\n${block(lightShiki)}\n}\nbody[data-ds-dark-theme]{\n${block(darkStat)}\n${block(darkAlias)}\n${block(darkShiki)}\n}`;
1135
+ }
1136
+ //#endregion
1137
+ //#region src/client/style-injector.ts
1138
+ function createStyleInjector() {
1139
+ const disposers = /* @__PURE__ */ new Set();
1140
+ function insert(css) {
1141
+ try {
1142
+ if (typeof styles !== "undefined" && typeof styles.insert === "function") {
1143
+ const dispose = styles.insert(css);
1144
+ const wrapped = () => {
1145
+ try {
1146
+ dispose?.();
1147
+ } catch {}
1148
+ disposers.delete(wrapped);
1149
+ };
1150
+ disposers.add(wrapped);
1151
+ return wrapped;
1152
+ }
1153
+ } catch {}
1154
+ const tag = document.createElement("style");
1155
+ tag.dataset.plugin = "dsh-cool-theme";
1156
+ tag.textContent = css;
1157
+ document.head.appendChild(tag);
1158
+ const wrapped = () => {
1159
+ tag.remove();
1160
+ disposers.delete(wrapped);
1161
+ };
1162
+ disposers.add(wrapped);
1163
+ return wrapped;
1164
+ }
1165
+ function disposeAll() {
1166
+ for (const d of [...disposers]) try {
1167
+ d();
1168
+ } catch {}
1169
+ disposers.clear();
1170
+ }
1171
+ return {
1172
+ insert,
1173
+ disposeAll
1174
+ };
1175
+ }
1176
+ //#endregion
1177
+ //#region src/client/components.tsx
1178
+ /**
1179
+ * Theme settings UI: scheme selector + preset picker.
1180
+ */
1181
+ function IconChevron() {
1182
+ return react.createElement("svg", {
1183
+ width: 14,
1184
+ height: 14,
1185
+ viewBox: "0 0 14 14",
1186
+ fill: "none",
1187
+ xmlns: "http://www.w3.org/2000/svg"
1188
+ }, react.createElement("path", {
1189
+ d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
1190
+ fill: "currentColor"
1191
+ }));
1192
+ }
1193
+ function IconCheck() {
1194
+ return react.createElement("svg", {
1195
+ width: 16,
1196
+ height: 16,
1197
+ viewBox: "0 0 16 16",
1198
+ fill: "none",
1199
+ xmlns: "http://www.w3.org/2000/svg",
1200
+ style: {
1201
+ marginLeft: "auto",
1202
+ color: "var(--dsw-alias-label-primary)",
1203
+ display: "inline-flex"
1204
+ }
1205
+ }, react.createElement("path", {
1206
+ d: "M15.0498 3.92579L8.49512 12.3818C8.25774 12.6881 8.04517 12.9645 7.84668 13.1689C7.63957 13.3823 7.38732 13.5841 7.04492 13.6719C6.86373 13.7183 6.6757 13.7346 6.48926 13.7197C6.13666 13.6915 5.8528 13.5355 5.6123 13.3604C5.38201 13.1926 5.12573 12.9567 4.83984 12.6953L1.03125 9.21289L1.96875 8.1875L5.77734 11.6699C6.08684 11.9529 6.27773 12.1249 6.43066 12.2363C6.50183 12.2882 6.54699 12.3135 6.57324 12.3252C6.58525 12.3305 6.59269 12.3322 6.5957 12.333C6.59802 12.3336 6.59961 12.334 6.59961 12.334C6.63317 12.3367 6.66758 12.3335 6.7002 12.3252C6.7002 12.3252 6.70211 12.3251 6.7041 12.3242C6.70698 12.3229 6.71348 12.319 6.72461 12.3115C6.74849 12.2956 6.78843 12.2642 6.84961 12.2012C6.98138 12.0654 7.13957 11.8628 7.39648 11.5313L13.9502 3.07422L15.0498 3.92579Z",
1207
+ fill: "currentColor"
1208
+ }));
1209
+ }
1210
+ function SchemeMenu(props) {
1211
+ const { value, options, onSelect } = props;
1212
+ const [open, setOpen] = react.useState(false);
1213
+ const rootRef = react.useRef(null);
1214
+ const listRef = react.useRef(null);
1215
+ react.useEffect(() => {
1216
+ if (!open) return;
1217
+ function onDown(e) {
1218
+ if (!(e.target instanceof Node)) return;
1219
+ if (rootRef.current?.contains(e.target)) return;
1220
+ if (listRef.current?.contains(e.target)) return;
1221
+ setOpen(false);
1222
+ }
1223
+ function onKey(e) {
1224
+ if (e.key === "Escape") setOpen(false);
1225
+ }
1226
+ document.addEventListener("pointerdown", onDown);
1227
+ document.addEventListener("keydown", onKey);
1228
+ return () => {
1229
+ document.removeEventListener("pointerdown", onDown);
1230
+ document.removeEventListener("keydown", onKey);
1231
+ };
1232
+ }, [open]);
1233
+ const selected = options.find((o) => o.value === value);
1234
+ return react.createElement("span", {
1235
+ ref: rootRef,
1236
+ style: {
1237
+ position: "relative",
1238
+ display: "inline-flex"
1239
+ }
1240
+ }, react.createElement("button", {
1241
+ type: "button",
1242
+ className: "ct-select",
1243
+ "aria-haspopup": "menu",
1244
+ "aria-expanded": open,
1245
+ onClick: () => setOpen(!open)
1246
+ }, react.createElement("span", { className: "ct-select-label" }, selected?.label ?? ""), react.createElement("span", { className: "ct-select-chevron" }, react.createElement(IconChevron, null))), open ? react.createElement("div", {
1247
+ ref: listRef,
1248
+ className: "ct-menu-list",
1249
+ style: {
1250
+ position: "absolute",
1251
+ top: "calc(100% + 4px)",
1252
+ right: 0,
1253
+ zIndex: 100
1254
+ },
1255
+ role: "menu",
1256
+ onClick: (e) => e.stopPropagation()
1257
+ }, ...options.map((o) => {
1258
+ const sel = o.value === value;
1259
+ return react.createElement("button", {
1260
+ key: o.value,
1261
+ type: "button",
1262
+ role: "menuitem",
1263
+ className: "ct-menu-item",
1264
+ onClick: () => {
1265
+ setOpen(false);
1266
+ onSelect(o.value);
1267
+ }
1268
+ }, react.createElement("span", { className: "ct-menu-item-label" }, o.label), sel ? react.createElement(IconCheck, null) : null);
1269
+ })) : null);
1270
+ }
1271
+ function ThemePanel(props) {
1272
+ const { theme, getPreset, setPreset, t } = props;
1273
+ let initScheme = "system";
1274
+ try {
1275
+ const snap = theme?.getTheme();
1276
+ if (snap?.preference) initScheme = snap.preference;
1277
+ } catch {}
1278
+ const [scheme, setScheme] = react.useState(initScheme);
1279
+ const [active, setActive] = react.useState(() => getPreset());
1280
+ function pickScheme(id) {
1281
+ setScheme(id);
1282
+ try {
1283
+ theme?.setTheme(id);
1284
+ } catch {}
1285
+ }
1286
+ function pickPreset(id) {
1287
+ setActive(id);
1288
+ setPreset(id);
1289
+ }
1290
+ const schemeOptions = [
1291
+ {
1292
+ value: "light",
1293
+ label: t("scheme.light")
1294
+ },
1295
+ {
1296
+ value: "dark",
1297
+ label: t("scheme.dark")
1298
+ },
1299
+ {
1300
+ value: "system",
1301
+ label: t("scheme.system")
1302
+ }
1303
+ ];
1304
+ return react.createElement("div", { style: {
1305
+ display: "flex",
1306
+ flexDirection: "column",
1307
+ maxWidth: 760,
1308
+ paddingBottom: 8
1309
+ } }, react.createElement("div", { className: "ct-row" }, react.createElement("div", { className: "ct-row-main" }, react.createElement("div", { className: "ct-row-title" }, t("appearance.title")), react.createElement("div", { className: "ct-row-desc" }, t("appearance.desc"))), react.createElement(SchemeMenu, {
1310
+ value: scheme,
1311
+ options: schemeOptions,
1312
+ onSelect: pickScheme
1313
+ })), react.createElement("div", { className: "ct-row" }, react.createElement("div", { className: "ct-row-main" }, react.createElement("div", { className: "ct-row-title" }, t("presets.title")), react.createElement("div", { className: "ct-row-desc" }, t("presets.desc"))), react.createElement(SchemeMenu, {
1314
+ value: active,
1315
+ options: presetOptions,
1316
+ onSelect: (v) => pickPreset(v)
1317
+ })));
1318
+ }
1319
+ //#endregion
1320
+ //#region src/client/locales.ts
1321
+ /**
1322
+ * Theme settings dictionaries (zh is the key-set source of truth; en mirrors
1323
+ * it completely). Preset names stay as proper nouns in both locales, so they
1324
+ * live in presets.ts, not here.
1325
+ */
1326
+ /** Simplified Chinese dictionary (the key-set source of truth). */
1327
+ const zh = {
1328
+ nav: "主题",
1329
+ "appearance.title": "外观",
1330
+ "appearance.desc": "深色 / 浅色 / 跟随系统",
1331
+ "presets.title": "预设主题",
1332
+ "presets.desc": "一键套用主流配色方案",
1333
+ "scheme.light": "浅色",
1334
+ "scheme.dark": "深色",
1335
+ "scheme.system": "跟随系统"
1336
+ };
1337
+ /** English dictionary, checked complete against the zh key set. */
1338
+ const en = {
1339
+ nav: "Theme",
1340
+ "appearance.title": "Appearance",
1341
+ "appearance.desc": "Dark / Light / System",
1342
+ "presets.title": "Preset themes",
1343
+ "presets.desc": "Apply popular color schemes in one click",
1344
+ "scheme.light": "Light",
1345
+ "scheme.dark": "Dark",
1346
+ "scheme.system": "System"
1347
+ };
1348
+ //#endregion
1349
+ //#region src/client/theme.tsx
1350
+ /**
1351
+ * Client theme module — registers settings.section id=cool-theme.
1352
+ */
1353
+ const PALETTE_ICON_PATH = "M12 22a1 1 0 0 1 0-20a10 9 0 0 1 10 9a5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z";
1354
+ const PALETTE_ICON_DOTS = [
1355
+ {
1356
+ cx: "13.5",
1357
+ cy: "6.5",
1358
+ r: "1.4"
1359
+ },
1360
+ {
1361
+ cx: "17.5",
1362
+ cy: "10.5",
1363
+ r: "1.4"
1364
+ },
1365
+ {
1366
+ cx: "6.5",
1367
+ cy: "12.5",
1368
+ r: "1.4"
1369
+ },
1370
+ {
1371
+ cx: "8.5",
1372
+ cy: "7.5",
1373
+ r: "1.4"
1374
+ }
1375
+ ];
1376
+ function registerTheme(ctx) {
1377
+ const slots = ctx.get("slots");
1378
+ const theme = ctx.get("theme");
1379
+ if (!slots) return;
1380
+ const NS = "cool-theme";
1381
+ const locale = ctx.get("locale");
1382
+ let t = (key) => zh[key];
1383
+ if (locale) {
1384
+ ctx.effect(() => locale.register(NS, {
1385
+ zh,
1386
+ en
1387
+ }), "dsh-cool-theme: theme dictionaries");
1388
+ t = locale.bind(NS);
1389
+ }
1390
+ const baseCss = [
1391
+ ".ct-select{box-sizing:border-box;display:inline-flex;align-items:center;gap:12px;height:36px;padding:0 14px;border:none;border-radius:18px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:14px;line-height:22px;white-space:nowrap;width:auto;min-width:0;max-width:100%;}",
1392
+ ".ct-select:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);}",
1393
+ ".ct-select:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
1394
+ ".ct-select-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;}",
1395
+ ".ct-select-chevron{flex:none;color:var(--dsw-alias-label-tertiary);display:inline-flex;transition:transform 120ms ease;}",
1396
+ ".ct-select[aria-expanded=\"true\"] .ct-select-chevron{transform:rotate(180deg);}",
1397
+ ".ct-menu-list{box-sizing:border-box;padding:4px;display:flex;flex-direction:column;gap:0;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);min-width:218px;max-width:360px;}",
1398
+ ".ct-menu-item{display:flex;align-items:center;gap:8px;width:100%;min-height:40px;padding:8px 10px;border:none;border-radius:10px;background:transparent;cursor:pointer;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary);text-align:left;font-family:inherit;}",
1399
+ ".ct-menu-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);}",
1400
+ ".ct-menu-check{flex:none;color:var(--dsw-alias-label-primary);display:inline-flex;margin-left:auto;}",
1401
+ ".ct-menu-item-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
1402
+ ".ct-row{border-bottom:1px solid var(--dsw-alias-border-l2);padding:16px 2px;display:flex;align-items:center;gap:16px;}",
1403
+ ".ct-row-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;padding-right:48px;}",
1404
+ ".ct-row-title{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px;}",
1405
+ ".ct-row-desc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px;}",
1406
+ "[class*=\"navCell\"]:hover{background:var(--dsw-specific-sidebar-nav-item-hover) !important;}",
1407
+ "[class*=\"navCell\"].active,[class*=\"navCell\"][aria-current=\"true\"]{background:var(--dsw-specific-sidebar-nav-item-active) !important;font-weight:500;}",
1408
+ "[class*=\"navCell\"].active [class*=\"navIcon\"],[class*=\"navCell\"][aria-current=\"true\"] [class*=\"navIcon\"]{color:var(--dsw-alias-brand-primary) !important;}",
1409
+ ".ct-select:hover,.ct-select[aria-expanded=\"true\"]{background:var(--dsw-alias-interactive-bg-hover) !important;}",
1410
+ ".ct-menu-item:hover{background:var(--dsw-alias-interactive-bg-hover) !important;}",
1411
+ ".ct-menu-item:active{background:var(--dsw-alias-interactive-bg-active) !important;}",
1412
+ "[class*=\"AppearanceRow_group\"]{display:none !important;}",
1413
+ ":root{--dsw-cool-theme-toast-bg:#ffffff;--dsw-cool-theme-toast-fg:#2e3440;--dsw-cool-theme-toast-border:#e5e9f0;}",
1414
+ "body[data-ds-dark-theme]{--dsw-cool-theme-toast-bg:#3b4252;--dsw-cool-theme-toast-fg:#eceff4;--dsw-cool-theme-toast-border:#4c566a;}",
1415
+ "[class*=\"Toast_toast\"],[class*=\"toast\"],[role=\"alert\"],[data-sonner-toast]{background:var(--dsw-cool-theme-toast-bg) !important;color:var(--dsw-cool-theme-toast-fg) !important;border:1px solid var(--dsw-cool-theme-toast-border, var(--dsw-alias-border-l1)) !important;box-shadow:var(--dsw-shadow-lv3, 0 8px 24px rgba(0,0,0,.12)) !important;}",
1416
+ "body:not([data-ds-dark-theme]) [class*=\"toast\"], body:not([data-ds-dark-theme]) [class*=\"Toast_toast\"], body:not([data-ds-dark-theme]) [data-sonner-toast]{background:#ffffff !important;color:#2e3440 !important;border-color:#e5e9f0 !important;}",
1417
+ "body[data-ds-dark-theme] [class*=\"toast\"], body[data-ds-dark-theme] [class*=\"Toast_toast\"], body[data-ds-dark-theme] [data-sonner-toast]{background:#3b4252 !important;color:#eceff4 !important;border-color:#4c566a !important;}",
1418
+ "[data-sonner-toast]{--normal-bg:var(--dsw-cool-theme-toast-bg) !important;--normal-border:var(--dsw-cool-theme-toast-border) !important;--normal-text:var(--dsw-cool-theme-toast-fg) !important;}",
1419
+ "button[class*=\"Button_primary\"]:hover,button[class*=\"primary\"]:hover{background:var(--dsw-alias-button-primary-hover) !important;color:var(--dsw-alias-label-primary-foreground) !important;}",
1420
+ "button[class*=\"Button_outline\"]:hover{color:var(--dsw-alias-label-primary) !important;}"
1421
+ ].join("\n");
1422
+ const injector = createStyleInjector();
1423
+ const baseDisposer = injector.insert(baseCss);
1424
+ let overrideDispose = null;
1425
+ let fallbackDispose = null;
1426
+ function isValidPreset(v) {
1427
+ return !!v && (v === "native" || v in PRESETS);
1428
+ }
1429
+ function getPreset() {
1430
+ try {
1431
+ const cur = localStorage.getItem(THEME_STORAGE_KEY);
1432
+ if (isValidPreset(cur)) return cur;
1433
+ const legacy = localStorage.getItem(THEME_STORAGE_KEY_LEGACY);
1434
+ if (isValidPreset(legacy)) {
1435
+ try {
1436
+ localStorage.setItem(THEME_STORAGE_KEY, legacy);
1437
+ } catch {}
1438
+ return legacy;
1439
+ }
1440
+ } catch {}
1441
+ return "native";
1442
+ }
1443
+ function applyPreset(id) {
1444
+ try {
1445
+ overrideDispose?.();
1446
+ } catch {}
1447
+ overrideDispose = null;
1448
+ try {
1449
+ fallbackDispose?.();
1450
+ } catch {}
1451
+ fallbackDispose = null;
1452
+ if (id === "native") return;
1453
+ const overrides = buildOverrides(id);
1454
+ if (theme && typeof theme.overrideTokens === "function") try {
1455
+ overrideDispose = theme.overrideTokens("dsh-cool-theme", overrides);
1456
+ return;
1457
+ } catch {}
1458
+ fallbackDispose = injector.insert(buildFullCssFallback(id));
1459
+ }
1460
+ function setPreset(id) {
1461
+ try {
1462
+ localStorage.setItem(THEME_STORAGE_KEY, id);
1463
+ } catch {}
1464
+ applyPreset(id);
1465
+ }
1466
+ try {
1467
+ const init = getPreset();
1468
+ if (init !== "native") applyPreset(init);
1469
+ } catch {}
1470
+ function hideGeneralAppearance() {
1471
+ try {
1472
+ const titles = document.querySelectorAll("[class*=\"AppearanceRow_title\"], [class*=\"title\"]");
1473
+ for (const el of Array.from(titles)) {
1474
+ const txt = (el.textContent || "").trim();
1475
+ if (txt === "外观" || txt === "Appearance" || txt.toLowerCase() === "appearance") {
1476
+ const group = el.closest("[class*=\"AppearanceRow_group\"]") || el.closest("[class*=\"group\"]") || el.parentElement;
1477
+ if (group && group.querySelector("[class*=\"themeCube\"]")) group.style.display = "none";
1478
+ }
1479
+ }
1480
+ const groups = document.querySelectorAll("[class*=\"AppearanceRow_group\"]");
1481
+ for (const g of Array.from(groups)) if (g.querySelector("[class*=\"themeCube\"]")) g.style.display = "none";
1482
+ } catch {}
1483
+ }
1484
+ function fixThemeNavIcon() {
1485
+ try {
1486
+ const cells = document.querySelectorAll("[class*=\"navCell\"]");
1487
+ for (const cell of Array.from(cells)) {
1488
+ const label = cell.querySelector("[class*=\"navLabel\"]");
1489
+ if (!label) continue;
1490
+ const txt = (label.textContent || "").trim();
1491
+ if (txt !== "主题" && txt !== "Theme") continue;
1492
+ const icon = cell.querySelector("svg");
1493
+ if (!icon || icon.dataset.ctPalette === "1") continue;
1494
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
1495
+ svg.setAttribute("class", icon.getAttribute("class") || "");
1496
+ svg.setAttribute("width", "16");
1497
+ svg.setAttribute("height", "16");
1498
+ svg.setAttribute("viewBox", "0 0 24 24");
1499
+ svg.setAttribute("fill", "none");
1500
+ svg.setAttribute("data-ct-palette", "1");
1501
+ const body = document.createElementNS("http://www.w3.org/2000/svg", "path");
1502
+ body.setAttribute("fill", "none");
1503
+ body.setAttribute("stroke", "currentColor");
1504
+ body.setAttribute("stroke-width", "2");
1505
+ body.setAttribute("stroke-linecap", "round");
1506
+ body.setAttribute("stroke-linejoin", "round");
1507
+ body.setAttribute("d", PALETTE_ICON_PATH);
1508
+ svg.appendChild(body);
1509
+ for (const dot of PALETTE_ICON_DOTS) {
1510
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
1511
+ circle.setAttribute("fill", "currentColor");
1512
+ circle.setAttribute("stroke", "none");
1513
+ circle.setAttribute("cx", dot.cx);
1514
+ circle.setAttribute("cy", dot.cy);
1515
+ circle.setAttribute("r", dot.r);
1516
+ svg.appendChild(circle);
1517
+ }
1518
+ icon.replaceWith(svg);
1519
+ }
1520
+ } catch {}
1521
+ }
1522
+ hideGeneralAppearance();
1523
+ fixThemeNavIcon();
1524
+ try {
1525
+ const obs = new MutationObserver(() => {
1526
+ hideGeneralAppearance();
1527
+ fixThemeNavIcon();
1528
+ });
1529
+ obs.observe(document.body, {
1530
+ childList: true,
1531
+ subtree: true
1532
+ });
1533
+ ctx.effect(() => () => obs.disconnect());
1534
+ } catch {}
1535
+ ctx.effect(() => () => {
1536
+ try {
1537
+ baseDisposer();
1538
+ } catch {}
1539
+ try {
1540
+ overrideDispose?.();
1541
+ } catch {}
1542
+ try {
1543
+ fallbackDispose?.();
1544
+ } catch {}
1545
+ try {
1546
+ injector.disposeAll();
1547
+ } catch {}
1548
+ });
1549
+ slots.inject("settings.section", () => {
1550
+ const options = {
1551
+ name: "settings.section",
1552
+ id: "cool-theme",
1553
+ order: 5,
1554
+ label: () => t("nav")
1555
+ };
1556
+ if (locale) options.locale = NS;
1557
+ return slots.register(options, (props) => react.createElement(ThemePanel, {
1558
+ t: props?.t ?? ((key) => zh[key]),
1559
+ theme,
1560
+ getPreset,
1561
+ setPreset
1562
+ }));
1563
+ });
1564
+ }
1565
+ //#endregion
1566
+ //#region src/client/index.ts
1567
+ /**
1568
+ * Client entry for dsh-cool-theme.
1569
+ */
1570
+ const name = "dsh-cool-theme/client";
1571
+ const inject = [
1572
+ "slots",
1573
+ "theme",
1574
+ "locale"
1575
+ ];
1576
+ function apply(ctx) {
1577
+ registerTheme(ctx);
1578
+ }
1579
+ //#endregion
1580
+ exports.apply = apply;
1581
+ exports.inject = inject;
1582
+ exports.name = name;
1583
+ return module.exports;
1584
+ }
1585
+ });