dsh-theme-studio 0.2.0 → 0.3.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.
@@ -8,29 +8,28 @@ var zh = {
8
8
  presetHint: "\u9009\u62E9\u4E00\u4E2A\u9884\u8BBE\u914D\u8272\u65B9\u6848",
9
9
  noPreset: "\u65E0\uFF08\u4F7F\u7528\u9ED8\u8BA4\uFF09",
10
10
  accentSection: "\u5F3A\u8C03\u8272",
11
- accentHint: "\u81EA\u5B9A\u4E49\u754C\u9762\u5F3A\u8C03\u8272\uFF0C\u8986\u76D6\u9884\u8BBE\u4E2D\u7684\u5F3A\u8C03\u8272",
12
- accentPlaceholder: "#4B8BBE",
11
+ accentHint: "\u540C\u65F6\u4F5C\u7528\u4E8E\u4E3B\u6309\u94AE\u3001\u94FE\u63A5\u3001\u5BFC\u822A\u9009\u4E2D\u6001\u4E0E\u60AC\u505C\u9AD8\u4EAE",
12
+ accentPlaceholder: "#4d6bfe",
13
+ accentApplying: "\u5F53\u524D\u751F\u6548\uFF1A",
13
14
  darkAccentSection: "\u6697\u8272\u6A21\u5F0F\u5F3A\u8C03\u8272",
14
15
  darkAccentHint: "\u6697\u8272\u6A21\u5F0F\u4E0B\u4F7F\u7528\u7684\u5F3A\u8C03\u8272\uFF0C\u7559\u7A7A\u5219\u6CBF\u7528\u4E0A\u9762\u7684\u989C\u8272",
15
16
  preserveContrast: "\u5DF2\u81EA\u52A8\u63D0\u4EAE\u4EE5\u4FDD\u8BC1\u6697\u8272\u4E0B\u53EF\u8BFB",
17
+ tokenNote: "\u672C\u9762\u677F\u53EA\u5199 dsh \u771F\u5B9E\u5B58\u5728\u7684\u8BBE\u8BA1\u4EE4\u724C\uFF08{count} \u4E2A\uFF0C\u5747\u4ECE dsh \u6837\u5F0F\u8868\u6838\u5B9E\uFF09\u3002dsh \u6309\u7EC4\u4EF6\u786C\u7F16\u7801\u4E86\u5706\u89D2\u4E14\u672A\u63D0\u4F9B\u52A8\u753B\u4EE4\u724C\uFF0C\u56E0\u6B64\u4E0D\u63D0\u4F9B\u5706\u89D2\u8C03\u8282\uFF0C\u52A8\u753B\u5F00\u5173\u6539\u7528\u6837\u5F0F\u8868\u5B9E\u73B0\u3002",
16
18
  densitySection: "\u5BC6\u5EA6",
17
19
  densityCompact: "\u7D27\u51D1",
18
20
  densityComfortable: "\u8212\u9002",
19
21
  densitySpacious: "\u5BBD\u677E",
20
22
  radiusSection: "\u5706\u89D2",
21
- radiusSharp: "\u9510\u5229",
22
- radiusRounded: "\u5706\u89D2",
23
- radiusSoft: "\u67D4\u548C",
24
23
  fontSection: "\u5B57\u4F53",
25
24
  fontSystem: "\u7CFB\u7EDF",
26
25
  fontMono: "\u7B49\u5BBD",
27
26
  fontSerif: "\u886C\u7EBF",
28
27
  customCssSection: "\u81EA\u5B9A\u4E49 CSS",
29
- customCssHint: "\u76F4\u63A5\u8986\u76D6 CSS \u81EA\u5B9A\u4E49\u5C5E\u6027\uFF0C\u6BCF\u884C\u4E00\u4E2A `--property: value;`",
30
- customCssPlaceholder: "--accent: #ff0000;\n--border: 1px solid red;",
28
+ customCssHint: "\u8986\u76D6 dsh \u4EE4\u724C\uFF0C\u6BCF\u884C\u4E00\u4E2A `--dsw-* \u6216 --dsh-*: value;`",
29
+ customCssPlaceholder: "--dsw-alias-brand-primary: #ff0000;\n--dsw-alias-label-primary: #111111;",
31
30
  behaviorSection: "\u884C\u4E3A",
32
31
  animations: "\u754C\u9762\u52A8\u753B",
33
- animationsHint: "\u5173\u95ED\u53EF\u51CF\u5C11\u52A8\u753B\u5E72\u6270\uFF0C\u63D0\u5347\u54CD\u5E94\u901F\u5EA6",
32
+ animationsHint: "\u5173\u95ED\u53EF\u51CF\u5C11\u52A8\u753B\u5E72\u6270\uFF08\u7528\u6837\u5F0F\u8868\u628A\u8FC7\u6E21\u65F6\u957F\u538B\u5230\u8FD1\u96F6\uFF0C\u4E8B\u4EF6\u4ECD\u4F1A\u89E6\u53D1\uFF09",
34
33
  ioSection: "\u5BFC\u5165 / \u5BFC\u51FA",
35
34
  export: "\u5BFC\u51FA\u4E3B\u9898",
36
35
  import: "\u5BFC\u5165\u4E3B\u9898",
@@ -40,18 +39,13 @@ var zh = {
40
39
  importSuccess: "\u4E3B\u9898\u5DF2\u5BFC\u5165",
41
40
  importFailed: "\u5BFC\u5165\u5931\u8D25\uFF1A\u4E0D\u662F\u6709\u6548\u7684\u4E3B\u9898 JSON",
42
41
  exportSuccess: "\u4E3B\u9898\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
43
- exportFailed: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u590D\u5236",
44
- copy: "\u590D\u5236",
42
+ exportFailed: "\u590D\u5236\u5931\u8D25\uFF0C\u5DF2\u586B\u5165\u4E0B\u65B9\u6587\u672C\u6846",
45
43
  preview: "\u9884\u89C8",
46
- apply: "\u5E94\u7528",
47
44
  reset: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4",
48
45
  resetConfirm: "\u786E\u5B9A\u8981\u91CD\u7F6E\u6240\u6709\u4E3B\u9898\u8BBE\u7F6E\u5417\uFF1F",
49
- applied: "\u4E3B\u9898\u5DF2\u5E94\u7528",
50
46
  resetted: "\u5DF2\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u4E3B\u9898",
51
- card: "\u5361\u7247",
52
- button: "\u6309\u94AE",
53
- badge: "\u6807\u7B7E",
54
- text: "\u8FD9\u662F\u4E00\u6BB5\u793A\u4F8B\u6587\u672C\uFF0C\u7528\u4E8E\u9884\u89C8\u4E3B\u9898\u6548\u679C\u3002"
47
+ link: "\u94FE\u63A5",
48
+ text: "\u8FD9\u662F\u4E00\u6BB5\u793A\u4F8B\u6587\u672C\uFF0C\u7528\u4E8E\u9884\u89C8\u5B57\u53F7\u4E0E\u5B57\u4F53\u3002"
55
49
  };
56
50
  var en = {
57
51
  nav: "Theme Studio",
@@ -61,29 +55,29 @@ var en = {
61
55
  presetHint: "Choose a pre-built color scheme",
62
56
  noPreset: "None (use default)",
63
57
  accentSection: "Accent Color",
64
- accentHint: "Custom accent color, overrides the preset",
65
- accentPlaceholder: "#4B8BBE",
58
+ accentHint: "Custom accent color \u2014 drives buttons, links, the active nav item and hover tints",
59
+ accentPlaceholder: "#4d6bfe",
60
+ accentApplying: "Currently applied:",
66
61
  darkAccentSection: "Dark Mode Accent",
67
62
  darkAccentHint: "Accent used in dark mode; leave empty to reuse the color above",
68
63
  preserveContrast: "Lightened automatically for dark-mode readability",
64
+ tokenNote: "This panel only writes design tokens that actually exist in dsh ({count} verified against its stylesheets). dsh hardcodes per-component corner radii and ships no motion tokens, so there is no radius control and the animation toggle is implemented as a stylesheet.",
69
65
  densitySection: "Density",
70
66
  densityCompact: "Compact",
71
67
  densityComfortable: "Comfortable",
72
68
  densitySpacious: "Spacious",
73
69
  radiusSection: "Border Radius",
74
- radiusSharp: "Sharp",
75
- radiusRounded: "Rounded",
76
- radiusSoft: "Soft",
70
+ radiusUnavailable: "dsh ships no radius token, so this cannot be adjusted",
77
71
  fontSection: "Font Family",
78
72
  fontSystem: "System",
79
73
  fontMono: "Monospace",
80
74
  fontSerif: "Serif",
81
75
  customCssSection: "Custom CSS",
82
- customCssHint: "Override CSS custom properties directly, one `--property: value;` per line",
83
- customCssPlaceholder: "--accent: #ff0000;\n--border: 1px solid red;",
76
+ customCssHint: "Override dsh tokens, one `--dsw-* or --dsh-*: value;` per line",
77
+ customCssPlaceholder: "--dsw-alias-brand-primary: #ff0000;\n--dsw-alias-label-primary: #111111;",
84
78
  behaviorSection: "Behavior",
85
79
  animations: "UI Animations",
86
- animationsHint: "Turn off to reduce motion and speed up interaction",
80
+ animationsHint: "Turn off to reduce motion (a stylesheet compresses transition durations to near-zero so events still fire)",
87
81
  ioSection: "Import / Export",
88
82
  export: "Export Theme",
89
83
  import: "Import Theme",
@@ -93,18 +87,13 @@ var en = {
93
87
  importSuccess: "Theme imported",
94
88
  importFailed: "Import failed: not a valid theme JSON",
95
89
  exportSuccess: "Theme copied to clipboard",
96
- exportFailed: "Copy failed, please copy manually",
97
- copy: "Copy",
90
+ exportFailed: "Copy failed \u2014 filled into the box below",
98
91
  preview: "Preview",
99
- apply: "Apply",
100
92
  reset: "Reset to Default",
101
93
  resetConfirm: "Reset all theme settings to default?",
102
- applied: "Theme applied",
103
94
  resetted: "Reset to default theme",
104
- card: "Card",
105
- button: "Button",
106
- badge: "Badge",
107
- text: "This is sample text to preview the theme."
95
+ link: "Link",
96
+ text: "Sample text for previewing size and font family."
108
97
  };
109
98
 
110
99
  // src/client/view.tsx
@@ -116,207 +105,121 @@ var DEFAULT_PREFERENCES = {
116
105
  accentColor: null,
117
106
  darkAccentColor: null,
118
107
  density: "comfortable",
119
- radius: "rounded",
120
108
  fontFamily: "system",
121
109
  animations: true,
122
110
  customCss: ""
123
111
  };
124
112
  var STORAGE_KEY = "dsh-theme-studio";
113
+ var STYLE_ELEMENT_ID = "dsh-theme-studio-overrides";
125
114
 
126
- // src/themes.ts
127
- var PRESETS = [
128
- {
129
- id: "ocean",
130
- name: "Ocean",
131
- description: "Deep blue accent with cool neutrals",
132
- tokens: {
133
- "--accent": "#2563eb",
134
- "--accent-hover": "#1d4ed8",
135
- "--dsw-alias-state-business-primary": "#2563eb",
136
- "--dsw-alias-state-business-secondary": "#dbeafe",
137
- "--dsw-alias-interactive-bg-hover": "rgba(37,99,235,0.08)"
138
- }
139
- },
140
- {
141
- id: "forest",
142
- name: "Forest",
143
- description: "Green accent with earthy neutrals",
144
- tokens: {
145
- "--accent": "#16a34a",
146
- "--accent-hover": "#15803d",
147
- "--dsw-alias-state-business-primary": "#16a34a",
148
- "--dsw-alias-state-business-secondary": "#dcfce7",
149
- "--dsw-alias-interactive-bg-hover": "rgba(22,163,74,0.08)"
150
- }
151
- },
152
- {
153
- id: "sunset",
154
- name: "Sunset",
155
- description: "Warm orange accent with amber highlights",
156
- tokens: {
157
- "--accent": "#ea580c",
158
- "--accent-hover": "#c2410c",
159
- "--dsw-alias-state-business-primary": "#ea580c",
160
- "--dsw-alias-state-business-secondary": "#fed7aa",
161
- "--dsw-alias-interactive-bg-hover": "rgba(234,88,12,0.08)"
162
- }
163
- },
164
- {
165
- id: "monochrome",
166
- name: "Monochrome",
167
- description: "Grayscale only \u2014 no color accent",
168
- tokens: {
169
- "--accent": "#404040",
170
- "--accent-hover": "#262626",
171
- "--dsw-alias-state-business-primary": "#404040",
172
- "--dsw-alias-state-business-secondary": "#e5e5e5",
173
- "--dsw-alias-interactive-bg-hover": "rgba(64,64,64,0.08)"
174
- }
175
- },
176
- {
177
- id: "nord",
178
- name: "Nord",
179
- description: "Frost blue inspired by the Nord palette",
180
- tokens: {
181
- "--accent": "#5e81ac",
182
- "--accent-hover": "#4c6f96",
183
- "--dsw-alias-state-business-primary": "#5e81ac",
184
- "--dsw-alias-state-business-secondary": "#e5ebf1",
185
- "--dsw-alias-interactive-bg-hover": "rgba(94,129,172,0.08)"
186
- }
187
- },
188
- {
189
- id: "dracula",
190
- name: "Dracula",
191
- description: "Purple accent with dark mode flair",
192
- tokens: {
193
- "--accent": "#bd93f9",
194
- "--accent-hover": "#a678e8",
195
- "--dsw-alias-state-business-primary": "#bd93f9",
196
- "--dsw-alias-state-business-secondary": "#3a3a5c",
197
- "--dsw-alias-interactive-bg-hover": "rgba(189,147,249,0.12)"
198
- },
199
- darkTokens: {
200
- "--dsw-alias-state-business-secondary": "#44475a",
201
- "--dsw-alias-interactive-bg-hover": "rgba(189,147,249,0.18)"
202
- }
203
- },
204
- {
205
- id: "gruvbox",
206
- name: "Gruvbox",
207
- description: "Retro groove with warm earthy tones",
208
- tokens: {
209
- "--accent": "#d65d0e",
210
- "--accent-hover": "#cc241d",
211
- "--dsw-alias-state-business-primary": "#d65d0e",
212
- "--dsw-alias-state-business-secondary": "#fabd2f",
213
- "--dsw-alias-interactive-bg-hover": "rgba(214,93,14,0.08)"
214
- },
215
- darkTokens: {
216
- "--accent": "#fe8019",
217
- "--accent-hover": "#fabd2f",
218
- "--dsw-alias-state-business-primary": "#fe8019",
219
- "--dsw-alias-state-business-secondary": "#3c3836"
220
- }
221
- },
222
- {
223
- id: "solarized",
224
- name: "Solarized",
225
- description: "Ethan Schoonover's precision palette",
226
- tokens: {
227
- "--accent": "#268bd2",
228
- "--accent-hover": "#1e6fa8",
229
- "--dsw-alias-state-business-primary": "#268bd2",
230
- "--dsw-alias-state-business-secondary": "#eee8d5",
231
- "--dsw-alias-interactive-bg-hover": "rgba(38,139,210,0.08)"
232
- },
233
- darkTokens: {
234
- "--accent": "#839496",
235
- "--accent-hover": "#93a1a1",
236
- "--dsw-alias-state-business-primary": "#268bd2",
237
- "--dsw-alias-state-business-secondary": "#073642"
238
- }
239
- },
240
- {
241
- id: "tokyo-night",
242
- name: "Tokyo Night",
243
- description: "Inspired by the lights of downtown Tokyo at night",
244
- tokens: {
245
- "--accent": "#7aa2f7",
246
- "--accent-hover": "#6183f0",
247
- "--dsw-alias-state-business-primary": "#7aa2f7",
248
- "--dsw-alias-state-business-secondary": "#bb9af7",
249
- "--dsw-alias-interactive-bg-hover": "rgba(122,162,247,0.08)"
250
- },
251
- darkTokens: {
252
- "--dsw-alias-state-business-secondary": "#1a1b26",
253
- "--dsw-alias-interactive-bg-hover": "rgba(122,162,247,0.15)"
254
- }
255
- },
256
- {
257
- id: "catppuccin",
258
- name: "Catppuccin",
259
- description: "Soothing pastel theme for high contrast",
260
- tokens: {
261
- "--accent": "#89b4fa",
262
- "--accent-hover": "#74a8fc",
263
- "--dsw-alias-state-business-primary": "#89b4fa",
264
- "--dsw-alias-state-business-secondary": "#f5e0dc",
265
- "--dsw-alias-interactive-bg-hover": "rgba(137,180,250,0.08)"
266
- },
267
- darkTokens: {
268
- "--accent": "#cba6f7",
269
- "--accent-hover": "#b48bef",
270
- "--dsw-alias-state-business-primary": "#cba6f7",
271
- "--dsw-alias-state-business-secondary": "#313244",
272
- "--dsw-alias-interactive-bg-hover": "rgba(203,166,247,0.12)"
273
- }
274
- }
115
+ // src/tokens.ts
116
+ var VERIFIED_TOKENS = [
117
+ // Accent / business
118
+ "--dsw-alias-state-business-primary",
119
+ "--dsw-alias-state-business-tertiary",
120
+ "--dsw-alias-brand-primary",
121
+ "--dsw-alias-brand-text",
122
+ "--dsw-alias-link",
123
+ "--dsw-alias-interactive-bg-hover",
124
+ "--dsw-alias-interactive-bg-hover-accent",
125
+ "--dsw-alias-button-primary-fill",
126
+ "--dsw-alias-button-primary-hover",
127
+ // Typography
128
+ "--dsw-font-family",
129
+ "--dsw-font-mono",
130
+ "--dsw-font-xs-13",
131
+ "--dsw-font-xs-strong-13",
132
+ "--dsw-font-xxs-12",
133
+ "--dsw-font-xxxs-11",
134
+ "--dsw-font-s-14",
135
+ "--dsw-font-l-20",
136
+ "--dsh-content-font-size",
137
+ "--dsh-content-font-delta"
275
138
  ];
276
- var DENSITY_TOKENS = {
277
- compact: {
278
- "--dsh-content-font-size": "13px",
279
- "--dsh-spacing-unit": "4px"
280
- },
281
- comfortable: {
282
- "--dsh-content-font-size": "14px",
283
- "--dsh-spacing-unit": "6px"
284
- },
285
- spacious: {
286
- "--dsh-content-font-size": "15px",
287
- "--dsh-spacing-unit": "8px"
139
+ var VERIFIED = new Set(VERIFIED_TOKENS);
140
+ function tint(hex, alpha) {
141
+ const value = hex.trim().replace(/^#/, "");
142
+ let r;
143
+ let g;
144
+ let b;
145
+ if (value.length === 3) {
146
+ r = parseInt(value[0] + value[0], 16);
147
+ g = parseInt(value[1] + value[1], 16);
148
+ b = parseInt(value[2] + value[2], 16);
149
+ } else if (value.length === 6) {
150
+ r = parseInt(value.slice(0, 2), 16);
151
+ g = parseInt(value.slice(2, 4), 16);
152
+ b = parseInt(value.slice(4, 6), 16);
153
+ } else {
154
+ return hex;
288
155
  }
156
+ if ([r, g, b].some((n) => Number.isNaN(n))) return hex;
157
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
158
+ }
159
+ function accentTokens(hex) {
160
+ return {
161
+ "--dsw-alias-state-business-primary": hex,
162
+ "--dsw-alias-state-business-tertiary": tint(hex, 0.12),
163
+ "--dsw-alias-brand-primary": hex,
164
+ "--dsw-alias-brand-text": hex,
165
+ "--dsw-alias-link": hex,
166
+ "--dsw-alias-interactive-bg-hover-accent": tint(hex, 0.1),
167
+ "--dsw-alias-button-primary-fill": hex,
168
+ "--dsw-alias-button-primary-hover": hex
169
+ };
170
+ }
171
+ var DENSITY_TOKENS = {
172
+ compact: { "--dsh-content-font-size": "13px" },
173
+ comfortable: { "--dsh-content-font-size": "14px" },
174
+ spacious: { "--dsh-content-font-size": "15px" }
289
175
  };
290
- var RADIUS_TOKENS = {
291
- sharp: {
292
- "--dsh-radius-small": "2px",
293
- "--dsh-radius-medium": "4px",
294
- "--dsh-radius-large": "6px"
176
+ var FONT_TOKENS = {
177
+ system: {
178
+ "--dsw-font-family": "system-ui, -apple-system, 'Segoe UI', sans-serif",
179
+ "--dsw-font-mono": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace"
295
180
  },
296
- rounded: {
297
- "--dsh-radius-small": "6px",
298
- "--dsh-radius-medium": "10px",
299
- "--dsh-radius-large": "14px"
181
+ mono: {
182
+ "--dsw-font-family": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace",
183
+ "--dsw-font-mono": "'Cascadia Code', 'JetBrains Mono', Consolas, monospace"
300
184
  },
301
- soft: {
302
- "--dsh-radius-small": "10px",
303
- "--dsh-radius-medium": "16px",
304
- "--dsh-radius-large": "22px"
185
+ serif: {
186
+ "--dsw-font-family": "Georgia, 'Times New Roman', serif",
187
+ "--dsw-font-mono": "'Cascadia Code', Consolas, monospace"
305
188
  }
306
189
  };
307
- var FONT_TOKENS = {
308
- system: { "--dsh-font-family": "system-ui, -apple-system, sans-serif" },
309
- mono: { "--dsh-font-family": "'JetBrains Mono', 'Fira Code', monospace" },
310
- serif: { "--dsh-font-family": "'Georgia', 'Times New Roman', serif" }
311
- };
312
- var ANIMATION_ON_TOKENS = {
313
- "--dsh-transition-fast": "0.15s ease",
314
- "--dsh-transition-normal": "0.25s ease"
315
- };
316
- var ANIMATION_OFF_TOKENS = {
317
- "--dsh-transition-fast": "0s",
318
- "--dsh-transition-normal": "0s"
319
- };
190
+ var MOTION_OFF_CSS = `
191
+ *, *::before, *::after {
192
+ transition-duration: 0.001ms !important;
193
+ transition-delay: 0ms !important;
194
+ animation-duration: 0.001ms !important;
195
+ animation-delay: 0ms !important;
196
+ animation-iteration-count: 1 !important;
197
+ scroll-behavior: auto !important;
198
+ }
199
+ `.trim();
200
+
201
+ // src/themes.ts
202
+ function preset(id, name, description, lightAccent, darkAccent) {
203
+ const base = { id, name, description, tokens: accentTokens(lightAccent) };
204
+ if (darkAccent !== void 0 && darkAccent.toLowerCase() !== lightAccent.toLowerCase()) {
205
+ base.darkTokens = accentTokens(darkAccent);
206
+ }
207
+ return base;
208
+ }
209
+ var PRESETS = [
210
+ preset("ocean", "Ocean", "Deep blue, close to dsh default", "#4d6bfe"),
211
+ preset("forest", "Forest", "Calm green", "#16a34a", "#22c55e"),
212
+ preset("sunset", "Sunset", "Warm orange", "#ea580c", "#fb923c"),
213
+ preset("monochrome", "Monochrome", "No color accent at all", "#5c5c5c", "#9e9e9e"),
214
+ preset("nord", "Nord", "Frost blue", "#5e81ac", "#88c0d0"),
215
+ preset("dracula", "Dracula", "Purple, brighter on dark", "#7c5cd6", "#bd93f9"),
216
+ preset("gruvbox", "Gruvbox", "Retro warm earth tones", "#b57614", "#fe8019"),
217
+ preset("solarized", "Solarized", "Schoonover precision palette", "#268bd2", "#5fa8d3"),
218
+ preset("tokyo-night", "Tokyo Night", "City lights blue", "#3d59a1", "#7aa2f7"),
219
+ preset("catppuccin", "Catppuccin", "Soft pastel", "#7287fd", "#cba6f7"),
220
+ preset("rose", "Ros\xE9", "Muted pink", "#b3276b", "#f472b6"),
221
+ preset("ember", "Ember", "Deep red", "#b91c1c", "#ef4444")
222
+ ];
320
223
  function getPreset(id) {
321
224
  return PRESETS.find((p) => p.id === id);
322
225
  }
@@ -332,7 +235,6 @@ function exportTheme(prefs, name) {
332
235
  return JSON.stringify(payload, null, 2);
333
236
  }
334
237
  var DENSITIES = /* @__PURE__ */ new Set(["compact", "comfortable", "spacious"]);
335
- var RADII = /* @__PURE__ */ new Set(["sharp", "rounded", "soft"]);
336
238
  var FONTS = /* @__PURE__ */ new Set(["system", "mono", "serif"]);
337
239
  function asColor(value) {
338
240
  if (typeof value !== "string") return null;
@@ -359,9 +261,6 @@ function parseTheme(raw) {
359
261
  if (typeof source["density"] === "string" && DENSITIES.has(source["density"])) {
360
262
  result.density = source["density"];
361
263
  }
362
- if (typeof source["radius"] === "string" && RADII.has(source["radius"])) {
363
- result.radius = source["radius"];
364
- }
365
264
  if (typeof source["fontFamily"] === "string" && FONTS.has(source["fontFamily"])) {
366
265
  result.fontFamily = source["fontFamily"];
367
266
  }
@@ -419,6 +318,104 @@ function ensureDarkContrast(hex) {
419
318
  return { color: current, adjusted: true };
420
319
  }
421
320
 
321
+ // src/apply.ts
322
+ function themeTarget() {
323
+ if (typeof document === "undefined") return null;
324
+ return document.body ?? null;
325
+ }
326
+ function isDshToken(name) {
327
+ return /^--dsh-\S+$/.test(name) || /^--dsw-\S+$/.test(name);
328
+ }
329
+ function isDarkMode() {
330
+ if (typeof document === "undefined") return false;
331
+ return document.body.hasAttribute("data-ds-dark-theme");
332
+ }
333
+ function observeDarkMode(onChange) {
334
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
335
+ return () => {
336
+ };
337
+ }
338
+ const observer = new MutationObserver(() => onChange(isDarkMode()));
339
+ observer.observe(document.body, {
340
+ attributes: true,
341
+ attributeFilter: ["data-ds-dark-theme"]
342
+ });
343
+ return () => observer.disconnect();
344
+ }
345
+ function resolveAccent(prefs, dark) {
346
+ const chosen = dark ? prefs.darkAccentColor ?? prefs.accentColor : prefs.accentColor;
347
+ if (chosen === null || chosen.trim() === "") return { accent: null, adjusted: false };
348
+ if (!dark) return { accent: chosen, adjusted: false };
349
+ const guarded = ensureDarkContrast(chosen);
350
+ return { accent: guarded.color, adjusted: guarded.adjusted };
351
+ }
352
+ function parseCustomCss(css, allow) {
353
+ const out = {};
354
+ for (const line of css.split("\n")) {
355
+ const match = line.match(/^\s*(--[\w-]+)\s*:\s*([^;{}/*]+?)\s*;?\s*$/);
356
+ if (match === null) continue;
357
+ if (!allow(match[1])) continue;
358
+ out[match[1]] = match[2];
359
+ }
360
+ return out;
361
+ }
362
+ function clearManagedProperties(fullCustomCss = "") {
363
+ const target = themeTarget();
364
+ if (target === null) return;
365
+ const names = /* @__PURE__ */ new Set([
366
+ ...Object.keys(accentTokens("#000000")),
367
+ ...Object.values(DENSITY_TOKENS).flatMap((t) => Object.keys(t)),
368
+ ...Object.values(FONT_TOKENS).flatMap((t) => Object.keys(t))
369
+ ]);
370
+ for (const line of fullCustomCss.split("\n")) {
371
+ const match = line.match(/^\s*(--[\w-]+)\s*:/);
372
+ if (match !== null) names.add(match[1]);
373
+ }
374
+ for (const name of names) target.style.removeProperty(name);
375
+ }
376
+ function motionStylesheet() {
377
+ if (typeof document === "undefined") return null;
378
+ let el = document.getElementById(STYLE_ELEMENT_ID);
379
+ if (el === null) {
380
+ el = document.createElement("style");
381
+ el.id = STYLE_ELEMENT_ID;
382
+ document.head.appendChild(el);
383
+ }
384
+ return el;
385
+ }
386
+ function applyTheme(prefs, dark = isDarkMode()) {
387
+ const target = themeTarget();
388
+ if (target === null) return false;
389
+ clearManagedProperties(prefs.customCss);
390
+ const tokens = {};
391
+ if (prefs.preset !== null) {
392
+ const found = getPreset(prefs.preset);
393
+ if (found !== void 0) {
394
+ Object.assign(tokens, found.tokens);
395
+ if (dark && found.darkTokens !== void 0) Object.assign(tokens, found.darkTokens);
396
+ }
397
+ }
398
+ const { accent, adjusted } = resolveAccent(prefs, dark);
399
+ if (accent !== null) Object.assign(tokens, accentTokens(accent));
400
+ Object.assign(tokens, DENSITY_TOKENS[prefs.density] ?? {});
401
+ Object.assign(tokens, FONT_TOKENS[prefs.fontFamily] ?? {});
402
+ for (const [name, value] of Object.entries(tokens)) {
403
+ target.style.setProperty(name, value);
404
+ }
405
+ const custom = parseCustomCss(prefs.customCss, isDshToken);
406
+ for (const [name, value] of Object.entries(custom)) {
407
+ target.style.setProperty(name, value);
408
+ }
409
+ const sheet = motionStylesheet();
410
+ if (sheet !== null) sheet.textContent = prefs.animations ? "" : MOTION_OFF_CSS;
411
+ return adjusted;
412
+ }
413
+ function resetTheme() {
414
+ clearManagedProperties();
415
+ const sheet = typeof document !== "undefined" ? document.getElementById(STYLE_ELEMENT_ID) : null;
416
+ if (sheet !== null) sheet.textContent = "";
417
+ }
418
+
422
419
  // src/client/ui.tsx
423
420
  import {
424
421
  createContext,
@@ -787,7 +784,7 @@ function ToastProvider({ children }) {
787
784
  fontWeight: 500,
788
785
  boxShadow: "0 6px 20px rgba(0,0,0,0.2)",
789
786
  color: "#fff",
790
- background: t.type === "success" ? T.success : t.type === "error" ? T.error : T.accent,
787
+ background: t.type === "success" ? T.success : t.type === "error" ? T.error : t.type === "warning" ? T.warning : T.accent,
791
788
  maxWidth: 360
792
789
  },
793
790
  children: t.message
@@ -872,21 +869,6 @@ function Field({
872
869
 
873
870
  // src/client/view.tsx
874
871
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
875
- var MANAGED_PROPERTIES = [
876
- "--accent",
877
- "--accent-hover",
878
- "--dsh-content-font-size",
879
- "--dsh-spacing-unit",
880
- "--dsh-radius-small",
881
- "--dsh-radius-medium",
882
- "--dsh-radius-large",
883
- "--dsh-font-family",
884
- "--dsh-transition-fast",
885
- "--dsh-transition-normal",
886
- "--dsw-alias-state-business-primary",
887
- "--dsw-alias-state-business-secondary",
888
- "--dsw-alias-interactive-bg-hover"
889
- ];
890
872
  function loadPreferences() {
891
873
  if (typeof localStorage === "undefined") return { ...DEFAULT_PREFERENCES };
892
874
  try {
@@ -901,71 +883,9 @@ function savePreferences(prefs) {
901
883
  if (typeof localStorage === "undefined") return;
902
884
  localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
903
885
  }
904
- function isDarkMode() {
905
- if (typeof document === "undefined") return false;
906
- return document.body.hasAttribute("data-ds-dark-theme");
907
- }
908
- function observeDarkMode(onChange) {
909
- if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
910
- return () => {
911
- };
912
- }
913
- const observer = new MutationObserver(() => onChange(isDarkMode()));
914
- observer.observe(document.body, { attributes: true, attributeFilter: ["data-ds-dark-theme"] });
915
- return () => observer.disconnect();
916
- }
917
- function resolveTokens(prefs, dark) {
918
- const tokens = {};
919
- let contrastAdjusted = false;
920
- const preset = prefs.preset !== null ? getPreset(prefs.preset) : void 0;
921
- if (preset !== void 0) {
922
- Object.assign(tokens, preset.tokens);
923
- if (dark && preset.darkTokens !== void 0) Object.assign(tokens, preset.darkTokens);
924
- }
925
- const chosenAccent = dark ? prefs.darkAccentColor ?? prefs.accentColor : prefs.accentColor;
926
- if (chosenAccent !== null && chosenAccent.trim() !== "") {
927
- let accent = chosenAccent;
928
- if (dark) {
929
- const guarded = ensureDarkContrast(accent);
930
- accent = guarded.color;
931
- contrastAdjusted = guarded.adjusted;
932
- }
933
- tokens["--accent"] = accent;
934
- }
935
- Object.assign(tokens, DENSITY_TOKENS[prefs.density] ?? {});
936
- Object.assign(tokens, RADIUS_TOKENS[prefs.radius] ?? {});
937
- Object.assign(tokens, FONT_TOKENS[prefs.fontFamily] ?? {});
938
- Object.assign(tokens, prefs.animations ? ANIMATION_ON_TOKENS : ANIMATION_OFF_TOKENS);
939
- return { tokens, contrastAdjusted };
940
- }
941
- function parseCustomCss(css) {
942
- const out = {};
943
- for (const line of css.split("\n")) {
944
- const match = line.match(/^\s*(--[\w-]+)\s*:\s*(.+?)\s*;?\s*$/);
945
- if (match !== null) out[match[1]] = match[2];
946
- }
947
- return out;
948
- }
949
- function applyTheme(prefs, dark = isDarkMode()) {
950
- if (typeof document === "undefined") return false;
951
- const root = document.documentElement;
952
- const { tokens, contrastAdjusted } = resolveTokens(prefs, dark);
953
- const custom = parseCustomCss(prefs.customCss);
954
- const merged = { ...tokens, ...custom };
955
- for (const prop of MANAGED_PROPERTIES) {
956
- if (!(prop in merged)) root.style.removeProperty(prop);
957
- }
958
- for (const [prop, value] of Object.entries(merged)) root.style.setProperty(prop, value);
959
- return contrastAdjusted;
960
- }
961
- function clearTheme() {
962
- if (typeof document === "undefined") return;
963
- const root = document.documentElement;
964
- for (const prop of MANAGED_PROPERTIES) root.style.removeProperty(prop);
965
- }
966
- function PresetCard({ preset, selected, onClick }) {
967
- const accent = preset.tokens["--accent"] ?? "#4B8BBE";
968
- const secondary = preset.tokens["--dsw-alias-state-business-secondary"] ?? "#e5e5e5";
886
+ function PresetCard({ preset: preset2, selected, onClick }) {
887
+ const accent = preset2.tokens["--dsw-alias-state-business-primary"] ?? "#4d6bfe";
888
+ const darkAccent = preset2.darkTokens?.["--dsw-alias-state-business-primary"];
969
889
  return /* @__PURE__ */ jsxs2(
970
890
  "div",
971
891
  {
@@ -974,27 +894,31 @@ function PresetCard({ preset, selected, onClick }) {
974
894
  cursor: "pointer",
975
895
  borderRadius: 10,
976
896
  padding: 12,
977
- border: selected ? "2px solid var(--accent, #4B8BBE)" : "1px solid var(--border, rgba(128,128,128,0.2))",
978
- background: selected ? "rgba(75,139,190,0.06)" : "var(--bg-secondary, rgba(128,128,128,0.04))",
897
+ border: selected ? `2px solid ${accent}` : "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
898
+ background: selected ? "var(--dsw-alias-interactive-bg-hover-accent, rgba(77,107,254,0.08))" : "transparent",
979
899
  transition: "all 0.15s ease"
980
900
  },
981
901
  children: [
982
902
  /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }, children: [
983
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 3 }, children: [
984
- /* @__PURE__ */ jsx2("div", { style: { width: 14, height: 14, borderRadius: "50%", background: accent, border: "1px solid rgba(128,128,128,0.2)" } }),
985
- /* @__PURE__ */ jsx2("div", { style: { width: 14, height: 14, borderRadius: "50%", background: secondary, border: "1px solid rgba(128,128,128,0.2)" } })
903
+ /* @__PURE__ */ jsxs2("span", { style: { display: "flex", gap: 3 }, children: [
904
+ /* @__PURE__ */ jsx2("i", { style: { width: 14, height: 14, borderRadius: "50%", background: accent, display: "block" } }),
905
+ darkAccent !== void 0 && /* @__PURE__ */ jsx2("i", { style: { width: 14, height: 14, borderRadius: "50%", background: darkAccent, display: "block" } })
986
906
  ] }),
987
- /* @__PURE__ */ jsx2("strong", { style: { fontSize: 13 }, children: preset.name }),
988
- preset.darkTokens !== void 0 && /* @__PURE__ */ jsx2(Badge, { color: "info", children: "\u25D0" }),
907
+ /* @__PURE__ */ jsx2("strong", { style: { fontSize: 13 }, children: preset2.name }),
989
908
  selected && /* @__PURE__ */ jsx2(Badge, { color: "success", children: "\u2713" })
990
909
  ] }),
991
- /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.6, lineHeight: 1.4 }, children: preset.description })
910
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.65, lineHeight: 1.4 }, children: preset2.description })
992
911
  ]
993
912
  }
994
913
  );
995
914
  }
996
915
  function Segmented({ value, options, onChange }) {
997
- return /* @__PURE__ */ jsx2("div", { style: { display: "inline-flex", borderRadius: 8, overflow: "hidden", border: "1px solid var(--border, rgba(128,128,128,0.2))" }, children: options.map((opt) => /* @__PURE__ */ jsx2(
916
+ return /* @__PURE__ */ jsx2("div", { style: {
917
+ display: "inline-flex",
918
+ borderRadius: 8,
919
+ overflow: "hidden",
920
+ border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
921
+ }, children: options.map((opt) => /* @__PURE__ */ jsx2(
998
922
  "button",
999
923
  {
1000
924
  type: "button",
@@ -1006,8 +930,8 @@ function Segmented({ value, options, onChange }) {
1006
930
  fontSize: 13,
1007
931
  fontWeight: 500,
1008
932
  fontFamily: "inherit",
1009
- background: value === opt.value ? "var(--accent, #4B8BBE)" : "transparent",
1010
- color: value === opt.value ? "#fff" : "var(--text-primary, inherit)",
933
+ background: value === opt.value ? "var(--dsw-alias-button-primary-fill, #4d6bfe)" : "transparent",
934
+ color: value === opt.value ? "#fff" : "inherit",
1011
935
  transition: "all 0.15s ease"
1012
936
  },
1013
937
  children: opt.label
@@ -1021,9 +945,15 @@ function ColorRow({ value, onChange, placeholder }) {
1021
945
  "input",
1022
946
  {
1023
947
  type: "color",
1024
- value: value ?? "#4B8BBE",
948
+ value: value ?? "#4d6bfe",
1025
949
  onChange: (e) => onChange(e.target.value),
1026
- style: { width: 40, height: 40, cursor: "pointer", borderRadius: 8, border: "1px solid var(--border, rgba(128,128,128,0.2))" }
950
+ style: {
951
+ width: 40,
952
+ height: 40,
953
+ cursor: "pointer",
954
+ borderRadius: 8,
955
+ border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
956
+ }
1027
957
  }
1028
958
  ),
1029
959
  /* @__PURE__ */ jsx2(
@@ -1038,32 +968,113 @@ function ColorRow({ value, onChange, placeholder }) {
1038
968
  value !== null && /* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "sm", onClick: () => onChange(null), children: "\u2715" })
1039
969
  ] });
1040
970
  }
1041
- function PreviewArea({ t, dark }) {
971
+ function PreviewArea({ t, dark, accentApplied }) {
1042
972
  return /* @__PURE__ */ jsx2(
1043
973
  Card,
1044
974
  {
1045
975
  title: t("preview"),
1046
976
  icon: "\u{1F441}",
1047
977
  actions: /* @__PURE__ */ jsx2(Badge, { color: dark ? "info" : "warning", children: dark ? "\u{1F319} dark" : "\u2600 light" }),
1048
- children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 10 }, children: [
1049
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
1050
- /* @__PURE__ */ jsx2(Badge, { color: "info", children: "Info" }),
1051
- /* @__PURE__ */ jsx2(Badge, { color: "success", children: "Success" }),
1052
- /* @__PURE__ */ jsx2(Badge, { color: "warning", children: "Warning" }),
1053
- /* @__PURE__ */ jsx2(Badge, { color: "error", children: "Error" })
978
+ children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
979
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap" }, children: [
980
+ /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
981
+ /* @__PURE__ */ jsx2("i", { style: {
982
+ width: 18,
983
+ height: 18,
984
+ borderRadius: 4,
985
+ display: "block",
986
+ background: "var(--dsw-alias-state-business-primary, #4d6bfe)"
987
+ } }),
988
+ "accent"
989
+ ] }),
990
+ /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
991
+ /* @__PURE__ */ jsx2("i", { style: {
992
+ width: 18,
993
+ height: 18,
994
+ borderRadius: 4,
995
+ display: "block",
996
+ background: "var(--dsw-alias-button-primary-fill, #4d6bfe)"
997
+ } }),
998
+ "button"
999
+ ] }),
1000
+ /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
1001
+ /* @__PURE__ */ jsx2("i", { style: {
1002
+ width: 18,
1003
+ height: 18,
1004
+ borderRadius: 4,
1005
+ display: "block",
1006
+ background: "var(--dsw-alias-label-primary, currentColor)"
1007
+ } }),
1008
+ "label"
1009
+ ] }),
1010
+ /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: 6, fontSize: 12 }, children: [
1011
+ /* @__PURE__ */ jsx2("i", { style: {
1012
+ width: 18,
1013
+ height: 18,
1014
+ borderRadius: 4,
1015
+ display: "block",
1016
+ background: "var(--dsw-alias-bg-layer-1, rgba(128,128,128,0.1))",
1017
+ border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))"
1018
+ } }),
1019
+ "surface"
1020
+ ] })
1054
1021
  ] }),
1055
- /* @__PURE__ */ jsxs2(Card, { children: [
1056
- /* @__PURE__ */ jsx2("div", { style: { fontSize: 13, marginBottom: 8 }, children: t("text") }),
1057
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8 }, children: [
1058
- /* @__PURE__ */ jsx2(Button, { variant: "primary", size: "sm", children: t("button") }),
1059
- /* @__PURE__ */ jsx2(Button, { variant: "secondary", size: "sm", children: "Secondary" }),
1060
- /* @__PURE__ */ jsx2(Button, { variant: "danger", size: "sm", children: "Danger" })
1022
+ /* @__PURE__ */ jsxs2("div", { style: {
1023
+ padding: 12,
1024
+ borderRadius: 10,
1025
+ border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
1026
+ background: "var(--dsw-alias-bg-layer-1, transparent)"
1027
+ }, children: [
1028
+ /* @__PURE__ */ jsx2(
1029
+ "div",
1030
+ {
1031
+ style: {
1032
+ fontSize: "var(--dsh-content-font-size, 14px)",
1033
+ fontFamily: "var(--dsw-font-family, inherit)",
1034
+ marginBottom: 10
1035
+ },
1036
+ children: t("text")
1037
+ }
1038
+ ),
1039
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }, children: [
1040
+ /* @__PURE__ */ jsx2("span", { style: {
1041
+ display: "inline-block",
1042
+ padding: "7px 16px",
1043
+ borderRadius: 7,
1044
+ background: "var(--dsw-alias-button-primary-fill, #4d6bfe)",
1045
+ color: "var(--dsw-alias-label-primary-inverted, #fff)",
1046
+ fontSize: 13
1047
+ }, children: t("button") }),
1048
+ /* @__PURE__ */ jsx2("span", { style: {
1049
+ display: "inline-block",
1050
+ padding: "7px 16px",
1051
+ borderRadius: 7,
1052
+ border: "1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))",
1053
+ fontSize: 13
1054
+ }, children: t("link") }),
1055
+ /* @__PURE__ */ jsx2(
1056
+ "a",
1057
+ {
1058
+ href: "#preview",
1059
+ onClick: (e) => e.preventDefault(),
1060
+ style: { color: "var(--dsw-alias-link, #4d6bfe)", fontSize: 13 },
1061
+ children: t("link")
1062
+ }
1063
+ )
1061
1064
  ] })
1065
+ ] }),
1066
+ accentApplied !== null && /* @__PURE__ */ jsxs2("div", { style: { fontSize: 11, opacity: 0.6, fontFamily: "var(--dsw-font-mono, monospace)" }, children: [
1067
+ t("accentApplying"),
1068
+ " ",
1069
+ accentApplied
1062
1070
  ] })
1063
1071
  ] })
1064
1072
  }
1065
1073
  );
1066
1074
  }
1075
+ function TokenCoverage({ t }) {
1076
+ return /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, lineHeight: 1.5 }, children: t("tokenNote", { count: VERIFIED_TOKENS.length }) });
1077
+ }
1067
1078
  function ThemePanelInner({ t }) {
1068
1079
  const toast = useToast();
1069
1080
  const [prefs, setPrefs] = useState2(loadPreferences);
@@ -1078,11 +1089,14 @@ function ThemePanelInner({ t }) {
1078
1089
  savePreferences(prefs);
1079
1090
  }, [prefs, dark]);
