@nsnanocat/preference-panes 0.9.6 → 0.9.8

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.
@@ -130,24 +130,24 @@ function element(tag, className, text) {
130
130
  }
131
131
 
132
132
  /**
133
- * 用官方 b-style 组合行布局,不绑定某个 App 内置页面的编译作用域。
134
- * Compose rows with official b-style utilities without private app-page compilation scopes.
133
+ * 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
134
+ * Create a generic settings row whose appearance can be overridden through pp classes.
135
135
  * @template {"div" | "label"} T
136
136
  * @param {T} tag 行元素 / Row element.
137
137
  * @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
138
138
  */
139
139
  function settingRow(tag) {
140
- return element(tag, "pp-row flex_between pd_md bb_1 bc_line_regular bg_bg1");
140
+ return element(tag, "pp-row");
141
141
  }
142
142
 
143
143
  /**
144
- * 搜索、选择和文本控件共用官方输入配色与间距,交互由标准 HTML 控件负责。
145
- * Share official colors and spacing while native HTML controls own input interaction.
144
+ * 为标准 HTML 输入控件添加通用面板类名。
145
+ * Add the generic panel class to a standard HTML input control.
146
146
  * @param {HTMLElement} control 已创建的原生控件 / Existing native control.
147
147
  * @returns {HTMLElement} 输入控件 / Input control.
148
148
  */
149
149
  function fieldControl(control) {
150
- control.classList.add("pp-editor", "bg_bg3", "text1", "pd_sm", "bd_radius_md");
150
+ control.classList.add("pp-editor");
151
151
  return control;
152
152
  }
153
153
 
@@ -213,9 +213,7 @@ function requestConfirmation(host, message) {
213
213
  });
214
214
  }
215
215
 
