dsh-background-by-model 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -24,12 +24,11 @@ window.__ModuleLoader__.load({
24
24
  pageInterface: "界面",
25
25
  pageModelBg: "模型背景",
26
26
  pageProfile: "配置",
27
- descInterface: "为主界面的各个区域单独调节透明度与模糊,营造空间层次感。这里的设置对所有模型生效",
27
+ descInterface: "为主界面的各个区域单独调节透明度,营造空间层次感。这里的设置对所有模型生效",
28
28
  descModelBg: "每条规则 = 一个匹配串 + 一组背景图与外观。切换模型时,从上往下找第一条匹配串出现在模型名里的规则;都没中就使用第 1 条。一条规则可以放多张图,按你设的节奏轮换",
29
29
  descProfile: "调整壁纸切换效果,并把当前全部规则连同图片导出备份,或从文件一键恢复",
30
30
  uiTitle: "主界面",
31
31
  uiOpacity: "透明度",
32
- uiBlur: "模糊度",
33
32
  uiOpacityBg: "主背景",
34
33
  uiOpacitySide: "左侧栏",
35
34
  uiOpacityCard: "卡片与菜单面板",
@@ -38,6 +37,7 @@ window.__ModuleLoader__.load({
38
37
  uiSop: "设置界面透明度",
39
38
  uiChatRegion: "对话文本框",
40
39
  uiTrajectory: "轨迹页",
40
+ uiPage: "插件页面",
41
41
  uiPreview: "右侧栏",
42
42
  statusUnknownHint: "检测不到时一律使用第 1 条可用规则;切换一次模型或稍等片刻会自动重试",
43
43
  statusSourceDefaultHint: "只读到宿主默认模型,它不是本会话当前选择的模型;本会话的模型选择可用后会自动纠正",
@@ -84,7 +84,7 @@ window.__ModuleLoader__.load({
84
84
  ruleImagePendingHint: "这张图片还没有取到内容,稍后会自己出现(也可以直接替换它)",
85
85
  ruleColor: "主题色",
86
86
  ruleColorNone: "跟随系统主题",
87
- ruleColorNoneHint: "未设颜色时跟随系统主题:界面用宿主的配色,壁纸与各部位的透明度、模糊照旧生效",
87
+ ruleColorNoneHint: "未设颜色时跟随系统主题:界面用宿主的配色,壁纸与各部位的透明度照旧生效",
88
88
  ruleColorPick: "自定义颜色",
89
89
  ruleColorPickHint: "优先从本图取色,取不到就用默认色",
90
90
  ruleColorNoImageHint: "这条规则还没有图片,取不到色:选一个颜色可以只铺主题色,或先添加图片",
@@ -96,8 +96,9 @@ window.__ModuleLoader__.load({
96
96
  ruleLayoutNoImage: "添加图片后可分别设置每张图的布局模式",
97
97
  ruleFramingEdit: "编辑位置",
98
98
  ruleOpacity: "背景透明度",
99
+ ruleBrightness: "背景亮度",
99
100
  ruleBlur: "背景模糊",
100
- ruleBlurHint: "背景模糊作用于壁纸层;界面页里的模糊作用于界面各区域,两者互不影响",
101
+ ruleBlurHint: "这三条滑块都作用于壁纸层;界面页里的透明度作用于界面各区域,两者互不影响",
101
102
  rotTitle: "多图轮换",
102
103
  rotEnable: "轮换这组图",
103
104
  rotNeedTwo: "至少两张图才能轮换",
@@ -194,12 +195,11 @@ window.__ModuleLoader__.load({
194
195
  pageInterface: "Interface",
195
196
  pageModelBg: "Model background",
196
197
  pageProfile: "Profile",
197
- descInterface: "Tune opacity and blur per surface to build depth. These settings are global and apply to every model",
198
+ descInterface: "Tune opacity per surface to build depth. These settings are global and apply to every model",
198
199
  descModelBg: "Each rule is a match string plus a set of wallpapers and one look. On a model switch the list is scanned top-down for the first match string contained in the model name; if nothing hits, rule 1 is used. A rule can hold several images and rotate through them on a rhythm you set",
199
200
  descProfile: "Tune how the wallpaper switches, and back up every rule together with its image — or restore one from a file",
200
201
  uiTitle: "Interface",
201
202
  uiOpacity: "Opacity",
202
- uiBlur: "Blur",
203
203
  uiOpacityBg: "Main background",
204
204
  uiOpacitySide: "Left panel",
205
205
  uiOpacityCard: "Cards & menus",
@@ -208,6 +208,7 @@ window.__ModuleLoader__.load({
208
208
  uiSop: "Settings interface opacity",
209
209
  uiChatRegion: "Conversation text frame",
210
210
  uiTrajectory: "Trajectory view",
211
+ uiPage: "Plugin pages",
211
212
  uiPreview: "Right panel",
212
213
  statusUnknownHint: "Without a detected model rule 1 is always used; switching the model once or waiting a moment retries automatically",
213
214
  statusSourceDefaultHint: "Only the host-wide default model could be read — that is not necessarily this session's selection. It self-corrects once this session's model selection is available.",
@@ -254,7 +255,7 @@ window.__ModuleLoader__.load({
254
255
  ruleImagePendingHint: "This image has no content yet — it appears once it loads; you can also replace it",
255
256
  ruleColor: "Theme color",
256
257
  ruleColorNone: "Follow system theme",
257
- ruleColorNoneHint: "Without a color this rule follows the system theme: the host palette paints the interface while the wallpaper and every opacity/blur slider keep working",
258
+ ruleColorNoneHint: "Without a color this rule follows the system theme: the host palette paints the interface while the wallpaper and every opacity slider keep working",
258
259
  ruleColorPick: "Custom color",
259
260
  ruleColorPickHint: "Extracts from this image when it can, otherwise uses a default color",
260
261
  ruleColorNoImageHint: "This rule has no image to take a color from: pick a color to tint the interface alone, or add an image first",
@@ -266,8 +267,9 @@ window.__ModuleLoader__.load({
266
267
  ruleLayoutNoImage: "Add an image to give each one its own layout mode",
267
268
  ruleFramingEdit: "Edit position",
268
269
  ruleOpacity: "Background opacity",
270
+ ruleBrightness: "Background brightness",
269
271
  ruleBlur: "Background blur",
270
- ruleBlurHint: "Background blur affects the wallpaper layer; the blur on the Interface page affects interface surfaces — they are independent",
272
+ ruleBlurHint: "These three sliders all treat the wallpaper layer; the opacity on the Interface page affects interface surfaces — they are independent",
271
273
  rotTitle: "Image rotation",
272
274
  rotEnable: "Rotate these images",
273
275
  rotNeedTwo: "At least two images are needed to rotate",
@@ -654,37 +656,6 @@ window.__ModuleLoader__.load({
654
656
  code: .81,
655
657
  input: .88
656
658
  };
657
- /**
658
- * Interface blur (px, 0..60), global (Interface page):
659
- * `bg` main background (AppFrame grid)
660
- * `sidebar` sidebar column
661
- * `card` cards/panels (center + details columns, dialog option panels)
662
- * `settings` settings panel
663
- * `chat` conversation text region (message column of the chat view)
664
- * `trajectory` trajectory view surface
665
- * `rightbar` file-preview panel — the right sidebar a file click opens
666
- * `input` input/control surfaces ([data-composer-card], [data-cordis-panel])
667
- */
668
- const PART_BLUR_KEYS = [
669
- "bg",
670
- "sidebar",
671
- "card",
672
- "settings",
673
- "chat",
674
- "trajectory",
675
- "rightbar",
676
- "input"
677
- ];
678
- const DEFAULT_PART_BLURS = {
679
- bg: 0,
680
- sidebar: 0,
681
- card: 0,
682
- settings: 0,
683
- chat: 0,
684
- trajectory: 0,
685
- rightbar: 0,
686
- input: 60
687
- };
688
659
  /** Longest allowed switch duration; 0 is a hard cut. */
689
660
  const TRANSITION_MAX_MS = 3e3;
690
661
  /** Every accepted `effect`, in UI order. */
@@ -805,6 +776,7 @@ window.__ModuleLoader__.load({
805
776
  enabled: true,
806
777
  color,
807
778
  wallpaperOpacity: 1,
779
+ brightness: 100,
808
780
  blur: 0,
809
781
  rotate: defaultRotation()
810
782
  };
@@ -838,6 +810,7 @@ window.__ModuleLoader__.load({
838
810
  enabled: true,
839
811
  color: null,
840
812
  wallpaperOpacity: 1,
813
+ brightness: 100,
841
814
  blur: 0,
842
815
  rotate: defaultRotation()
843
816
  };
@@ -856,12 +829,12 @@ window.__ModuleLoader__.load({
856
829
  return {
857
830
  rules: [blankRule("r1")],
858
831
  opacities: { ...DEFAULT_PART_OPACITIES },
859
- blurs: { ...DEFAULT_PART_BLURS },
860
832
  transition: defaultTransition(),
861
833
  settingsOpacity: 1,
862
834
  chatTextOpacity: DEFAULT_CHAT_TEXT_OPACITY,
863
835
  trajectoryOpacity: DEFAULT_TRAJECTORY_OPACITY,
864
836
  rightbarOpacity: DEFAULT_RIGHTBAR_OPACITY,
837
+ pageOpacity: 0,
865
838
  autoExtract: true,
866
839
  holidays: {
867
840
  enabled: false,
@@ -1048,7 +1021,8 @@ window.__ModuleLoader__.load({
1048
1021
  if (images.length === 0 && !hadList) return null;
1049
1022
  const rotate = normalizeRotation(r.rotate);
1050
1023
  if (images.length < 2) rotate.enabled = false;
1051
- return {
1024
+ const brightness = r.brightness === void 0 ? void 0 : clamp$1(r.brightness, 0, 200, 100);
1025
+ const rule = {
1052
1026
  id,
1053
1027
  images,
1054
1028
  match: typeof r.match === "string" ? r.match : "",
@@ -1058,6 +1032,8 @@ window.__ModuleLoader__.load({
1058
1032
  blur: clamp$1(r.blur, 0, 60, 0),
1059
1033
  rotate
1060
1034
  };
1035
+ if (brightness !== void 0) rule.brightness = brightness;
1036
+ return rule;
1061
1037
  }
1062
1038
  /**
1063
1039
  * Coerce one persisted holiday entry.
@@ -1081,6 +1057,7 @@ window.__ModuleLoader__.load({
1081
1057
  ...base,
1082
1058
  enabled: r.enabled !== false,
1083
1059
  wallpaperOpacity: clamp01(r.wallpaperOpacity, base.wallpaperOpacity),
1060
+ brightness: clamp$1(r.brightness, 0, 200, base.brightness ?? 100),
1084
1061
  blur: clamp$1(r.blur, 0, 60, base.blur),
1085
1062
  images: base.images.map((image) => ({
1086
1063
  slot: image.slot,
@@ -1130,20 +1107,17 @@ window.__ModuleLoader__.load({
1130
1107
  const r = raw ?? {};
1131
1108
  const rules = Array.isArray(r.rules) ? r.rules.map(normalizeRule).filter((x) => x !== null) : [blankRule("r1")];
1132
1109
  const ops = r.opacities ?? {};
1133
- const bl = r.blurs ?? {};
1134
- const blurs = {};
1135
- for (const k of PART_BLUR_KEYS) blurs[k] = clamp$1(bl[k], 0, 60, DEFAULT_PART_BLURS[k]);
1136
1110
  const opacities = {};
1137
1111
  for (const k of PART_OPACITY_KEYS) opacities[k] = clamp01(ops[k], DEFAULT_PART_OPACITIES[k]);
1138
1112
  return {
1139
1113
  rules,
1140
1114
  opacities,
1141
- blurs,
1142
1115
  transition: normalizeTransition(r.transition, legacyFadeMs(r.rules)),
1143
1116
  settingsOpacity: clamp01(r.settingsOpacity, 1),
1144
1117
  chatTextOpacity: clamp01(r.chatTextOpacity, DEFAULT_CHAT_TEXT_OPACITY),
1145
1118
  trajectoryOpacity: clamp01(r.trajectoryOpacity, DEFAULT_TRAJECTORY_OPACITY),
1146
1119
  rightbarOpacity: normalizeRightbarOpacity(r.rightbarOpacity),
1120
+ pageOpacity: clamp01(r.pageOpacity, 0),
1147
1121
  autoExtract: r.autoExtract !== false,
1148
1122
  holidays: normalizeHolidays(r.holidays)
1149
1123
  };
@@ -1356,6 +1330,19 @@ window.__ModuleLoader__.load({
1356
1330
  function rWop() {
1357
1331
  return clamp01(activeRule()?.wallpaperOpacity, 1);
1358
1332
  }
1333
+ /**
1334
+ * Brightness of the wallpaper layer, in percent (100 = the picture exactly as the
1335
+ * file has it).
1336
+ *
1337
+ * Read from the ACTIVE rule like the opacity and blur beside it, and defaulted the
1338
+ * same way: a rule whose `brightness` key is absent — every config written before
1339
+ * the setting existed — is left alone, so an upgrade changes nothing on screen.
1340
+ * The default and the ceiling live in ../schema, so the render layer holds no
1341
+ * numbers of its own (see ./wallpaper's `wpFilter`).
1342
+ */
1343
+ function rBrightness() {
1344
+ return clamp$1(activeRule()?.brightness, 0, 200, 100);
1345
+ }
1359
1346
  function rBl() {
1360
1347
  return clamp$1(activeRule()?.blur, 0, 60, 0);
1361
1348
  }
@@ -1395,12 +1382,6 @@ window.__ModuleLoader__.load({
1395
1382
  for (const k of PART_OPACITY_KEYS) out[k] = clamp01(o[k], DEFAULT_PART_OPACITIES[k]);
1396
1383
  return out;
1397
1384
  }
1398
- function rBlurs() {
1399
- const b = cfg.blurs ?? {};
1400
- const out = {};
1401
- for (const k of PART_BLUR_KEYS) out[k] = clamp$1(b[k], 0, 60, DEFAULT_PART_BLURS[k]);
1402
- return out;
1403
- }
1404
1385
  function rSop() {
1405
1386
  return clamp01(cfg.settingsOpacity, 1);
1406
1387
  }
@@ -1415,6 +1396,10 @@ window.__ModuleLoader__.load({
1415
1396
  const own = cfg.rightbarOpacity;
1416
1397
  return typeof own === "number" && isFinite(own) ? clamp01(own, 1) : rOps().bg;
1417
1398
  }
1399
+ /** Tint behind whatever page the main slot is showing (0 = add nothing at all). */
1400
+ function rPageOpacity() {
1401
+ return clamp01(cfg.pageOpacity, 0);
1402
+ }
1418
1403
  /** Move a possibly-absent partial config into the shape the UI reads. */
1419
1404
  function adoptConfig(raw) {
1420
1405
  cfg = normalizeConfig(raw);
@@ -1670,7 +1655,7 @@ window.__ModuleLoader__.load({
1670
1655
  const d = data;
1671
1656
  const slots = Array.isArray(d.slots) ? d.slots.filter((s) => typeof s === "string") : [];
1672
1657
  const schema = typeof d.schema === "number" && isFinite(d.schema) ? d.schema : null;
1673
- hostShape = schema === null ? "legacy" : schema >= 6 ? "current" : "legacy";
1658
+ hostShape = schema === null ? "legacy" : schema >= 9 ? "current" : "legacy";
1674
1659
  if (hostShape === "legacy") holdWrite();
1675
1660
  return {
1676
1661
  config: d.config,
@@ -3033,13 +3018,9 @@ window.__ModuleLoader__.load({
3033
3018
  }
3034
3019
  }
3035
3020
  const SETTINGS_PANEL_SEL = "[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby]";
3036
- const SETTINGS_STYLE_RULE = `${SETTINGS_PANEL_SEL}{background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));backdrop-filter:var(--dsh-any-blur-settings,none);}html[${THEMED_ATTR}] ${SETTINGS_PANEL_SEL}{--dsw-alias-bg-layer-1:var(--dsh-any-bg-settings-layer-1);--dsw-alias-bg-layer-2:var(--dsh-any-bg-settings-layer-2);--dsw-alias-bg-layer-3:var(--dsh-any-bg-settings-layer-3)}${SETTINGS_PANEL_SEL} .dab-card{backdrop-filter:var(--dsh-any-blur-card-panels,none);-webkit-backdrop-filter:var(--dsh-any-blur-card-panels,none)}`;
3021
+ const SETTINGS_STYLE_RULE = `${SETTINGS_PANEL_SEL}{background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2));}html[${THEMED_ATTR}] ${SETTINGS_PANEL_SEL}{--dsw-alias-bg-layer-1:var(--dsh-any-bg-settings-layer-1);--dsw-alias-bg-layer-2:var(--dsh-any-bg-settings-layer-2);--dsw-alias-bg-layer-3:var(--dsh-any-bg-settings-layer-3)}`;
3037
3022
  const CORDIS_PANEL_SEL = "[data-cordis-panel]";
3038
- const INPUT_BLUR_RULE = `[data-composer-card],${CORDIS_PANEL_SEL}{-webkit-backdrop-filter:var(--dsh-any-input-blur,none);backdrop-filter:var(--dsh-any-input-blur,none)}${CORDIS_PANEL_SEL}{--dsw-specific-menu:var(--dsh-any-op-menu-cordis)!important}`;
3039
- function applyInputBlur(px) {
3040
- if (px > 0) document.documentElement.style.setProperty("--dsh-any-input-blur", `blur(${px}px)`);
3041
- else document.documentElement.style.removeProperty("--dsh-any-input-blur");
3042
- }
3023
+ const INPUT_STYLE_RULE = `${CORDIS_PANEL_SEL}{--dsw-specific-menu:var(--dsh-any-op-menu-cordis)!important}`;
3043
3024
  function applySettingsOverrides(op) {
3044
3025
  const tokens = palette()?.tokens ?? {};
3045
3026
  const root = document.documentElement;
@@ -3232,7 +3213,7 @@ window.__ModuleLoader__.load({
3232
3213
  return paletteFadeInline(animate ? paletteFadeMs() : 0, rTransition().easing);
3233
3214
  }
3234
3215
  const RIGHTBAR_SEL = "div[data-sidebar-right-panel]:not(:has([data-dockkit-content],[data-dockkit-empty]))[data-sidebar-right-open],div[data-sidebar-right-panel] [data-dockkit-content]:not([data-dockkit-float]),div[data-sidebar-right-panel] [data-dockkit-empty]";
3235
- const RIGHTBAR_STYLE_RULE = `${RIGHTBAR_SEL}{background:var(--dsh-any-bg-rightbar,var(--dsw-alias-bg-base))!important}div[data-sidebar-right-panel][data-sidebar-right-open]{-webkit-backdrop-filter:var(--dsh-any-blur-rightbar,none);backdrop-filter:var(--dsh-any-blur-rightbar,none)}`;
3216
+ const RIGHTBAR_STYLE_RULE = `${RIGHTBAR_SEL}{background:var(--dsh-any-bg-rightbar,var(--dsw-alias-bg-base))!important}`;
3236
3217
  /** Paint the file-preview panel's surface from its own slider. */
3237
3218
  function applyRightbarOverrides(op) {
3238
3219
  const root = document.documentElement;
@@ -3243,26 +3224,31 @@ window.__ModuleLoader__.load({
3243
3224
  }
3244
3225
  root.style.setProperty("--dsh-any-bg-rightbar", withAlpha(base, op));
3245
3226
  }
3246
- /** Extra backdrop frost for the file-preview panel (0 = no frost of its own). */
3247
- function applyRightbarBlur(px) {
3248
- if (px > 0) document.documentElement.style.setProperty("--dsh-any-blur-rightbar", `blur(${px}px)`);
3249
- else document.documentElement.style.removeProperty("--dsh-any-blur-rightbar");
3250
- }
3251
3227
  let frameEl = null;
3252
- let sidebarEl = null;
3253
3228
  let centerEl = null;
3254
3229
  let detailsEl = null;
3255
- const PART_BLUR_CLASS = "dab-part-blur";
3256
- const PART_UNDERLAY_CLASS = "dab-part-underlay";
3257
- const PART_BLUR_RULE = `${PART_BLUR_CLASS}{isolation:isolate}.${PART_UNDERLAY_CLASS}{position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;backdrop-filter:var(--dsh-any-part-blur,none);-webkit-backdrop-filter:var(--dsh-any-part-blur,none)}`;
3258
- let partBlurStyleEl = null;
3259
- function ensurePartBlurStyle() {
3260
- if (partBlurStyleEl?.isConnected) return;
3261
- partBlurStyleEl = document.createElement("style");
3262
- partBlurStyleEl.dataset.plugin = "dsh-background-by-model-parts";
3263
- markOwnSheet(partBlurStyleEl);
3264
- partBlurStyleEl.textContent = PART_BLUR_RULE;
3265
- document.head.appendChild(partBlurStyleEl);
3230
+ /** Class-name suffixes the harness's CSS modules end the column names with. */
3231
+ const PART_CLASS = {
3232
+ center: "centerCol",
3233
+ rightbar: "rightbarCol"
3234
+ };
3235
+ /**
3236
+ * Whether one of the element's class names ENDS with `suffix`.
3237
+ *
3238
+ * A SUFFIX test, deliberately not `classList.contains`: the harness emits these
3239
+ * classes from a CSS module, so a column carries `pI_x6G_centerCol` and matching
3240
+ * the whole string `centerCol` is false for every column of every build. The
3241
+ * failure mode is the quiet one — the class never matches, the part falls through
3242
+ * to a weaker guess and a setting disappears without an error.
3243
+ */
3244
+ function hasClassSuffix(el, suffix) {
3245
+ for (const name of Array.from(el.classList)) if (name === suffix || name.endsWith(suffix)) return true;
3246
+ return false;
3247
+ }
3248
+ /** The frame's direct child whose class list carries `suffix` (null when absent). */
3249
+ function childWithClass(frame, suffix) {
3250
+ for (const el of Array.from(frame.children)) if (el instanceof HTMLElement && hasClassSuffix(el, suffix)) return el;
3251
+ return null;
3266
3252
  }
3267
3253
  function discoverParts() {
3268
3254
  const overlay = document.querySelector("[data-shell-overlay]");
@@ -3270,40 +3256,12 @@ window.__ModuleLoader__.load({
3270
3256
  const frame = overlay.parentElement;
3271
3257
  if (frame === null) return;
3272
3258
  frameEl = frame;
3273
- const idx = Array.from(frame.children).indexOf(overlay);
3274
- sidebarEl = frame.children[idx - 3] ?? null;
3275
- centerEl = frame.children[idx - 2] ?? null;
3276
- detailsEl = frame.children[idx - 1] ?? null;
3277
- }
3278
- function setBlur(el, px) {
3279
- if (el === null) return;
3280
- const underlay = el.querySelector(`:scope > .${PART_UNDERLAY_CLASS}`);
3281
- if (px > 0) {
3282
- ensurePartBlurStyle();
3283
- if (!el.classList.contains(PART_BLUR_CLASS) && getComputedStyle(el).position === "static") {
3284
- el.style.position = "relative";
3285
- el.setAttribute("data-dab-pos-patched", "1");
3286
- }
3287
- el.classList.add(PART_BLUR_CLASS);
3288
- if (underlay === null) {
3289
- const node = document.createElement("div");
3290
- node.className = PART_UNDERLAY_CLASS;
3291
- el.prepend(node);
3292
- }
3293
- el.style.setProperty("--dsh-any-part-blur", `blur(${px}px)`);
3294
- } else {
3295
- el.classList.remove(PART_BLUR_CLASS);
3296
- el.style.removeProperty("--dsh-any-part-blur");
3297
- underlay?.remove();
3298
- if (el.getAttribute("data-dab-pos-patched") === "1") {
3299
- el.style.removeProperty("position");
3300
- el.removeAttribute("data-dab-pos-patched");
3301
- }
3302
- }
3303
- }
3304
- function applySettingsBlur(px) {
3305
- if (px > 0) document.documentElement.style.setProperty("--dsh-any-blur-settings", `blur(${px}px)`);
3306
- else document.documentElement.style.removeProperty("--dsh-any-blur-settings");
3259
+ const rightbar = frame.querySelector(":scope > [data-rightbar-col]") ?? childWithClass(frame, PART_CLASS.rightbar);
3260
+ const overlayIdx = Array.from(frame.children).indexOf(overlay);
3261
+ /** The direct child at `offset` relative to the overlay, when there is one. */
3262
+ const at = (offset) => frame.children[overlayIdx + offset] ?? null;
3263
+ centerEl = childWithClass(frame, PART_CLASS.center) ?? at(-2);
3264
+ detailsEl = rightbar ?? at(-1);
3307
3265
  }
3308
3266
  /** Apply the main-background opacity to the center/details columns instead of
3309
3267
  * the frame. The frame's translucent bg-base sits UNDER the sidebar, so
@@ -3332,69 +3290,93 @@ window.__ModuleLoader__.load({
3332
3290
  detailsEl.style.background = withAlpha(base, ops.bg);
3333
3291
  }
3334
3292
  }
3335
- /** Blur of the option panels inside the settings dialog (.dab-card), owned by
3336
- * the "dialog option panel" (card) blur slider. Written as a plugin-owned
3337
- * variable consumed by SETTINGS_STYLE_RULE — deliberately NOT applied to the
3338
- * homepage center/details columns, which this slider must never touch. */
3339
- function applyCardPanelsBlur(px) {
3340
- if (px > 0) document.documentElement.style.setProperty("--dsh-any-blur-card-panels", `blur(${px}px)`);
3341
- else document.documentElement.style.removeProperty("--dsh-any-blur-card-panels");
3293
+ /**
3294
+ * Re-derive every plugin-owned interface surface that is not a palette token:
3295
+ * the conversation view card and the function pages in the main slot.
3296
+ *
3297
+ * ONE pass, run by the full apply and by the frame observer: a page mounts and
3298
+ * unmounts with a NAVIGATION, not with a slider, so its discovery has to happen
3299
+ * on the same beat as everything else. `fade` carries the palette-moved case
3300
+ * through to the inline-painted view card (see `applyCustomTokens`).
3301
+ */
3302
+ function applyInterfaceParts(fade = false) {
3303
+ applyViewCards(fade);
3304
+ applyPageSurfaces();
3342
3305
  }
3343
- /** Apply per-part interface blur to the AppFrame columns + settings panel. */
3344
- function applyPartBlurs(blurs) {
3345
- discoverParts();
3346
- setBlur(frameEl, 0);
3347
- setBlur(sidebarEl, blurs.sidebar);
3348
- setBlur(centerEl, blurs.bg);
3349
- setBlur(detailsEl, blurs.bg);
3350
- applyCardPanelsBlur(blurs.card);
3351
- applySettingsBlur(blurs.settings);
3352
- applyInputBlur(blurs.input);
3353
- applyRightbarBlur(blurs.rightbar);
3354
- applyViewCards();
3355
- }
3356
- /** Live per-part blur update during slider drag (no full re-apply). */
3357
- function setPartBlur(part, v) {
3358
- if (part === "settings") {
3359
- applySettingsBlur(v);
3360
- return;
3361
- }
3362
- if (part === "card") {
3363
- applyCardPanelsBlur(v);
3364
- return;
3365
- }
3366
- if (part === "input") {
3367
- applyInputBlur(v);
3368
- return;
3369
- }
3370
- if (part === "rightbar") {
3371
- applyRightbarBlur(v);
3372
- return;
3373
- }
3374
- if (part === "chat" || part === "trajectory") {
3375
- applyViewCards();
3376
- return;
3306
+ const PAGE_ANCHOR_SEL = "[data-slot=\"main\"]";
3307
+ const PAGE_MARK = "data-dab-page";
3308
+ /**
3309
+ * `!important`, because the page's own background is a class rule of the host's
3310
+ * and equal-specificity cascade order is not something to rely on. The fallback
3311
+ * is the host's own surface token, so a mark that ever outlives its discovery
3312
+ * paints what that page would have painted anyway.
3313
+ */
3314
+ const PAGE_STYLE_RULE = `[${PAGE_MARK}]{background:var(--dsh-any-bg-page,var(--dsw-alias-bg-base))!important}`;
3315
+ /** The elements currently marked — unmarked again at zero or on teardown. */
3316
+ let pageEls = [];
3317
+ /** Every function page mounted in the centre column (empty while the chat is). */
3318
+ function discoverPageEls() {
3319
+ if (centerEl === null || !document.body.contains(centerEl)) return [];
3320
+ const anchor = centerEl.querySelector(`:scope > ${PAGE_ANCHOR_SEL}`) ?? centerEl.querySelector(PAGE_ANCHOR_SEL);
3321
+ if (anchor === null) return [];
3322
+ const seen = /* @__PURE__ */ new Set();
3323
+ const out = [];
3324
+ /** Step through `display:contents` wrappers to the element that owns a box. */
3325
+ const boxed = (start) => {
3326
+ let el = start;
3327
+ for (let depth = 0; depth < 10; depth++) {
3328
+ if (getComputedStyle(el).display !== "contents") return el;
3329
+ const next = el.firstElementChild;
3330
+ if (!(next instanceof HTMLElement) || seen.has(next)) return null;
3331
+ seen.add(next);
3332
+ el = next;
3333
+ }
3334
+ return null;
3335
+ };
3336
+ for (const child of Array.from(anchor.children)) {
3337
+ if (!(child instanceof HTMLElement) || seen.has(child)) continue;
3338
+ seen.add(child);
3339
+ const root = boxed(child);
3340
+ if (root === null || root.querySelector("[data-conversation-scroll]") !== null) continue;
3341
+ out.push(root);
3377
3342
  }
3343
+ return out;
3344
+ }
3345
+ /** Whether a function page is what the centre column is showing. */
3346
+ function pageIsShowing() {
3347
+ return discoverPageEls().length > 0;
3348
+ }
3349
+ /**
3350
+ * Point the 插件页面 item at whatever the main slot is showing.
3351
+ *
3352
+ * Called from `applyInterfaceParts`, the one pass the full apply and the frame
3353
+ * observer both run, and from the item's own drag: a page mounts and unmounts
3354
+ * with a NAVIGATION, not with a slider, so the discovery has to happen on the
3355
+ * same beat as everything else.
3356
+ */
3357
+ function applyPageSurfaces() {
3378
3358
  discoverParts();
3379
- if (part === "bg") {
3380
- setBlur(centerEl, v);
3381
- setBlur(detailsEl, v);
3382
- } else setBlur(sidebarEl, v);
3359
+ const base = palette()?.tokens["--dsw-alias-bg-base"];
3360
+ const op = rPageOpacity();
3361
+ const paint = op > 0 && base !== void 0;
3362
+ if (paint) document.documentElement.style.setProperty("--dsh-any-bg-page", withAlpha(base, op));
3363
+ else document.documentElement.style.removeProperty("--dsh-any-bg-page");
3364
+ const next = paint ? discoverPageEls() : [];
3365
+ for (const el of pageEls) if (!next.includes(el)) el.removeAttribute(PAGE_MARK);
3366
+ for (const el of next) el.setAttribute(PAGE_MARK, "1");
3367
+ pageEls = next;
3368
+ }
3369
+ /** Hand every marked page back to the host untouched (teardown only). */
3370
+ function removePageSurfaces() {
3371
+ for (const el of pageEls) el.removeAttribute(PAGE_MARK);
3372
+ pageEls = [];
3383
3373
  }
3384
3374
  const VIEW_CARDS = [{
3385
3375
  sel: "[data-chat-flow]",
3386
3376
  mark: "data-dab-chat-card",
3387
3377
  prev: "dabChatPrev",
3388
3378
  opacity: rChatTextOpacity,
3389
- blur: () => rBlurs().chat,
3390
3379
  fallback: true
3391
- }, {
3392
- sel: "[data-conversation-composer-overlay]",
3393
- mark: "data-dab-traj-card",
3394
- prev: "dabTrajPrev",
3395
- opacity: rTrajectoryOpacity,
3396
- blur: () => rBlurs().trajectory,
3397
- plain: true
3398
3380
  }];
3399
3381
  const viewTargets = VIEW_CARDS.map(() => null);
3400
3382
  function isScrollableY(el) {
@@ -3436,10 +3418,7 @@ window.__ModuleLoader__.load({
3436
3418
  const marked = centerEl.querySelector(spec.sel);
3437
3419
  const cached = viewTargets[idx];
3438
3420
  if (marked !== null) {
3439
- if (cached !== null && cached !== marked) {
3440
- setBlur(cached, 0);
3441
- restoreCardHost(cached, spec.mark, spec.prev, spec.plain === true);
3442
- }
3421
+ if (cached !== null && cached !== marked) restoreCardHost(cached, spec.mark, spec.prev);
3443
3422
  viewTargets[idx] = marked;
3444
3423
  return marked;
3445
3424
  }
@@ -3447,7 +3426,8 @@ window.__ModuleLoader__.load({
3447
3426
  viewTargets[idx] = null;
3448
3427
  if (spec.fallback !== true) return null;
3449
3428
  if (centerEl.querySelector("[data-conversation-scroll]") !== null) return null;
3450
- if (spec.opacity() <= 0 && spec.blur() <= 0) return null;
3429
+ if (pageIsShowing()) return null;
3430
+ if (spec.opacity() <= 0) return null;
3451
3431
  let best = null;
3452
3432
  let bestArea = 0;
3453
3433
  for (const el of Array.from(centerEl.querySelectorAll("*"))) {
@@ -3469,16 +3449,15 @@ window.__ModuleLoader__.load({
3469
3449
  return refined;
3470
3450
  }
3471
3451
  /** Stash the host's own inline values so teardown restores them exactly. */
3472
- function stashCardPrev(el, prev, plain) {
3452
+ function stashCardPrev(el, prev) {
3473
3453
  const ds = el.dataset;
3474
3454
  ds[prev + "Bg"] = el.style.getPropertyValue("background");
3475
- if (plain) return;
3476
3455
  ds[prev + "Border"] = el.style.getPropertyValue("border");
3477
3456
  ds[prev + "Radius"] = el.style.getPropertyValue("border-radius");
3478
3457
  ds[prev + "Padding"] = el.style.getPropertyValue("padding");
3479
3458
  }
3480
3459
  /** Undo the inline styling, restoring the host's previous inline values. */
3481
- function restoreCardHost(el, mark, prev, plain) {
3460
+ function restoreCardHost(el, mark, prev) {
3482
3461
  if (!el.hasAttribute(mark)) return;
3483
3462
  const ds = el.dataset;
3484
3463
  const restore = (prop, v) => {
@@ -3486,14 +3465,12 @@ window.__ModuleLoader__.load({
3486
3465
  else el.style.removeProperty(prop);
3487
3466
  };
3488
3467
  restore("background", ds[prev + "Bg"]);
3489
- if (!plain) {
3490
- restore("border", ds[prev + "Border"]);
3491
- restore("border-radius", ds[prev + "Radius"]);
3492
- restore("padding", ds[prev + "Padding"]);
3493
- delete ds[prev + "Border"];
3494
- delete ds[prev + "Radius"];
3495
- delete ds[prev + "Padding"];
3496
- }
3468
+ restore("border", ds[prev + "Border"]);
3469
+ restore("border-radius", ds[prev + "Radius"]);
3470
+ restore("padding", ds[prev + "Padding"]);
3471
+ delete ds[prev + "Border"];
3472
+ delete ds[prev + "Radius"];
3473
+ delete ds[prev + "Padding"];
3497
3474
  delete ds[prev + "Bg"];
3498
3475
  el.removeAttribute(mark);
3499
3476
  }
@@ -3501,10 +3478,7 @@ window.__ModuleLoader__.load({
3501
3478
  function removeViewCards() {
3502
3479
  VIEW_CARDS.forEach((spec, i) => {
3503
3480
  const el = viewTargets[i];
3504
- if (el !== null) {
3505
- setBlur(el, 0);
3506
- restoreCardHost(el, spec.mark, spec.prev, spec.plain === true);
3507
- }
3481
+ if (el !== null) restoreCardHost(el, spec.mark, spec.prev);
3508
3482
  viewTargets[i] = null;
3509
3483
  });
3510
3484
  }
@@ -3522,9 +3496,9 @@ window.__ModuleLoader__.load({
3522
3496
  "}"
3523
3497
  ].join("\n");
3524
3498
  let tableFixStyleEl = null;
3525
- /** Toggle the wide-table clamp according to the chat region's opacity & blur. */
3499
+ /** Toggle the wide-table clamp according to the chat region's opacity. */
3526
3500
  function syncTableFix() {
3527
- if (!(rChatTextOpacity() > 0 || rBlurs().chat > 0)) {
3501
+ if (!(rChatTextOpacity() > 0)) {
3528
3502
  if (tableFixStyleEl !== null) {
3529
3503
  tableFixStyleEl.remove();
3530
3504
  tableFixStyleEl = null;
@@ -3539,7 +3513,7 @@ window.__ModuleLoader__.load({
3539
3513
  }
3540
3514
  if (!tableFixStyleEl.isConnected) document.head.appendChild(tableFixStyleEl);
3541
3515
  }
3542
- /** Re-derive the conversation view cards from the current config. */
3516
+ /** Re-derive the conversation view card from the current config. */
3543
3517
  function applyViewCards(fade = false) {
3544
3518
  discoverParts();
3545
3519
  if (centerEl === null) return;
@@ -3548,31 +3522,26 @@ window.__ModuleLoader__.load({
3548
3522
  VIEW_CARDS.forEach((spec, i) => {
3549
3523
  const target = discoverViewTarget(i, spec);
3550
3524
  if (target === null) return;
3551
- const plain = spec.plain === true;
3552
3525
  const opacity = spec.opacity();
3553
- const blurPx = spec.blur();
3554
- if (!plain) {
3555
- if (!target.hasAttribute(spec.mark)) stashCardPrev(target, spec.prev, false);
3556
- const borderAlpha = opacity > 0 ? Math.min(1, opacity * 1.5) : blurPx > 0 ? .35 : 0;
3557
- target.style.transition = transition;
3558
- target.style.background = surface !== void 0 ? withAlpha(surface, opacity) : "transparent";
3559
- target.style.border = surface !== void 0 ? `1px solid ${withAlpha(surface, borderAlpha)}` : "1px solid transparent";
3560
- target.style.borderRadius = "16px";
3561
- target.style.padding = "18px";
3562
- }
3526
+ if (!target.hasAttribute(spec.mark)) stashCardPrev(target, spec.prev);
3527
+ const borderAlpha = opacity > 0 ? Math.min(1, opacity * 1.5) : 0;
3528
+ target.style.transition = transition;
3529
+ target.style.background = surface !== void 0 ? withAlpha(surface, opacity) : "transparent";
3530
+ target.style.border = surface !== void 0 ? `1px solid ${withAlpha(surface, borderAlpha)}` : "1px solid transparent";
3531
+ target.style.borderRadius = "16px";
3532
+ target.style.padding = "18px";
3563
3533
  target.setAttribute(spec.mark, "1");
3564
- setBlur(target, blurPx);
3565
3534
  });
3566
3535
  syncTableFix();
3567
3536
  }
3568
3537
  let partsObserver = null;
3569
- /** Watch for the AppFrame mounting so persisted blurs land even when the shell
3570
- * renders after this plugin's apply. */
3538
+ /** Watch for the AppFrame mounting so persisted opacities land even when the
3539
+ * shell renders after this plugin's apply. */
3571
3540
  function watchParts() {
3572
3541
  if (partsObserver !== null || typeof MutationObserver === "undefined") return;
3573
3542
  partsObserver = new MutationObserver(() => {
3574
- if (frameEl !== null && sidebarEl !== null && centerEl !== null && detailsEl !== null && document.body.contains(frameEl) && viewTargets.every((el) => el !== null && document.body.contains(el))) return;
3575
- applyPartBlurs(rBlurs());
3543
+ if (frameEl !== null && centerEl !== null && detailsEl !== null && document.body.contains(frameEl) && viewTargets.every((el) => el !== null && document.body.contains(el))) return;
3544
+ applyInterfaceParts();
3576
3545
  applyPartOpacities(rOps());
3577
3546
  });
3578
3547
  partsObserver.observe(document.body, {
@@ -3869,11 +3838,34 @@ window.__ModuleLoader__.load({
3869
3838
  });
3870
3839
  fadeTimer = window.setTimeout(() => finishFade(idx), plan.durationMs + 160);
3871
3840
  }
3841
+ /**
3842
+ * The `filter` a wallpaper layer carries, from the active rule's brightness and
3843
+ * blur.
3844
+ *
3845
+ * ONE declaration, because the two are one CSS property: assigning `filter` twice
3846
+ * would leave whichever ran last, so a rule that is both brightened and blurred
3847
+ * would silently lose one of them. Brightness is written first and blur second for
3848
+ * a reason that is visible: blurring a dimmed picture softens the highlights the
3849
+ * dimming just brought down, while dimming an already-blurred one simply darkens
3850
+ * the result — and the order a user reads the sliders in (brightness above blur,
3851
+ * see ModelBgPage) is the order the filter composes in.
3852
+ *
3853
+ * The neutral brightness is LEFT OUT rather than written as `brightness(100%)`.
3854
+ * A layer with neither effect gets `''`, which is what an untouched wallpaper has
3855
+ * always carried, and keeps the layer off the compositor's filter path entirely.
3856
+ */
3857
+ function wpFilter() {
3858
+ const parts = [];
3859
+ const brightness = rBrightness();
3860
+ if (brightness !== 100) parts.push(`brightness(${brightness}%)`);
3861
+ const blur = rBl();
3862
+ if (blur > 0) parts.push(`blur(${blur}px)`);
3863
+ return parts.join(" ");
3864
+ }
3872
3865
  function applyWpEffects() {
3873
3866
  if (wpEl === null || layers === null) return;
3874
3867
  wpEl.style.opacity = String(rWop());
3875
- const blur = rBl();
3876
- const filter = blur > 0 ? `blur(${blur}px)` : "";
3868
+ const filter = wpFilter();
3877
3869
  layers[0].el.style.filter = filter;
3878
3870
  layers[1].el.style.filter = filter;
3879
3871
  }
@@ -3898,8 +3890,7 @@ window.__ModuleLoader__.load({
3898
3890
  applySettingsOverrides(rSop());
3899
3891
  applyTrajectoryOverrides(rTrajectoryOpacity());
3900
3892
  applyRightbarOverrides(rRightbarOpacity());
3901
- applyPartBlurs(rBlurs());
3902
- applyViewCards(paletteMoved);
3893
+ applyInterfaceParts(paletteMoved);
3903
3894
  }
3904
3895
  function teardownWp() {
3905
3896
  dropWpContainer();
@@ -3907,16 +3898,14 @@ window.__ModuleLoader__.load({
3907
3898
  tokenStyleEl?.remove();
3908
3899
  tokenStyleEl = null;
3909
3900
  removeViewCards();
3901
+ removePageSurfaces();
3910
3902
  document.documentElement.removeAttribute(THEMED_ATTR);
3911
3903
  document.body.style.removeProperty("color-scheme");
3912
3904
  clearOwnedSurfaces();
3913
3905
  adoptHostScheme();
3914
3906
  invalidateHostPalette();
3915
- document.documentElement.style.removeProperty("--dsh-any-blur-settings");
3916
- document.documentElement.style.removeProperty("--dsh-any-blur-card-panels");
3917
- document.documentElement.style.removeProperty("--dsh-any-input-blur");
3918
3907
  document.documentElement.style.removeProperty("--dsh-any-bg-rightbar");
3919
- document.documentElement.style.removeProperty("--dsh-any-blur-rightbar");
3908
+ document.documentElement.style.removeProperty("--dsh-any-bg-page");
3920
3909
  for (const v of Object.values(OPACITY_VARS)) document.documentElement.style.removeProperty(v);
3921
3910
  if (tokensRaf !== null) {
3922
3911
  cancelAnimationFrame(tokensRaf);
@@ -3925,10 +3914,6 @@ window.__ModuleLoader__.load({
3925
3914
  pendingOps = null;
3926
3915
  tableFixStyleEl?.remove();
3927
3916
  tableFixStyleEl = null;
3928
- setBlur(frameEl, 0);
3929
- setBlur(sidebarEl, 0);
3930
- setBlur(centerEl, 0);
3931
- setBlur(detailsEl, 0);
3932
3917
  stopWatchingParts();
3933
3918
  }
3934
3919
  //#endregion
@@ -4407,6 +4392,12 @@ window.__ModuleLoader__.load({
4407
4392
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M11 5.6h1.2M11 8h1.2" })
4408
4393
  ]
4409
4394
  });
4395
+ /** A whole page of the main slot — a sheet, not one surface on it. */
4396
+ const PageIcon = ({ size, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Glyph, {
4397
+ size,
4398
+ className,
4399
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3.6 2.2h5.2l3.6 3.6v8H3.6z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M8.8 2.2v3.6h3.6" })]
4400
+ });
4410
4401
  const ChatIcon = ({ size, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Glyph, {
4411
4402
  size,
4412
4403
  className,
@@ -4632,8 +4623,7 @@ window.__ModuleLoader__.load({
4632
4623
  {
4633
4624
  opKey: "code",
4634
4625
  labelKey: "uiOpacityCode",
4635
- Icon: CodeIcon,
4636
- noBlur: true
4626
+ Icon: CodeIcon
4637
4627
  },
4638
4628
  {
4639
4629
  opKey: "input",
@@ -4654,10 +4644,15 @@ window.__ModuleLoader__.load({
4654
4644
  isTrajectory: true,
4655
4645
  labelKey: "uiTrajectory",
4656
4646
  Icon: TrajectoryIcon
4647
+ },
4648
+ {
4649
+ isPage: true,
4650
+ labelKey: "uiPage",
4651
+ Icon: PageIcon
4657
4652
  }
4658
4653
  ];
4659
4654
  function InterfacePage({ p }) {
4660
- const { t, setOps, setBlurs, setSop, setRightbarOpacity } = p;
4655
+ const { t, setOps, setSop, setRightbarOpacity } = p;
4661
4656
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
4662
4657
  className: "dab-head dab-rise",
4663
4658
  style: { "--d": 0 },
@@ -4678,94 +4673,77 @@ window.__ModuleLoader__.load({
4678
4673
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4679
4674
  className: "dab-grid-parts",
4680
4675
  children: PARTS.map((part, i) => {
4681
- const { labelKey, Icon, isSettings, isChat, isTrajectory, isRightbar, noBlur } = part;
4676
+ const { labelKey, Icon, isSettings, isChat, isTrajectory, isRightbar, isPage } = part;
4682
4677
  const opKey = part.opKey;
4683
- const blurKey = isChat ? "chat" : isTrajectory ? "trajectory" : isRightbar ? "rightbar" : isSettings ? "settings" : noBlur ? null : opKey;
4684
- const opacity = isChat ? rChatTextOpacity() : isTrajectory ? rTrajectoryOpacity() : isRightbar ? rRightbarOpacity() : isSettings ? rSop() : rOps()[opKey];
4678
+ const opacity = isChat ? rChatTextOpacity() : isTrajectory ? rTrajectoryOpacity() : isRightbar ? rRightbarOpacity() : isPage ? rPageOpacity() : isSettings ? rSop() : rOps()[opKey];
4685
4679
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4686
4680
  className: "dab-card dab-card-hover dab-rise",
4687
4681
  style: { "--d": i + 1 },
4688
- children: [
4689
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4690
- className: "dab-part-head",
4691
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4692
- className: "dab-part-ico",
4693
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { size: 16 })
4694
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4695
- className: "dab-part-name",
4696
- children: t(labelKey)
4697
- })]
4698
- }),
4699
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
4700
- label: t("uiOpacity"),
4701
- min: 0,
4702
- max: 100,
4703
- step: 1,
4704
- def: Math.round(opacity * 100),
4705
- fmt: (v) => `${v}%`,
4706
- onInput: (v) => {
4707
- const op = v / 100;
4708
- if (isChat) {
4709
- cfg.chatTextOpacity = op;
4710
- applyViewCards();
4711
- } else if (isTrajectory) {
4712
- cfg.trajectoryOpacity = op;
4713
- applyTrajectoryOverrides(op);
4714
- } else if (isRightbar) {
4715
- cfg.rightbarOpacity = op;
4716
- applyRightbarOverrides(op);
4717
- } else if (isSettings) {
4718
- cfg.settingsOpacity = op;
4719
- applySettingsOverrides(op);
4720
- } else {
4721
- const ops = { ...rOps() };
4722
- ops[opKey] = op;
4723
- cfg.opacities = ops;
4724
- applyCustomTokens(ops);
4725
- }
4726
- saveConfig();
4727
- },
4728
- onChange: (v) => {
4729
- const op = v / 100;
4730
- if (isChat) {
4731
- cfg.chatTextOpacity = op;
4732
- applyViewCards();
4733
- saveConfig();
4734
- } else if (isTrajectory) {
4735
- cfg.trajectoryOpacity = op;
4736
- applyTrajectoryOverrides(op);
4737
- saveConfig();
4738
- } else if (isRightbar) setRightbarOpacity(op);
4739
- else if (isSettings) setSop(op);
4740
- else {
4741
- const ops = { ...rOps() };
4742
- ops[opKey] = op;
4743
- setOps(ops);
4744
- }
4682
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4683
+ className: "dab-part-head",
4684
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4685
+ className: "dab-part-ico",
4686
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { size: 16 })
4687
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4688
+ className: "dab-part-name",
4689
+ children: t(labelKey)
4690
+ })]
4691
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
4692
+ label: t("uiOpacity"),
4693
+ min: 0,
4694
+ max: 100,
4695
+ step: 1,
4696
+ def: Math.round(opacity * 100),
4697
+ fmt: (v) => `${v}%`,
4698
+ onInput: (v) => {
4699
+ const op = v / 100;
4700
+ if (isChat) {
4701
+ cfg.chatTextOpacity = op;
4702
+ applyViewCards();
4703
+ } else if (isTrajectory) {
4704
+ cfg.trajectoryOpacity = op;
4705
+ applyTrajectoryOverrides(op);
4706
+ } else if (isRightbar) {
4707
+ cfg.rightbarOpacity = op;
4708
+ applyRightbarOverrides(op);
4709
+ } else if (isPage) {
4710
+ cfg.pageOpacity = op;
4711
+ applyPageSurfaces();
4712
+ } else if (isSettings) {
4713
+ cfg.settingsOpacity = op;
4714
+ applySettingsOverrides(op);
4715
+ } else {
4716
+ const ops = { ...rOps() };
4717
+ ops[opKey] = op;
4718
+ cfg.opacities = ops;
4719
+ applyCustomTokens(ops);
4745
4720
  }
4746
- }),
4747
- blurKey !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
4748
- label: t("uiBlur"),
4749
- min: 0,
4750
- max: 60,
4751
- step: 1,
4752
- def: rBlurs()[blurKey],
4753
- fmt: (v) => `${v}px`,
4754
- onInput: (v) => {
4755
- const blurs = { ...rBlurs() };
4756
- blurs[blurKey] = v;
4757
- cfg.blurs = blurs;
4758
- setPartBlur(blurKey, v);
4721
+ saveConfig();
4722
+ },
4723
+ onChange: (v) => {
4724
+ const op = v / 100;
4725
+ if (isChat) {
4726
+ cfg.chatTextOpacity = op;
4727
+ applyViewCards();
4759
4728
  saveConfig();
4760
- },
4761
- onChange: (v) => {
4762
- const blurs = { ...rBlurs() };
4763
- blurs[blurKey] = v;
4764
- setBlurs(blurs);
4729
+ } else if (isTrajectory) {
4730
+ cfg.trajectoryOpacity = op;
4731
+ applyTrajectoryOverrides(op);
4732
+ saveConfig();
4733
+ } else if (isRightbar) setRightbarOpacity(op);
4734
+ else if (isPage) {
4735
+ cfg.pageOpacity = op;
4736
+ applyPageSurfaces();
4737
+ saveConfig();
4738
+ } else if (isSettings) setSop(op);
4739
+ else {
4740
+ const ops = { ...rOps() };
4741
+ ops[opKey] = op;
4742
+ setOps(ops);
4765
4743
  }
4766
- })
4767
- ]
4768
- }, blurKey ?? opKey);
4744
+ }
4745
+ })]
4746
+ }, opKey ?? labelKey);
4769
4747
  })
4770
4748
  })] });
4771
4749
  }
@@ -6478,6 +6456,15 @@ window.__ModuleLoader__.load({
6478
6456
  fmt: (v) => `${v}%`,
6479
6457
  onChange: (v) => p.setRule(rule.id, { wallpaperOpacity: v / 100 })
6480
6458
  }),
6459
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
6460
+ label: t("ruleBrightness"),
6461
+ min: 0,
6462
+ max: 200,
6463
+ step: 1,
6464
+ def: rule.brightness ?? 100,
6465
+ fmt: (v) => `${v}%`,
6466
+ onChange: (v) => p.setRule(rule.id, { brightness: v })
6467
+ }),
6481
6468
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
6482
6469
  label: t("ruleBlur"),
6483
6470
  min: 0,
@@ -7383,7 +7370,7 @@ window.__ModuleLoader__.load({
7383
7370
  const styleEl = document.createElement("style");
7384
7371
  styleEl.dataset.plugin = "dsh-background-by-model";
7385
7372
  markOwnSheet(styleEl);
7386
- styleEl.textContent = `body[data-ds-dark-theme="${OWN_SCHEME}"]::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}${SETTINGS_STYLE_RULE}${TRAJECTORY_STYLE_RULE}${RIGHTBAR_STYLE_RULE}${INPUT_BLUR_RULE}[data-composer-card] textarea::placeholder,[data-composer-card] input::placeholder,[data-composer-card] [contenteditable]::placeholder,[data-cordis-panel] input::placeholder,[data-cordis-panel] textarea::placeholder,.dab-input::placeholder,.dab-input textarea::placeholder,.dab-input input::placeholder{color:var(--dsh-any-placeholder,var(--dsw-alias-label-caption,#8a8f98))!important;font-style:italic;opacity:.85}`;
7373
+ styleEl.textContent = `body[data-ds-dark-theme="${OWN_SCHEME}"]::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}${SETTINGS_STYLE_RULE}${TRAJECTORY_STYLE_RULE}${RIGHTBAR_STYLE_RULE}${PAGE_STYLE_RULE}${INPUT_STYLE_RULE}[data-composer-card] textarea::placeholder,[data-composer-card] input::placeholder,[data-composer-card] [contenteditable]::placeholder,[data-cordis-panel] input::placeholder,[data-cordis-panel] textarea::placeholder,.dab-input::placeholder,.dab-input textarea::placeholder,.dab-input input::placeholder{color:var(--dsh-any-placeholder,var(--dsw-alias-label-caption,#8a8f98))!important;font-style:italic;opacity:.85}`;
7387
7374
  document.head.appendChild(styleEl);
7388
7375
  ctx.effect(() => () => {
7389
7376
  styleEl?.parentNode?.removeChild(styleEl);
@@ -7858,7 +7845,7 @@ window.__ModuleLoader__.load({
7858
7845
  * left to fail at.
7859
7846
  */
7860
7847
  const applyThemeFile = async (data, wipeFirst) => {
7861
- if (typeof data.version === "number" && data.version > 6) return false;
7848
+ if (typeof data.version === "number" && data.version > 9) return false;
7862
7849
  if (typeof data.config !== "object" || data.config === null) return false;
7863
7850
  if (wipeFirst) {
7864
7851
  await resetStore();
@@ -8153,12 +8140,6 @@ window.__ModuleLoader__.load({
8153
8140
  sync();
8154
8141
  saveConfig();
8155
8142
  },
8156
- setBlurs: (blurs) => {
8157
- cfg.blurs = blurs;
8158
- applyWp();
8159
- sync();
8160
- saveConfig();
8161
- },
8162
8143
  setSop: (v) => {
8163
8144
  cfg.settingsOpacity = v;
8164
8145
  applySettingsOverrides(v);
@@ -8207,7 +8188,7 @@ window.__ModuleLoader__.load({
8207
8188
  if (url !== null) images[slot] = url;
8208
8189
  }
8209
8190
  const payload = {
8210
- version: 6,
8191
+ version: 9,
8211
8192
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
8212
8193
  config: cfg,
8213
8194
  images