1080
1091
  useEffect2(() => observeDarkMode(setDark), []);
1092
+ useEffect2(() => () => {
1093
+ applyTheme(loadPreferences(), isDarkMode());
1094
+ }, []);
1081
1095
  const update = useCallback2((key, value) => {
1082
1096
  setPrefs((p) => ({ ...p, [key]: value }));
1083
1097
  }, []);
1084
1098
  const handleReset = useCallback2(() => {
1085
- clearTheme();
1099
+ resetTheme();
1086
1100
  setPrefs({ ...DEFAULT_PREFERENCES });
1087
1101
  setConfirmReset(false);
1088
1102
  toast("success", t("resetted"));
@@ -1120,6 +1134,7 @@ function ThemePanelInner({ t }) {
1120
1134
  if (file === void 0) return;
1121
1135
  file.text().then(runImport, () => toast("error", t("importFailed")));
1122
1136
  }, [runImport, t, toast]);
1137
+ const { accent: accentApplied } = resolveAccent(prefs, dark);
1123
1138
  return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 16, maxWidth: 860 }, children: [
1124
1139
  /* @__PURE__ */ jsxs2("header", { style: { display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }, children: [
1125
1140
  /* @__PURE__ */ jsxs2("strong", { style: { fontSize: 15 }, children: [
@@ -1211,7 +1226,7 @@ function ThemePanelInner({ t }) {
1211
1226
  placeholder: t("accentPlaceholder")
1212
1227
  }
1213
1228
  ),
1214
- /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.5, marginTop: 6 }, children: t("accentHint") }),
1229
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, marginTop: 6 }, children: t("accentHint") }),
1215
1230
  /* @__PURE__ */ jsx2("div", { style: { height: 14 } }),
