@nsnanocat/preference-panes 1.3.1 → 1.3.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # v1.3.2
2
+
3
+ ### 🐛 Bug Fixes
4
+
5
+ * 默认网页导航的标题排版对齐 DualSubs 官网,共用官网已有字体资源,修复相同字号下文字宽度与行高不一致的问题;表单正文和原生导航保持现状。
6
+ * 返回键与分隔线保持固定位置,没有历史时禁用返回键,修复新标签首次进入与从模块返回后首页品牌横向跳动的问题。
7
+
1
8
  # v1.3.1
2
9
 
3
10
  ### 🆕 New Features
package/README.md CHANGED
@@ -126,6 +126,10 @@ BoxJS app 可声明 `cachePath: "@DualSubs.Composite.Caches"`,必须属于相
126
126
 
127
127
  网页导航沿用 Rspress 2.0.18 `rp-nav` 的布局和滚动视觉规则,不依赖 React 或官网运行时。全宽导航高 64px 加安全区,左右默认 20px,1280px 以上按 1588px 内容基准增加留白。标题靠左,前方只有返回键;有操作时显示菜单按钮,桌面端也保留。导航始终保留 25px 背景模糊;滚动不足 100px 时背景和分隔线透明,达到 100px 后在 200ms 内渐显为 60% 不透明底色,内容可滚动到导航背后。操作菜单的底部弹层、遮罩、取消、键盘及焦点恢复保持共用实现。原生 Bridge 不创建网页导航,品牌 CSS 和原生 MORE 接入继续由项目维护。
128
128
 
129
+ 导航排版以 DualSubs 官网为基准:链接使用 Rspress 的 `1rem`/`600`,文字继承链接样式;导航使用官网的 `1.7` 行高、字体栈及渲染规则。`SF Pro Display` 属于官网主题定制,默认 CSS 的 `@font-face` 直接引用同站已有 `/static/font/SFPRODISPLAYBOLD.21a7ca4497.woff2`,不复制或内嵌字体,也不增加发布资产。该文件声明为正常体 `700`,标题保持 `600`,沿用官网的字体匹配。宿主网站须提供对应字体资源;官网改变字体产物地址时须同步更新引用。表单正文排版与原生 Bridge 保持独立。
130
+
131
+ 返回键和分隔线始终显示;没有可返回的历史时禁用返回键,保持 Logo 与标题的位置稳定,避免新标签首次进入和从模块返回后发生水平移动。
132
+
129
133
  ## 构建与验证
130
134
 
