waybetter 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +1 -2
  2. package/bin/waybetter.mjs +2 -5
  3. package/cli/buildenv.mjs +1 -1
  4. package/cli/release.mjs +11 -18
  5. package/cli/releasecheck.mjs +15 -0
  6. package/cli/remote.mjs +4 -4
  7. package/cli/store.mjs +80 -28
  8. package/cli/strings.mjs +2 -0
  9. package/dist/runtime/stringPackHook.js +2 -2
  10. package/dist/runtime/stringPackHook.js.map +1 -1
  11. package/dist/runtime/stringPackTranslate.d.ts +3 -1
  12. package/dist/runtime/stringPackTranslate.js +6 -3
  13. package/dist/runtime/stringPackTranslate.js.map +1 -1
  14. package/dist/runtime/stringPacks.d.ts +53 -5
  15. package/dist/runtime/stringPacks.js +161 -25
  16. package/dist/runtime/stringPacks.js.map +1 -1
  17. package/dist/runtime/themeBar.d.ts +28 -0
  18. package/dist/runtime/themeBar.js +82 -0
  19. package/dist/runtime/themeBar.js.map +1 -0
  20. package/dist/runtime/themeComponents.js +16 -3
  21. package/dist/runtime/themeComponents.js.map +1 -1
  22. package/dist/runtime/themeDecor.js +3 -1
  23. package/dist/runtime/themeDecor.js.map +1 -1
  24. package/dist/runtime/themeDerive.d.ts +69 -0
  25. package/dist/runtime/themeDerive.js +117 -0
  26. package/dist/runtime/themeDerive.js.map +1 -0
  27. package/dist/runtime/themeDoctor.d.ts +44 -3
  28. package/dist/runtime/themeDoctor.js +86 -25
  29. package/dist/runtime/themeDoctor.js.map +1 -1
  30. package/dist/runtime/themeGuards.d.ts +60 -0
  31. package/dist/runtime/themeGuards.js +235 -0
  32. package/dist/runtime/themeGuards.js.map +1 -0
  33. package/dist/runtime/themeIcons.d.ts +1 -1
  34. package/dist/runtime/themeIcons.js +13 -5
  35. package/dist/runtime/themeIcons.js.map +1 -1
  36. package/dist/runtime/themeInk.d.ts +37 -0
  37. package/dist/runtime/themeInk.js +111 -0
  38. package/dist/runtime/themeInk.js.map +1 -0
  39. package/dist/runtime/themeInvariants.d.ts +39 -0
  40. package/dist/runtime/themeInvariants.js +273 -0
  41. package/dist/runtime/themeInvariants.js.map +1 -0
  42. package/dist/runtime/themeRuntime.d.ts +15 -1
  43. package/dist/runtime/themeRuntime.js +78 -5
  44. package/dist/runtime/themeRuntime.js.map +1 -1
  45. package/dist/runtime/themeSpec.d.ts +5 -1
  46. package/dist/runtime/themeSpec.js +9 -13
  47. package/dist/runtime/themeSpec.js.map +1 -1
  48. package/dist/shell/InstallDialog.js +14 -8
  49. package/dist/shell/InstallDialog.js.map +1 -1
  50. package/dist/shell/StoreView.d.ts +12 -0
  51. package/dist/shell/StoreView.js +9 -4
  52. package/dist/shell/StoreView.js.map +1 -1
  53. package/dist/shell/frame/AppMenu.d.ts +26 -3
  54. package/dist/shell/frame/AppMenu.js +106 -27
  55. package/dist/shell/frame/AppMenu.js.map +1 -1
  56. package/dist/shell/frame/FindBar.js +1 -1
  57. package/dist/shell/frame/FindBar.js.map +1 -1
  58. package/dist/shell/frame/Shell.d.ts +1 -0
  59. package/dist/shell/frame/Shell.js +10 -2
  60. package/dist/shell/frame/Shell.js.map +1 -1
  61. package/dist/shell/frame/Titlebar.d.ts +2 -1
  62. package/dist/shell/frame/Titlebar.js +5 -3
  63. package/dist/shell/frame/Titlebar.js.map +1 -1
  64. package/dist/shell/frame/WebPanel.js +4 -1
  65. package/dist/shell/frame/WebPanel.js.map +1 -1
  66. package/dist/shell/frame/accountSwitcher.css +10 -10
  67. package/dist/shell/frame/appMenu.css +19 -13
  68. package/dist/shell/frame/boot.js +2 -0
  69. package/dist/shell/frame/boot.js.map +1 -1
  70. package/dist/shell/frame/chromeTheme.d.ts +19 -1
  71. package/dist/shell/frame/chromeTheme.js +51 -14
  72. package/dist/shell/frame/chromeTheme.js.map +1 -1
  73. package/dist/shell/frame/deck.css +30 -30
  74. package/dist/shell/frame/edges.css +159 -0
  75. package/dist/shell/frame/index.d.ts +2 -2
  76. package/dist/shell/frame/index.js +1 -1
  77. package/dist/shell/frame/index.js.map +1 -1
  78. package/dist/shell/frame/mediaModel.d.ts +13 -0
  79. package/dist/shell/frame/mediaModel.js +14 -0
  80. package/dist/shell/frame/mediaModel.js.map +1 -1
  81. package/dist/shell/frame/menuMessages.en.json +43 -1
  82. package/dist/shell/frame/menuModel.d.ts +42 -0
  83. package/dist/shell/frame/menuModel.js +8 -0
  84. package/dist/shell/frame/menuModel.js.map +1 -1
  85. package/dist/shell/frame/nativeMenu.d.ts +5 -0
  86. package/dist/shell/frame/nativeMenu.js +178 -0
  87. package/dist/shell/frame/nativeMenu.js.map +1 -0
  88. package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
  89. package/dist/shell/frame/nativeMenuModel.js +186 -0
  90. package/dist/shell/frame/nativeMenuModel.js.map +1 -0
  91. package/dist/shell/frame/paletteModel.js +3 -1
  92. package/dist/shell/frame/paletteModel.js.map +1 -1
  93. package/dist/shell/frame/paneTheme.css +1 -1
  94. package/dist/shell/frame/reportModel.d.ts +1 -1
  95. package/dist/shell/frame/reportModel.js +1 -1
  96. package/dist/shell/frame/reportModel.js.map +1 -1
  97. package/dist/shell/frame/shell.css +56 -51
  98. package/dist/shell/frame/state.d.ts +2 -0
  99. package/dist/shell/frame/state.js +3 -1
  100. package/dist/shell/frame/state.js.map +1 -1
  101. package/dist/shell/frame/themeStore.js +21 -6
  102. package/dist/shell/frame/themeStore.js.map +1 -1
  103. package/dist/shell/frame/workspaces.css +12 -12
  104. package/dist/shell/installController.d.ts +16 -1
  105. package/dist/shell/installController.js +31 -5
  106. package/dist/shell/installController.js.map +1 -1
  107. package/dist/shell/panel/Appearance.js +12 -3
  108. package/dist/shell/panel/Appearance.js.map +1 -1
  109. package/dist/shell/panel/Settings.d.ts +1 -1
  110. package/dist/shell/panel/Settings.js +4 -3
  111. package/dist/shell/panel/Settings.js.map +1 -1
  112. package/dist/shell/panel/StoreSection.d.ts +2 -1
  113. package/dist/shell/panel/StoreSection.js +31 -1
  114. package/dist/shell/panel/StoreSection.js.map +1 -1
  115. package/dist/shell/panel/StringPacks.d.ts +12 -3
  116. package/dist/shell/panel/StringPacks.js +33 -8
  117. package/dist/shell/panel/StringPacks.js.map +1 -1
  118. package/dist/shell/panel/backup.css +1 -1
  119. package/dist/shell/panel/builder.css +48 -40
  120. package/dist/shell/panel/make.css +8 -7
  121. package/dist/shell/panel/panel.css +401 -401
  122. package/dist/shell/panel/panelMessages.d.ts +41 -1
  123. package/dist/shell/panel/panelMessages.js +13 -1
  124. package/dist/shell/panel/panelMessages.js.map +1 -1
  125. package/dist/shell/panel/plugins.css +5 -5
  126. package/dist/shell/panel/strings.css +1 -1
  127. package/dist/shell/store.css +34 -14
  128. package/dist/shell/storeMessages.d.ts +24 -0
  129. package/dist/shell/storeMessages.js +24 -0
  130. package/dist/shell/storeMessages.js.map +1 -1
  131. package/dist/shell/storeModel.d.ts +31 -7
  132. package/dist/shell/storeModel.js +15 -2
  133. package/dist/shell/storeModel.js.map +1 -1
  134. package/dist/shell/stringPacksModel.js +7 -2
  135. package/dist/shell/stringPacksModel.js.map +1 -1
  136. package/icons.schema.json +9 -0
  137. package/locales/ar.json +109 -2
  138. package/locales/bg.json +109 -2
  139. package/locales/bn.json +109 -2
  140. package/locales/ca.json +109 -2
  141. package/locales/cs.json +109 -2
  142. package/locales/da.json +109 -2
  143. package/locales/de.json +109 -2
  144. package/locales/el.json +109 -2
  145. package/locales/en.json +108 -2
  146. package/locales/es.json +109 -2
  147. package/locales/eu.json +109 -2
  148. package/locales/fa.json +109 -2
  149. package/locales/fi.json +109 -2
  150. package/locales/fil.json +109 -2
  151. package/locales/fr.json +109 -2
  152. package/locales/ga.json +109 -2
  153. package/locales/gl.json +109 -2
  154. package/locales/gu.json +109 -2
  155. package/locales/ha.json +109 -2
  156. package/locales/he.json +109 -2
  157. package/locales/hi.json +109 -2
  158. package/locales/hr.json +109 -2
  159. package/locales/hu.json +110 -2
  160. package/locales/id.json +109 -2
  161. package/locales/ig.json +109 -2
  162. package/locales/it.json +109 -2
  163. package/locales/ja.json +109 -2
  164. package/locales/kn.json +109 -2
  165. package/locales/ko.json +109 -2
  166. package/locales/mr.json +109 -2
  167. package/locales/ms.json +109 -2
  168. package/locales/nb.json +109 -2
  169. package/locales/nl.json +109 -2
  170. package/locales/pl.json +109 -2
  171. package/locales/pt.json +109 -2
  172. package/locales/ro.json +109 -2
  173. package/locales/ru.json +109 -2
  174. package/locales/sk.json +109 -2
  175. package/locales/sr.json +109 -2
  176. package/locales/sv.json +109 -2
  177. package/locales/ta.json +109 -2
  178. package/locales/th.json +109 -2
  179. package/locales/tr.json +109 -2
  180. package/locales/uk.json +109 -2
  181. package/locales/ur.json +109 -2
  182. package/locales/vi.json +109 -2
  183. package/locales/yo.json +109 -2
  184. package/locales/zh-Hans.json +109 -2
  185. package/locales/zh-Hant.json +109 -2
  186. package/package.json +2 -3
  187. package/store-catalog.schema.json +18 -5
  188. package/theme.schema.json +9 -0
  189. package/windows/installer.nsi +22 -2
  190. package/cli/privacy.mjs +0 -768