1216
1231
  /* @__PURE__ */ jsx2(Field, { label: t("darkAccentSection"), hint: t("darkAccentHint"), children: /* @__PURE__ */ jsx2(
1217
1232
  ColorRow,
@@ -1239,19 +1254,6 @@ function ThemePanelInner({ t }) {
1239
1254
  ]
1240
1255
  }
1241
1256
  ),
1242
- /* @__PURE__ */ jsx2(SectionTitle, { icon: "\u2B1C", children: t("radiusSection") }),
1243
- /* @__PURE__ */ jsx2(
1244
- Segmented,
1245
- {
1246
- value: prefs.radius,
1247
- onChange: (v) => update("radius", v),
1248
- options: [
1249
- { value: "sharp", label: t("radiusSharp") },
1250
- { value: "rounded", label: t("radiusRounded") },
1251
- { value: "soft", label: t("radiusSoft") }
1252
- ]
1253
- }
1254
- ),
1255
1257
  /* @__PURE__ */ jsx2(SectionTitle, { icon: "\u{1F524}", children: t("fontSection") }),
1256
1258
  /* @__PURE__ */ jsx2(
1257
1259
  Segmented,
@@ -1280,7 +1282,7 @@ function ThemePanelInner({ t }) {
1280
1282
  ),
1281
1283
  /* @__PURE__ */ jsx2("label", { htmlFor: "theme-animations", style: { fontSize: 13, cursor: "pointer" }, children: t("animations") })
1282
1284
  ] }),
1283
- /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.5, marginTop: 6, marginLeft: 26 }, children: t("animationsHint") })
1285
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: 11, opacity: 0.55, marginTop: 6, marginLeft: 26 }, children: t("animationsHint") })
1284
1286
  ] }),
1285
1287
  /* @__PURE__ */ jsx2(SectionTitle, { icon: "\u270F\uFE0F", children: t("customCssSection") }),
1286
1288
  /* @__PURE__ */ jsx2(Card, { children: /* @__PURE__ */ jsx2(Field, { label: t("customCssSection"), hint: t("customCssHint"), children: /* @__PURE__ */ jsx2(
@@ -1292,7 +1294,8 @@ function ThemePanelInner({ t }) {
1292
1294
  rows: 4
1293
1295
  }
1294
1296
  ) }) }),
1295
- /* @__PURE__ */ jsx2(PreviewArea, { t, dark }),
1297
+ /* @__PURE__ */ jsx2(PreviewArea, { t, dark, accentApplied }),
1298
+ /* @__PURE__ */ jsx2(TokenCoverage, { t }),
1296
1299
  confirmReset && /* @__PURE__ */ jsx2(
1297
1300
  ConfirmDialog,
1298
1301
  {