131
135
  ```sh
package/dist/home.html CHANGED
@@ -1644,9 +1644,8 @@ function browserHost({ menu, back }) {
1644
1644
  brandLink.href = state.logoHref ?? "/";
1645
1645
  logo.hidden = !state.logo;
1646
1646
  if (state.logo) image.src = state.logo;
1647
- left.hidden = !state.canGoBack;
1648
1647
  menu.element.hidden = !state.actions.length;
1649
- button.disabled = state.busy;
1648
+ button.disabled = state.busy || !state.canGoBack;
1650
1649
  scroll();
1651
1650
  },
1652
1651
  confirm: message => window.confirm(message),
@@ -1896,7 +1895,7 @@ class PageController {
1896
1895
  }
1897
1896
  }
1898
1897
 
1899
- var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n:root {\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 --pp-warning: #9a6700;\n --pp-host-height: 0px;\n --pp-keyboard-height: 0px;\n}\n.pp-panel {\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 width: 100%;\n max-width: 100vw;\n min-width: 0;\n}\n\n:root[data-theme=\"dark\"] {\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 --pp-warning: #f0b849;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n.pp-viewport {\n min-width: 0;\n}\n.pp-fields,\n.pp-choice-page,\n.pp-settings-page,\n.pp-cache-page {\n box-sizing: border-box;\n min-width: 0;\n padding: calc(12px + var(--pp-host-height)) max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n scroll-padding-bottom: var(--pp-keyboard-height);\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-panel a.pp-choice-link {\n color: var(--pp-accent);\n text-decoration: none;\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 font-size: 16px;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\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-field-warning {\n margin-top: 4px;\n color: var(--pp-warning);\n font-size: 12px;\n overflow-wrap: anywhere;\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-width: 0;\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-status {\n position: absolute;\n inset: 0;\n display: grid;\n place-content: center;\n justify-items: center;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n margin: 0;\n padding: 24px;\n color: var(--pp-muted, GrayText);\n text-align: center;\n background: var(--pp-background, Canvas);\n}\n.pp-viewport > .pp-status {\n position: absolute;\n}\n.pp-status-spinner {\n box-sizing: border-box;\n width: 28px;\n height: 28px;\n border: 3px solid var(--pp-border, #8884);\n border-top-color: var(--pp-accent, AccentColor);\n border-radius: 50%;\n animation: pp-status-spin 0.8s linear infinite;\n}\n.pp-status-message {\n max-width: 100%;\n margin: 0;\n overflow-wrap: anywhere;\n}\n.pp-status-action {\n min-width: 96px;\n min-height: 44px;\n padding: 8px 16px;\n border: 0;\n border-radius: 6px;\n color: var(--pp-text, ButtonText);\n font: inherit;\n cursor: pointer;\n background: var(--pp-surface, ButtonFace);\n}\n@keyframes pp-status-spin {\n to {\n transform: rotate(1turn);\n }\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n\n/* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。\n * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */\n:root.pp-page {\n color-scheme: light dark;\n}\n.pp-page body {\n margin: 0;\n overflow: hidden;\n font:\n 16px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n background: var(--pp-background, Canvas);\n color: var(--pp-text, CanvasText);\n}\n[data-preference-panes-pages] {\n position: relative;\n height: 100vh;\n background: inherit;\n overflow: hidden;\n}\n@supports (height: 100dvh) {\n [data-preference-panes-pages] {\n height: 100dvh;\n }\n}\n.pp-home,\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n position: absolute;\n inset: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--pp-background);\n}\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n z-index: 1;\n box-shadow: -8px 0 24px #00000014;\n}\n.pp-link-page {\n top: var(--pp-host-height);\n}\n.pp-link-page iframe {\n display: block;\n border: 0;\n width: 100%;\n height: 100%;\n background: inherit;\n}\n.pp-host-header {\n box-sizing: border-box;\n position: fixed;\n inset: 0 0 auto;\n z-index: 2;\n display: flex;\n align-items: center;\n height: calc(64px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));\n border-bottom: 1px solid transparent;\n background: transparent;\n -webkit-backdrop-filter: blur(25px);\n backdrop-filter: blur(25px);\n color: var(--pp-text);\n transition:\n background-color 200ms ease-in-out,\n border-color 200ms ease-in-out;\n}\n.pp-host-header.pp-scrolled {\n background: rgba(255, 255, 255, 0.6);\n border-color: var(--pp-border);\n}\n:root[data-theme=\"dark\"] .pp-host-header.pp-scrolled {\n background: rgba(13, 14, 15, 0.6);\n}\n@media (min-width: 1280px) {\n .pp-host-header {\n padding-right: max(20px, calc((100vw - 1588px) / 2));\n padding-left: max(20px, calc((100vw - 1588px) / 2));\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .pp-host-header {\n transition: none;\n }\n}\n.pp-host-brand {\n display: flex;\n align-items: center;\n flex: 1;\n height: 36px;\n min-width: 0;\n margin-right: 8px;\n}\n.pp-host-brand-link {\n display: flex;\n align-items: center;\n height: 100%;\n min-width: 0;\n max-width: 100%;\n color: inherit;\n text-decoration: none;\n transition: opacity 0.3s;\n}\n.pp-host-brand-link:hover {\n opacity: 0.6;\n}\n.pp-host-logo {\n flex: none;\n min-width: 2rem;\n margin-right: 0.25rem;\n}\n.pp-host-logo img {\n display: block;\n height: 1.6rem;\n}\n.pp-host-title {\n min-width: 0;\n text-align: left;\n font-size: 16px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-host-left {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n}\n.pp-host-left::after {\n content: \"\";\n display: inline-block;\n width: 1px;\n height: 24px;\n margin: 0 16px;\n background-color: #0000001f;\n}\n:root[data-theme=\"dark\"] .pp-host-left::after {\n background-color: #5454547a;\n}\n.pp-host-left[hidden] {\n display: none;\n}\n.pp-host-back {\n border: 0;\n border-radius: 18px;\n background: none;\n color: inherit;\n width: 36px;\n height: 36px;\n padding: 8px;\n cursor: pointer;\n transition: background-color 0.2s ease-in-out;\n}\n.pp-host-back svg {\n display: block;\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n}\n.pp-host-back:hover {\n background: #f1f1f1;\n}\n:root[data-theme=\"dark\"] .pp-host-back:hover {\n background: #343a46;\n}\n.pp-host-toast {\n position: fixed;\n z-index: 3;\n bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100% - 48px);\n padding: 10px 18px;\n border-radius: 12px;\n background: #222e;\n color: #fff;\n font-size: 14px;\n text-align: center;\n}\n.pp-host-toast[hidden] {\n display: none;\n}\n.pp-host-error {\n margin: 24px;\n padding: 16px;\n border: 1px solid var(--pp-danger, #e45656);\n border-radius: 12px;\n font-size: 16px;\n overflow-wrap: anywhere;\n}\n\n.pp-home {\n max-width: 1000px;\n margin: auto;\n padding: var(--pp-host-height) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));\n}\n.pp-home-entries {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-around;\n row-gap: 16px;\n padding: 16px 0;\n background: var(--pp-surface);\n}\n.pp-home-item {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 25%;\n min-width: 0;\n padding: 0 4px;\n border: 0;\n background: none;\n color: var(--pp-text);\n font:\n 12px / 1.5 -apple-system,\n sans-serif;\n cursor: pointer;\n text-decoration: none;\n}\n@media (min-width: 500px) {\n .pp-home-item {\n width: calc(100% / 6);\n }\n}\n@media (min-width: 700px) {\n .pp-home-item {\n width: 12.5%;\n }\n}\n.pp-home-icon {\n box-sizing: border-box;\n width: 56px;\n height: 56px;\n padding: 8px;\n border-radius: 50%;\n background: var(--pp-field);\n font-size: 32px;\n line-height: 40px;\n text-align: center;\n}\n.pp-home-icon img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-home-name {\n margin-top: 8px;\n}\n.pp-home-content {\n min-width: 0;\n width: 100%;\n}\n.pp-home-content > span {\n display: block;\n}\n.pp-home-name,\n.pp-home-item [data-module-status] {\n width: 100%;\n overflow: hidden;\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-home-item [data-module-status] {\n min-height: 20px;\n}\n.pp-home-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.pp-home-entries[data-layout=\"list\"] {\n display: block;\n padding: 0;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item {\n flex-direction: row;\n gap: 12px;\n width: 100%;\n padding: 12px 16px;\n font-size: 15px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item + .pp-home-item {\n border-top: 1px solid var(--pp-border);\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-icon {\n flex: none;\n width: 40px;\n height: 40px;\n padding: 4px;\n font-size: 24px;\n line-height: 32px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-name {\n margin-top: 0;\n text-align: left;\n}\n.pp-home-arrow {\n color: var(--pp-muted);\n font-size: 24px;\n}\n.pp-home-footer {\n margin-top: 16px;\n text-align: center;\n white-space: normal;\n}\n.pp-home-footer p {\n margin: 8px 0 0;\n}\n";
1898
+ var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n:root {\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 --pp-warning: #9a6700;\n --pp-host-height: 0px;\n --pp-keyboard-height: 0px;\n}\n.pp-panel {\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 width: 100%;\n max-width: 100vw;\n min-width: 0;\n}\n\n:root[data-theme=\"dark\"] {\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 --pp-warning: #f0b849;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n.pp-viewport {\n min-width: 0;\n}\n.pp-fields,\n.pp-choice-page,\n.pp-settings-page,\n.pp-cache-page {\n box-sizing: border-box;\n min-width: 0;\n padding: calc(12px + var(--pp-host-height)) max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n scroll-padding-bottom: var(--pp-keyboard-height);\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-panel a.pp-choice-link {\n color: var(--pp-accent);\n text-decoration: none;\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 font-size: 16px;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\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-field-warning {\n margin-top: 4px;\n color: var(--pp-warning);\n font-size: 12px;\n overflow-wrap: anywhere;\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-width: 0;\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-status {\n position: absolute;\n inset: 0;\n display: grid;\n place-content: center;\n justify-items: center;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n margin: 0;\n padding: 24px;\n color: var(--pp-muted, GrayText);\n text-align: center;\n background: var(--pp-background, Canvas);\n}\n.pp-viewport > .pp-status {\n position: absolute;\n}\n.pp-status-spinner {\n box-sizing: border-box;\n width: 28px;\n height: 28px;\n border: 3px solid var(--pp-border, #8884);\n border-top-color: var(--pp-accent, AccentColor);\n border-radius: 50%;\n animation: pp-status-spin 0.8s linear infinite;\n}\n.pp-status-message {\n max-width: 100%;\n margin: 0;\n overflow-wrap: anywhere;\n}\n.pp-status-action {\n min-width: 96px;\n min-height: 44px;\n padding: 8px 16px;\n border: 0;\n border-radius: 6px;\n color: var(--pp-text, ButtonText);\n font: inherit;\n cursor: pointer;\n background: var(--pp-surface, ButtonFace);\n}\n@keyframes pp-status-spin {\n to {\n transform: rotate(1turn);\n }\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n\n/* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。\n * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */\n:root.pp-page {\n color-scheme: light dark;\n font-size: 16px;\n}\n.pp-page body {\n margin: 0;\n overflow: hidden;\n font:\n 16px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n background: var(--pp-background, Canvas);\n color: var(--pp-text, CanvasText);\n}\n[data-preference-panes-pages] {\n position: relative;\n height: 100vh;\n background: inherit;\n overflow: hidden;\n}\n@supports (height: 100dvh) {\n [data-preference-panes-pages] {\n height: 100dvh;\n }\n}\n.pp-home,\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n position: absolute;\n inset: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--pp-background);\n}\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n z-index: 1;\n box-shadow: -8px 0 24px #00000014;\n}\n.pp-link-page {\n top: var(--pp-host-height);\n}\n.pp-link-page iframe {\n display: block;\n border: 0;\n width: 100%;\n height: 100%;\n background: inherit;\n}\n/* 网页导航复用宿主官网已有字体;官网更换字体产物时须同步资源地址。\n * The web navigation reuses the host site's existing font; update the URL when its font artifact changes. */\n@font-face {\n font-family: \"SF Pro Display\";\n font-style: normal;\n font-weight: 700;\n src:\n local(\"SF Pro Display\"),\n url(\"/static/font/SFPRODISPLAYBOLD.21a7ca4497.woff2\") format(\"woff2\");\n}\n.pp-host-header {\n box-sizing: border-box;\n position: fixed;\n inset: 0 0 auto;\n z-index: 2;\n display: flex;\n align-items: center;\n height: calc(64px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));\n border-bottom: 1px solid transparent;\n background: transparent;\n -webkit-backdrop-filter: blur(25px);\n backdrop-filter: blur(25px);\n color: var(--pp-text);\n font-family: \"SF Pro Display\", \"Inter var experimental\", \"Inter var\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n line-height: 1.7;\n font-synthesis: style;\n text-rendering: optimizelegibility;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n -webkit-text-size-adjust: 100%;\n transition:\n background-color 200ms ease-in-out,\n border-color 200ms ease-in-out;\n}\n.pp-host-header.pp-scrolled {\n background: rgba(255, 255, 255, 0.6);\n border-color: var(--pp-border);\n}\n:root[data-theme=\"dark\"] .pp-host-header.pp-scrolled {\n background: rgba(13, 14, 15, 0.6);\n}\n@media (min-width: 1280px) {\n .pp-host-header {\n padding-right: max(20px, calc((100vw - 1588px) / 2));\n padding-left: max(20px, calc((100vw - 1588px) / 2));\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .pp-host-header {\n transition: none;\n }\n}\n.pp-host-brand {\n display: flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n margin-right: 8px;\n}\n.pp-host-brand-link {\n display: flex;\n align-items: center;\n height: 100%;\n min-width: 0;\n max-width: 100%;\n color: inherit;\n text-decoration: none;\n font-size: 1rem;\n font-weight: 600;\n transition: opacity 0.3s;\n}\n.pp-host-brand-link:hover {\n opacity: 0.6;\n}\n.pp-host-logo {\n flex: none;\n min-width: 2rem;\n margin-right: 0.25rem;\n}\n.pp-host-logo img {\n display: block;\n height: 1.6rem;\n}\n.pp-host-title {\n min-width: 0;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-host-left {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n}\n.pp-host-left::after {\n content: \"\";\n display: inline-block;\n width: 1px;\n height: 24px;\n margin: 0 16px;\n background-color: #0000001f;\n}\n:root[data-theme=\"dark\"] .pp-host-left::after {\n background-color: #5454547a;\n}\n.pp-host-back {\n border: 0;\n border-radius: 18px;\n background: none;\n color: inherit;\n width: 36px;\n height: 36px;\n padding: 8px;\n cursor: pointer;\n transition: background-color 0.2s ease-in-out;\n}\n.pp-host-back:disabled {\n cursor: default;\n}\n.pp-host-back svg {\n display: block;\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n}\n.pp-host-back:hover {\n background: #f1f1f1;\n}\n:root[data-theme=\"dark\"] .pp-host-back:hover {\n background: #343a46;\n}\n.pp-host-toast {\n position: fixed;\n z-index: 3;\n bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100% - 48px);\n padding: 10px 18px;\n border-radius: 12px;\n background: #222e;\n color: #fff;\n font-size: 14px;\n text-align: center;\n}\n.pp-host-toast[hidden] {\n display: none;\n}\n.pp-host-error {\n margin: 24px;\n padding: 16px;\n border: 1px solid var(--pp-danger, #e45656);\n border-radius: 12px;\n font-size: 16px;\n overflow-wrap: anywhere;\n}\n\n.pp-home {\n max-width: 1000px;\n margin: auto;\n padding: var(--pp-host-height) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));\n}\n.pp-home-entries {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-around;\n row-gap: 16px;\n padding: 16px 0;\n background: var(--pp-surface);\n}\n.pp-home-item {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 25%;\n min-width: 0;\n padding: 0 4px;\n border: 0;\n background: none;\n color: var(--pp-text);\n font:\n 12px / 1.5 -apple-system,\n sans-serif;\n cursor: pointer;\n text-decoration: none;\n}\n@media (min-width: 500px) {\n .pp-home-item {\n width: calc(100% / 6);\n }\n}\n@media (min-width: 700px) {\n .pp-home-item {\n width: 12.5%;\n }\n}\n.pp-home-icon {\n box-sizing: border-box;\n width: 56px;\n height: 56px;\n padding: 8px;\n border-radius: 50%;\n background: var(--pp-field);\n font-size: 32px;\n line-height: 40px;\n text-align: center;\n}\n.pp-home-icon img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-home-name {\n margin-top: 8px;\n}\n.pp-home-content {\n min-width: 0;\n width: 100%;\n}\n.pp-home-content > span {\n display: block;\n}\n.pp-home-name,\n.pp-home-item [data-module-status] {\n width: 100%;\n overflow: hidden;\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-home-item [data-module-status] {\n min-height: 20px;\n}\n.pp-home-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.pp-home-entries[data-layout=\"list\"] {\n display: block;\n padding: 0;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item {\n flex-direction: row;\n gap: 12px;\n width: 100%;\n padding: 12px 16px;\n font-size: 15px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item + .pp-home-item {\n border-top: 1px solid var(--pp-border);\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-icon {\n flex: none;\n width: 40px;\n height: 40px;\n padding: 4px;\n font-size: 24px;\n line-height: 32px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-name {\n margin-top: 0;\n text-align: left;\n}\n.pp-home-arrow {\n color: var(--pp-muted);\n font-size: 24px;\n}\n.pp-home-footer {\n margin-top: 16px;\n text-align: center;\n white-space: normal;\n}\n.pp-home-footer p {\n margin: 8px 0 0;\n}\n";
1900
1899
 
1901
1900
  const selector = "style[data-preference-panes-defaults]";
1902
1901
  const stylesheetSelector = "link[data-preference-panes-stylesheet]";
@@ -1508,9 +1508,8 @@ function browserHost({ menu, back }) {
1508
1508
  brandLink.href = state.logoHref ?? "/";
1509
1509
  logo.hidden = !state.logo;
1510
1510
  if (state.logo) image.src = state.logo;
1511
- left.hidden = !state.canGoBack;
1512
1511
  menu.element.hidden = !state.actions.length;
1513
- button.disabled = state.busy;
1512
+ button.disabled = state.busy || !state.canGoBack;
1514
1513
  scroll();
1515
1514
  },
1516
1515
  confirm: message => window.confirm(message),
@@ -1760,7 +1759,7 @@ class PageController {
1760
1759
  }
1761
1760
  }
1762
1761
 
1763
- var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n:root {\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 --pp-warning: #9a6700;\n --pp-host-height: 0px;\n --pp-keyboard-height: 0px;\n}\n.pp-panel {\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 width: 100%;\n max-width: 100vw;\n min-width: 0;\n}\n\n:root[data-theme=\"dark\"] {\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 --pp-warning: #f0b849;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n.pp-viewport {\n min-width: 0;\n}\n.pp-fields,\n.pp-choice-page,\n.pp-settings-page,\n.pp-cache-page {\n box-sizing: border-box;\n min-width: 0;\n padding: calc(12px + var(--pp-host-height)) max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n scroll-padding-bottom: var(--pp-keyboard-height);\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-panel a.pp-choice-link {\n color: var(--pp-accent);\n text-decoration: none;\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 font-size: 16px;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\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-field-warning {\n margin-top: 4px;\n color: var(--pp-warning);\n font-size: 12px;\n overflow-wrap: anywhere;\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-width: 0;\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-status {\n position: absolute;\n inset: 0;\n display: grid;\n place-content: center;\n justify-items: center;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n margin: 0;\n padding: 24px;\n color: var(--pp-muted, GrayText);\n text-align: center;\n background: var(--pp-background, Canvas);\n}\n.pp-viewport > .pp-status {\n position: absolute;\n}\n.pp-status-spinner {\n box-sizing: border-box;\n width: 28px;\n height: 28px;\n border: 3px solid var(--pp-border, #8884);\n border-top-color: var(--pp-accent, AccentColor);\n border-radius: 50%;\n animation: pp-status-spin 0.8s linear infinite;\n}\n.pp-status-message {\n max-width: 100%;\n margin: 0;\n overflow-wrap: anywhere;\n}\n.pp-status-action {\n min-width: 96px;\n min-height: 44px;\n padding: 8px 16px;\n border: 0;\n border-radius: 6px;\n color: var(--pp-text, ButtonText);\n font: inherit;\n cursor: pointer;\n background: var(--pp-surface, ButtonFace);\n}\n@keyframes pp-status-spin {\n to {\n transform: rotate(1turn);\n }\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n\n/* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。\n * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */\n:root.pp-page {\n color-scheme: light dark;\n}\n.pp-page body {\n margin: 0;\n overflow: hidden;\n font:\n 16px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n background: var(--pp-background, Canvas);\n color: var(--pp-text, CanvasText);\n}\n[data-preference-panes-pages] {\n position: relative;\n height: 100vh;\n background: inherit;\n overflow: hidden;\n}\n@supports (height: 100dvh) {\n [data-preference-panes-pages] {\n height: 100dvh;\n }\n}\n.pp-home,\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n position: absolute;\n inset: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--pp-background);\n}\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n z-index: 1;\n box-shadow: -8px 0 24px #00000014;\n}\n.pp-link-page {\n top: var(--pp-host-height);\n}\n.pp-link-page iframe {\n display: block;\n border: 0;\n width: 100%;\n height: 100%;\n background: inherit;\n}\n.pp-host-header {\n box-sizing: border-box;\n position: fixed;\n inset: 0 0 auto;\n z-index: 2;\n display: flex;\n align-items: center;\n height: calc(64px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));\n border-bottom: 1px solid transparent;\n background: transparent;\n -webkit-backdrop-filter: blur(25px);\n backdrop-filter: blur(25px);\n color: var(--pp-text);\n transition:\n background-color 200ms ease-in-out,\n border-color 200ms ease-in-out;\n}\n.pp-host-header.pp-scrolled {\n background: rgba(255, 255, 255, 0.6);\n border-color: var(--pp-border);\n}\n:root[data-theme=\"dark\"] .pp-host-header.pp-scrolled {\n background: rgba(13, 14, 15, 0.6);\n}\n@media (min-width: 1280px) {\n .pp-host-header {\n padding-right: max(20px, calc((100vw - 1588px) / 2));\n padding-left: max(20px, calc((100vw - 1588px) / 2));\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .pp-host-header {\n transition: none;\n }\n}\n.pp-host-brand {\n display: flex;\n align-items: center;\n flex: 1;\n height: 36px;\n min-width: 0;\n margin-right: 8px;\n}\n.pp-host-brand-link {\n display: flex;\n align-items: center;\n height: 100%;\n min-width: 0;\n max-width: 100%;\n color: inherit;\n text-decoration: none;\n transition: opacity 0.3s;\n}\n.pp-host-brand-link:hover {\n opacity: 0.6;\n}\n.pp-host-logo {\n flex: none;\n min-width: 2rem;\n margin-right: 0.25rem;\n}\n.pp-host-logo img {\n display: block;\n height: 1.6rem;\n}\n.pp-host-title {\n min-width: 0;\n text-align: left;\n font-size: 16px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-host-left {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n}\n.pp-host-left::after {\n content: \"\";\n display: inline-block;\n width: 1px;\n height: 24px;\n margin: 0 16px;\n background-color: #0000001f;\n}\n:root[data-theme=\"dark\"] .pp-host-left::after {\n background-color: #5454547a;\n}\n.pp-host-left[hidden] {\n display: none;\n}\n.pp-host-back {\n border: 0;\n border-radius: 18px;\n background: none;\n color: inherit;\n width: 36px;\n height: 36px;\n padding: 8px;\n cursor: pointer;\n transition: background-color 0.2s ease-in-out;\n}\n.pp-host-back svg {\n display: block;\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n}\n.pp-host-back:hover {\n background: #f1f1f1;\n}\n:root[data-theme=\"dark\"] .pp-host-back:hover {\n background: #343a46;\n}\n.pp-host-toast {\n position: fixed;\n z-index: 3;\n bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100% - 48px);\n padding: 10px 18px;\n border-radius: 12px;\n background: #222e;\n color: #fff;\n font-size: 14px;\n text-align: center;\n}\n.pp-host-toast[hidden] {\n display: none;\n}\n.pp-host-error {\n margin: 24px;\n padding: 16px;\n border: 1px solid var(--pp-danger, #e45656);\n border-radius: 12px;\n font-size: 16px;\n overflow-wrap: anywhere;\n}\n\n.pp-home {\n max-width: 1000px;\n margin: auto;\n padding: var(--pp-host-height) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));\n}\n.pp-home-entries {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-around;\n row-gap: 16px;\n padding: 16px 0;\n background: var(--pp-surface);\n}\n.pp-home-item {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 25%;\n min-width: 0;\n padding: 0 4px;\n border: 0;\n background: none;\n color: var(--pp-text);\n font:\n 12px / 1.5 -apple-system,\n sans-serif;\n cursor: pointer;\n text-decoration: none;\n}\n@media (min-width: 500px) {\n .pp-home-item {\n width: calc(100% / 6);\n }\n}\n@media (min-width: 700px) {\n .pp-home-item {\n width: 12.5%;\n }\n}\n.pp-home-icon {\n box-sizing: border-box;\n width: 56px;\n height: 56px;\n padding: 8px;\n border-radius: 50%;\n background: var(--pp-field);\n font-size: 32px;\n line-height: 40px;\n text-align: center;\n}\n.pp-home-icon img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-home-name {\n margin-top: 8px;\n}\n.pp-home-content {\n min-width: 0;\n width: 100%;\n}\n.pp-home-content > span {\n display: block;\n}\n.pp-home-name,\n.pp-home-item [data-module-status] {\n width: 100%;\n overflow: hidden;\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-home-item [data-module-status] {\n min-height: 20px;\n}\n.pp-home-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.pp-home-entries[data-layout=\"list\"] {\n display: block;\n padding: 0;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item {\n flex-direction: row;\n gap: 12px;\n width: 100%;\n padding: 12px 16px;\n font-size: 15px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item + .pp-home-item {\n border-top: 1px solid var(--pp-border);\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-icon {\n flex: none;\n width: 40px;\n height: 40px;\n padding: 4px;\n font-size: 24px;\n line-height: 32px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-name {\n margin-top: 0;\n text-align: left;\n}\n.pp-home-arrow {\n color: var(--pp-muted);\n font-size: 24px;\n}\n.pp-home-footer {\n margin-top: 16px;\n text-align: center;\n white-space: normal;\n}\n.pp-home-footer p {\n margin: 8px 0 0;\n}\n";
1762
+ var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n:root {\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 --pp-warning: #9a6700;\n --pp-host-height: 0px;\n --pp-keyboard-height: 0px;\n}\n.pp-panel {\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 width: 100%;\n max-width: 100vw;\n min-width: 0;\n}\n\n:root[data-theme=\"dark\"] {\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 --pp-warning: #f0b849;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n.pp-viewport {\n min-width: 0;\n}\n.pp-fields,\n.pp-choice-page,\n.pp-settings-page,\n.pp-cache-page {\n box-sizing: border-box;\n min-width: 0;\n padding: calc(12px + var(--pp-host-height)) max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n scroll-padding-bottom: var(--pp-keyboard-height);\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-panel a.pp-choice-link {\n color: var(--pp-accent);\n text-decoration: none;\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 font-size: 16px;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\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-field-warning {\n margin-top: 4px;\n color: var(--pp-warning);\n font-size: 12px;\n overflow-wrap: anywhere;\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-width: 0;\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-status {\n position: absolute;\n inset: 0;\n display: grid;\n place-content: center;\n justify-items: center;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n margin: 0;\n padding: 24px;\n color: var(--pp-muted, GrayText);\n text-align: center;\n background: var(--pp-background, Canvas);\n}\n.pp-viewport > .pp-status {\n position: absolute;\n}\n.pp-status-spinner {\n box-sizing: border-box;\n width: 28px;\n height: 28px;\n border: 3px solid var(--pp-border, #8884);\n border-top-color: var(--pp-accent, AccentColor);\n border-radius: 50%;\n animation: pp-status-spin 0.8s linear infinite;\n}\n.pp-status-message {\n max-width: 100%;\n margin: 0;\n overflow-wrap: anywhere;\n}\n.pp-status-action {\n min-width: 96px;\n min-height: 44px;\n padding: 8px 16px;\n border: 0;\n border-radius: 6px;\n color: var(--pp-text, ButtonText);\n font: inherit;\n cursor: pointer;\n background: var(--pp-surface, ButtonFace);\n}\n@keyframes pp-status-spin {\n to {\n transform: rotate(1turn);\n }\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n\n/* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。\n * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */\n:root.pp-page {\n color-scheme: light dark;\n font-size: 16px;\n}\n.pp-page body {\n margin: 0;\n overflow: hidden;\n font:\n 16px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n background: var(--pp-background, Canvas);\n color: var(--pp-text, CanvasText);\n}\n[data-preference-panes-pages] {\n position: relative;\n height: 100vh;\n background: inherit;\n overflow: hidden;\n}\n@supports (height: 100dvh) {\n [data-preference-panes-pages] {\n height: 100dvh;\n }\n}\n.pp-home,\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n position: absolute;\n inset: 0;\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n background: var(--pp-background);\n}\n.pp-module-page,\n.pp-detail,\n.pp-link-page {\n z-index: 1;\n box-shadow: -8px 0 24px #00000014;\n}\n.pp-link-page {\n top: var(--pp-host-height);\n}\n.pp-link-page iframe {\n display: block;\n border: 0;\n width: 100%;\n height: 100%;\n background: inherit;\n}\n/* 网页导航复用宿主官网已有字体;官网更换字体产物时须同步资源地址。\n * The web navigation reuses the host site's existing font; update the URL when its font artifact changes. */\n@font-face {\n font-family: \"SF Pro Display\";\n font-style: normal;\n font-weight: 700;\n src:\n local(\"SF Pro Display\"),\n url(\"/static/font/SFPRODISPLAYBOLD.21a7ca4497.woff2\") format(\"woff2\");\n}\n.pp-host-header {\n box-sizing: border-box;\n position: fixed;\n inset: 0 0 auto;\n z-index: 2;\n display: flex;\n align-items: center;\n height: calc(64px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));\n border-bottom: 1px solid transparent;\n background: transparent;\n -webkit-backdrop-filter: blur(25px);\n backdrop-filter: blur(25px);\n color: var(--pp-text);\n font-family: \"SF Pro Display\", \"Inter var experimental\", \"Inter var\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n line-height: 1.7;\n font-synthesis: style;\n text-rendering: optimizelegibility;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n -webkit-text-size-adjust: 100%;\n transition:\n background-color 200ms ease-in-out,\n border-color 200ms ease-in-out;\n}\n.pp-host-header.pp-scrolled {\n background: rgba(255, 255, 255, 0.6);\n border-color: var(--pp-border);\n}\n:root[data-theme=\"dark\"] .pp-host-header.pp-scrolled {\n background: rgba(13, 14, 15, 0.6);\n}\n@media (min-width: 1280px) {\n .pp-host-header {\n padding-right: max(20px, calc((100vw - 1588px) / 2));\n padding-left: max(20px, calc((100vw - 1588px) / 2));\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .pp-host-header {\n transition: none;\n }\n}\n.pp-host-brand {\n display: flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n margin-right: 8px;\n}\n.pp-host-brand-link {\n display: flex;\n align-items: center;\n height: 100%;\n min-width: 0;\n max-width: 100%;\n color: inherit;\n text-decoration: none;\n font-size: 1rem;\n font-weight: 600;\n transition: opacity 0.3s;\n}\n.pp-host-brand-link:hover {\n opacity: 0.6;\n}\n.pp-host-logo {\n flex: none;\n min-width: 2rem;\n margin-right: 0.25rem;\n}\n.pp-host-logo img {\n display: block;\n height: 1.6rem;\n}\n.pp-host-title {\n min-width: 0;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-host-left {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n}\n.pp-host-left::after {\n content: \"\";\n display: inline-block;\n width: 1px;\n height: 24px;\n margin: 0 16px;\n background-color: #0000001f;\n}\n:root[data-theme=\"dark\"] .pp-host-left::after {\n background-color: #5454547a;\n}\n.pp-host-back {\n border: 0;\n border-radius: 18px;\n background: none;\n color: inherit;\n width: 36px;\n height: 36px;\n padding: 8px;\n cursor: pointer;\n transition: background-color 0.2s ease-in-out;\n}\n.pp-host-back:disabled {\n cursor: default;\n}\n.pp-host-back svg {\n display: block;\n width: 20px;\n height: 20px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n}\n.pp-host-back:hover {\n background: #f1f1f1;\n}\n:root[data-theme=\"dark\"] .pp-host-back:hover {\n background: #343a46;\n}\n.pp-host-toast {\n position: fixed;\n z-index: 3;\n bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));\n left: 50%;\n transform: translateX(-50%);\n max-width: calc(100% - 48px);\n padding: 10px 18px;\n border-radius: 12px;\n background: #222e;\n color: #fff;\n font-size: 14px;\n text-align: center;\n}\n.pp-host-toast[hidden] {\n display: none;\n}\n.pp-host-error {\n margin: 24px;\n padding: 16px;\n border: 1px solid var(--pp-danger, #e45656);\n border-radius: 12px;\n font-size: 16px;\n overflow-wrap: anywhere;\n}\n\n.pp-home {\n max-width: 1000px;\n margin: auto;\n padding: var(--pp-host-height) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));\n}\n.pp-home-entries {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-around;\n row-gap: 16px;\n padding: 16px 0;\n background: var(--pp-surface);\n}\n.pp-home-item {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 25%;\n min-width: 0;\n padding: 0 4px;\n border: 0;\n background: none;\n color: var(--pp-text);\n font:\n 12px / 1.5 -apple-system,\n sans-serif;\n cursor: pointer;\n text-decoration: none;\n}\n@media (min-width: 500px) {\n .pp-home-item {\n width: calc(100% / 6);\n }\n}\n@media (min-width: 700px) {\n .pp-home-item {\n width: 12.5%;\n }\n}\n.pp-home-icon {\n box-sizing: border-box;\n width: 56px;\n height: 56px;\n padding: 8px;\n border-radius: 50%;\n background: var(--pp-field);\n font-size: 32px;\n line-height: 40px;\n text-align: center;\n}\n.pp-home-icon img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-home-name {\n margin-top: 8px;\n}\n.pp-home-content {\n min-width: 0;\n width: 100%;\n}\n.pp-home-content > span {\n display: block;\n}\n.pp-home-name,\n.pp-home-item [data-module-status] {\n width: 100%;\n overflow: hidden;\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.pp-home-item [data-module-status] {\n min-height: 20px;\n}\n.pp-home-item:disabled {\n opacity: 0.45;\n cursor: default;\n}\n.pp-home-entries[data-layout=\"list\"] {\n display: block;\n padding: 0;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item {\n flex-direction: row;\n gap: 12px;\n width: 100%;\n padding: 12px 16px;\n font-size: 15px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-item + .pp-home-item {\n border-top: 1px solid var(--pp-border);\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-icon {\n flex: none;\n width: 40px;\n height: 40px;\n padding: 4px;\n font-size: 24px;\n line-height: 32px;\n}\n.pp-home-entries[data-layout=\"list\"] .pp-home-name {\n margin-top: 0;\n text-align: left;\n}\n.pp-home-arrow {\n color: var(--pp-muted);\n font-size: 24px;\n}\n.pp-home-footer {\n margin-top: 16px;\n text-align: center;\n white-space: normal;\n}\n.pp-home-footer p {\n margin: 8px 0 0;\n}\n";
1764
1763
 
1765
1764
  const selector = "style[data-preference-panes-defaults]";
1766
1765
  const stylesheetSelector = "link[data-preference-panes-stylesheet]";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsnanocat/preference-panes",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Generic BoxJS settings frontend and persistence API for JavaScript proxy modules",
5
5
  "author": "VirgilClyne <Virgil@nanocat.me>",
6
6
  "homepage": "https://NSNanoCat.github.io/preference-panes",
@@ -72,9 +72,8 @@ export function browserHost({ menu, back }) {
72
72
  brandLink.href = state.logoHref ?? "/";
73
73
  logo.hidden = !state.logo;
74
74
  if (state.logo) image.src = state.logo;
75
- left.hidden = !state.canGoBack;
76
75
  menu.element.hidden = !state.actions.length;
77
- button.disabled = state.busy;
76
+ button.disabled = state.busy || !state.canGoBack;
78
77
  scroll();
79
78
  },
80
79
  confirm: message => window.confirm(message),
@@ -247,6 +247,7 @@
247
247
  * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */
248
248
  :root.pp-page {
249
249
  color-scheme: light dark;
250
+ font-size: 16px;
250
251
  }
251
252
  .pp-page body {
252
253
  margin: 0;
@@ -297,6 +298,16 @@
297
298
  height: 100%;
298
299
  background: inherit;
299
300
  }
301
+ /* 网页导航复用宿主官网已有字体;官网更换字体产物时须同步资源地址。
302
+ * The web navigation reuses the host site's existing font; update the URL when its font artifact changes. */
303
+ @font-face {
304
+ font-family: "SF Pro Display";
305
+ font-style: normal;
306
+ font-weight: 700;
307
+ src:
308
+ local("SF Pro Display"),
309
+ url("/static/font/SFPRODISPLAYBOLD.21a7ca4497.woff2") format("woff2");
310
+ }
300
311
  .pp-host-header {
301
312
  box-sizing: border-box;
302
313
  position: fixed;
@@ -311,6 +322,13 @@
311
322
  -webkit-backdrop-filter: blur(25px);
312
323
  backdrop-filter: blur(25px);
313
324
  color: var(--pp-text);
325
+ font-family: "SF Pro Display", "Inter var experimental", "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
326
+ line-height: 1.7;
327
+ font-synthesis: style;
328
+ text-rendering: optimizelegibility;
329
+ -webkit-font-smoothing: antialiased;
330
+ -moz-osx-font-smoothing: grayscale;
331
+ -webkit-text-size-adjust: 100%;
314
332
  transition:
315
333
  background-color 200ms ease-in-out,
316
334
  border-color 200ms ease-in-out;
@@ -337,7 +355,6 @@
337
355
  display: flex;
338
356
  align-items: center;
339
357
  flex: 1;
340
- height: 36px;
341
358
  min-width: 0;
342
359
  margin-right: 8px;
343
360
  }
@@ -349,6 +366,8 @@
349
366
  max-width: 100%;
350
367
  color: inherit;
351
368
  text-decoration: none;
369
+ font-size: 1rem;
370
+ font-weight: 600;
352
371
  transition: opacity 0.3s;
353
372
  }
354
373
  .pp-host-brand-link:hover {
@@ -366,8 +385,6 @@
366
385
  .pp-host-title {
367
386
  min-width: 0;
368
387
  text-align: left;
369
- font-size: 16px;
370
- font-weight: 600;
371
388
  overflow: hidden;
372
389
  text-overflow: ellipsis;
373
390
  white-space: nowrap;
@@ -389,9 +406,6 @@
389
406
  :root[data-theme="dark"] .pp-host-left::after {
390
407
  background-color: #5454547a;
391
408
  }
392
- .pp-host-left[hidden] {
393
- display: none;
394
- }
395
409
  .pp-host-back {
396
410
  border: 0;
397
411
  border-radius: 18px;
@@ -403,6 +417,9 @@
403
417
  cursor: pointer;
404
418
  transition: background-color 0.2s ease-in-out;
405
419
  }
420
+ .pp-host-back:disabled {
421
+ cursor: default;
422
+ }
406
423
  .pp-host-back svg {
407
424
  display: block;
408
425
  width: 20px;