@@ -1 +1 @@
1
- {"version":3,"file":"themeRuntime.js","sourceRoot":"","sources":["../../../runtime/src/themeRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["// The theme engine in a site's page: keeps one `<style>` with the theme's CSS in sync while the site\n// adds its own rules (React apps insert them lazily), exposes the resolved theme as `--wb-*` custom\n// properties for plugins and the UI kit, follows the site's own color mode, and paints the last\n// theme from the page's first frame (a snapshot in the page's storage). What the CSS is comes from\n// the site adapter (`ThemeRuntimeSite`): X re-declares its own stylesheet rules with the theme's\n// colors (`buildThemeCss`) and adds type/shape/layout rules over its selectors.\n\nimport { domRoots } from './domHub.ts';\nimport { FONT_ROLE_NAMES, themeKey, themeVarsCss, type ResolvedFonts, type ResolvedTheme } from './themeApi.ts';\nimport type { ThemeCatalog, ThemeChoice } from './themeChoice.ts';\nimport { bundledFontsUsed, isNeutral, resolveFontRoles, type FontSpec, type ThemeSpec } from './themeSpec.ts';\n\n/** A style rule as the engine reads it (CSSStyleRule, or a plain object in tests). */\nexport type RuleLike = { selectorText: string; style: { getPropertyValue(name: string): string; length?: number } };\n\n/** The font roles as the plugin API reports them in a site's page; an inheriting interface uses `siteStack` (the site's own font). */\nexport function resolvedFonts(font: FontSpec, siteStack: string): ResolvedFonts {\n const roles = resolveFontRoles(font, siteStack);\n return Object.fromEntries(FONT_ROLE_NAMES.map(role => {\n const { stack, weight, size, tracking, tabular, inherited } = roles[role];\n return [role, { stack, weight, size, tracking, tabular, inherited }];\n })) as ResolvedFonts;\n}\n\ntype RuleNode = { selectorText?: string; style?: RuleLike['style']; cssRules?: ArrayLike<RuleNode>; conditionText?: string; type?: number; constructor?: { name?: string } };\nconst isSupports = (rule: RuleNode) => rule.type === 12 || rule.constructor?.name === 'CSSSupportsRule';\n\n/**\n * A style rule as it takes effect. Tailwind 4 writes an opacity utility as a fallback plus the real\n * value in a nested `@supports`:\n * `.bg-white\\/15 { background-color: var(--white); @supports (color: color-mix(in lab, red, red)) { background-color: color-mix(in oklab, var(--white) 15%, transparent) } }`.\n * Read alone, the outer declaration is a solid white fill; where the browser passes the condition the\n * nested one is what paints, so it answers for the rule.\n */\nfunction effectiveRule(rule: RuleNode, supported: (condition: string) => boolean): RuleLike {\n const overrides: Array<RuleLike['style']> = [];\n for (const child of Array.from(rule.cssRules ?? [])) {\n if (!isSupports(child) || !supported(child.conditionText ?? '')) continue;\n for (const inner of Array.from(child.cssRules ?? [])) {\n // Bare declarations inside the group: a CSSNestedDeclarations, or `& { }` in older engines.\n if (inner.style && (inner.selectorText === undefined || inner.selectorText === '&')) overrides.push(inner.style);\n }\n }\n if (!overrides.length) return rule as RuleLike;\n const outer = rule.style!;\n return {\n selectorText: rule.selectorText!,\n style: {\n getPropertyValue(name) {\n for (let i = overrides.length - 1; i >= 0; i--) { const value = overrides[i]!.getPropertyValue(name); if (value) return value; }\n return outer.getPropertyValue(name);\n },\n length: outer.length,\n },\n };\n}\n\n/**\n * Every style rule of `doc`'s stylesheets (inside media/supports groups too), except `own`'s (the\n * engine's own sheets: read as the site's, their radii and colors would be re-declared), each as it\n * takes effect (`effectiveRule`). A `@supports` group the browser does not pass is left out.\n */\nexport function collectRules(doc: Document, own: HTMLStyleElement | null | ReadonlyArray<HTMLStyleElement | null>): RuleLike[] {\n const ours = (Array.isArray(own) ? own : [own]).filter(Boolean) as HTMLStyleElement[];\n const sheets = Array.from(doc.styleSheets).filter(sheet => !ours.includes(sheet.ownerNode as HTMLStyleElement));\n return rulesOf(sheets, (doc.defaultView as (Window & typeof globalThis) | null)?.CSS);\n}\n\ntype SheetLike = { cssRules: CSSRuleList | ArrayLike<unknown> };\n/**\n * The same for an open shadow root the site renders a part of itself in (X's chat embed): its adopted\n * sheets and its `<style>` elements, except the engine's own adopted `own` sheet.\n */\nexport function collectRootRules(root: { adoptedStyleSheets?: readonly SheetLike[]; styleSheets?: ArrayLike<SheetLike> }, own: SheetLike | null, css?: { supports?(condition: string): boolean }): RuleLike[] {\n const sheets = [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])].filter(sheet => sheet !== own);\n return rulesOf(sheets, css);\n}\n\nfunction rulesOf(sheets: readonly SheetLike[], css: { supports?(condition: string): boolean } | undefined): RuleLike[] {\n const rules: RuleLike[] = [];\n const verdicts = new Map<string, boolean>();\n const supported = (condition: string) => {\n if (!condition || !css?.supports) return true;\n let verdict = verdicts.get(condition);\n if (verdict === undefined) { try { verdict = css.supports(condition); } catch { verdict = true; } verdicts.set(condition, verdict); }\n return verdict;\n };\n const walk = (list: ArrayLike<RuleNode>) => {\n for (const rule of Array.from(list)) {\n if (rule.selectorText !== undefined && rule.style) rules.push(effectiveRule(rule, supported));\n else if (rule.cssRules && rule.selectorText === undefined && (!isSupports(rule) || supported(rule.conditionText ?? ''))) walk(rule.cssRules);\n }\n };\n for (const sheet of sheets) {\n try { walk(sheet.cssRules as unknown as ArrayLike<RuleNode>); } catch { /* Cross-origin sheet. */ }\n }\n return rules;\n}\n\nfunction rootRuleCount(root: ShadowRoot, own: CSSStyleSheet | null): number {\n let count = 0;\n for (const sheet of [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])]) {\n if (sheet === own) continue;\n try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ }\n }\n return count;\n}\n\nfunction ruleCount(doc: Document): number {\n let count = 0;\n for (const sheet of Array.from(doc.styleSheets)) { try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ } }\n return count;\n}\n\n/**\n * The last theme CSS a tab showed, kept in the page's own storage so the next document paints it\n * from its first frame: native code only hands the theme over once the page has finished loading,\n * and the live CSS needs the site's rules, which it inserts while it renders. sessionStorage is per\n * tab and survives reloads and navigations; localStorage (smaller cap: the site uses it too) is per\n * account and covers a tab's first document.\n */\nexport type ThemeSnapshot = { key: string; choice: unknown; css: string };\nconst SNAPSHOT_KEY = 'wb:theme-snapshot';\nexport const SNAPSHOT_SESSION_MAX = 1_000_000;\nexport const SNAPSHOT_LOCAL_MAX = 200_000;\nexport type SnapshotStores = { session?: Storage | null; local?: Storage | null };\n\nfunction stores(win: Window): SnapshotStores {\n const get = (name: 'sessionStorage' | 'localStorage') => { try { return win[name]; } catch { return null; } };\n return { session: get('sessionStorage'), local: get('localStorage') };\n}\n\nexport function readSnapshot({ session, local }: SnapshotStores): ThemeSnapshot | null {\n for (const store of [session, local]) {\n try {\n const value = JSON.parse(store?.getItem(SNAPSHOT_KEY) || 'null') as Partial<ThemeSnapshot> | null;\n if (value && typeof value.key === 'string' && typeof value.css === 'string' && value.css && value.choice) return value as ThemeSnapshot;\n } catch { /* Missing, blocked or foreign data: no snapshot. */ }\n }\n return null;\n}\n\n/** Stores `snapshot` (null clears it: the site's own look needs none), each store within its cap. */\nexport function writeSnapshot({ session, local }: SnapshotStores, snapshot: ThemeSnapshot | null) {\n const json = snapshot ? JSON.stringify(snapshot) : '';\n for (const [store, max] of [[session, SNAPSHOT_SESSION_MAX], [local, SNAPSHOT_LOCAL_MAX]] as const) {\n try {\n if (json && json.length <= max) store?.setItem(SNAPSHOT_KEY, json);\n else store?.removeItem(SNAPSHOT_KEY);\n } catch { /* Quota or blocked storage: the next document just starts unthemed. */ }\n }\n}\n\n/** What the engine needs to know about a site. `Mode` is the site's own color mode (X: light, dim, dark). */\nexport type ThemeRuntimeSite<Mode extends string = string> = {\n /** The site's built-in themes (themeChoice.ts). */\n catalog: ThemeCatalog;\n /** The mode before the page has a body. */\n initialMode: Mode;\n /** The site's color mode as the page paints it now (read before the theme's own override: e.g. the body's inline style). */\n readMode(win: Window): Mode;\n /** The theme's CSS for the site's current `rules` (the engine's own sheet excluded) in `mode`; `vars` are `siteVars` as the site sets them. */\n css(rules: RuleLike[], choice: ThemeChoice, mode: Mode, vars: Record<string, string>): string;\n /** The active theme resolved for plugins and the UI kit (the site's own palette when the theme keeps its colors). */\n resolved(choice: ThemeChoice, mode: Mode): ResolvedTheme;\n /** Custom properties of the site's root read with the theme's sheet disabled (their unthemed values). */\n siteVars?: readonly string[];\n /**\n * The theme's CSS that does not depend on the site's stylesheet: components, variants, decoration,\n * icons. It lives in its own sheet (`staticId`), so the site inserting rules never rebuilds it; it is\n * rebuilt when the theme or the site's mode changes and on `refresh()` (the owner's switches, the\n * icon choice, the language).\n */\n staticCss?(choice: ThemeChoice, mode: Mode): string;\n /** Id of that sheet's `<style>` (default `wb-theme-static`). */\n staticId?: string;\n /** Id of the theme's `<style>` (default `wb-theme-css`). */\n styleId?: string;\n /** Name in console errors. */\n name?: string;\n};\n\nexport type ThemeHandle<Mode extends string = string> = {\n apply(choice: unknown): void;\n current(): ThemeChoice;\n theme(): ThemeSpec;\n /** The site's color mode the theme was last rendered for. */\n mode(): Mode;\n /** The active theme as values for plugins (`api.theme.current()`). */\n resolved(): ResolvedTheme;\n /** Calls `listener` after the theme or the site's color mode changes. */\n onChange(listener: () => void): () => void;\n /** Rebuilds the theme's CSS now: something it depends on besides the theme changed (the owner's switches, the icon choice). */\n refresh(): void;\n};\nexport type ThemeRuntimeOptions = { /** Registers bundled families (e.g. \"Geist\") in the page before they are used. */ loadFonts?(names: string[]): void };\n\nconst VARS_ID = 'wb-theme-vars';\n\n/** Keeps the site's page in the owner's theme (see the top of this file). */\nexport function installThemeRuntime<Mode extends string>(win: Window, site: ThemeRuntimeSite<Mode>, options: ThemeRuntimeOptions = {}): ThemeHandle<Mode> {\n const doc = win.document;\n const name = site.name ?? 'wayBetter';\n const styleId = site.styleId ?? 'wb-theme-css';\n const staticId = site.staticId ?? 'wb-theme-static';\n const { catalog } = site;\n // Document start (no <html> yet): the snapshot as an adopted sheet paints with the site's first\n // frame. It stays while the live CSS is for the same theme and site mode, and goes when they differ.\n const storage = stores(win);\n const snapshot = readSnapshot(storage);\n let early: CSSStyleSheet | null = null;\n if (snapshot) {\n try {\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n early = new Sheet();\n early.replaceSync(snapshot.css);\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, early];\n } catch { early = null; }\n }\n const dropEarly = () => {\n if (!early) return;\n const sheet = early;\n early = null;\n try { doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Never break the site. */ }\n };\n let savedCss = snapshot?.css ?? '';\n let choice = catalog.defaultChoice;\n let theme = catalog.resolve(choice);\n let lastKey = '';\n let timer: ReturnType<typeof setInterval> | null = null;\n const active = () => !isNeutral(theme) || !!choice.accent || !!choice.icons;\n let mode: Mode = site.initialMode;\n let resolved: ResolvedTheme = site.resolved(choice, mode);\n let resolvedKey = themeKey(resolved);\n const listeners = new Set<() => void>();\n const readMode = () => (doc.body ? site.readMode(win) : mode);\n /** `--wb-*` on :root for plugin CSS, and a change notice when anything visible changed. */\n const syncResolved = () => {\n if (doc.body) mode = readMode();\n resolved = site.resolved(choice, mode);\n const key = themeKey(resolved);\n let vars = doc.getElementById(VARS_ID) as HTMLStyleElement | null;\n if (!vars?.isConnected) {\n vars = doc.createElement('style');\n vars.id = VARS_ID;\n (doc.head || doc.documentElement).appendChild(vars);\n }\n const css = themeVarsCss(resolved);\n if (vars.textContent !== css) vars.textContent = css;\n if (key === resolvedKey) return;\n resolvedKey = key;\n for (const listener of [...listeners]) {\n try { listener(); } catch (error) { console.error(`[${name}] theme listener failed`, error); }\n }\n };\n let modeObserver: MutationObserver | null = null;\n const watchMode = () => {\n if (modeObserver || !doc.body) return;\n // Sites repaint the body when their own display setting changes (X: Default / Dim / Lights out).\n const Observer = (win as Window & typeof globalThis).MutationObserver ?? globalThis.MutationObserver;\n if (!Observer) return;\n modeObserver = new Observer(() => { try { if (readMode() !== mode) syncResolved(); } catch { /* Never break the site. */ } });\n modeObserver.observe(doc.body, { attributes: true, attributeFilter: ['style'] });\n };\n\n let staticKey = '';\n let staticText = '';\n let siteVars: Record<string, string> = {};\n // Open shadow roots the site renders a part of itself in (domHub `shadowHosts`; X's chat embed since\n // 2026-10-01): the document's sheets do not reach inside, so each root adopts the theme built from\n // its own rules plus the static sheet, kept last among its sheets, rebuilt when its rules change and\n // taken off when the theme is off or the root is gone.\n const rootSheets = new Map<ShadowRoot, { sheet: CSSStyleSheet; key: string }>();\n const detach = (root: ShadowRoot, sheet: CSSStyleSheet) => { try { root.adoptedStyleSheets = root.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Root gone. */ } };\n const syncRoots = (on: boolean, snapshotKey: string, force: boolean) => {\n let roots: ShadowRoot[] = [];\n if (on) { try { roots = domRoots(win).slice(1) as ShadowRoot[]; } catch { roots = []; } }\n for (const [root, item] of rootSheets) if (!roots.includes(root)) { detach(root, item.sheet); rootSheets.delete(root); }\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n for (const root of roots) {\n let item = rootSheets.get(root);\n if (!item) {\n try { item = { sheet: new Sheet(), key: '' }; } catch { continue; }\n rootSheets.set(root, item);\n }\n const key = `${snapshotKey}|${rootRuleCount(root, item.sheet)}|${staticText.length}`;\n if (force || item.key !== key) {\n item.key = key;\n // The site's primitives as the root sees them (its own sheets may declare them; the document may not), read with our sheet off.\n const vars = { ...siteVars };\n if (site.siteVars?.length) {\n const probe = root.firstElementChild ?? root.host;\n item.sheet.disabled = true;\n try { const style = win.getComputedStyle(probe); for (const name of site.siteVars) { const value = style.getPropertyValue(name).trim(); if (value) vars[name] = value; } } catch { /* Keep the document's. */ }\n item.sheet.disabled = false;\n }\n let css = '';\n try { css = site.css(collectRootRules(root, item.sheet, (win as Window & typeof globalThis).CSS), choice, mode, vars); } catch (error) { console.error(`[${name}] theme (shadow root) failed`, error); }\n try { item.sheet.replaceSync(staticText ? `${css}\\n${staticText}` : css); } catch { /* Keeps the last good rules. */ }\n }\n // Last, so equal-specificity `!important` rules win over the site's; the site may re-set its list.\n const list = root.adoptedStyleSheets;\n if (list[list.length - 1] !== item.sheet) { try { root.adoptedStyleSheets = [...list.filter(sheet => sheet !== item!.sheet), item.sheet]; } catch { /* Never break the site. */ } }\n }\n };\n /** The static sheet sits right after the palette sheet (its part rules are more specific anyway; order only breaks ties). */\n const placeStatic = (fixed: HTMLStyleElement | null, style: HTMLStyleElement | null) => {\n if (!fixed || !style?.isConnected) return;\n if (style.nextElementSibling !== fixed) style.after(fixed);\n };\n const render = (force = false) => {\n let style = doc.getElementById(styleId) as HTMLStyleElement | null;\n let fixed = doc.getElementById(staticId) as HTMLStyleElement | null;\n if (doc.body) { watchMode(); syncResolved(); }\n if (!active()) { style?.remove(); fixed?.remove(); lastKey = ''; staticKey = ''; dropEarly(); syncRoots(false, '', false); if (savedCss) { savedCss = ''; writeSnapshot(storage, null); } return; }\n if (!doc.body) return;\n const snapshotKey = `${JSON.stringify(choice)}|${mode}`;\n if (early && snapshot?.key !== snapshotKey) dropEarly();\n // The static sheet follows the theme and the mode only (and `refresh()`), never the site's rules.\n if (site.staticCss && (force || staticKey !== snapshotKey)) {\n staticKey = snapshotKey;\n let text = '';\n try { text = site.staticCss(choice, mode); } catch (error) { console.error(`[${name}] theme structure failed`, error); }\n staticText = text;\n if (text) {\n if (!fixed) { fixed = doc.createElement('style'); fixed.id = staticId; }\n if (fixed.textContent !== text) fixed.textContent = text;\n } else { fixed?.remove(); fixed = null; }\n }\n const key = `${JSON.stringify(choice)}|${mode}|${ruleCount(doc) - (style?.sheet?.cssRules.length ?? 0) - (fixed?.sheet?.cssRules.length ?? 0)}`;\n if (!force && key === lastKey) { placeStatic(fixed, style); syncRoots(true, snapshotKey, false); return; }\n lastKey = key;\n if (!style) { style = doc.createElement('style'); style.id = styleId; }\n // The site's own values, not the ones our previous render overrode (switching themes re-reads them).\n if (style.sheet) style.sheet.disabled = true;\n const vars: Record<string, string> = {};\n if (site.siteVars?.length) {\n const rootStyle = win.getComputedStyle(doc.documentElement);\n for (const name of site.siteVars) vars[name] = rootStyle.getPropertyValue(name).trim();\n }\n if (style.sheet) style.sheet.disabled = false;\n siteVars = vars;\n const css = site.css(collectRules(doc, [style, fixed]), choice, mode, vars);\n if (style.textContent !== css) style.textContent = css;\n // Last in <head> so equal-specificity `!important` rules win over the site's; the static sheet after it.\n const last = fixed?.isConnected && doc.head?.lastElementChild === fixed ? fixed.previousElementSibling : doc.head?.lastElementChild;\n if (style.parentNode !== doc.head || last !== style) (doc.head || doc.documentElement).appendChild(style);\n placeStatic(fixed, style);\n syncRoots(true, snapshotKey, force);\n const full = `${themeVarsCss(resolved)}\\n${css}${staticText ? `\\n${staticText}` : ''}`;\n if (full !== savedCss) { savedCss = full; writeSnapshot(storage, { key: snapshotKey, choice, css: full }); }\n };\n\n const handle: ThemeHandle<Mode> = {\n apply(input) {\n choice = catalog.normalize(input);\n theme = catalog.resolve(choice);\n const fonts = bundledFontsUsed(theme);\n if (fonts.length) { try { options.loadFonts?.(fonts); } catch (error) { console.error(`[${name}] theme fonts failed`, error); } }\n if (active()) {\n if (!timer) timer = setInterval(() => { try { render(); } catch { /* Never break the site. */ } }, 1200);\n } else if (timer) { clearInterval(timer); timer = null; }\n try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); }\n win.dispatchEvent(new CustomEvent('wb-theme'));\n },\n current: () => choice,\n theme: () => theme,\n mode: () => mode,\n resolved: () => {\n if (doc.body && readMode() !== mode) syncResolved();\n return resolved;\n },\n onChange(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n refresh() { try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); } },\n };\n // The snapshot's theme until native code hands over the current one (usually the same): the\n // live CSS then already renders at DOMContentLoaded instead of after the page finished loading.\n if (snapshot) { try { handle.apply(snapshot.choice); } catch { /* Never break the site. */ } }\n if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', () => render(true), { once: true });\n // `--wb-*` exist from the start (the site's own palette until a theme is applied), for plugins and the UI kit.\n else if (doc.body) { try { watchMode(); syncResolved(); } catch { /* Never break the site. */ } }\n return handle;\n}\n"]}
1
+ {"version":3,"file":"themeRuntime.js","sourceRoot":"","sources":["../../../runtime/src/themeRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["// The theme engine in a site's page: keeps one `<style>` with the theme's CSS in sync while the site\n// adds its own rules (React apps insert them lazily), exposes the resolved theme as `--wb-*` custom\n// properties for plugins and the UI kit, follows the site's own color mode, and paints the last\n// theme from the page's first frame (a snapshot in the page's storage). What the CSS is comes from\n// the site adapter (`ThemeRuntimeSite`): X re-declares its own stylesheet rules with the theme's\n// colors (`buildThemeCss`) and adds type/shape/layout rules over its selectors.\n\nimport { domRoots, watchDom, type DomWatchHandle } from './domHub.ts';\nimport { FONT_ROLE_NAMES, themeKey, themeVarsCss, type ResolvedFonts, type ResolvedTheme } from './themeApi.ts';\nimport type { ThemeCatalog, ThemeChoice } from './themeChoice.ts';\nimport { bundledFontsUsed, isNeutral, resolveFontRoles, type FontSpec, type ThemeSpec } from './themeSpec.ts';\n\n/** A style rule as the engine reads it (CSSStyleRule, or a plain object in tests). */\nexport type RuleLike = { selectorText: string; style: { getPropertyValue(name: string): string; length?: number } };\n\n/** The font roles as the plugin API reports them in a site's page; an inheriting interface uses `siteStack` (the site's own font). */\nexport function resolvedFonts(font: FontSpec, siteStack: string): ResolvedFonts {\n const roles = resolveFontRoles(font, siteStack);\n return Object.fromEntries(FONT_ROLE_NAMES.map(role => {\n const { stack, weight, size, tracking, tabular, inherited } = roles[role];\n return [role, { stack, weight, size, tracking, tabular, inherited }];\n })) as ResolvedFonts;\n}\n\ntype RuleNode = { selectorText?: string; style?: RuleLike['style']; cssRules?: ArrayLike<RuleNode>; conditionText?: string; type?: number; constructor?: { name?: string } };\nconst isSupports = (rule: RuleNode) => rule.type === 12 || rule.constructor?.name === 'CSSSupportsRule';\n\n/**\n * A style rule as it takes effect. Tailwind 4 writes an opacity utility as a fallback plus the real\n * value in a nested `@supports`:\n * `.bg-white\\/15 { background-color: var(--white); @supports (color: color-mix(in lab, red, red)) { background-color: color-mix(in oklab, var(--white) 15%, transparent) } }`.\n * Read alone, the outer declaration is a solid white fill; where the browser passes the condition the\n * nested one is what paints, so it answers for the rule.\n */\nfunction effectiveRule(rule: RuleNode, supported: (condition: string) => boolean): RuleLike {\n const overrides: Array<RuleLike['style']> = [];\n for (const child of Array.from(rule.cssRules ?? [])) {\n if (!isSupports(child) || !supported(child.conditionText ?? '')) continue;\n for (const inner of Array.from(child.cssRules ?? [])) {\n // Bare declarations inside the group: a CSSNestedDeclarations, or `& { }` in older engines.\n if (inner.style && (inner.selectorText === undefined || inner.selectorText === '&')) overrides.push(inner.style);\n }\n }\n if (!overrides.length) return rule as RuleLike;\n const outer = rule.style!;\n return {\n selectorText: rule.selectorText!,\n style: {\n getPropertyValue(name) {\n for (let i = overrides.length - 1; i >= 0; i--) { const value = overrides[i]!.getPropertyValue(name); if (value) return value; }\n return outer.getPropertyValue(name);\n },\n length: outer.length,\n },\n };\n}\n\n/**\n * Every style rule of `doc`'s stylesheets (inside media/supports groups too), except `own`'s (the\n * engine's own sheets: read as the site's, their radii and colors would be re-declared), each as it\n * takes effect (`effectiveRule`). A `@supports` group the browser does not pass is left out.\n */\nexport function collectRules(doc: Document, own: HTMLStyleElement | null | ReadonlyArray<HTMLStyleElement | null>): RuleLike[] {\n const ours = (Array.isArray(own) ? own : [own]).filter(Boolean) as HTMLStyleElement[];\n const sheets = Array.from(doc.styleSheets).filter(sheet => !ours.includes(sheet.ownerNode as HTMLStyleElement));\n return rulesOf(sheets, (doc.defaultView as (Window & typeof globalThis) | null)?.CSS);\n}\n\ntype SheetLike = { cssRules: CSSRuleList | ArrayLike<unknown> };\n/**\n * The same for an open shadow root the site renders a part of itself in (X's chat embed): its adopted\n * sheets and its `<style>` elements, except the engine's own adopted `own` sheet.\n */\nexport function collectRootRules(root: { adoptedStyleSheets?: readonly SheetLike[]; styleSheets?: ArrayLike<SheetLike> }, own: SheetLike | null, css?: { supports?(condition: string): boolean }): RuleLike[] {\n const sheets = [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])].filter(sheet => sheet !== own);\n return rulesOf(sheets, css);\n}\n\nfunction rulesOf(sheets: readonly SheetLike[], css: { supports?(condition: string): boolean } | undefined): RuleLike[] {\n const rules: RuleLike[] = [];\n const verdicts = new Map<string, boolean>();\n const supported = (condition: string) => {\n if (!condition || !css?.supports) return true;\n let verdict = verdicts.get(condition);\n if (verdict === undefined) { try { verdict = css.supports(condition); } catch { verdict = true; } verdicts.set(condition, verdict); }\n return verdict;\n };\n const walk = (list: ArrayLike<RuleNode>) => {\n for (const rule of Array.from(list)) {\n if (rule.selectorText !== undefined && rule.style) rules.push(effectiveRule(rule, supported));\n else if (rule.cssRules && rule.selectorText === undefined && (!isSupports(rule) || supported(rule.conditionText ?? ''))) walk(rule.cssRules);\n }\n };\n for (const sheet of sheets) {\n try { walk(sheet.cssRules as unknown as ArrayLike<RuleNode>); } catch { /* Cross-origin sheet. */ }\n }\n return rules;\n}\n\nfunction rootRuleCount(root: ShadowRoot, own: CSSStyleSheet | null): number {\n let count = 0;\n for (const sheet of [...Array.from(root.adoptedStyleSheets ?? []), ...Array.from(root.styleSheets ?? [])]) {\n if (sheet === own) continue;\n try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ }\n }\n return count;\n}\n\nfunction ruleCount(doc: Document): number {\n let count = 0;\n for (const sheet of Array.from(doc.styleSheets)) { try { count += sheet.cssRules.length; } catch { /* Cross-origin. */ } }\n return count;\n}\n\n/**\n * The last theme CSS a tab showed, kept in the page's own storage so the next document paints it\n * from its first frame: native code only hands the theme over once the page has finished loading,\n * and the live CSS needs the site's rules, which it inserts while it renders. sessionStorage is per\n * tab and survives reloads and navigations; localStorage (smaller cap: the site uses it too) is per\n * account and covers a tab's first document.\n */\nexport type ThemeSnapshot = { key: string; choice: unknown; css: string };\nconst SNAPSHOT_KEY = 'wb:theme-snapshot';\nexport const SNAPSHOT_SESSION_MAX = 1_000_000;\nexport const SNAPSHOT_LOCAL_MAX = 200_000;\nexport type SnapshotStores = { session?: Storage | null; local?: Storage | null };\n\nfunction stores(win: Window): SnapshotStores {\n const get = (name: 'sessionStorage' | 'localStorage') => { try { return win[name]; } catch { return null; } };\n return { session: get('sessionStorage'), local: get('localStorage') };\n}\n\nexport function readSnapshot({ session, local }: SnapshotStores): ThemeSnapshot | null {\n for (const store of [session, local]) {\n try {\n const value = JSON.parse(store?.getItem(SNAPSHOT_KEY) || 'null') as Partial<ThemeSnapshot> | null;\n if (value && typeof value.key === 'string' && typeof value.css === 'string' && value.css && value.choice) return value as ThemeSnapshot;\n } catch { /* Missing, blocked or foreign data: no snapshot. */ }\n }\n return null;\n}\n\n/** Stores `snapshot` (null clears it: the site's own look needs none), each store within its cap. */\nexport function writeSnapshot({ session, local }: SnapshotStores, snapshot: ThemeSnapshot | null) {\n const json = snapshot ? JSON.stringify(snapshot) : '';\n for (const [store, max] of [[session, SNAPSHOT_SESSION_MAX], [local, SNAPSHOT_LOCAL_MAX]] as const) {\n try {\n if (json && json.length <= max) store?.setItem(SNAPSHOT_KEY, json);\n else store?.removeItem(SNAPSHOT_KEY);\n } catch { /* Quota or blocked storage: the next document just starts unthemed. */ }\n }\n}\n\n/** What the engine needs to know about a site. `Mode` is the site's own color mode (X: light, dim, dark). */\nexport type ThemeRuntimeSite<Mode extends string = string> = {\n /** The site's built-in themes (themeChoice.ts). */\n catalog: ThemeCatalog;\n /** The mode before the page has a body. */\n initialMode: Mode;\n /** The site's color mode as the page paints it now (read before the theme's own override: e.g. the body's inline style). */\n readMode(win: Window): Mode;\n /** The theme's CSS for the site's current `rules` (the engine's own sheet excluded) in `mode`; `vars` are `siteVars` as the site sets them. */\n css(rules: RuleLike[], choice: ThemeChoice, mode: Mode, vars: Record<string, string>, flags: readonly string[]): string;\n /** The active theme resolved for plugins and the UI kit (the site's own palette when the theme keeps its colors). */\n resolved(choice: ThemeChoice, mode: Mode): ResolvedTheme;\n /** Custom properties of the site's root read with the theme's sheet disabled (their unthemed values). */\n siteVars?: readonly string[];\n /**\n * The theme's CSS that does not depend on the site's stylesheet: components, variants, decoration,\n * icons. It lives in its own sheet (`staticId`), so the site inserting rules never rebuilds it; it is\n * rebuilt when the theme or the site's mode changes and on `refresh()` (the owner's switches, the\n * icon choice, the language).\n */\n staticCss?(choice: ThemeChoice, mode: Mode): string;\n /** Id of that sheet's `<style>` (default `wb-theme-static`). */\n staticId?: string;\n /** Id of the theme's `<style>` (default `wb-theme-css`). */\n styleId?: string;\n /** Name in console errors. */\n name?: string;\n /**\n * Page states the theme's CSS keys on, as `html[data-wb-<name>]` attributes kept by the engine:\n * set while `selector` matches in the page or one of its open shadow roots (domHub `shadowHosts`).\n * A theme rule gated by `html[data-wb-chat]` costs nothing when the page changes; the same gate\n * as `html:has(...)` makes the browser re-match the whole page on every insertion (seen on x.com:\n * 10-100 ms per inserted node under a theme instead of 0.1 ms).\n */\n flags?: Readonly<Record<string, string>>;\n};\n\n/** The attribute a page flag sets on `<html>`. */\nexport const flagAttribute = (name: string) => `data-wb-${name}`;\n\n/** Which of `flags` hold in `roots` now (pure, for tests). */\nexport function pageFlags(roots: ReadonlyArray<{ querySelector(selector: string): unknown }>, flags: Readonly<Record<string, string>>): string[] {\n const on: string[] = [];\n for (const [name, selector] of Object.entries(flags)) {\n try { if (roots.some(root => !!root.querySelector(selector))) on.push(name); } catch { /* A bad selector is never on. */ }\n }\n return on;\n}\n\nexport type ThemeHandle<Mode extends string = string> = {\n apply(choice: unknown): void;\n current(): ThemeChoice;\n theme(): ThemeSpec;\n /** The site's color mode the theme was last rendered for. */\n mode(): Mode;\n /** The active theme as values for plugins (`api.theme.current()`). */\n resolved(): ResolvedTheme;\n /** Calls `listener` after the theme or the site's color mode changes. */\n onChange(listener: () => void): () => void;\n /** Rebuilds the theme's CSS now: something it depends on besides the theme changed (the owner's switches, the icon choice). */\n refresh(): void;\n};\nexport type ThemeRuntimeOptions = { /** Registers bundled families (e.g. \"Geist\") in the page before they are used. */ loadFonts?(names: string[]): void };\n\nconst VARS_ID = 'wb-theme-vars';\n\n/** Keeps the site's page in the owner's theme (see the top of this file). */\nexport function installThemeRuntime<Mode extends string>(win: Window, site: ThemeRuntimeSite<Mode>, options: ThemeRuntimeOptions = {}): ThemeHandle<Mode> {\n const doc = win.document;\n const name = site.name ?? 'wayBetter';\n const styleId = site.styleId ?? 'wb-theme-css';\n const staticId = site.staticId ?? 'wb-theme-static';\n const { catalog } = site;\n // Document start (no <html> yet): the snapshot as an adopted sheet paints with the site's first\n // frame. It stays while the live CSS is for the same theme and site mode, and goes when they differ.\n const storage = stores(win);\n const snapshot = readSnapshot(storage);\n let early: CSSStyleSheet | null = null;\n if (snapshot) {\n try {\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n early = new Sheet();\n early.replaceSync(snapshot.css);\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, early];\n } catch { early = null; }\n }\n const dropEarly = () => {\n if (!early) return;\n const sheet = early;\n early = null;\n try { doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Never break the site. */ }\n };\n let savedCss = snapshot?.css ?? '';\n let choice = catalog.defaultChoice;\n let theme = catalog.resolve(choice);\n let lastKey = '';\n let timer: ReturnType<typeof setInterval> | null = null;\n const active = () => !isNeutral(theme) || !!choice.accent || !!choice.icons;\n let mode: Mode = site.initialMode;\n let resolved: ResolvedTheme = site.resolved(choice, mode);\n let resolvedKey = themeKey(resolved);\n const listeners = new Set<() => void>();\n const readMode = () => (doc.body ? site.readMode(win) : mode);\n /** `--wb-*` on :root for plugin CSS, and a change notice when anything visible changed. */\n const syncResolved = () => {\n if (doc.body) mode = readMode();\n resolved = site.resolved(choice, mode);\n const key = themeKey(resolved);\n let vars = doc.getElementById(VARS_ID) as HTMLStyleElement | null;\n if (!vars?.isConnected) {\n vars = doc.createElement('style');\n vars.id = VARS_ID;\n (doc.head || doc.documentElement).appendChild(vars);\n }\n const css = themeVarsCss(resolved);\n if (vars.textContent !== css) vars.textContent = css;\n if (key === resolvedKey) return;\n resolvedKey = key;\n for (const listener of [...listeners]) {\n try { listener(); } catch (error) { console.error(`[${name}] theme listener failed`, error); }\n }\n };\n let modeObserver: MutationObserver | null = null;\n const watchMode = () => {\n if (modeObserver || !doc.body) return;\n // Sites repaint the body when their own display setting changes (X: Default / Dim / Lights out).\n const Observer = (win as Window & typeof globalThis).MutationObserver ?? globalThis.MutationObserver;\n if (!Observer) return;\n modeObserver = new Observer(() => { try { if (readMode() !== mode) syncResolved(); } catch { /* Never break the site. */ } });\n modeObserver.observe(doc.body, { attributes: true, attributeFilter: ['style'] });\n };\n\n let staticKey = '';\n let staticText = '';\n let siteVars: Record<string, string> = {};\n // Page flags (`site.flags`): checked once per hub frame after the page changed, on every page (heavy ones too).\n const flagNames = Object.keys(site.flags ?? {});\n let flagWatch: DomWatchHandle | null = null;\n // The flags that hold now; the theme's CSS is rebuilt when they change (a rule that only applies to a\n // signed-out page can then be left out of a signed-in one instead of being gated by `:has()`).\n let flagState: string[] = [];\n const syncFlags = () => {\n const root = doc.documentElement;\n if (!root || !flagNames.length) return;\n let on: string[] = [];\n try { on = pageFlags(domRoots(win), site.flags!); } catch { on = []; }\n for (const name of flagNames) {\n const attr = flagAttribute(name);\n const want = on.includes(name);\n if (root.hasAttribute(attr) !== want) { if (want) root.setAttribute(attr, ''); else root.removeAttribute(attr); }\n }\n const changed = on.join(' ') !== flagState.join(' ');\n flagState = on;\n return changed;\n };\n const flagsOn = (on: boolean) => {\n if (!flagNames.length) return;\n if (on) {\n syncFlags();\n if (!flagWatch) { try { flagWatch = watchDom(win as never, () => { if (syncFlags()) { try { render(); } catch { /* Never break the site. */ } } }, { offOnHeavy: false }); } catch { flagWatch = null; } }\n } else {\n flagWatch?.dispose(); flagWatch = null;\n for (const name of flagNames) doc.documentElement?.removeAttribute(flagAttribute(name));\n }\n };\n // Open shadow roots the site renders a part of itself in (domHub `shadowHosts`; X's chat embed since\n // 2026-10-01): the document's sheets do not reach inside, so each root adopts the theme built from\n // its own rules plus the static sheet, kept last among its sheets, rebuilt when its rules change and\n // taken off when the theme is off or the root is gone.\n const rootSheets = new Map<ShadowRoot, { sheet: CSSStyleSheet; key: string }>();\n const detach = (root: ShadowRoot, sheet: CSSStyleSheet) => { try { root.adoptedStyleSheets = root.adoptedStyleSheets.filter(item => item !== sheet); } catch { /* Root gone. */ } };\n const syncRoots = (on: boolean, snapshotKey: string, force: boolean) => {\n let roots: ShadowRoot[] = [];\n if (on) { try { roots = domRoots(win).slice(1) as ShadowRoot[]; } catch { roots = []; } }\n for (const [root, item] of rootSheets) if (!roots.includes(root)) { detach(root, item.sheet); rootSheets.delete(root); }\n const Sheet = (win as Window & typeof globalThis).CSSStyleSheet;\n for (const root of roots) {\n let item = rootSheets.get(root);\n if (!item) {\n try { item = { sheet: new Sheet(), key: '' }; } catch { continue; }\n rootSheets.set(root, item);\n }\n const key = `${snapshotKey}|${flagState.join(' ')}|${rootRuleCount(root, item.sheet)}|${staticText.length}`;\n if (force || item.key !== key) {\n item.key = key;\n // The site's primitives as the root sees them (its own sheets may declare them; the document may not), read with our sheet off.\n const vars = { ...siteVars };\n if (site.siteVars?.length) {\n const probe = root.firstElementChild ?? root.host;\n item.sheet.disabled = true;\n try { const style = win.getComputedStyle(probe); for (const name of site.siteVars) { const value = style.getPropertyValue(name).trim(); if (value) vars[name] = value; } } catch { /* Keep the document's. */ }\n item.sheet.disabled = false;\n }\n let css = '';\n try { css = site.css(collectRootRules(root, item.sheet, (win as Window & typeof globalThis).CSS), choice, mode, vars, flagState); } catch (error) { console.error(`[${name}] theme (shadow root) failed`, error); }\n try { item.sheet.replaceSync(staticText ? `${css}\\n${staticText}` : css); } catch { /* Keeps the last good rules. */ }\n }\n // Last, so equal-specificity `!important` rules win over the site's; the site may re-set its list.\n const list = root.adoptedStyleSheets;\n if (list[list.length - 1] !== item.sheet) { try { root.adoptedStyleSheets = [...list.filter(sheet => sheet !== item!.sheet), item.sheet]; } catch { /* Never break the site. */ } }\n }\n };\n /** The static sheet sits right after the palette sheet (its part rules are more specific anyway; order only breaks ties). */\n const placeStatic = (fixed: HTMLStyleElement | null, style: HTMLStyleElement | null) => {\n if (!fixed || !style?.isConnected) return;\n if (style.nextElementSibling !== fixed) style.after(fixed);\n };\n const render = (force = false) => {\n let style = doc.getElementById(styleId) as HTMLStyleElement | null;\n let fixed = doc.getElementById(staticId) as HTMLStyleElement | null;\n if (doc.body) { watchMode(); syncResolved(); }\n if (!active()) { style?.remove(); fixed?.remove(); lastKey = ''; staticKey = ''; dropEarly(); syncRoots(false, '', false); flagsOn(false); if (savedCss) { savedCss = ''; writeSnapshot(storage, null); } return; }\n if (!doc.body) return;\n flagsOn(true);\n const snapshotKey = `${JSON.stringify(choice)}|${mode}`;\n if (early && snapshot?.key !== snapshotKey) dropEarly();\n // The static sheet follows the theme and the mode only (and `refresh()`), never the site's rules.\n if (site.staticCss && (force || staticKey !== snapshotKey)) {\n staticKey = snapshotKey;\n let text = '';\n try { text = site.staticCss(choice, mode); } catch (error) { console.error(`[${name}] theme structure failed`, error); }\n staticText = text;\n if (text) {\n if (!fixed) { fixed = doc.createElement('style'); fixed.id = staticId; }\n if (fixed.textContent !== text) fixed.textContent = text;\n } else { fixed?.remove(); fixed = null; }\n }\n const key = `${JSON.stringify(choice)}|${mode}|${flagState.join(' ')}|${ruleCount(doc) - (style?.sheet?.cssRules.length ?? 0) - (fixed?.sheet?.cssRules.length ?? 0)}`;\n if (!force && key === lastKey) { placeStatic(fixed, style); syncRoots(true, snapshotKey, false); return; }\n lastKey = key;\n if (!style) { style = doc.createElement('style'); style.id = styleId; }\n // The site's own values, not the ones our previous render overrode (switching themes re-reads them).\n if (style.sheet) style.sheet.disabled = true;\n const vars: Record<string, string> = {};\n if (site.siteVars?.length) {\n const rootStyle = win.getComputedStyle(doc.documentElement);\n for (const name of site.siteVars) vars[name] = rootStyle.getPropertyValue(name).trim();\n }\n if (style.sheet) style.sheet.disabled = false;\n siteVars = vars;\n const css = site.css(collectRules(doc, [style, fixed]), choice, mode, vars, flagState);\n if (style.textContent !== css) style.textContent = css;\n // Last in <head> so equal-specificity `!important` rules win over the site's; the static sheet after it.\n const last = fixed?.isConnected && doc.head?.lastElementChild === fixed ? fixed.previousElementSibling : doc.head?.lastElementChild;\n if (style.parentNode !== doc.head || last !== style) (doc.head || doc.documentElement).appendChild(style);\n placeStatic(fixed, style);\n syncRoots(true, snapshotKey, force);\n const full = `${themeVarsCss(resolved)}\\n${css}${staticText ? `\\n${staticText}` : ''}`;\n if (full !== savedCss) { savedCss = full; writeSnapshot(storage, { key: snapshotKey, choice, css: full }); }\n };\n\n const handle: ThemeHandle<Mode> = {\n apply(input) {\n choice = catalog.normalize(input);\n theme = catalog.resolve(choice);\n const fonts = bundledFontsUsed(theme);\n if (fonts.length) { try { options.loadFonts?.(fonts); } catch (error) { console.error(`[${name}] theme fonts failed`, error); } }\n if (active()) {\n if (!timer) timer = setInterval(() => { try { render(); } catch { /* Never break the site. */ } }, 1200);\n } else if (timer) { clearInterval(timer); timer = null; }\n try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); }\n win.dispatchEvent(new CustomEvent('wb-theme'));\n },\n current: () => choice,\n theme: () => theme,\n mode: () => mode,\n resolved: () => {\n if (doc.body && readMode() !== mode) syncResolved();\n return resolved;\n },\n onChange(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n refresh() { try { render(true); } catch (error) { console.error(`[${name}] theme failed`, error); } },\n };\n // The snapshot's theme until native code hands over the current one (usually the same): the\n // live CSS then already renders at DOMContentLoaded instead of after the page finished loading.\n if (snapshot) { try { handle.apply(snapshot.choice); } catch { /* Never break the site. */ } }\n if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', () => render(true), { once: true });\n // `--wb-*` exist from the start (the site's own palette until a theme is applied), for plugins and the UI kit.\n else if (doc.body) { try { watchMode(); syncResolved(); } catch { /* Never break the site. */ } }\n return handle;\n}\n"]}
@@ -153,7 +153,11 @@ export declare const SYSTEM_SANS: string[];
153
153
  export declare const isHex: (value: unknown) => value is string;
154
154
  /** `#rrggbb` + alpha as `rgba()`. */
155
155
  export declare const rgba: (hex: string, alpha: number) => string;
156
- /** Moves `color` toward black or white until it reaches `ratio` against every surface. */
156
+ /**
157
+ * The colour closest to `color` (OKLCH lightness, hue kept) that reaches `ratio` against every surface
158
+ * (themeInk.ts). A colour that has to move gets 8% headroom: the site's hover and pressed tints are mixed
159
+ * from these surfaces, and an exact solver would leave the ink a hair under the target on them.
160
+ */
157
161
  export declare function reach(color: string, surfaces: string[], ratio: number): string;
158
162
  /**
159
163
  * Guarantees legibility for any palette (built-in, imported or overridden): text, secondary text
@@ -15,8 +15,9 @@
15
15
  // Fonts: sites usually block remote and `data:` fonts (CSP `font-src`), so a theme may name installed
16
16
  // system fonts, "Geist" / "Geist Mono" (bundled and registered from bytes: `FontFace(ArrayBuffer)` is
17
17
  // not a fetch), or Google Fonts families the owner downloaded (`source: "google"`, fonts.ts).
18
- import { FONT_ROLE_NAMES, MONO_FAMILIES, contrastRatio, hexToRgb, mix, relativeLuminance } from "./themeApi.js";
18
+ import { FONT_ROLE_NAMES, MONO_FAMILIES, hexToRgb, mix } from "./themeApi.js";
19
19
  import { deriveColors } from "./themeTokens.js";
20
+ import { inkOnEvery } from "./themeInk.js";
20
21
  import { ACTION_NAMES, sanitizeComponents } from "./themeComponents.js";
21
22
  import { sanitizeDecor } from "./themeDecor.js";
22
23
  import { sanitizeThemeIcons } from "./themeIcons.js";
@@ -42,19 +43,14 @@ export const SYSTEM_SANS = ['Segoe UI', '-apple-system', 'BlinkMacSystemFont', '
42
43
  export const isHex = (value) => typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value);
43
44
  /** `#rrggbb` + alpha as `rgba()`. */
44
45
  export const rgba = (hex, alpha) => `rgba(${hexToRgb(hex).join(', ')}, ${+alpha.toFixed(3)})`;
45
- /** Moves `color` toward black or white until it reaches `ratio` against every surface. */
46
+ /**
47
+ * The colour closest to `color` (OKLCH lightness, hue kept) that reaches `ratio` against every surface
48
+ * (themeInk.ts). A colour that has to move gets 8% headroom: the site's hover and pressed tints are mixed
49
+ * from these surfaces, and an exact solver would leave the ink a hair under the target on them.
50
+ */
46
51
  export function reach(color, surfaces, ratio) {
47
- const worst = (c) => Math.min(...surfaces.map(s => contrastRatio(c, s)));
48
- if (worst(color) >= ratio)
49
- return color;
50
- const lightSurfaces = surfaces.reduce((sum, s) => sum + relativeLuminance(s), 0) / surfaces.length > 0.18;
51
- const pole = lightSurfaces ? '#000000' : '#ffffff';
52
- for (let t = 0.04; t <= 1; t += 0.04) {
53
- const next = mix(color, pole, t);
54
- if (worst(next) >= ratio)
55
- return next;
56
- }
57
- return pole;
52
+ const kept = inkOnEvery(surfaces, color, ratio);
53
+ return kept.adjusted ? inkOnEvery(surfaces, color, ratio * 1.08).ink : kept.ink;
58
54
  }
59
55
  /**
60
56
  * Guarantees legibility for any palette (built-in, imported or overridden): text, secondary text
@@ -1 +1 @@
1
- {"version":3,"file":"themeSpec.js","sourceRoot":"","sources":["../../../runtime/src/themeSpec.ts"],"names":[],"mappings":"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","sourcesContent":["// Theme documents: a wayBetter theme is a JSON document (like a BetterDiscord theme, but data instead\n// of a stylesheet) describing colors, type, shape, density, layout, background and motion; the format\n// is `theme.schema.json` in the `waybetter` package. This module is the document side of the theme\n// engine: types, the schema's defaults, sanitizing, import, panel overrides, legibility, font roles\n// and stacks, and page backgrounds. Pure, so it runs in the page runtime, the settings previews and\n// the tests. What a theme does to one site's page (its selectors, its palette) is the site's\n// (themeRuntime.ts takes a site adapter).\n//\n// Safety: a theme is sanitized field by field before it becomes CSS. Colors are six-digit hex,\n// numbers are clamped, enums are fixed, font names match a strict pattern, background images are\n// `data:image/*;base64` only, and CSS is built from those values (never concatenated from raw\n// strings). The single escape hatch is `css`, which is the same trust level as the owner's own\n// Custom CSS and is shown as such when a theme is imported.\n//\n// Fonts: sites usually block remote and `data:` fonts (CSP `font-src`), so a theme may name installed\n// system fonts, \"Geist\" / \"Geist Mono\" (bundled and registered from bytes: `FontFace(ArrayBuffer)` is\n// not a fetch), or Google Fonts families the owner downloaded (`source: \"google\"`, fonts.ts).\n\nimport { FONT_ROLE_NAMES, MONO_FAMILIES, contrastRatio, hexToRgb, mix, relativeLuminance, type FontRoleName } from './themeApi.ts';\nimport { deriveColors } from './themeTokens.ts';\nimport { ACTION_NAMES, sanitizeComponents, type ActionColors, type ThemeComponents } from './themeComponents.ts';\nimport { sanitizeDecor, type ThemeDecor } from './themeDecor.ts';\nimport { sanitizeThemeIcons, type ThemeIcons } from './themeIcons.ts';\nimport { sanitizeVariants, type ThemeVariants } from './themeVariants.ts';\n\nexport { FONT_ROLE_NAMES } from './themeApi.ts';\nexport type { FontRoleName } from './themeApi.ts';\n\nexport type Role = 'bg' | 'surface' | 'elevated' | 'border' | 'text' | 'muted' | 'accent';\n/** The site's filled primary button (X: \"Post\"/\"Follow\"): an `inverse` background with an `onInverse` label. */\nexport type ButtonRole = 'inverse' | 'onInverse';\nexport type Palette = Record<Role, string> & Partial<Record<ButtonRole, string>>;\n/**\n * `page` is the canvas behind the site's columns (defaults to `bg`); the columns stay on `bg`.\n * `actions` are the colors of a set action (liked, reposted, bookmarked) and of the reply hover;\n * absent, the site's own action colors stay.\n */\nexport type ThemeColors = Palette & { page?: string; actions?: ActionColors };\n\nexport type Density = 'compact' | 'default' | 'comfortable';\nexport type AvatarShape = 'circle' | 'rounded' | 'square';\nexport type Pattern = 'dots' | 'grid' | 'diagonal' | 'scanlines' | 'paper' | 'clouds';\nexport type Background =\n | { kind: 'none' }\n | { kind: 'gradient'; from: string; to: string; angle: number; glow?: string }\n | { kind: 'pattern'; pattern: Pattern; ink: string; opacity: number; size: number }\n | { kind: 'image'; url: string; fit: 'cover' | 'tile'; dim: number };\n\n/**\n * One role's font (roles: themeApi.ts `FONT_ROLE_NAMES`). `family` is a font stack; empty keeps the\n * inherited family and only changes the rest. `source: \"google\"` says the first family comes from\n * Google Fonts (downloaded once, asked first when a theme is imported, loaded from bytes). `weight`\n * (100-900), `size` (0.75-1.5, relative to the site's size), `tracking` (em) and `tabular` figures\n * are optional; the interface role takes only `family`/`source` (its size, weights and tracking are\n * `scale`, `weight`, `bold` and `tracking` of the whole theme).\n */\nexport type FontRoleSpec = { family: string[]; source?: 'google'; weight?: number; size?: number; tracking?: number; tabular?: boolean };\nexport type FontRole = 'inherit' | FontRoleSpec;\nexport type FontRoles = Record<FontRoleName, FontRole>;\n\nexport type FontSpec = {\n /**\n * Interface font stack (replaces the site's own font everywhere). Empty keeps the site's.\n * Shorthand kept for older theme files and older apps: it always equals `roles.interface`'s family.\n */\n family: string[];\n /** Post text stack (e.g. a serif reading face); shorthand of `roles.post`'s family. */\n tweet: string[];\n /** Which font goes where. Every role inherits from `interface` unless it says otherwise. */\n roles: FontRoles;\n /** Multiplies the site's pixel font sizes (0.85-1.2). */\n scale: number;\n /** Regular weight (300-500) and bold weight (500-800) that replace the site's 400/700. */\n weight: number;\n bold: number;\n /** Letter spacing in em (-0.03-0.06). */\n tracking: number;\n /** Line height multiplier for post text (0 keeps the site's). */\n leading: number;\n};\nexport type ShapeSpec = { radius: number; button: number; avatar: AvatarShape };\nexport type LayoutSpec = { column: number; sidebar: number; density: Density; cards: boolean; frame: boolean };\nexport type EffectsSpec = { motion: number; hover: 'none' | 'tint' | 'lift' | 'glow'; shadow: 'none' | 'soft' | 'deep'; crt: boolean };\n\nexport type ThemeSpec = {\n id: string;\n name: string;\n description: string;\n author: string;\n version: 1;\n /** Which way the theme leans; used for scrollbars/form controls and previews. */\n mode: 'light' | 'dark' | 'auto';\n /** null keeps the site's own colors (X: Default / Dim / Lights out). */\n colors: ThemeColors | null;\n font: FontSpec;\n shape: ShapeSpec;\n layout: LayoutSpec;\n background: Background;\n effects: EffectsSpec;\n /** Free-form CSS appended last (owner-trusted, like Custom CSS). */\n css: string;\n // The groups below are optional and additive: a theme without them is drawn exactly as before,\n // and an app that does not know them drops them and draws the rest.\n /** How each piece of the site is built (themeComponents.ts). */\n components?: ThemeComponents;\n /** Structural choices: where the navigation sits, how a post is laid out (themeVariants.ts). */\n variants?: ThemeVariants;\n /** Lines, bars, focus ring, selection, scrollbars, motion (themeDecor.ts). */\n decor?: ThemeDecor;\n /** Which icon pack the theme suggests, with small adjustments (themeIcons.ts). */\n icons?: ThemeIcons;\n};\n\n/** Panel overrides: any group may be partially overridden on top of the selected theme. */\nexport type ThemeOverrides = {\n colors?: Partial<ThemeColors>;\n /** `roles` is merged role by role (a named role replaces that role only). */\n font?: Partial<Omit<FontSpec, 'roles'>> & { roles?: Partial<FontRoles> };\n shape?: Partial<ShapeSpec>;\n layout?: Partial<LayoutSpec>;\n background?: Background;\n effects?: Partial<EffectsSpec>;\n /** The theme's own CSS as edited in the panel (replaces the theme document's `css`). */\n css?: { text: string };\n /** The owner's say on a theme's layout suggestions, axis by axis (an axis set to the site's own option switches it off). */\n variants?: Record<string, string>;\n};\n\n// ---------------------------------------------------------------------------------------------\n// The schema's defaults: a theme that sets nothing changes nothing (the site keeps its own geometry;\n// a site's structure CSS only emits rules where a theme differs from these).\n\nexport const BASE_SHAPE: ShapeSpec = { radius: 16, button: 9999, avatar: 'circle' };\nexport const INHERIT_ROLES: FontRoles = { interface: 'inherit', post: 'inherit', heading: 'inherit', numbers: 'inherit', mono: 'inherit', chrome: 'inherit', dialog: 'inherit' };\n/** A font spec from the interface/post stacks alone (every other role inherits). */\nexport const withRoles = (font: Omit<FontSpec, 'roles'>): FontSpec => ({\n ...font,\n roles: { ...INHERIT_ROLES, ...(font.family.length ? { interface: { family: font.family } } : {}), ...(font.tweet.length ? { post: { family: font.tweet } } : {}) },\n});\nexport const BASE_FONT: FontSpec = withRoles({ family: [], tweet: [], scale: 1, weight: 400, bold: 700, tracking: 0, leading: 0 });\nexport const BASE_LAYOUT: LayoutSpec = { column: 600, sidebar: 350, density: 'default', cards: false, frame: false };\nexport const BASE_EFFECTS: EffectsSpec = { motion: 0, hover: 'none', shadow: 'none', crt: false };\n\n/** The system UI stack themes put after their own sans-serif families. */\nexport const SYSTEM_SANS = ['Segoe UI', '-apple-system', 'BlinkMacSystemFont', 'system-ui', 'sans-serif'];\n\n// ---------------------------------------------------------------------------------------------\n// Colors and contrast (luminance and ratios: themeApi.ts)\n\nexport const isHex = (value: unknown): value is string => typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value);\n/** `#rrggbb` + alpha as `rgba()`. */\nexport const rgba = (hex: string, alpha: number) => `rgba(${hexToRgb(hex).join(', ')}, ${+alpha.toFixed(3)})`;\n\n/** Moves `color` toward black or white until it reaches `ratio` against every surface. */\nexport function reach(color: string, surfaces: string[], ratio: number): string {\n const worst = (c: string) => Math.min(...surfaces.map(s => contrastRatio(c, s)));\n if (worst(color) >= ratio) return color;\n const lightSurfaces = surfaces.reduce((sum, s) => sum + relativeLuminance(s), 0) / surfaces.length > 0.18;\n const pole = lightSurfaces ? '#000000' : '#ffffff';\n for (let t = 0.04; t <= 1; t += 0.04) {\n const next = mix(color, pole, t);\n if (worst(next) >= ratio) return next;\n }\n return pole;\n}\n\n/**\n * Guarantees legibility for any palette (built-in, imported or overridden): text, secondary text\n * and links reach WCAG AA (4.5:1) on every surface, including the page canvas, and the site's filled\n * button keeps a readable label and stands out from the page (3:1).\n */\nexport function ensureContrast<T extends Palette & { page?: string; actions?: ActionColors }>(colors: T): T {\n const surfaces = [colors.bg, colors.surface, colors.elevated, ...(colors.page ? [colors.page] : [])];\n const out = { ...colors };\n out.text = reach(colors.text, surfaces, 7);\n out.muted = reach(colors.muted, surfaces, 4.5);\n // Links live inside the columns, never on the page canvas.\n out.accent = reach(colors.accent, [colors.bg, colors.surface, colors.elevated], 4.5);\n const inverse = colors.inverse ?? out.text;\n const onInverse = colors.onInverse ?? colors.bg;\n out.inverse = reach(inverse, [colors.bg], 3);\n out.onInverse = reach(onInverse, [out.inverse], 4.5);\n // Action colors are icons and counts: non-text contrast on the column and on a raised row.\n if (colors.actions) out.actions = Object.fromEntries(Object.entries(colors.actions).map(([name, color]) => [name, reach(color as string, [colors.bg, colors.surface], 3)]));\n return out;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Sanitizing\n\nconst GENERIC_FONTS = new Set(['system-ui', 'sans-serif', 'serif', 'monospace', 'cursive', 'ui-sans-serif', 'ui-serif', 'ui-monospace', 'ui-rounded', '-apple-system', 'BlinkMacSystemFont']);\nconst FONT_NAME = /^[A-Za-z0-9][A-Za-z0-9 .\\-]{0,47}$/;\nconst DATA_IMAGE = /^data:image\\/(png|jpeg|webp|gif|avif);base64,[A-Za-z0-9+/]+={0,2}$/;\nexport const MAX_IMAGE_CHARS = 1_100_000;\nexport const MAX_CSS_CHARS = 60_000;\nconst PATTERNS: Pattern[] = ['dots', 'grid', 'diagonal', 'scanlines', 'paper', 'clouds'];\n\nconst obj = (value: unknown): Record<string, unknown> => value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};\nconst num = (value: unknown, min: number, max: number, fallback: number) => typeof value === 'number' && Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : fallback;\nconst pick = <T extends string>(value: unknown, options: readonly T[], fallback: T): T => options.includes(value as T) ? value as T : fallback;\nconst text = (value: unknown, max: number, fallback = '') => typeof value === 'string' ? value.replace(/[\\u0000-\\u001f\\u007f]/g, '').trim().slice(0, max) : fallback;\n\nexport function sanitizeFonts(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((name): name is string => typeof name === 'string' && (GENERIC_FONTS.has(name) || FONT_NAME.test(name))).slice(0, 8);\n}\n\n/** A theme needs its background, text and accent; any other role it leaves out is derived from the\n * base structure (themeTokens.ts `deriveColors`), so every theme has the same proportions. */\nfunction sanitizeColors(value: unknown): ThemeColors | null {\n const source = obj(value);\n if (!(['bg', 'text', 'accent'] as const).every(role => isHex(source[role]))) return null;\n const named = Object.fromEntries((['bg', 'surface', 'elevated', 'border', 'text', 'muted', 'accent'] as Role[])\n .filter(role => isHex(source[role])).map(role => [role, (source[role] as string).toLowerCase()]));\n const colors = deriveColors(named as { bg: string; text: string; accent: string }) as ThemeColors;\n for (const role of ['inverse', 'onInverse', 'page'] as const) if (isHex(source[role])) colors[role] = (source[role] as string).toLowerCase();\n const actions = obj(source.actions);\n const named_actions = Object.fromEntries(ACTION_NAMES.filter(name => isHex(actions[name])).map(name => [name, (actions[name] as string).toLowerCase()]));\n if (Object.keys(named_actions).length) colors.actions = named_actions;\n return colors;\n}\n\nexport function sanitizeBackground(value: unknown): Background {\n const source = obj(value);\n if (source.kind === 'gradient' && isHex(source.from) && isHex(source.to)) {\n return { kind: 'gradient', from: source.from.toLowerCase(), to: source.to.toLowerCase(), angle: Math.round(num(source.angle, 0, 360, 180)), ...(isHex(source.glow) ? { glow: source.glow.toLowerCase() } : {}) };\n }\n if (source.kind === 'pattern' && isHex(source.ink)) {\n return { kind: 'pattern', pattern: pick(source.pattern, PATTERNS, 'dots'), ink: source.ink.toLowerCase(), opacity: num(source.opacity, 0, 0.6, 0.1), size: Math.round(num(source.size, 2, 400, 24)) };\n }\n if (source.kind === 'image' && typeof source.url === 'string' && source.url.length <= MAX_IMAGE_CHARS && DATA_IMAGE.test(source.url)) {\n return { kind: 'image', url: source.url, fit: pick(source.fit, ['cover', 'tile'] as const, 'cover'), dim: num(source.dim, 0.35, 0.95, 0.6) };\n }\n return { kind: 'none' };\n}\n\n/** Bounds of a role's own settings (the JSON Schema says the same; tested). */\nexport const ROLE_LIMITS = { weight: [100, 900], size: [0.75, 1.5], tracking: [-0.05, 0.1] } as const;\n\n/** One role from JSON: \"inherit\", or a stack with optional extras (clamped; unknown keys dropped). */\nexport function sanitizeFontRole(value: unknown, role: FontRoleName): FontRole {\n if (value === 'inherit' || value === null || value === undefined) return 'inherit';\n const source = obj(value);\n if (!Object.keys(source).length) return 'inherit';\n const family = sanitizeFonts(source.family);\n const out: FontRoleSpec = { family };\n if (source.source === 'google' && family.length && !GENERIC_FONTS.has(family[0]!)) out.source = 'google';\n if (role !== 'interface') {\n if (typeof source.weight === 'number' && Number.isFinite(source.weight)) out.weight = Math.round(num(source.weight, ...ROLE_LIMITS.weight, 400));\n if (typeof source.size === 'number' && Number.isFinite(source.size)) out.size = +num(source.size, ...ROLE_LIMITS.size, 1).toFixed(3);\n if (typeof source.tracking === 'number' && Number.isFinite(source.tracking)) out.tracking = +num(source.tracking, ...ROLE_LIMITS.tracking, 0).toFixed(4);\n if (source.tabular === true) out.tabular = true;\n }\n // A role that changes nothing is the same as inheriting.\n return Object.keys(out).length === 1 && !family.length ? 'inherit' : out;\n}\n\nconst roleFamily = (role: FontRole): string[] => role === 'inherit' ? [] : role.family;\n/** A role with a new family, keeping its other settings (and its Google source only for the same font). */\nexport function withFamily(role: FontRole, family: string[], source?: 'google'): FontRole {\n const rest = role === 'inherit' ? {} : { ...role };\n delete (rest as Partial<FontRoleSpec>).source;\n delete (rest as Partial<FontRoleSpec>).family;\n const next: FontRoleSpec = { ...rest, family, ...(source && family.length ? { source } : {}) };\n return Object.keys(next).length === 1 && !family.length ? 'inherit' : next;\n}\n\n/**\n * The roles of a font group from JSON over `base`: `roles.<name>` wins; the legacy shorthand\n * (`family` → interface, `tweet` → post) applies when that role is not named, so theme files and\n * saved customizations from before font roles keep working.\n */\nfunction sanitizeRoles(source: Record<string, unknown>, base: FontSpec): FontRoles {\n const named = obj(source.roles);\n const roles = { ...base.roles };\n for (const role of FONT_ROLE_NAMES) if (role in named) roles[role] = sanitizeFontRole(named[role], role);\n if (!('interface' in named) && 'family' in source) roles.interface = withFamily(base.roles.interface, sanitizeFonts(source.family), sameFirst(source.family, base.roles.interface));\n if (!('post' in named) && 'tweet' in source) roles.post = withFamily(base.roles.post, sanitizeFonts(source.tweet), sameFirst(source.tweet, base.roles.post));\n return roles;\n}\n/** Keeps a role's Google source when the shorthand still names the same first family. */\nfunction sameFirst(stack: unknown, role: FontRole): 'google' | undefined {\n return role !== 'inherit' && role.source === 'google' && Array.isArray(stack) && stack[0] === role.family[0] ? 'google' : undefined;\n}\n\nfunction sanitizeFont(value: unknown, base: FontSpec): FontSpec {\n const source = obj(value);\n const roles = sanitizeRoles(source, base);\n return {\n family: roleFamily(roles.interface),\n tweet: roleFamily(roles.post),\n roles,\n scale: num(source.scale, 0.85, 1.2, base.scale),\n weight: Math.round(num(source.weight, 300, 500, base.weight)),\n bold: Math.round(num(source.bold, 500, 800, base.bold)),\n tracking: num(source.tracking, -0.03, 0.06, base.tracking),\n leading: source.leading === 0 ? 0 : num(source.leading, 1.2, 1.8, base.leading),\n };\n}\nconst sanitizeShape = (value: unknown, base: ShapeSpec): ShapeSpec => {\n const source = obj(value);\n return { radius: Math.round(num(source.radius, 0, 28, base.radius)), button: Math.round(num(source.button, 0, 9999, base.button)), avatar: pick(source.avatar, ['circle', 'rounded', 'square'] as const, base.avatar) };\n};\nconst sanitizeLayout = (value: unknown, base: LayoutSpec): LayoutSpec => {\n const source = obj(value);\n return {\n column: Math.round(num(source.column, 520, 820, base.column)), sidebar: Math.round(num(source.sidebar, 290, 400, base.sidebar)),\n density: pick(source.density, ['compact', 'default', 'comfortable'] as const, base.density),\n cards: typeof source.cards === 'boolean' ? source.cards : base.cards, frame: typeof source.frame === 'boolean' ? source.frame : base.frame,\n };\n};\nconst sanitizeEffects = (value: unknown, base: EffectsSpec): EffectsSpec => {\n const source = obj(value);\n return {\n motion: Math.round(num(source.motion, 0, 400, base.motion)), hover: pick(source.hover, ['none', 'tint', 'lift', 'glow'] as const, base.hover),\n shadow: pick(source.shadow, ['none', 'soft', 'deep'] as const, base.shadow), crt: typeof source.crt === 'boolean' ? source.crt : base.crt,\n };\n};\n\nexport const slug = (value: string) => value.toLowerCase().normalize('NFKD').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40) || 'theme';\n\n/** Any JSON to a complete, safe theme. Missing groups fall back to the schema's defaults. */\nexport function sanitizeSpec(input: unknown): ThemeSpec {\n const source = obj(input);\n const name = text(source.name, 60) || 'Untitled theme';\n const id = typeof source.id === 'string' && /^[a-z0-9-]{1,40}$/.test(source.id) ? source.id : slug(name);\n return {\n id, name, description: text(source.description, 200), author: text(source.author, 60), version: 1,\n mode: pick(source.mode, ['light', 'dark', 'auto'] as const, 'auto'),\n colors: sanitizeColors(source.colors),\n font: sanitizeFont(source.font, BASE_FONT),\n shape: sanitizeShape(source.shape, BASE_SHAPE),\n layout: sanitizeLayout(source.layout, BASE_LAYOUT),\n background: sanitizeBackground(source.background),\n effects: sanitizeEffects(source.effects, BASE_EFFECTS),\n css: typeof source.css === 'string' ? source.css.slice(0, MAX_CSS_CHARS) : '',\n ...structureGroups(source),\n };\n}\n\n/** The optional structure groups of a theme, each present only when it says something valid. */\nfunction structureGroups(source: Record<string, unknown>): Pick<ThemeSpec, 'components' | 'variants' | 'decor' | 'icons'> {\n const components = sanitizeComponents(source.components), variants = sanitizeVariants(source.variants);\n const decor = sanitizeDecor(source.decor), icons = sanitizeThemeIcons(source.icons);\n return { ...(components ? { components } : {}), ...(variants ? { variants } : {}), ...(decor ? { decor } : {}), ...(icons ? { icons } : {}) };\n}\n\n/** True when a theme carries any of the structure groups (components, variants, decoration, icons). */\nexport const hasStructure = (theme: ThemeSpec) => !!(theme.components || theme.variants || theme.decor || theme.icons);\n\n/** Parses an imported file; errors are human-readable. */\nexport function parseThemeJson(json: string): { theme: ThemeSpec; warnings: string[] } | { error: string } {\n let raw: unknown;\n try { raw = JSON.parse(json); } catch { return { error: 'This file is not valid JSON.' }; }\n const source = obj(raw);\n if (typeof source.name !== 'string' || !source.name.trim()) return { error: 'A theme needs a \"name\".' };\n const theme = sanitizeSpec(raw);\n const warnings: string[] = [];\n if (source.colors !== undefined && source.colors !== null && !theme.colors) warnings.push('Colors were ignored: bg, text and accent must be #rrggbb (the other roles are derived when missing).');\n if (theme.css) warnings.push('Contains custom CSS, which runs inside the site like your own Custom CSS.');\n if (source.background && theme.background.kind === 'none' && obj(source.background).kind !== 'none') warnings.push('The background was ignored (images must be data:image/png, jpeg, webp, gif or avif, up to about 800 KB).');\n if (theme.colors) {\n const fixed = ensureContrast(theme.colors);\n if (fixed.text !== theme.colors.text || fixed.muted !== theme.colors.muted || fixed.accent !== theme.colors.accent) warnings.push('Some text colors were adjusted to stay readable.');\n }\n return { theme, warnings };\n}\n\n/** Applies panel overrides (and an accent) on top of a theme. Colors are then made legible. */\nexport function applyOverrides(theme: ThemeSpec, overrides: ThemeOverrides = {}, accent: string | null = null): ThemeSpec {\n const o = obj(overrides) as ThemeOverrides;\n let colors = theme.colors ? { ...theme.colors, ...Object.fromEntries(Object.entries(obj(o.colors)).filter(([, v]) => isHex(v))) } as ThemeColors : null;\n if (colors && accent) colors = { ...colors, accent, ...(theme.colors?.inverse === theme.colors?.accent ? { inverse: accent } : {}) };\n return {\n ...theme,\n colors: colors ? ensureContrast(colors) : null,\n // Missing keys fall back to the theme's own; the legacy `family`/`tweet` shorthand still overrides.\n font: o.font ? sanitizeFont(o.font, theme.font) : theme.font,\n shape: o.shape ? sanitizeShape({ ...theme.shape, ...o.shape }, theme.shape) : theme.shape,\n layout: o.layout ? sanitizeLayout({ ...theme.layout, ...o.layout }, theme.layout) : theme.layout,\n background: o.background ? sanitizeBackground(o.background) : theme.background,\n effects: o.effects ? sanitizeEffects({ ...theme.effects, ...o.effects }, theme.effects) : theme.effects,\n css: o.css && typeof o.css.text === 'string' ? o.css.text.slice(0, MAX_CSS_CHARS) : theme.css,\n ...variantOverrides(theme, o.variants),\n };\n}\n\n/** A theme's variants with the owner's per-axis say on top (the raw merge goes through the sanitizer, so the site's own option removes the axis). */\nfunction variantOverrides(theme: ThemeSpec, overrides: unknown): Pick<ThemeSpec, 'variants'> {\n if (!overrides || typeof overrides !== 'object') return {};\n const variants = sanitizeVariants({ ...theme.variants, ...(overrides as Record<string, unknown>) });\n return { variants: variants ?? undefined };\n}\n\n/** True when a theme changes nothing about the site (the site's own look without overrides). */\nexport function isNeutral(theme: ThemeSpec): boolean {\n return !theme.colors && JSON.stringify([theme.font, theme.shape, theme.layout, theme.effects]) === JSON.stringify([BASE_FONT, BASE_SHAPE, BASE_LAYOUT, BASE_EFFECTS])\n && theme.background.kind === 'none' && !theme.css && !hasStructure(theme);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Fonts\n\n/** Bundled families and the names they are registered under (shell: @fontsource; site pages: FontFace, fonts.ts). */\nexport const BUNDLED_FONTS: Record<string, string> = { 'Geist': 'Geist Variable', 'Geist Mono': 'Geist Mono Variable' };\n\nexport function fontStack(names: string[]): string {\n const out: string[] = [];\n for (const name of names) {\n const real = BUNDLED_FONTS[name];\n if (real) out.push(`\"${real}\"`);\n out.push(GENERIC_FONTS.has(name) ? name : `\"${name}\"`);\n }\n // Emoji and CJK keep working whatever the theme names.\n return [...new Set(out), '\"Segoe UI Emoji\"', '\"Apple Color Emoji\"', 'sans-serif'].join(', ');\n}\n/** Roles that are drawn inside the site's page (chrome is wayBetter's own window). */\nexport const PAGE_ROLES: FontRoleName[] = ['interface', 'post', 'heading', 'numbers', 'mono', 'dialog'];\nconst rolesUsing = (theme: ThemeSpec, roles: readonly FontRoleName[]) => roles.flatMap(role => roleFamily(theme.font.roles[role]));\n/** Bundled families (Geist, Geist Mono) a theme names in the site's page. */\nexport const bundledFontsUsed = (theme: ThemeSpec, roles: readonly FontRoleName[] = PAGE_ROLES) => {\n const names = new Set(rolesUsing(theme, roles));\n return Object.keys(BUNDLED_FONTS).filter(name => names.has(name));\n};\n/** Google Fonts families a theme uses (`source: \"google\"`), for the given roles. */\nexport function googleFontsUsed(theme: ThemeSpec, roles: readonly FontRoleName[] = FONT_ROLE_NAMES): string[] {\n const out = new Set<string>();\n for (const role of roles) {\n const spec = theme.font.roles[role];\n if (spec !== 'inherit' && spec.source === 'google' && spec.family[0]) out.add(spec.family[0]);\n }\n return [...out];\n}\n\n/** A role resolved to what is drawn: the stack actually used and its settings. */\nexport type ResolvedFontRole = {\n /** CSS `font-family`. */\n stack: string;\n /** The families of that stack (empty when it is the site's or app's own font). */\n family: string[];\n /** True when the family comes from another role (or the site/app default). */\n inherited: boolean;\n /** A Google Fonts family the stack starts with. */\n google: string | null;\n weight: number | null;\n size: number;\n tracking: number | null;\n tabular: boolean;\n};\nexport type ResolvedFontRoles = Record<FontRoleName, ResolvedFontRole>;\n\n/**\n * Every role resolved. `site` is the stack an inheriting interface uses: the site's own font in its\n * page, wayBetter's own UI font in the shell. Every other role inherits the interface, except that an\n * inheriting `mono` keeps a monospaced stack (`mono`: themeApi.ts `MONO_FAMILIES`, code rarely suits\n * an interface font).\n */\nexport function resolveFontRoles(font: FontSpec, site: string, mono = fontStack(MONO_FAMILIES)): ResolvedFontRoles {\n const base = font.roles.interface;\n const baseFamily = roleFamily(base);\n const root: ResolvedFontRole = {\n stack: baseFamily.length ? fontStack(baseFamily) : site, family: baseFamily, inherited: !baseFamily.length,\n google: base !== 'inherit' && base.source === 'google' ? baseFamily[0] ?? null : null,\n weight: null, size: 1, tracking: null, tabular: false,\n };\n const out = { interface: root } as ResolvedFontRoles;\n for (const role of FONT_ROLE_NAMES) {\n if (role === 'interface') continue;\n const spec = font.roles[role];\n const own = roleFamily(spec);\n const from = own.length\n ? { stack: fontStack(own), family: own, inherited: false, google: spec !== 'inherit' && spec.source === 'google' ? own[0]! : null }\n : role === 'mono' ? { stack: mono, family: [] as string[], inherited: true, google: null }\n : { stack: root.stack, family: root.family, inherited: true, google: root.google };\n out[role] = {\n ...from,\n weight: spec === 'inherit' ? null : spec.weight ?? null,\n size: spec === 'inherit' ? 1 : spec.size ?? 1,\n tracking: spec === 'inherit' ? null : spec.tracking ?? null,\n tabular: spec !== 'inherit' && !!spec.tabular,\n };\n }\n return out;\n}\n\n/**\n * A named font stack offered by the panel's pickers. `key` names its translated label\n * (`wb.fonts.choice.*`); `label` is the English one. A site adds its own font first (X: \"X's Chirp\",\n * an empty family that keeps the site's type).\n */\nexport type FontChoice = { id: string; label: string; key?: string; family: string[] };\n/** Font choices offered by the panel; any installed family can also be named in theme JSON. */\nexport const FONT_CHOICES: FontChoice[] = [\n { id: 'geist', label: 'Geist', family: ['Geist', ...SYSTEM_SANS] },\n { id: 'geist-mono', label: 'Geist Mono', family: ['Geist Mono', 'Cascadia Mono', 'Consolas', 'Menlo', 'ui-monospace', 'monospace'] },\n { id: 'system', label: 'System UI', key: 'wb.fonts.choice.system', family: SYSTEM_SANS },\n { id: 'helvetica', label: 'Helvetica / Arial', family: ['Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'] },\n { id: 'humanist', label: 'Humanist (Segoe, Avenir)', key: 'wb.fonts.choice.humanist', family: ['Avenir Next', 'Segoe UI Variable Text', 'Segoe UI', 'sans-serif'] },\n { id: 'rounded', label: 'Rounded', key: 'wb.fonts.choice.rounded', family: ['ui-rounded', 'SF Pro Rounded', 'Nunito', 'Bahnschrift', 'Segoe UI', 'sans-serif'] },\n { id: 'serif', label: 'Serif (Charter, Georgia)', key: 'wb.fonts.choice.serif', family: ['Charter', 'Iowan Old Style', 'Georgia', 'Cambria', 'serif'] },\n { id: 'mono', label: 'System mono', key: 'wb.fonts.choice.mono', family: ['Cascadia Mono', 'SF Mono', 'Consolas', 'Menlo', 'ui-monospace', 'monospace'] },\n];\n/** The choice whose stack is exactly `family` in `choices`, or `custom`. */\nexport const fontChoiceOf = (family: string[], choices: readonly FontChoice[] = FONT_CHOICES) => choices.find(choice => choice.family.join('|') === family.join('|'))?.id ?? 'custom';\n\n// ---------------------------------------------------------------------------------------------\n// Backgrounds\n\nconst svgUrl = (svg: string) => `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n\n/**\n * The site's page background. A site's `<html>` and `<body>` are often one viewport tall while the\n * content overflows them (X's timeline), so a background painted on both had `<body>` paint its own\n * copy over its box, which scrolls away: after a partial scroll the gradient/glow showed only below a hard seam. Now\n * `<html>` holds the plain page color, `<body>` is transparent (beating, by specificity, the\n * palette's `html,body{background-color}` and its `[style^=\"background-color: …\"]` remap of the\n * inline color X puts on `<body>`) and every layer sits on one viewport-sized fixed\n * layer behind all of the page (`z-index:-1` in the root stacking context), with no `fixed` attachments.\n */\nexport function pageBackgroundCss(background: Background, page: string): string[] {\n const out = [`html:root{background:${page} !important}`, `html:root body{background:transparent !important}`];\n if (background.kind !== 'none') {\n out.push(`html:root::before{content:\"\";position:fixed;inset:0;z-index:-1;pointer-events:none;contain:strict;background:${backgroundLayers(background, page, false)}}`);\n }\n return out;\n}\n\n/**\n * CSS `background` layers for the page canvas (behind the site's columns). `attach` keeps the `fixed`\n * attachments for a box that scrolls (the Theme Builder preview); the site's page gets the layers without\n * them, on one viewport-sized fixed layer (`pageBackgroundCss`).\n */\nexport function backgroundLayers(background: Background, page: string, attach = true): string {\n const fixed = attach ? ' fixed' : '';\n switch (background.kind) {\n case 'gradient': {\n const glow = background.glow ? `radial-gradient(1200px 600px at 50% -10%, ${rgba(background.glow, 0.55)}, transparent 70%), ` : '';\n return `${glow}linear-gradient(${background.angle}deg, ${background.from}, ${background.to})${fixed}, ${page}`;\n }\n case 'pattern': {\n const { ink, opacity: a, size: s } = background;\n const c = rgba(ink, a);\n switch (background.pattern) {\n case 'dots': return `radial-gradient(${c} 1px, transparent 1.6px) 0 0 / ${s}px ${s}px, ${page}`;\n case 'grid': return `linear-gradient(${c} 1px, transparent 1px) 0 0 / ${s}px ${s}px, linear-gradient(90deg, ${c} 1px, transparent 1px) 0 0 / ${s}px ${s}px, ${page}`;\n case 'diagonal': return `repeating-linear-gradient(135deg, ${c} 0 1px, transparent 1px ${s}px), ${page}`;\n case 'scanlines': return `repeating-linear-gradient(0deg, ${c} 0 1px, transparent 1px ${s}px), radial-gradient(ellipse at 50% 40%, ${rgba(ink, a * 1.6)}, transparent 70%)${fixed}, ${page}`;\n case 'paper': return `${svgUrl(`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${s}\" height=\"${s}\"><filter id=\"n\"><feTurbulence type=\"fractalNoise\" baseFrequency=\".85\" numOctaves=\"3\" stitchTiles=\"stitch\"/><feColorMatrix values=\"0 0 0 0 ${hexToRgb(ink).map(v => (v / 255).toFixed(3)).join(' 0 0 0 0 ')} 0 0 0 ${(a * 2.2).toFixed(3)} 0\"/></filter><rect width=\"100%\" height=\"100%\" filter=\"url(#n)\"/></svg>`)} 0 0 / ${s}px ${s}px, ${page}`;\n case 'clouds': return [\n `radial-gradient(${s}px ${Math.round(s * 0.42)}px at 12% 22%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 1.3)}px ${Math.round(s * 0.5)}px at 86% 12%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 1.1)}px ${Math.round(s * 0.4)}px at 78% 70%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 0.9)}px ${Math.round(s * 0.36)}px at 18% 82%, ${c}, transparent 70%)${fixed}`,\n `linear-gradient(180deg, ${mix(page, '#ffffff', 0.25)}, ${page} 60%)${fixed}`, page,\n ].join(', ');\n }\n return page;\n }\n case 'image': {\n const scrim = `linear-gradient(${rgba(page, background.dim)}, ${rgba(page, background.dim)})${fixed}`;\n return background.fit === 'tile' ? `${scrim}, url(\"${background.url}\") 0 0 / auto repeat, ${page}` : `${scrim}, url(\"${background.url}\") center / cover no-repeat${fixed}, ${page}`;\n }\n default: return page;\n }\n}\n"]}
1
+ {"version":3,"file":"themeSpec.js","sourceRoot":"","sources":["../../../runtime/src/themeSpec.ts"],"names":[],"mappings":"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","sourcesContent":["// Theme documents: a wayBetter theme is a JSON document (like a BetterDiscord theme, but data instead\n// of a stylesheet) describing colors, type, shape, density, layout, background and motion; the format\n// is `theme.schema.json` in the `waybetter` package. This module is the document side of the theme\n// engine: types, the schema's defaults, sanitizing, import, panel overrides, legibility, font roles\n// and stacks, and page backgrounds. Pure, so it runs in the page runtime, the settings previews and\n// the tests. What a theme does to one site's page (its selectors, its palette) is the site's\n// (themeRuntime.ts takes a site adapter).\n//\n// Safety: a theme is sanitized field by field before it becomes CSS. Colors are six-digit hex,\n// numbers are clamped, enums are fixed, font names match a strict pattern, background images are\n// `data:image/*;base64` only, and CSS is built from those values (never concatenated from raw\n// strings). The single escape hatch is `css`, which is the same trust level as the owner's own\n// Custom CSS and is shown as such when a theme is imported.\n//\n// Fonts: sites usually block remote and `data:` fonts (CSP `font-src`), so a theme may name installed\n// system fonts, \"Geist\" / \"Geist Mono\" (bundled and registered from bytes: `FontFace(ArrayBuffer)` is\n// not a fetch), or Google Fonts families the owner downloaded (`source: \"google\"`, fonts.ts).\n\nimport { FONT_ROLE_NAMES, MONO_FAMILIES, hexToRgb, mix, type FontRoleName } from './themeApi.ts';\nimport { deriveColors } from './themeTokens.ts';\nimport { inkOnEvery } from './themeInk.ts';\nimport { ACTION_NAMES, sanitizeComponents, type ActionColors, type ThemeComponents } from './themeComponents.ts';\nimport { sanitizeDecor, type ThemeDecor } from './themeDecor.ts';\nimport { sanitizeThemeIcons, type ThemeIcons } from './themeIcons.ts';\nimport { sanitizeVariants, type ThemeVariants } from './themeVariants.ts';\n\nexport { FONT_ROLE_NAMES } from './themeApi.ts';\nexport type { FontRoleName } from './themeApi.ts';\n\nexport type Role = 'bg' | 'surface' | 'elevated' | 'border' | 'text' | 'muted' | 'accent';\n/** The site's filled primary button (X: \"Post\"/\"Follow\"): an `inverse` background with an `onInverse` label. */\nexport type ButtonRole = 'inverse' | 'onInverse';\nexport type Palette = Record<Role, string> & Partial<Record<ButtonRole, string>>;\n/**\n * `page` is the canvas behind the site's columns (defaults to `bg`); the columns stay on `bg`.\n * `actions` are the colors of a set action (liked, reposted, bookmarked) and of the reply hover;\n * absent, the site's own action colors stay.\n */\nexport type ThemeColors = Palette & { page?: string; actions?: ActionColors };\n\nexport type Density = 'compact' | 'default' | 'comfortable';\nexport type AvatarShape = 'circle' | 'rounded' | 'square';\nexport type Pattern = 'dots' | 'grid' | 'diagonal' | 'scanlines' | 'paper' | 'clouds';\nexport type Background =\n | { kind: 'none' }\n | { kind: 'gradient'; from: string; to: string; angle: number; glow?: string }\n | { kind: 'pattern'; pattern: Pattern; ink: string; opacity: number; size: number }\n | { kind: 'image'; url: string; fit: 'cover' | 'tile'; dim: number };\n\n/**\n * One role's font (roles: themeApi.ts `FONT_ROLE_NAMES`). `family` is a font stack; empty keeps the\n * inherited family and only changes the rest. `source: \"google\"` says the first family comes from\n * Google Fonts (downloaded once, asked first when a theme is imported, loaded from bytes). `weight`\n * (100-900), `size` (0.75-1.5, relative to the site's size), `tracking` (em) and `tabular` figures\n * are optional; the interface role takes only `family`/`source` (its size, weights and tracking are\n * `scale`, `weight`, `bold` and `tracking` of the whole theme).\n */\nexport type FontRoleSpec = { family: string[]; source?: 'google'; weight?: number; size?: number; tracking?: number; tabular?: boolean };\nexport type FontRole = 'inherit' | FontRoleSpec;\nexport type FontRoles = Record<FontRoleName, FontRole>;\n\nexport type FontSpec = {\n /**\n * Interface font stack (replaces the site's own font everywhere). Empty keeps the site's.\n * Shorthand kept for older theme files and older apps: it always equals `roles.interface`'s family.\n */\n family: string[];\n /** Post text stack (e.g. a serif reading face); shorthand of `roles.post`'s family. */\n tweet: string[];\n /** Which font goes where. Every role inherits from `interface` unless it says otherwise. */\n roles: FontRoles;\n /** Multiplies the site's pixel font sizes (0.85-1.2). */\n scale: number;\n /** Regular weight (300-500) and bold weight (500-800) that replace the site's 400/700. */\n weight: number;\n bold: number;\n /** Letter spacing in em (-0.03-0.06). */\n tracking: number;\n /** Line height multiplier for post text (0 keeps the site's). */\n leading: number;\n};\nexport type ShapeSpec = { radius: number; button: number; avatar: AvatarShape };\nexport type LayoutSpec = { column: number; sidebar: number; density: Density; cards: boolean; frame: boolean };\nexport type EffectsSpec = { motion: number; hover: 'none' | 'tint' | 'lift' | 'glow'; shadow: 'none' | 'soft' | 'deep'; crt: boolean };\n\nexport type ThemeSpec = {\n id: string;\n name: string;\n description: string;\n author: string;\n version: 1;\n /** Which way the theme leans; used for scrollbars/form controls and previews. */\n mode: 'light' | 'dark' | 'auto';\n /** null keeps the site's own colors (X: Default / Dim / Lights out). */\n colors: ThemeColors | null;\n font: FontSpec;\n shape: ShapeSpec;\n layout: LayoutSpec;\n background: Background;\n effects: EffectsSpec;\n /** Free-form CSS appended last (owner-trusted, like Custom CSS). */\n css: string;\n // The groups below are optional and additive: a theme without them is drawn exactly as before,\n // and an app that does not know them drops them and draws the rest.\n /** How each piece of the site is built (themeComponents.ts). */\n components?: ThemeComponents;\n /** Structural choices: where the navigation sits, how a post is laid out (themeVariants.ts). */\n variants?: ThemeVariants;\n /** Lines, bars, focus ring, selection, scrollbars, motion (themeDecor.ts). */\n decor?: ThemeDecor;\n /** Which icon pack the theme suggests, with small adjustments (themeIcons.ts). */\n icons?: ThemeIcons;\n};\n\n/** Panel overrides: any group may be partially overridden on top of the selected theme. */\nexport type ThemeOverrides = {\n colors?: Partial<ThemeColors>;\n /** `roles` is merged role by role (a named role replaces that role only). */\n font?: Partial<Omit<FontSpec, 'roles'>> & { roles?: Partial<FontRoles> };\n shape?: Partial<ShapeSpec>;\n layout?: Partial<LayoutSpec>;\n background?: Background;\n effects?: Partial<EffectsSpec>;\n /** The theme's own CSS as edited in the panel (replaces the theme document's `css`). */\n css?: { text: string };\n /** The owner's say on a theme's layout suggestions, axis by axis (an axis set to the site's own option switches it off). */\n variants?: Record<string, string>;\n};\n\n// ---------------------------------------------------------------------------------------------\n// The schema's defaults: a theme that sets nothing changes nothing (the site keeps its own geometry;\n// a site's structure CSS only emits rules where a theme differs from these).\n\nexport const BASE_SHAPE: ShapeSpec = { radius: 16, button: 9999, avatar: 'circle' };\nexport const INHERIT_ROLES: FontRoles = { interface: 'inherit', post: 'inherit', heading: 'inherit', numbers: 'inherit', mono: 'inherit', chrome: 'inherit', dialog: 'inherit' };\n/** A font spec from the interface/post stacks alone (every other role inherits). */\nexport const withRoles = (font: Omit<FontSpec, 'roles'>): FontSpec => ({\n ...font,\n roles: { ...INHERIT_ROLES, ...(font.family.length ? { interface: { family: font.family } } : {}), ...(font.tweet.length ? { post: { family: font.tweet } } : {}) },\n});\nexport const BASE_FONT: FontSpec = withRoles({ family: [], tweet: [], scale: 1, weight: 400, bold: 700, tracking: 0, leading: 0 });\nexport const BASE_LAYOUT: LayoutSpec = { column: 600, sidebar: 350, density: 'default', cards: false, frame: false };\nexport const BASE_EFFECTS: EffectsSpec = { motion: 0, hover: 'none', shadow: 'none', crt: false };\n\n/** The system UI stack themes put after their own sans-serif families. */\nexport const SYSTEM_SANS = ['Segoe UI', '-apple-system', 'BlinkMacSystemFont', 'system-ui', 'sans-serif'];\n\n// ---------------------------------------------------------------------------------------------\n// Colors and contrast (luminance and ratios: themeApi.ts)\n\nexport const isHex = (value: unknown): value is string => typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value);\n/** `#rrggbb` + alpha as `rgba()`. */\nexport const rgba = (hex: string, alpha: number) => `rgba(${hexToRgb(hex).join(', ')}, ${+alpha.toFixed(3)})`;\n\n/**\n * The colour closest to `color` (OKLCH lightness, hue kept) that reaches `ratio` against every surface\n * (themeInk.ts). A colour that has to move gets 8% headroom: the site's hover and pressed tints are mixed\n * from these surfaces, and an exact solver would leave the ink a hair under the target on them.\n */\nexport function reach(color: string, surfaces: string[], ratio: number): string {\n const kept = inkOnEvery(surfaces, color, ratio);\n return kept.adjusted ? inkOnEvery(surfaces, color, ratio * 1.08).ink : kept.ink;\n}\n\n\n/**\n * Guarantees legibility for any palette (built-in, imported or overridden): text, secondary text\n * and links reach WCAG AA (4.5:1) on every surface, including the page canvas, and the site's filled\n * button keeps a readable label and stands out from the page (3:1).\n */\nexport function ensureContrast<T extends Palette & { page?: string; actions?: ActionColors }>(colors: T): T {\n const surfaces = [colors.bg, colors.surface, colors.elevated, ...(colors.page ? [colors.page] : [])];\n const out = { ...colors };\n out.text = reach(colors.text, surfaces, 7);\n out.muted = reach(colors.muted, surfaces, 4.5);\n // Links live inside the columns, never on the page canvas.\n out.accent = reach(colors.accent, [colors.bg, colors.surface, colors.elevated], 4.5);\n const inverse = colors.inverse ?? out.text;\n const onInverse = colors.onInverse ?? colors.bg;\n out.inverse = reach(inverse, [colors.bg], 3);\n out.onInverse = reach(onInverse, [out.inverse], 4.5);\n // Action colors are icons and counts: non-text contrast on the column and on a raised row.\n if (colors.actions) out.actions = Object.fromEntries(Object.entries(colors.actions).map(([name, color]) => [name, reach(color as string, [colors.bg, colors.surface], 3)]));\n return out;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Sanitizing\n\nconst GENERIC_FONTS = new Set(['system-ui', 'sans-serif', 'serif', 'monospace', 'cursive', 'ui-sans-serif', 'ui-serif', 'ui-monospace', 'ui-rounded', '-apple-system', 'BlinkMacSystemFont']);\nconst FONT_NAME = /^[A-Za-z0-9][A-Za-z0-9 .\\-]{0,47}$/;\nconst DATA_IMAGE = /^data:image\\/(png|jpeg|webp|gif|avif);base64,[A-Za-z0-9+/]+={0,2}$/;\nexport const MAX_IMAGE_CHARS = 1_100_000;\nexport const MAX_CSS_CHARS = 60_000;\nconst PATTERNS: Pattern[] = ['dots', 'grid', 'diagonal', 'scanlines', 'paper', 'clouds'];\n\nconst obj = (value: unknown): Record<string, unknown> => value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};\nconst num = (value: unknown, min: number, max: number, fallback: number) => typeof value === 'number' && Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : fallback;\nconst pick = <T extends string>(value: unknown, options: readonly T[], fallback: T): T => options.includes(value as T) ? value as T : fallback;\nconst text = (value: unknown, max: number, fallback = '') => typeof value === 'string' ? value.replace(/[\\u0000-\\u001f\\u007f]/g, '').trim().slice(0, max) : fallback;\n\nexport function sanitizeFonts(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((name): name is string => typeof name === 'string' && (GENERIC_FONTS.has(name) || FONT_NAME.test(name))).slice(0, 8);\n}\n\n/** A theme needs its background, text and accent; any other role it leaves out is derived from the\n * base structure (themeTokens.ts `deriveColors`), so every theme has the same proportions. */\nfunction sanitizeColors(value: unknown): ThemeColors | null {\n const source = obj(value);\n if (!(['bg', 'text', 'accent'] as const).every(role => isHex(source[role]))) return null;\n const named = Object.fromEntries((['bg', 'surface', 'elevated', 'border', 'text', 'muted', 'accent'] as Role[])\n .filter(role => isHex(source[role])).map(role => [role, (source[role] as string).toLowerCase()]));\n const colors = deriveColors(named as { bg: string; text: string; accent: string }) as ThemeColors;\n for (const role of ['inverse', 'onInverse', 'page'] as const) if (isHex(source[role])) colors[role] = (source[role] as string).toLowerCase();\n const actions = obj(source.actions);\n const named_actions = Object.fromEntries(ACTION_NAMES.filter(name => isHex(actions[name])).map(name => [name, (actions[name] as string).toLowerCase()]));\n if (Object.keys(named_actions).length) colors.actions = named_actions;\n return colors;\n}\n\nexport function sanitizeBackground(value: unknown): Background {\n const source = obj(value);\n if (source.kind === 'gradient' && isHex(source.from) && isHex(source.to)) {\n return { kind: 'gradient', from: source.from.toLowerCase(), to: source.to.toLowerCase(), angle: Math.round(num(source.angle, 0, 360, 180)), ...(isHex(source.glow) ? { glow: source.glow.toLowerCase() } : {}) };\n }\n if (source.kind === 'pattern' && isHex(source.ink)) {\n return { kind: 'pattern', pattern: pick(source.pattern, PATTERNS, 'dots'), ink: source.ink.toLowerCase(), opacity: num(source.opacity, 0, 0.6, 0.1), size: Math.round(num(source.size, 2, 400, 24)) };\n }\n if (source.kind === 'image' && typeof source.url === 'string' && source.url.length <= MAX_IMAGE_CHARS && DATA_IMAGE.test(source.url)) {\n return { kind: 'image', url: source.url, fit: pick(source.fit, ['cover', 'tile'] as const, 'cover'), dim: num(source.dim, 0.35, 0.95, 0.6) };\n }\n return { kind: 'none' };\n}\n\n/** Bounds of a role's own settings (the JSON Schema says the same; tested). */\nexport const ROLE_LIMITS = { weight: [100, 900], size: [0.75, 1.5], tracking: [-0.05, 0.1] } as const;\n\n/** One role from JSON: \"inherit\", or a stack with optional extras (clamped; unknown keys dropped). */\nexport function sanitizeFontRole(value: unknown, role: FontRoleName): FontRole {\n if (value === 'inherit' || value === null || value === undefined) return 'inherit';\n const source = obj(value);\n if (!Object.keys(source).length) return 'inherit';\n const family = sanitizeFonts(source.family);\n const out: FontRoleSpec = { family };\n if (source.source === 'google' && family.length && !GENERIC_FONTS.has(family[0]!)) out.source = 'google';\n if (role !== 'interface') {\n if (typeof source.weight === 'number' && Number.isFinite(source.weight)) out.weight = Math.round(num(source.weight, ...ROLE_LIMITS.weight, 400));\n if (typeof source.size === 'number' && Number.isFinite(source.size)) out.size = +num(source.size, ...ROLE_LIMITS.size, 1).toFixed(3);\n if (typeof source.tracking === 'number' && Number.isFinite(source.tracking)) out.tracking = +num(source.tracking, ...ROLE_LIMITS.tracking, 0).toFixed(4);\n if (source.tabular === true) out.tabular = true;\n }\n // A role that changes nothing is the same as inheriting.\n return Object.keys(out).length === 1 && !family.length ? 'inherit' : out;\n}\n\nconst roleFamily = (role: FontRole): string[] => role === 'inherit' ? [] : role.family;\n/** A role with a new family, keeping its other settings (and its Google source only for the same font). */\nexport function withFamily(role: FontRole, family: string[], source?: 'google'): FontRole {\n const rest = role === 'inherit' ? {} : { ...role };\n delete (rest as Partial<FontRoleSpec>).source;\n delete (rest as Partial<FontRoleSpec>).family;\n const next: FontRoleSpec = { ...rest, family, ...(source && family.length ? { source } : {}) };\n return Object.keys(next).length === 1 && !family.length ? 'inherit' : next;\n}\n\n/**\n * The roles of a font group from JSON over `base`: `roles.<name>` wins; the legacy shorthand\n * (`family` → interface, `tweet` → post) applies when that role is not named, so theme files and\n * saved customizations from before font roles keep working.\n */\nfunction sanitizeRoles(source: Record<string, unknown>, base: FontSpec): FontRoles {\n const named = obj(source.roles);\n const roles = { ...base.roles };\n for (const role of FONT_ROLE_NAMES) if (role in named) roles[role] = sanitizeFontRole(named[role], role);\n if (!('interface' in named) && 'family' in source) roles.interface = withFamily(base.roles.interface, sanitizeFonts(source.family), sameFirst(source.family, base.roles.interface));\n if (!('post' in named) && 'tweet' in source) roles.post = withFamily(base.roles.post, sanitizeFonts(source.tweet), sameFirst(source.tweet, base.roles.post));\n return roles;\n}\n/** Keeps a role's Google source when the shorthand still names the same first family. */\nfunction sameFirst(stack: unknown, role: FontRole): 'google' | undefined {\n return role !== 'inherit' && role.source === 'google' && Array.isArray(stack) && stack[0] === role.family[0] ? 'google' : undefined;\n}\n\nfunction sanitizeFont(value: unknown, base: FontSpec): FontSpec {\n const source = obj(value);\n const roles = sanitizeRoles(source, base);\n return {\n family: roleFamily(roles.interface),\n tweet: roleFamily(roles.post),\n roles,\n scale: num(source.scale, 0.85, 1.2, base.scale),\n weight: Math.round(num(source.weight, 300, 500, base.weight)),\n bold: Math.round(num(source.bold, 500, 800, base.bold)),\n tracking: num(source.tracking, -0.03, 0.06, base.tracking),\n leading: source.leading === 0 ? 0 : num(source.leading, 1.2, 1.8, base.leading),\n };\n}\nconst sanitizeShape = (value: unknown, base: ShapeSpec): ShapeSpec => {\n const source = obj(value);\n return { radius: Math.round(num(source.radius, 0, 28, base.radius)), button: Math.round(num(source.button, 0, 9999, base.button)), avatar: pick(source.avatar, ['circle', 'rounded', 'square'] as const, base.avatar) };\n};\nconst sanitizeLayout = (value: unknown, base: LayoutSpec): LayoutSpec => {\n const source = obj(value);\n return {\n column: Math.round(num(source.column, 520, 820, base.column)), sidebar: Math.round(num(source.sidebar, 290, 400, base.sidebar)),\n density: pick(source.density, ['compact', 'default', 'comfortable'] as const, base.density),\n cards: typeof source.cards === 'boolean' ? source.cards : base.cards, frame: typeof source.frame === 'boolean' ? source.frame : base.frame,\n };\n};\nconst sanitizeEffects = (value: unknown, base: EffectsSpec): EffectsSpec => {\n const source = obj(value);\n return {\n motion: Math.round(num(source.motion, 0, 400, base.motion)), hover: pick(source.hover, ['none', 'tint', 'lift', 'glow'] as const, base.hover),\n shadow: pick(source.shadow, ['none', 'soft', 'deep'] as const, base.shadow), crt: typeof source.crt === 'boolean' ? source.crt : base.crt,\n };\n};\n\nexport const slug = (value: string) => value.toLowerCase().normalize('NFKD').replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 40) || 'theme';\n\n/** Any JSON to a complete, safe theme. Missing groups fall back to the schema's defaults. */\nexport function sanitizeSpec(input: unknown): ThemeSpec {\n const source = obj(input);\n const name = text(source.name, 60) || 'Untitled theme';\n const id = typeof source.id === 'string' && /^[a-z0-9-]{1,40}$/.test(source.id) ? source.id : slug(name);\n return {\n id, name, description: text(source.description, 200), author: text(source.author, 60), version: 1,\n mode: pick(source.mode, ['light', 'dark', 'auto'] as const, 'auto'),\n colors: sanitizeColors(source.colors),\n font: sanitizeFont(source.font, BASE_FONT),\n shape: sanitizeShape(source.shape, BASE_SHAPE),\n layout: sanitizeLayout(source.layout, BASE_LAYOUT),\n background: sanitizeBackground(source.background),\n effects: sanitizeEffects(source.effects, BASE_EFFECTS),\n css: typeof source.css === 'string' ? source.css.slice(0, MAX_CSS_CHARS) : '',\n ...structureGroups(source),\n };\n}\n\n/** The optional structure groups of a theme, each present only when it says something valid. */\nfunction structureGroups(source: Record<string, unknown>): Pick<ThemeSpec, 'components' | 'variants' | 'decor' | 'icons'> {\n const components = sanitizeComponents(source.components), variants = sanitizeVariants(source.variants);\n const decor = sanitizeDecor(source.decor), icons = sanitizeThemeIcons(source.icons);\n return { ...(components ? { components } : {}), ...(variants ? { variants } : {}), ...(decor ? { decor } : {}), ...(icons ? { icons } : {}) };\n}\n\n/** True when a theme carries any of the structure groups (components, variants, decoration, icons). */\nexport const hasStructure = (theme: ThemeSpec) => !!(theme.components || theme.variants || theme.decor || theme.icons);\n\n/** Parses an imported file; errors are human-readable. */\nexport function parseThemeJson(json: string): { theme: ThemeSpec; warnings: string[] } | { error: string } {\n let raw: unknown;\n try { raw = JSON.parse(json); } catch { return { error: 'This file is not valid JSON.' }; }\n const source = obj(raw);\n if (typeof source.name !== 'string' || !source.name.trim()) return { error: 'A theme needs a \"name\".' };\n const theme = sanitizeSpec(raw);\n const warnings: string[] = [];\n if (source.colors !== undefined && source.colors !== null && !theme.colors) warnings.push('Colors were ignored: bg, text and accent must be #rrggbb (the other roles are derived when missing).');\n if (theme.css) warnings.push('Contains custom CSS, which runs inside the site like your own Custom CSS.');\n if (source.background && theme.background.kind === 'none' && obj(source.background).kind !== 'none') warnings.push('The background was ignored (images must be data:image/png, jpeg, webp, gif or avif, up to about 800 KB).');\n if (theme.colors) {\n const fixed = ensureContrast(theme.colors);\n if (fixed.text !== theme.colors.text || fixed.muted !== theme.colors.muted || fixed.accent !== theme.colors.accent) warnings.push('Some text colors were adjusted to stay readable.');\n }\n return { theme, warnings };\n}\n\n/** Applies panel overrides (and an accent) on top of a theme. Colors are then made legible. */\nexport function applyOverrides(theme: ThemeSpec, overrides: ThemeOverrides = {}, accent: string | null = null): ThemeSpec {\n const o = obj(overrides) as ThemeOverrides;\n let colors = theme.colors ? { ...theme.colors, ...Object.fromEntries(Object.entries(obj(o.colors)).filter(([, v]) => isHex(v))) } as ThemeColors : null;\n if (colors && accent) colors = { ...colors, accent, ...(theme.colors?.inverse === theme.colors?.accent ? { inverse: accent } : {}) };\n return {\n ...theme,\n colors: colors ? ensureContrast(colors) : null,\n // Missing keys fall back to the theme's own; the legacy `family`/`tweet` shorthand still overrides.\n font: o.font ? sanitizeFont(o.font, theme.font) : theme.font,\n shape: o.shape ? sanitizeShape({ ...theme.shape, ...o.shape }, theme.shape) : theme.shape,\n layout: o.layout ? sanitizeLayout({ ...theme.layout, ...o.layout }, theme.layout) : theme.layout,\n background: o.background ? sanitizeBackground(o.background) : theme.background,\n effects: o.effects ? sanitizeEffects({ ...theme.effects, ...o.effects }, theme.effects) : theme.effects,\n css: o.css && typeof o.css.text === 'string' ? o.css.text.slice(0, MAX_CSS_CHARS) : theme.css,\n ...variantOverrides(theme, o.variants),\n };\n}\n\n/** A theme's variants with the owner's per-axis say on top (the raw merge goes through the sanitizer, so the site's own option removes the axis). */\nfunction variantOverrides(theme: ThemeSpec, overrides: unknown): Pick<ThemeSpec, 'variants'> {\n if (!overrides || typeof overrides !== 'object') return {};\n const variants = sanitizeVariants({ ...theme.variants, ...(overrides as Record<string, unknown>) });\n return { variants: variants ?? undefined };\n}\n\n/** True when a theme changes nothing about the site (the site's own look without overrides). */\nexport function isNeutral(theme: ThemeSpec): boolean {\n return !theme.colors && JSON.stringify([theme.font, theme.shape, theme.layout, theme.effects]) === JSON.stringify([BASE_FONT, BASE_SHAPE, BASE_LAYOUT, BASE_EFFECTS])\n && theme.background.kind === 'none' && !theme.css && !hasStructure(theme);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Fonts\n\n/** Bundled families and the names they are registered under (shell: @fontsource; site pages: FontFace, fonts.ts). */\nexport const BUNDLED_FONTS: Record<string, string> = { 'Geist': 'Geist Variable', 'Geist Mono': 'Geist Mono Variable' };\n\nexport function fontStack(names: string[]): string {\n const out: string[] = [];\n for (const name of names) {\n const real = BUNDLED_FONTS[name];\n if (real) out.push(`\"${real}\"`);\n out.push(GENERIC_FONTS.has(name) ? name : `\"${name}\"`);\n }\n // Emoji and CJK keep working whatever the theme names.\n return [...new Set(out), '\"Segoe UI Emoji\"', '\"Apple Color Emoji\"', 'sans-serif'].join(', ');\n}\n/** Roles that are drawn inside the site's page (chrome is wayBetter's own window). */\nexport const PAGE_ROLES: FontRoleName[] = ['interface', 'post', 'heading', 'numbers', 'mono', 'dialog'];\nconst rolesUsing = (theme: ThemeSpec, roles: readonly FontRoleName[]) => roles.flatMap(role => roleFamily(theme.font.roles[role]));\n/** Bundled families (Geist, Geist Mono) a theme names in the site's page. */\nexport const bundledFontsUsed = (theme: ThemeSpec, roles: readonly FontRoleName[] = PAGE_ROLES) => {\n const names = new Set(rolesUsing(theme, roles));\n return Object.keys(BUNDLED_FONTS).filter(name => names.has(name));\n};\n/** Google Fonts families a theme uses (`source: \"google\"`), for the given roles. */\nexport function googleFontsUsed(theme: ThemeSpec, roles: readonly FontRoleName[] = FONT_ROLE_NAMES): string[] {\n const out = new Set<string>();\n for (const role of roles) {\n const spec = theme.font.roles[role];\n if (spec !== 'inherit' && spec.source === 'google' && spec.family[0]) out.add(spec.family[0]);\n }\n return [...out];\n}\n\n/** A role resolved to what is drawn: the stack actually used and its settings. */\nexport type ResolvedFontRole = {\n /** CSS `font-family`. */\n stack: string;\n /** The families of that stack (empty when it is the site's or app's own font). */\n family: string[];\n /** True when the family comes from another role (or the site/app default). */\n inherited: boolean;\n /** A Google Fonts family the stack starts with. */\n google: string | null;\n weight: number | null;\n size: number;\n tracking: number | null;\n tabular: boolean;\n};\nexport type ResolvedFontRoles = Record<FontRoleName, ResolvedFontRole>;\n\n/**\n * Every role resolved. `site` is the stack an inheriting interface uses: the site's own font in its\n * page, wayBetter's own UI font in the shell. Every other role inherits the interface, except that an\n * inheriting `mono` keeps a monospaced stack (`mono`: themeApi.ts `MONO_FAMILIES`, code rarely suits\n * an interface font).\n */\nexport function resolveFontRoles(font: FontSpec, site: string, mono = fontStack(MONO_FAMILIES)): ResolvedFontRoles {\n const base = font.roles.interface;\n const baseFamily = roleFamily(base);\n const root: ResolvedFontRole = {\n stack: baseFamily.length ? fontStack(baseFamily) : site, family: baseFamily, inherited: !baseFamily.length,\n google: base !== 'inherit' && base.source === 'google' ? baseFamily[0] ?? null : null,\n weight: null, size: 1, tracking: null, tabular: false,\n };\n const out = { interface: root } as ResolvedFontRoles;\n for (const role of FONT_ROLE_NAMES) {\n if (role === 'interface') continue;\n const spec = font.roles[role];\n const own = roleFamily(spec);\n const from = own.length\n ? { stack: fontStack(own), family: own, inherited: false, google: spec !== 'inherit' && spec.source === 'google' ? own[0]! : null }\n : role === 'mono' ? { stack: mono, family: [] as string[], inherited: true, google: null }\n : { stack: root.stack, family: root.family, inherited: true, google: root.google };\n out[role] = {\n ...from,\n weight: spec === 'inherit' ? null : spec.weight ?? null,\n size: spec === 'inherit' ? 1 : spec.size ?? 1,\n tracking: spec === 'inherit' ? null : spec.tracking ?? null,\n tabular: spec !== 'inherit' && !!spec.tabular,\n };\n }\n return out;\n}\n\n/**\n * A named font stack offered by the panel's pickers. `key` names its translated label\n * (`wb.fonts.choice.*`); `label` is the English one. A site adds its own font first (X: \"X's Chirp\",\n * an empty family that keeps the site's type).\n */\nexport type FontChoice = { id: string; label: string; key?: string; family: string[] };\n/** Font choices offered by the panel; any installed family can also be named in theme JSON. */\nexport const FONT_CHOICES: FontChoice[] = [\n { id: 'geist', label: 'Geist', family: ['Geist', ...SYSTEM_SANS] },\n { id: 'geist-mono', label: 'Geist Mono', family: ['Geist Mono', 'Cascadia Mono', 'Consolas', 'Menlo', 'ui-monospace', 'monospace'] },\n { id: 'system', label: 'System UI', key: 'wb.fonts.choice.system', family: SYSTEM_SANS },\n { id: 'helvetica', label: 'Helvetica / Arial', family: ['Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'] },\n { id: 'humanist', label: 'Humanist (Segoe, Avenir)', key: 'wb.fonts.choice.humanist', family: ['Avenir Next', 'Segoe UI Variable Text', 'Segoe UI', 'sans-serif'] },\n { id: 'rounded', label: 'Rounded', key: 'wb.fonts.choice.rounded', family: ['ui-rounded', 'SF Pro Rounded', 'Nunito', 'Bahnschrift', 'Segoe UI', 'sans-serif'] },\n { id: 'serif', label: 'Serif (Charter, Georgia)', key: 'wb.fonts.choice.serif', family: ['Charter', 'Iowan Old Style', 'Georgia', 'Cambria', 'serif'] },\n { id: 'mono', label: 'System mono', key: 'wb.fonts.choice.mono', family: ['Cascadia Mono', 'SF Mono', 'Consolas', 'Menlo', 'ui-monospace', 'monospace'] },\n];\n/** The choice whose stack is exactly `family` in `choices`, or `custom`. */\nexport const fontChoiceOf = (family: string[], choices: readonly FontChoice[] = FONT_CHOICES) => choices.find(choice => choice.family.join('|') === family.join('|'))?.id ?? 'custom';\n\n// ---------------------------------------------------------------------------------------------\n// Backgrounds\n\nconst svgUrl = (svg: string) => `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n\n/**\n * The site's page background. A site's `<html>` and `<body>` are often one viewport tall while the\n * content overflows them (X's timeline), so a background painted on both had `<body>` paint its own\n * copy over its box, which scrolls away: after a partial scroll the gradient/glow showed only below a hard seam. Now\n * `<html>` holds the plain page color, `<body>` is transparent (beating, by specificity, the\n * palette's `html,body{background-color}` and its `[style^=\"background-color: …\"]` remap of the\n * inline color X puts on `<body>`) and every layer sits on one viewport-sized fixed\n * layer behind all of the page (`z-index:-1` in the root stacking context), with no `fixed` attachments.\n */\nexport function pageBackgroundCss(background: Background, page: string): string[] {\n const out = [`html:root{background:${page} !important}`, `html:root body{background:transparent !important}`];\n if (background.kind !== 'none') {\n out.push(`html:root::before{content:\"\";position:fixed;inset:0;z-index:-1;pointer-events:none;contain:strict;background:${backgroundLayers(background, page, false)}}`);\n }\n return out;\n}\n\n/**\n * CSS `background` layers for the page canvas (behind the site's columns). `attach` keeps the `fixed`\n * attachments for a box that scrolls (the Theme Builder preview); the site's page gets the layers without\n * them, on one viewport-sized fixed layer (`pageBackgroundCss`).\n */\nexport function backgroundLayers(background: Background, page: string, attach = true): string {\n const fixed = attach ? ' fixed' : '';\n switch (background.kind) {\n case 'gradient': {\n const glow = background.glow ? `radial-gradient(1200px 600px at 50% -10%, ${rgba(background.glow, 0.55)}, transparent 70%), ` : '';\n return `${glow}linear-gradient(${background.angle}deg, ${background.from}, ${background.to})${fixed}, ${page}`;\n }\n case 'pattern': {\n const { ink, opacity: a, size: s } = background;\n const c = rgba(ink, a);\n switch (background.pattern) {\n case 'dots': return `radial-gradient(${c} 1px, transparent 1.6px) 0 0 / ${s}px ${s}px, ${page}`;\n case 'grid': return `linear-gradient(${c} 1px, transparent 1px) 0 0 / ${s}px ${s}px, linear-gradient(90deg, ${c} 1px, transparent 1px) 0 0 / ${s}px ${s}px, ${page}`;\n case 'diagonal': return `repeating-linear-gradient(135deg, ${c} 0 1px, transparent 1px ${s}px), ${page}`;\n case 'scanlines': return `repeating-linear-gradient(0deg, ${c} 0 1px, transparent 1px ${s}px), radial-gradient(ellipse at 50% 40%, ${rgba(ink, a * 1.6)}, transparent 70%)${fixed}, ${page}`;\n case 'paper': return `${svgUrl(`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${s}\" height=\"${s}\"><filter id=\"n\"><feTurbulence type=\"fractalNoise\" baseFrequency=\".85\" numOctaves=\"3\" stitchTiles=\"stitch\"/><feColorMatrix values=\"0 0 0 0 ${hexToRgb(ink).map(v => (v / 255).toFixed(3)).join(' 0 0 0 0 ')} 0 0 0 ${(a * 2.2).toFixed(3)} 0\"/></filter><rect width=\"100%\" height=\"100%\" filter=\"url(#n)\"/></svg>`)} 0 0 / ${s}px ${s}px, ${page}`;\n case 'clouds': return [\n `radial-gradient(${s}px ${Math.round(s * 0.42)}px at 12% 22%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 1.3)}px ${Math.round(s * 0.5)}px at 86% 12%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 1.1)}px ${Math.round(s * 0.4)}px at 78% 70%, ${c}, transparent 70%)${fixed}`,\n `radial-gradient(${Math.round(s * 0.9)}px ${Math.round(s * 0.36)}px at 18% 82%, ${c}, transparent 70%)${fixed}`,\n `linear-gradient(180deg, ${mix(page, '#ffffff', 0.25)}, ${page} 60%)${fixed}`, page,\n ].join(', ');\n }\n return page;\n }\n case 'image': {\n const scrim = `linear-gradient(${rgba(page, background.dim)}, ${rgba(page, background.dim)})${fixed}`;\n return background.fit === 'tile' ? `${scrim}, url(\"${background.url}\") 0 0 / auto repeat, ${page}` : `${scrim}, url(\"${background.url}\") center / cover no-repeat${fixed}, ${page}`;\n }\n default: return page;\n }\n}\n"]}