216
- var styleURLs = ["https://s1.hdslb.com/bfs/seed/jinkela/short/b-style/theme.min.css","https://s1.hdslb.com/bfs/seed/jinkela/short/b-style/b-style.min.css"];
217
-
218
- var defaults = "/* 官方 b-style 负责行布局与配色;本文件只定义面板容器和控件约束。\n * Official b-style owns row layout and colors; this file defines panel containers and control constraints. */\n.pp-panel {\n --pp-text: var(--text1);\n --pp-background: var(--bg2);\n --pp-surface: var(--bg1);\n --pp-border: var(--line_regular);\n --pp-muted: var(--text3);\n --pp-accent: var(--brand_pink);\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n font: inherit;\n border: 0;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n}\n.pp-row {\n min-height: 48px;\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
216
+ var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n.pp-panel {\n --pp-text: #18191c;\n --pp-background: #f6f7f8;\n --pp-surface: #fff;\n --pp-field: #f1f2f3;\n --pp-border: #e3e5e7;\n --pp-muted: #797f87;\n --pp-accent: #1677ff;\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n\n:root[data-theme=\"dark\"] .pp-panel {\n --pp-text: #f1f2f3;\n --pp-background: #0d0e0f;\n --pp-surface: #18191c;\n --pp-field: #2f3238;\n --pp-border: #2f3238;\n --pp-muted: #9499a0;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n padding: 8px 10px;\n font: inherit;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n margin-right: 16px;\n}\n.pp-field-name {\n color: var(--pp-text);\n font-size: 15px;\n}\n.pp-field-description {\n margin-top: 2px;\n color: var(--pp-muted);\n font-size: 12px;\n}\n.pp-group {\n margin-top: 16px;\n}\n.pp-group-title {\n margin: 0 0 8px;\n color: var(--pp-muted);\n font-size: 15px;\n font-weight: 400;\n}\n.pp-row {\n min-height: 48px;\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
219
217
 
220
218
  /**
221
219
  * 标题栏共用三点菜单;Shadow DOM 隔离项目样式,保留继承的主题色。
@@ -1046,17 +1044,17 @@ function mountPanel(root, catalog) {
1046
1044
  const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
1047
1045
  const group = match?.[1] ?? "通用";
1048
1046
  if (!groups.has(group)) {
1049
- const section = element("section", "pp-group mt_md");
1047
+ const section = element("section", "pp-group");
1050
1048
  const rows = element("div", "pp-rows");
1051
- section.append(element("h2", "text3 fs_4 fw_400 mb_sm", group), rows);
1049
+ section.append(element("h2", "pp-group-title", group), rows);
1052
1050
  groups.set(group, rows);
1053
1051
  view.append(section);
1054
1052
  }
1055
1053
  const row = settingRow("div");
1056
1054
  row.classList.add("pp-field");
1057
- const label = element("div", "pp-label flex_col items_start mr_md");
1058
- label.append(element("span", "text1 fs_4", match?.[2] ?? field.name));
1059
- if (field.description) label.append(element("span", "text3 fs_5 mt_2", field.description));
1055
+ const label = element("div", "pp-label");
1056
+ label.append(element("span", "pp-field-name", match?.[2] ?? field.name));
1057
+ if (field.description) label.append(element("span", "pp-field-description", field.description));
1060
1058
  row.append(label);
1061
1059
  const value = values[field.key];
1062
1060
  /**
@@ -1304,8 +1302,8 @@ function mountPanel(root, catalog) {
1304
1302
  }
1305
1303
 
1306
1304
  /**
1307
- * 挂载模块设置页;内置资源只引用官方地址,CSS 输入仅用于该页。
1308
- * Mount the module page with official resource URLs and optional page-specific CSS.
1305
+ * 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
1306
+ * Mount a module page with package defaults and optional module-scoped CSS.
1309
1307
  * @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
1310
1308
  * @param {string} [css] 可选 CSS 正文 / Optional CSS text.
1311
1309
  * @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
@@ -1323,22 +1321,13 @@ function mount(boxjs, css = "") {
1323
1321
  root.id = "preferences";
1324
1322
  document.body.append(root);
1325
1323
  }
1326
- // 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
1327
- // Load remote visual resources separately so network state cannot control page positioning.
1328
- const links = styleURLs.map(url => {
1329
- const link = element("link", "");
1330
- link.rel = "stylesheet";
1331
- link.href = url;
1332
- return link;
1333
- });
1334
1324
  const base = element("style", ""),
1335
1325
  custom = element("style", "");
1336
1326
  base.textContent = defaults;
1337
1327
  custom.textContent = css;
1338
- document.head.append(...links, base, custom);
1328
+ document.head.append(base, custom);
1339
1329
  const previousTitle = document.title;
1340
1330
  const previousTheme = document.documentElement.dataset.theme;
1341
- const previousDark = document.documentElement.classList.contains("bili_dark");
1342
1331
  const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
1343
1332
  const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
1344
1333
  const host = window.frameElement?.ownerDocument.documentElement;
@@ -1350,7 +1339,6 @@ function mount(boxjs, css = "") {
1350
1339
  const syncAppearance = () => {
1351
1340
  const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
1352
1341
  document.documentElement.dataset.theme = theme;
1353
- document.documentElement.classList.toggle("bili_dark", theme === "dark");
1354
1342
  if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
1355
1343
  };
1356
1344
  let observer;
@@ -1371,9 +1359,7 @@ function mount(boxjs, css = "") {
1371
1359
  destroy() {
1372
1360
  observer?.disconnect();
1373
1361
  systemTheme.removeEventListener("change", syncAppearance);
1374
- document.documentElement.classList.toggle("bili_dark", previousDark);
1375
1362
  panel?.destroy();
1376
- for (const link of links) link.remove();
1377
1363
  base.remove();
1378
1364
  custom.remove();
1379
1365
  if (existing) root.replaceChildren();
@@ -9,6 +9,6 @@
9
9
  </head>
10
10
  <body>
11
11
  <main id="preferences"></main>
12
- <script type="module" src="/settings/assets/app.mjs?v=0.9.6"></script>
12
+ <script type="module" src="/settings/assets/app.mjs?v=0.9.8"></script>
13
13
  </body>
14
14
  </html>
@@ -1,6 +1,4 @@
1
- var styleURLs = ["https://s1.hdslb.com/bfs/seed/jinkela/short/b-style/theme.min.css","https://s1.hdslb.com/bfs/seed/jinkela/short/b-style/b-style.min.css"];
2
-
3
- var defaults = "/* 官方 b-style 负责行布局与配色;本文件只定义面板容器和控件约束。\n * Official b-style owns row layout and colors; this file defines panel containers and control constraints. */\n.pp-panel {\n --pp-text: var(--text1);\n --pp-background: var(--bg2);\n --pp-surface: var(--bg1);\n --pp-border: var(--line_regular);\n --pp-muted: var(--text3);\n --pp-accent: var(--brand_pink);\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n font: inherit;\n border: 0;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n}\n.pp-row {\n min-height: 48px;\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
1
+ var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n.pp-panel {\n --pp-text: #18191c;\n --pp-background: #f6f7f8;\n --pp-surface: #fff;\n --pp-field: #f1f2f3;\n --pp-border: #e3e5e7;\n --pp-muted: #797f87;\n --pp-accent: #1677ff;\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n\n:root[data-theme=\"dark\"] .pp-panel {\n --pp-text: #f1f2f3;\n --pp-background: #0d0e0f;\n --pp-surface: #18191c;\n --pp-field: #2f3238;\n --pp-border: #2f3238;\n --pp-muted: #9499a0;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n padding: 8px 10px;\n font: inherit;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n margin-right: 16px;\n}\n.pp-field-name {\n color: var(--pp-text);\n font-size: 15px;\n}\n.pp-field-description {\n margin-top: 2px;\n color: var(--pp-muted);\n font-size: 12px;\n}\n.pp-group {\n margin-top: 16px;\n}\n.pp-group-title {\n margin: 0 0 8px;\n color: var(--pp-muted);\n font-size: 15px;\n font-weight: 400;\n}\n.pp-row {\n min-height: 48px;\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
4
2
 
5
3
  /**
6
4
  * 校验原始路径片段,不进行 URL 编码转换。
@@ -116,24 +114,24 @@ function element(tag, className, text) {
116
114
  }
117
115
 
118
116
  /**
119
- * 用官方 b-style 组合行布局,不绑定某个 App 内置页面的编译作用域。
120
- * Compose rows with official b-style utilities without private app-page compilation scopes.
117
+ * 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
118
+ * Create a generic settings row whose appearance can be overridden through pp classes.
121
119
  * @template {"div" | "label"} T
122
120
  * @param {T} tag 行元素 / Row element.
123
121
  * @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
124
122
  */
125
123
  function settingRow(tag) {
126
- return element(tag, "pp-row flex_between pd_md bb_1 bc_line_regular bg_bg1");
124
+ return element(tag, "pp-row");
127
125
  }
128
126
 
129
127
  /**
130
- * 搜索、选择和文本控件共用官方输入配色与间距,交互由标准 HTML 控件负责。
131
- * Share official colors and spacing while native HTML controls own input interaction.
128
+ * 为标准 HTML 输入控件添加通用面板类名。
129
+ * Add the generic panel class to a standard HTML input control.
132
130
  * @param {HTMLElement} control 已创建的原生控件 / Existing native control.
133
131
  * @returns {HTMLElement} 输入控件 / Input control.
134
132
  */
135
133
  function fieldControl(control) {
136
- control.classList.add("pp-editor", "bg_bg3", "text1", "pd_sm", "bd_radius_md");
134
+ control.classList.add("pp-editor");
137
135
  return control;
138
136
  }
139
137
 
@@ -1028,17 +1026,17 @@ function mountPanel(root, catalog) {
1028
1026
  const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
1029
1027
  const group = match?.[1] ?? "通用";
1030
1028
  if (!groups.has(group)) {
1031
- const section = element("section", "pp-group mt_md");
1029
+ const section = element("section", "pp-group");
1032
1030
  const rows = element("div", "pp-rows");
1033
- section.append(element("h2", "text3 fs_4 fw_400 mb_sm", group), rows);
1031
+ section.append(element("h2", "pp-group-title", group), rows);
1034
1032
  groups.set(group, rows);
1035
1033
  view.append(section);
1036
1034
  }
1037
1035
  const row = settingRow("div");
1038
1036
  row.classList.add("pp-field");
1039
- const label = element("div", "pp-label flex_col items_start mr_md");
1040
- label.append(element("span", "text1 fs_4", match?.[2] ?? field.name));
1041
- if (field.description) label.append(element("span", "text3 fs_5 mt_2", field.description));
1037
+ const label = element("div", "pp-label");
1038
+ label.append(element("span", "pp-field-name", match?.[2] ?? field.name));
1039
+ if (field.description) label.append(element("span", "pp-field-description", field.description));
1042
1040
  row.append(label);
1043
1041
  const value = values[field.key];
1044
1042
  /**
@@ -1286,8 +1284,8 @@ function mountPanel(root, catalog) {
1286
1284
  }
1287
1285
 
1288
1286
  /**
1289
- * 挂载模块设置页;内置资源只引用官方地址,CSS 输入仅用于该页。
1290
- * Mount the module page with official resource URLs and optional page-specific CSS.
1287
+ * 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
1288
+ * Mount a module page with package defaults and optional module-scoped CSS.
1291
1289
  * @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
1292
1290
  * @param {string} [css] 可选 CSS 正文 / Optional CSS text.
1293
1291
  * @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
@@ -1305,22 +1303,13 @@ function mount(boxjs, css = "") {
1305
1303
  root.id = "preferences";
1306
1304
  document.body.append(root);
1307
1305
  }
1308
- // 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
1309
- // Load remote visual resources separately so network state cannot control page positioning.
1310
- const links = styleURLs.map(url => {
1311
- const link = element("link", "");
1312
- link.rel = "stylesheet";
1313
- link.href = url;
1314
- return link;
1315
- });
1316
1306
  const base = element("style", ""),
1317
1307
  custom = element("style", "");
1318
1308
  base.textContent = defaults;
1319
1309
  custom.textContent = css;
1320
- document.head.append(...links, base, custom);
1310
+ document.head.append(base, custom);
1321
1311
  const previousTitle = document.title;
1322
1312
  const previousTheme = document.documentElement.dataset.theme;
1323
- const previousDark = document.documentElement.classList.contains("bili_dark");
1324
1313
  const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
1325
1314
  const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
1326
1315
  const host = window.frameElement?.ownerDocument.documentElement;
@@ -1332,7 +1321,6 @@ function mount(boxjs, css = "") {
1332
1321
  const syncAppearance = () => {
1333
1322
  const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
1334
1323
  document.documentElement.dataset.theme = theme;
1335
- document.documentElement.classList.toggle("bili_dark", theme === "dark");
1336
1324
  if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
1337
1325
  };
1338
1326
  let observer;
@@ -1353,9 +1341,7 @@ function mount(boxjs, css = "") {
1353
1341
  destroy() {
1354
1342
  observer?.disconnect();
1355
1343
  systemTheme.removeEventListener("change", syncAppearance);
1356
- document.documentElement.classList.toggle("bili_dark", previousDark);
1357
1344
  panel?.destroy();
1358
- for (const link of links) link.remove();
1359
1345
  base.remove();
1360
1346
  custom.remove();
1361
1347
  if (existing) root.replaceChildren();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsnanocat/preference-panes",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "description": "Shared settings API runtime for JavaScript proxy modules",
5
5
  "author": "VirgilClyne <Virgil@nanocat.me>",
6
6
  "homepage": "https://NSNanoCat.github.io/preference-panes",
@@ -15,24 +15,24 @@ export function element(tag, className, text) {
15
15
  }
16
16
 
17
17
  /**
18
- * 用官方 b-style 组合行布局,不绑定某个 App 内置页面的编译作用域。
19
- * Compose rows with official b-style utilities without private app-page compilation scopes.
18
+ * 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
19
+ * Create a generic settings row whose appearance can be overridden through pp classes.
20
20
  * @template {"div" | "label"} T
21
21
  * @param {T} tag 行元素 / Row element.
22
22
  * @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
23
23
  */
24
24
  export function settingRow(tag) {
25
- return element(tag, "pp-row flex_between pd_md bb_1 bc_line_regular bg_bg1");
25
+ return element(tag, "pp-row");
26
26
  }
27
27
 
28
28
  /**
29
- * 搜索、选择和文本控件共用官方输入配色与间距,交互由标准 HTML 控件负责。
30
- * Share official colors and spacing while native HTML controls own input interaction.
29
+ * 为标准 HTML 输入控件添加通用面板类名。
30
+ * Add the generic panel class to a standard HTML input control.
31
31
  * @param {HTMLElement} control 已创建的原生控件 / Existing native control.
32
32
  * @returns {HTMLElement} 输入控件 / Input control.
33
33
  */
34
34
  export function fieldControl(control) {
35
- control.classList.add("pp-editor", "bg_bg3", "text1", "pd_sm", "bd_radius_md");
35
+ control.classList.add("pp-editor");
36
36
  return control;
37
37
  }
38
38
 
@@ -1,12 +1,11 @@
1
- import styleURLs from "#style-urls";
2
1
  import defaults from "#styles";
3
2
  import { BoxJS } from "../BoxJS.mjs";
4
3
  import { element, resourceURL } from "./components.mjs";
5
4
  import { mountPanel } from "./panel.mjs";
6
5
 
7
6
  /**
8
- * 挂载模块设置页;内置资源只引用官方地址,CSS 输入仅用于该页。
9
- * Mount the module page with official resource URLs and optional page-specific CSS.
7
+ * 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
8
+ * Mount a module page with package defaults and optional module-scoped CSS.
10
9
  * @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
11
10
  * @param {string} [css] 可选 CSS 正文 / Optional CSS text.
12
11
  * @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
@@ -24,22 +23,13 @@ export function mount(boxjs, css = "") {
24
23
  root.id = "preferences";
25
24
  document.body.append(root);
26
25
  }
27
- // 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
28
- // Load remote visual resources separately so network state cannot control page positioning.
29
- const links = styleURLs.map(url => {
30
- const link = element("link", "");
31
- link.rel = "stylesheet";
32
- link.href = url;
33
- return link;
34
- });
35
26
  const base = element("style", ""),
36
27
  custom = element("style", "");
37
28
  base.textContent = defaults;
38
29
  custom.textContent = css;
39
- document.head.append(...links, base, custom);
30
+ document.head.append(base, custom);
40
31
  const previousTitle = document.title;
41
32
  const previousTheme = document.documentElement.dataset.theme;
42
- const previousDark = document.documentElement.classList.contains("bili_dark");
43
33
  const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
44
34
  const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
45
35
  const host = window.frameElement?.ownerDocument.documentElement;
@@ -51,7 +41,6 @@ export function mount(boxjs, css = "") {
51
41
  const syncAppearance = () => {
52
42
  const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
53
43
  document.documentElement.dataset.theme = theme;
54
- document.documentElement.classList.toggle("bili_dark", theme === "dark");
55
44
  if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
56
45
  };
57
46
  let observer;
@@ -72,9 +61,7 @@ export function mount(boxjs, css = "") {
72
61
  destroy() {
73
62
  observer?.disconnect();
74
63
  systemTheme.removeEventListener("change", syncAppearance);
75
- document.documentElement.classList.toggle("bili_dark", previousDark);
76
64
  panel?.destroy();
77
- for (const link of links) link.remove();
78
65
  base.remove();
79
66
  custom.remove();
80
67
  if (existing) root.replaceChildren();
@@ -1,12 +1,13 @@
1
- /* 官方 b-style 负责行布局与配色;本文件只定义面板容器和控件约束。
2
- * Official b-style owns row layout and colors; this file defines panel containers and control constraints. */
1
+ /* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。
2
+ * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */
3
3
  .pp-panel {
4
- --pp-text: var(--text1);
5
- --pp-background: var(--bg2);
6
- --pp-surface: var(--bg1);
7
- --pp-border: var(--line_regular);
8
- --pp-muted: var(--text3);
9
- --pp-accent: var(--brand_pink);
4
+ --pp-text: #18191c;
5
+ --pp-background: #f6f7f8;
6
+ --pp-surface: #fff;
7
+ --pp-field: #f1f2f3;
8
+ --pp-border: #e3e5e7;
9
+ --pp-muted: #797f87;
10
+ --pp-accent: #1677ff;
10
11
  font:
11
12
  15px / 1.5 -apple-system,
12
13
  BlinkMacSystemFont,
@@ -19,6 +20,15 @@
19
20
  flex-direction: column;
20
21
  height: 100vh;
21
22
  }
23
+
24
+ :root[data-theme="dark"] .pp-panel {
25
+ --pp-text: #f1f2f3;
26
+ --pp-background: #0d0e0f;
27
+ --pp-surface: #18191c;
28
+ --pp-field: #2f3238;
29
+ --pp-border: #2f3238;
30
+ --pp-muted: #9499a0;
31
+ }
22
32
  .pp-panel * {
23
33
  box-sizing: border-box;
24
34
  letter-spacing: 0;
@@ -147,8 +157,12 @@
147
157
  width: 45%;
148
158
  min-width: 0;
149
159
  min-height: 36px;
160
+ padding: 8px 10px;
150
161
  font: inherit;
162
+ color: var(--pp-text);
163
+ background: var(--pp-field);
151
164
  border: 0;
165
+ border-radius: 6px;
152
166
  }
153
167
  .pp-search {
154
168
  width: 100%;
@@ -167,9 +181,37 @@
167
181
  .pp-label {
168
182
  flex: 1;
169
183
  min-width: 0;
184
+ display: flex;
185
+ flex-direction: column;
186
+ align-items: flex-start;
187
+ margin-right: 16px;
188
+ }
189
+ .pp-field-name {
190
+ color: var(--pp-text);
191
+ font-size: 15px;
192
+ }
193
+ .pp-field-description {
194
+ margin-top: 2px;
195
+ color: var(--pp-muted);
196
+ font-size: 12px;
197
+ }
198
+ .pp-group {
199
+ margin-top: 16px;
200
+ }
201
+ .pp-group-title {
202
+ margin: 0 0 8px;
203
+ color: var(--pp-muted);
204
+ font-size: 15px;
205
+ font-weight: 400;
170
206
  }
171
207
  .pp-row {
172
208
  min-height: 48px;
209
+ padding: 16px;
210
+ display: flex;
211
+ align-items: center;
212
+ justify-content: space-between;
213
+ background: var(--pp-surface);
214
+ border-bottom: 1px solid var(--pp-border);
173
215
  }
174
216
  .pp-rows > :last-child {
175
217
  border-bottom: 0 !important;
@@ -236,17 +236,17 @@ export function mountPanel(root, catalog) {
236
236
  const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
237
237
  const group = match?.[1] ?? "通用";
238
238
  if (!groups.has(group)) {
239
- const section = node("section", "pp-group mt_md");
239
+ const section = node("section", "pp-group");
240
240
  const rows = node("div", "pp-rows");
241
- section.append(node("h2", "text3 fs_4 fw_400 mb_sm", group), rows);
241
+ section.append(node("h2", "pp-group-title", group), rows);
242
242
  groups.set(group, rows);
243
243
  view.append(section);
244
244
  }
245
245
  const row = settingRow("div");
246
246
  row.classList.add("pp-field");
247
- const label = node("div", "pp-label flex_col items_start mr_md");
248
- label.append(node("span", "text1 fs_4", match?.[2] ?? field.name));
249
- if (field.description) label.append(node("span", "text3 fs_5 mt_2", field.description));
247
+ const label = node("div", "pp-label");
248
+ label.append(node("span", "pp-field-name", match?.[2] ?? field.name));
249
+ if (field.description) label.append(node("span", "pp-field-description", field.description));
250
250
  row.append(label);
251
251
  const value = values[field.key];
252
252
  /**