waybetter 0.1.0 → 0.6.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 (515) hide show
  1. package/README.md +143 -9
  2. package/bin/waybetter.mjs +46 -0
  3. package/build/runtime.mjs +105 -0
  4. package/cli/buildenv.mjs +130 -0
  5. package/cli/dev.mjs +97 -0
  6. package/cli/i18n.mjs +382 -0
  7. package/cli/manifests.mjs +383 -0
  8. package/cli/privacy.mjs +768 -0
  9. package/cli/release.mjs +444 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +326 -0
  12. package/cli/strings.mjs +121 -0
  13. package/dist/runtime/column.d.ts +93 -0
  14. package/dist/runtime/column.js +451 -0
  15. package/dist/runtime/column.js.map +1 -0
  16. package/dist/runtime/commandReport.d.ts +19 -0
  17. package/dist/runtime/commandReport.js +47 -0
  18. package/dist/runtime/commandReport.js.map +1 -0
  19. package/dist/runtime/commands.d.ts +72 -0
  20. package/dist/runtime/commands.js +214 -0
  21. package/dist/runtime/commands.js.map +1 -0
  22. package/dist/runtime/devErrors.d.ts +16 -0
  23. package/dist/runtime/devErrors.js +30 -0
  24. package/dist/runtime/devErrors.js.map +1 -0
  25. package/dist/runtime/domHub.d.ts +21 -0
  26. package/dist/runtime/domHub.js +139 -4
  27. package/dist/runtime/domHub.js.map +1 -1
  28. package/dist/runtime/featureModules.d.ts +157 -0
  29. package/dist/runtime/featureModules.js +484 -0
  30. package/dist/runtime/featureModules.js.map +1 -0
  31. package/dist/runtime/featureTable.d.ts +144 -0
  32. package/dist/runtime/featureTable.js +223 -0
  33. package/dist/runtime/featureTable.js.map +1 -0
  34. package/dist/runtime/fonts.d.ts +22 -0
  35. package/dist/runtime/fonts.js +72 -0
  36. package/dist/runtime/fonts.js.map +1 -0
  37. package/dist/runtime/i18n.d.ts +138 -0
  38. package/dist/runtime/i18n.js +614 -0
  39. package/dist/runtime/i18n.js.map +1 -0
  40. package/dist/runtime/i18nCheck.d.ts +30 -0
  41. package/dist/runtime/i18nCheck.js +224 -0
  42. package/dist/runtime/i18nCheck.js.map +1 -0
  43. package/dist/runtime/pageLang.d.ts +8 -0
  44. package/dist/runtime/pageLang.js +64 -0
  45. package/dist/runtime/pageLang.js.map +1 -0
  46. package/dist/runtime/pageStrings.d.ts +35 -0
  47. package/dist/runtime/pageStrings.js +76 -0
  48. package/dist/runtime/pageStrings.js.map +1 -0
  49. package/dist/runtime/panelButton.d.ts +33 -0
  50. package/dist/runtime/panelButton.js +83 -0
  51. package/dist/runtime/panelButton.js.map +1 -0
  52. package/dist/runtime/permissions.d.ts +47 -0
  53. package/dist/runtime/permissions.js +141 -0
  54. package/dist/runtime/permissions.js.map +1 -0
  55. package/dist/runtime/pluginApi.d.ts +51 -2
  56. package/dist/runtime/pluginApi.js +137 -22
  57. package/dist/runtime/pluginApi.js.map +1 -1
  58. package/dist/runtime/pluginI18n.d.ts +29 -0
  59. package/dist/runtime/pluginI18n.js +119 -0
  60. package/dist/runtime/pluginI18n.js.map +1 -0
  61. package/dist/runtime/settingsForm.d.ts +66 -0
  62. package/dist/runtime/settingsForm.js +114 -0
  63. package/dist/runtime/settingsForm.js.map +1 -0
  64. package/dist/runtime/site.d.ts +5 -0
  65. package/dist/runtime/site.js +1 -1
  66. package/dist/runtime/site.js.map +1 -1
  67. package/dist/runtime/siteRuntime.d.ts +144 -0
  68. package/dist/runtime/siteRuntime.js +175 -0
  69. package/dist/runtime/siteRuntime.js.map +1 -0
  70. package/dist/runtime/stringPackHook.d.ts +84 -0
  71. package/dist/runtime/stringPackHook.js +220 -0
  72. package/dist/runtime/stringPackHook.js.map +1 -0
  73. package/dist/runtime/stringPackTranslate.d.ts +59 -0
  74. package/dist/runtime/stringPackTranslate.js +264 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +200 -0
  77. package/dist/runtime/stringPacks.js +474 -0
  78. package/dist/runtime/stringPacks.js.map +1 -0
  79. package/dist/runtime/styles.d.ts +15 -0
  80. package/dist/runtime/styles.js +81 -0
  81. package/dist/runtime/styles.js.map +1 -0
  82. package/dist/runtime/textNet.d.ts +15 -0
  83. package/dist/runtime/textNet.js +131 -0
  84. package/dist/runtime/textNet.js.map +1 -0
  85. package/dist/runtime/themeApi.d.ts +121 -0
  86. package/dist/runtime/themeApi.js +220 -0
  87. package/dist/runtime/themeApi.js.map +1 -0
  88. package/dist/runtime/themeChoice.d.ts +52 -0
  89. package/dist/runtime/themeChoice.js +69 -0
  90. package/dist/runtime/themeChoice.js.map +1 -0
  91. package/dist/runtime/themeComponents.d.ts +435 -0
  92. package/dist/runtime/themeComponents.js +463 -0
  93. package/dist/runtime/themeComponents.js.map +1 -0
  94. package/dist/runtime/themeDecor.d.ts +73 -0
  95. package/dist/runtime/themeDecor.js +131 -0
  96. package/dist/runtime/themeDecor.js.map +1 -0
  97. package/dist/runtime/themeDoctor.d.ts +11 -0
  98. package/dist/runtime/themeDoctor.js +51 -0
  99. package/dist/runtime/themeDoctor.js.map +1 -0
  100. package/dist/runtime/themeIcons.d.ts +130 -0
  101. package/dist/runtime/themeIcons.js +263 -0
  102. package/dist/runtime/themeIcons.js.map +1 -0
  103. package/dist/runtime/themeRuntime.d.ts +100 -0
  104. package/dist/runtime/themeRuntime.js +497 -0
  105. package/dist/runtime/themeRuntime.js.map +1 -0
  106. package/dist/runtime/themeSchema.d.ts +10 -0
  107. package/dist/runtime/themeSchema.js +150 -0
  108. package/dist/runtime/themeSchema.js.map +1 -0
  109. package/dist/runtime/themeSpec.d.ts +259 -0
  110. package/dist/runtime/themeSpec.js +439 -0
  111. package/dist/runtime/themeSpec.js.map +1 -0
  112. package/dist/runtime/themeTokens.d.ts +12 -0
  113. package/dist/runtime/themeTokens.js +14 -6
  114. package/dist/runtime/themeTokens.js.map +1 -1
  115. package/dist/runtime/themeVariants.d.ts +30 -0
  116. package/dist/runtime/themeVariants.js +53 -0
  117. package/dist/runtime/themeVariants.js.map +1 -0
  118. package/dist/runtime/ui.d.ts +192 -0
  119. package/dist/runtime/ui.js +926 -0
  120. package/dist/runtime/ui.js.map +1 -0
  121. package/dist/shell/InstallDialog.d.ts +40 -0
  122. package/dist/shell/InstallDialog.js +170 -0
  123. package/dist/shell/InstallDialog.js.map +1 -0
  124. package/dist/shell/StoreView.d.ts +66 -0
  125. package/dist/shell/StoreView.js +103 -0
  126. package/dist/shell/StoreView.js.map +1 -0
  127. package/dist/shell/addressModel.js.map +1 -1
  128. package/dist/shell/chrome.js.map +1 -1
  129. package/dist/shell/deckModel.d.ts +117 -0
  130. package/dist/shell/deckModel.js +267 -0
  131. package/dist/shell/deckModel.js.map +1 -0
  132. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  133. package/dist/shell/frame/AccountSwitcher.js +243 -0
  134. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  135. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  136. package/dist/shell/frame/AddColumnDialog.js +81 -0
  137. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  138. package/dist/shell/frame/AppMenu.d.ts +21 -0
  139. package/dist/shell/frame/AppMenu.js +642 -0
  140. package/dist/shell/frame/AppMenu.js.map +1 -0
  141. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  142. package/dist/shell/frame/CommandPalette.js +118 -0
  143. package/dist/shell/frame/CommandPalette.js.map +1 -0
  144. package/dist/shell/frame/DeckView.d.ts +13 -0
  145. package/dist/shell/frame/DeckView.js +287 -0
  146. package/dist/shell/frame/DeckView.js.map +1 -0
  147. package/dist/shell/frame/FindBar.d.ts +10 -0
  148. package/dist/shell/frame/FindBar.js +108 -0
  149. package/dist/shell/frame/FindBar.js.map +1 -0
  150. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  151. package/dist/shell/frame/MediaPanel.js +76 -0
  152. package/dist/shell/frame/MediaPanel.js.map +1 -0
  153. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  154. package/dist/shell/frame/NewTabPage.js +71 -0
  155. package/dist/shell/frame/NewTabPage.js.map +1 -0
  156. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  157. package/dist/shell/frame/PaneTheme.js +67 -0
  158. package/dist/shell/frame/PaneTheme.js.map +1 -0
  159. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  160. package/dist/shell/frame/ReportDialog.js +95 -0
  161. package/dist/shell/frame/ReportDialog.js.map +1 -0
  162. package/dist/shell/frame/Shell.d.ts +8 -0
  163. package/dist/shell/frame/Shell.js +1131 -0
  164. package/dist/shell/frame/Shell.js.map +1 -0
  165. package/dist/shell/frame/Titlebar.d.ts +16 -0
  166. package/dist/shell/frame/Titlebar.js +77 -0
  167. package/dist/shell/frame/Titlebar.js.map +1 -0
  168. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  169. package/dist/shell/frame/TitlebarExtras.js +202 -0
  170. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  171. package/dist/shell/frame/WebPanel.d.ts +4 -0
  172. package/dist/shell/frame/WebPanel.js +182 -0
  173. package/dist/shell/frame/WebPanel.js.map +1 -0
  174. package/dist/shell/frame/accountModel.d.ts +49 -0
  175. package/dist/shell/frame/accountModel.js +67 -0
  176. package/dist/shell/frame/accountModel.js.map +1 -0
  177. package/dist/shell/frame/accountSwitcher.css +91 -0
  178. package/dist/shell/frame/appI18n.d.ts +44 -0
  179. package/dist/shell/frame/appI18n.js +64 -0
  180. package/dist/shell/frame/appI18n.js.map +1 -0
  181. package/dist/shell/frame/appMenu.css +121 -0
  182. package/dist/shell/frame/backupModel.d.ts +38 -0
  183. package/dist/shell/frame/backupModel.js +192 -0
  184. package/dist/shell/frame/backupModel.js.map +1 -0
  185. package/dist/shell/frame/boot.d.ts +8 -0
  186. package/dist/shell/frame/boot.js +35 -0
  187. package/dist/shell/frame/boot.js.map +1 -0
  188. package/dist/shell/frame/brand.d.ts +1 -0
  189. package/dist/shell/frame/brand.js +4 -0
  190. package/dist/shell/frame/brand.js.map +1 -0
  191. package/dist/shell/frame/bridge.d.ts +35 -0
  192. package/dist/shell/frame/bridge.js +70 -0
  193. package/dist/shell/frame/bridge.js.map +1 -0
  194. package/dist/shell/frame/chromeTheme.d.ts +29 -0
  195. package/dist/shell/frame/chromeTheme.js +81 -0
  196. package/dist/shell/frame/chromeTheme.js.map +1 -0
  197. package/dist/shell/frame/deck.css +209 -0
  198. package/dist/shell/frame/deckStore.d.ts +89 -0
  199. package/dist/shell/frame/deckStore.js +239 -0
  200. package/dist/shell/frame/deckStore.js.map +1 -0
  201. package/dist/shell/frame/devHost.d.ts +35 -0
  202. package/dist/shell/frame/devHost.js +80 -0
  203. package/dist/shell/frame/devHost.js.map +1 -0
  204. package/dist/shell/frame/devModel.d.ts +7 -0
  205. package/dist/shell/frame/devModel.js +17 -0
  206. package/dist/shell/frame/devModel.js.map +1 -0
  207. package/dist/shell/frame/diag.d.ts +7 -0
  208. package/dist/shell/frame/diag.js +39 -0
  209. package/dist/shell/frame/diag.js.map +1 -0
  210. package/dist/shell/frame/findBar.css +14 -0
  211. package/dist/shell/frame/frameMessages.d.ts +248 -0
  212. package/dist/shell/frame/frameMessages.js +252 -0
  213. package/dist/shell/frame/frameMessages.js.map +1 -0
  214. package/dist/shell/frame/hooks.d.ts +39 -0
  215. package/dist/shell/frame/hooks.js +97 -0
  216. package/dist/shell/frame/hooks.js.map +1 -0
  217. package/dist/shell/frame/i18n.d.ts +27 -0
  218. package/dist/shell/frame/i18n.js +66 -0
  219. package/dist/shell/frame/i18n.js.map +1 -0
  220. package/dist/shell/frame/iconPack.d.ts +11 -0
  221. package/dist/shell/frame/iconPack.js +45 -0
  222. package/dist/shell/frame/iconPack.js.map +1 -0
  223. package/dist/shell/frame/icons.d.ts +71 -0
  224. package/dist/shell/frame/icons.js +75 -0
  225. package/dist/shell/frame/icons.js.map +1 -0
  226. package/dist/shell/frame/index.d.ts +34 -0
  227. package/dist/shell/frame/index.js +43 -0
  228. package/dist/shell/frame/index.js.map +1 -0
  229. package/dist/shell/frame/language.d.ts +58 -0
  230. package/dist/shell/frame/language.js +165 -0
  231. package/dist/shell/frame/language.js.map +1 -0
  232. package/dist/shell/frame/mediaModel.d.ts +34 -0
  233. package/dist/shell/frame/mediaModel.js +53 -0
  234. package/dist/shell/frame/mediaModel.js.map +1 -0
  235. package/dist/shell/frame/menuMessages.en.json +54 -0
  236. package/dist/shell/frame/menuModel.d.ts +277 -0
  237. package/dist/shell/frame/menuModel.js +293 -0
  238. package/dist/shell/frame/menuModel.js.map +1 -0
  239. package/dist/shell/frame/paletteModel.d.ts +139 -0
  240. package/dist/shell/frame/paletteModel.js +112 -0
  241. package/dist/shell/frame/paletteModel.js.map +1 -0
  242. package/dist/shell/frame/paneTheme.css +9 -0
  243. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  244. package/dist/shell/frame/pluginCommandStore.js +70 -0
  245. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  246. package/dist/shell/frame/reportModel.d.ts +52 -0
  247. package/dist/shell/frame/reportModel.js +105 -0
  248. package/dist/shell/frame/reportModel.js.map +1 -0
  249. package/dist/shell/frame/safeStore.d.ts +7 -0
  250. package/dist/shell/frame/safeStore.js +40 -0
  251. package/dist/shell/frame/safeStore.js.map +1 -0
  252. package/dist/shell/frame/searchInput.d.ts +2 -0
  253. package/dist/shell/frame/searchInput.js +11 -0
  254. package/dist/shell/frame/searchInput.js.map +1 -0
  255. package/dist/shell/frame/shell.css +629 -0
  256. package/dist/shell/frame/site.d.ts +206 -0
  257. package/dist/shell/frame/site.js +22 -0
  258. package/dist/shell/frame/site.js.map +1 -0
  259. package/dist/shell/frame/state.d.ts +99 -0
  260. package/dist/shell/frame/state.js +284 -0
  261. package/dist/shell/frame/state.js.map +1 -0
  262. package/dist/shell/frame/syncGate.d.ts +10 -0
  263. package/dist/shell/frame/syncGate.js +36 -0
  264. package/dist/shell/frame/syncGate.js.map +1 -0
  265. package/dist/shell/frame/syncHost.d.ts +35 -0
  266. package/dist/shell/frame/syncHost.js +85 -0
  267. package/dist/shell/frame/syncHost.js.map +1 -0
  268. package/dist/shell/frame/tabStill.d.ts +2 -0
  269. package/dist/shell/frame/tabStill.js +62 -0
  270. package/dist/shell/frame/tabStill.js.map +1 -0
  271. package/dist/shell/frame/themeScopes.d.ts +29 -0
  272. package/dist/shell/frame/themeScopes.js +61 -0
  273. package/dist/shell/frame/themeScopes.js.map +1 -0
  274. package/dist/shell/frame/themeStore.d.ts +99 -0
  275. package/dist/shell/frame/themeStore.js +252 -0
  276. package/dist/shell/frame/themeStore.js.map +1 -0
  277. package/dist/shell/frame/windowBinding.d.ts +2 -0
  278. package/dist/shell/frame/windowBinding.js +7 -0
  279. package/dist/shell/frame/windowBinding.js.map +1 -0
  280. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  281. package/dist/shell/frame/workspaceModel.js +250 -0
  282. package/dist/shell/frame/workspaceModel.js.map +1 -0
  283. package/dist/shell/frame/workspaces.css +84 -0
  284. package/dist/shell/frame/workspaces.d.ts +22 -0
  285. package/dist/shell/frame/workspaces.js +125 -0
  286. package/dist/shell/frame/workspaces.js.map +1 -0
  287. package/dist/shell/frame/zoomStore.d.ts +10 -0
  288. package/dist/shell/frame/zoomStore.js +65 -0
  289. package/dist/shell/frame/zoomStore.js.map +1 -0
  290. package/dist/shell/installController.d.ts +122 -0
  291. package/dist/shell/installController.js +146 -0
  292. package/dist/shell/installController.js.map +1 -0
  293. package/dist/shell/installerMessages.d.ts +30 -0
  294. package/dist/shell/installerMessages.js +36 -0
  295. package/dist/shell/installerMessages.js.map +1 -0
  296. package/dist/shell/linkDrop.js.map +1 -1
  297. package/dist/shell/messages.d.ts +16 -0
  298. package/dist/shell/messages.js +27 -0
  299. package/dist/shell/messages.js.map +1 -0
  300. package/dist/shell/palette.js.map +1 -1
  301. package/dist/shell/paneModel.d.ts +22 -0
  302. package/dist/shell/paneModel.js +24 -1
  303. package/dist/shell/paneModel.js.map +1 -1
  304. package/dist/shell/panel/Appearance.d.ts +8 -0
  305. package/dist/shell/panel/Appearance.js +256 -0
  306. package/dist/shell/panel/Appearance.js.map +1 -0
  307. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  308. package/dist/shell/panel/BackupPanel.js +198 -0
  309. package/dist/shell/panel/BackupPanel.js.map +1 -0
  310. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  311. package/dist/shell/panel/DeveloperPanel.js +51 -0
  312. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  313. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  314. package/dist/shell/panel/FeatureToggles.js +42 -0
  315. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  316. package/dist/shell/panel/Home.d.ts +3 -0
  317. package/dist/shell/panel/Home.js +23 -0
  318. package/dist/shell/panel/Home.js.map +1 -0
  319. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  320. package/dist/shell/panel/IconPackInstall.js +41 -0
  321. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  322. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  323. package/dist/shell/panel/LanguageSettings.js +54 -0
  324. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  325. package/dist/shell/panel/MakePanel.d.ts +3 -0
  326. package/dist/shell/panel/MakePanel.js +237 -0
  327. package/dist/shell/panel/MakePanel.js.map +1 -0
  328. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  329. package/dist/shell/panel/MarkdownDoc.js +35 -0
  330. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  331. package/dist/shell/panel/Modes.d.ts +40 -0
  332. package/dist/shell/panel/Modes.js +270 -0
  333. package/dist/shell/panel/Modes.js.map +1 -0
  334. package/dist/shell/panel/NavIcon.d.ts +4 -0
  335. package/dist/shell/panel/NavIcon.js +6 -0
  336. package/dist/shell/panel/NavIcon.js.map +1 -0
  337. package/dist/shell/panel/Panel.d.ts +7 -0
  338. package/dist/shell/panel/Panel.js +139 -0
  339. package/dist/shell/panel/Panel.js.map +1 -0
  340. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  341. package/dist/shell/panel/PluginFeatures.js +165 -0
  342. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  343. package/dist/shell/panel/Plugins.d.ts +33 -0
  344. package/dist/shell/panel/Plugins.js +112 -0
  345. package/dist/shell/panel/Plugins.js.map +1 -0
  346. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  347. package/dist/shell/panel/PowerSettings.js +52 -0
  348. package/dist/shell/panel/PowerSettings.js.map +1 -0
  349. package/dist/shell/panel/Settings.d.ts +23 -0
  350. package/dist/shell/panel/Settings.js +116 -0
  351. package/dist/shell/panel/Settings.js.map +1 -0
  352. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  353. package/dist/shell/panel/ShareSetup.js +130 -0
  354. package/dist/shell/panel/ShareSetup.js.map +1 -0
  355. package/dist/shell/panel/StoreSection.d.ts +6 -0
  356. package/dist/shell/panel/StoreSection.js +48 -0
  357. package/dist/shell/panel/StoreSection.js.map +1 -0
  358. package/dist/shell/panel/StringPacks.d.ts +11 -0
  359. package/dist/shell/panel/StringPacks.js +106 -0
  360. package/dist/shell/panel/StringPacks.js.map +1 -0
  361. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  362. package/dist/shell/panel/ThemeBuilder.js +205 -0
  363. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  364. package/dist/shell/panel/backup.css +34 -0
  365. package/dist/shell/panel/builder.css +232 -0
  366. package/dist/shell/panel/builderModel.d.ts +55 -0
  367. package/dist/shell/panel/builderModel.js +95 -0
  368. package/dist/shell/panel/builderModel.js.map +1 -0
  369. package/dist/shell/panel/compare.d.ts +10 -0
  370. package/dist/shell/panel/compare.js +51 -0
  371. package/dist/shell/panel/compare.js.map +1 -0
  372. package/dist/shell/panel/controls.d.ts +135 -0
  373. package/dist/shell/panel/controls.js +213 -0
  374. package/dist/shell/panel/controls.js.map +1 -0
  375. package/dist/shell/panel/featureModel.d.ts +69 -0
  376. package/dist/shell/panel/featureModel.js +79 -0
  377. package/dist/shell/panel/featureModel.js.map +1 -0
  378. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  379. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  380. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  381. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  382. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  383. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  384. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  385. package/dist/shell/panel/fonts/catalog.js +68 -0
  386. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  387. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  388. package/dist/shell/panel/index.d.ts +20 -0
  389. package/dist/shell/panel/index.js +34 -0
  390. package/dist/shell/panel/index.js.map +1 -0
  391. package/dist/shell/panel/languageModel.d.ts +5 -0
  392. package/dist/shell/panel/languageModel.js +7 -0
  393. package/dist/shell/panel/languageModel.js.map +1 -0
  394. package/dist/shell/panel/make.css +72 -0
  395. package/dist/shell/panel/makeModel.d.ts +32 -0
  396. package/dist/shell/panel/makeModel.js +84 -0
  397. package/dist/shell/panel/makeModel.js.map +1 -0
  398. package/dist/shell/panel/markdown.d.ts +46 -0
  399. package/dist/shell/panel/markdown.js +100 -0
  400. package/dist/shell/panel/markdown.js.map +1 -0
  401. package/dist/shell/panel/nav.d.ts +12 -0
  402. package/dist/shell/panel/nav.js +50 -0
  403. package/dist/shell/panel/nav.js.map +1 -0
  404. package/dist/shell/panel/panel.css +401 -0
  405. package/dist/shell/panel/panelMessages.d.ts +763 -0
  406. package/dist/shell/panel/panelMessages.js +767 -0
  407. package/dist/shell/panel/panelMessages.js.map +1 -0
  408. package/dist/shell/panel/plugins.css +59 -0
  409. package/dist/shell/panel/setupModel.d.ts +87 -0
  410. package/dist/shell/panel/setupModel.js +152 -0
  411. package/dist/shell/panel/setupModel.js.map +1 -0
  412. package/dist/shell/panel/site.d.ts +259 -0
  413. package/dist/shell/panel/site.js +25 -0
  414. package/dist/shell/panel/site.js.map +1 -0
  415. package/dist/shell/panel/strings.css +7 -0
  416. package/dist/shell/panel/themes.d.ts +10 -0
  417. package/dist/shell/panel/themes.js +8 -0
  418. package/dist/shell/panel/themes.js.map +1 -0
  419. package/dist/shell/profileModel.d.ts +3 -2
  420. package/dist/shell/profileModel.js +7 -5
  421. package/dist/shell/profileModel.js.map +1 -1
  422. package/dist/shell/store.css +230 -0
  423. package/dist/shell/storeMessages.d.ts +169 -0
  424. package/dist/shell/storeMessages.js +172 -0
  425. package/dist/shell/storeMessages.js.map +1 -0
  426. package/dist/shell/storeModel.d.ts +181 -0
  427. package/dist/shell/storeModel.js +133 -0
  428. package/dist/shell/storeModel.js.map +1 -0
  429. package/dist/shell/stringPacksModel.d.ts +44 -0
  430. package/dist/shell/stringPacksModel.js +94 -0
  431. package/dist/shell/stringPacksModel.js.map +1 -0
  432. package/dist/shell/updateModel.d.ts +2 -1
  433. package/dist/shell/updateModel.js +5 -4
  434. package/dist/shell/updateModel.js.map +1 -1
  435. package/dist/shell/windowControls.d.ts +4 -0
  436. package/dist/shell/windowControls.js +5 -0
  437. package/dist/shell/windowControls.js.map +1 -1
  438. package/i18n-config.schema.json +29 -0
  439. package/i18n-meta.schema.json +26 -0
  440. package/i18n.schema.json +42 -0
  441. package/icons.schema.json +646 -0
  442. package/languages.schema.json +23 -0
  443. package/locales/ar-x-fm.json +11 -0
  444. package/locales/ar.json +1281 -0
  445. package/locales/bg.json +1280 -0
  446. package/locales/bn.json +1280 -0
  447. package/locales/ca.json +1280 -0
  448. package/locales/cs.json +1280 -0
  449. package/locales/da.json +1280 -0
  450. package/locales/de.json +1280 -0
  451. package/locales/el.json +1280 -0
  452. package/locales/en-GB.json +27 -0
  453. package/locales/en.json +1280 -0
  454. package/locales/en.meta.json +51 -0
  455. package/locales/es.json +1280 -0
  456. package/locales/eu.json +1280 -0
  457. package/locales/fa.json +1281 -0
  458. package/locales/fi.json +1280 -0
  459. package/locales/fil.json +1280 -0
  460. package/locales/fr.json +1280 -0
  461. package/locales/ga.json +1280 -0
  462. package/locales/gl.json +1280 -0
  463. package/locales/gu.json +1280 -0
  464. package/locales/ha.json +1280 -0
  465. package/locales/he.json +1281 -0
  466. package/locales/hi.json +1280 -0
  467. package/locales/hr.json +1280 -0
  468. package/locales/hu.json +1279 -0
  469. package/locales/id.json +1280 -0
  470. package/locales/ig.json +1280 -0
  471. package/locales/it.json +1280 -0
  472. package/locales/ja.json +1280 -0
  473. package/locales/kn.json +1280 -0
  474. package/locales/ko.json +1280 -0
  475. package/locales/mr.json +1280 -0
  476. package/locales/ms.json +1280 -0
  477. package/locales/nb.json +1280 -0
  478. package/locales/nl.json +1280 -0
  479. package/locales/pl.json +1280 -0
  480. package/locales/pt.json +1280 -0
  481. package/locales/ro.json +1280 -0
  482. package/locales/ru.json +1280 -0
  483. package/locales/sk.json +1280 -0
  484. package/locales/sr.json +1280 -0
  485. package/locales/sv.json +1280 -0
  486. package/locales/ta.json +1280 -0
  487. package/locales/th.json +1280 -0
  488. package/locales/tr.json +1280 -0
  489. package/locales/uk.json +1280 -0
  490. package/locales/ur.json +1281 -0
  491. package/locales/vi.json +1280 -0
  492. package/locales/yo.json +1280 -0
  493. package/locales/zh-Hans.json +1280 -0
  494. package/locales/zh-Hant.json +1280 -0
  495. package/package.json +148 -6
  496. package/store-catalog.schema.json +65 -0
  497. package/theme.schema.json +4659 -0
  498. package/windows/installer.nsi +926 -0
  499. package/windows/languages/Basque.nsh +28 -0
  500. package/windows/languages/Catalan.nsh +28 -0
  501. package/windows/languages/Croatian.nsh +28 -0
  502. package/windows/languages/Czech.nsh +28 -0
  503. package/windows/languages/Danish.nsh +28 -0
  504. package/windows/languages/Finnish.nsh +28 -0
  505. package/windows/languages/Galician.nsh +28 -0
  506. package/windows/languages/Greek.nsh +28 -0
  507. package/windows/languages/Hungarian.nsh +28 -0
  508. package/windows/languages/Indonesian.nsh +28 -0
  509. package/windows/languages/Irish.nsh +28 -0
  510. package/windows/languages/Malay.nsh +28 -0
  511. package/windows/languages/Polish.nsh +28 -0
  512. package/windows/languages/Romanian.nsh +28 -0
  513. package/windows/languages/Serbian.nsh +28 -0
  514. package/windows/languages/Slovak.nsh +28 -0
  515. package/windows/languages/Thai.nsh +28 -0
@@ -0,0 +1,205 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // The Theme Builder: a full editor for a theme document with a live preview on the real site panes (a
3
+ // native, unsaved preview; closing the builder gives every tab its own theme back), the local
4
+ // miniature and the chrome. Three base colors derive the whole palette; a contrast report shows every
5
+ // pair the site draws and can fix them; fonts per role with the Google Fonts browser; shape, layout,
6
+ // background, effects and theme CSS. Undo/redo (Ctrl+Z / Ctrl+Shift+Z), Save as theme, Export, Share.
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ import { MAX_CSS_CHARS, MAX_IMAGE_CHARS, isHex, sanitizeSpec, } from "../../runtime/themeSpec.js";
9
+ import { chromeVars } from "../frame/chromeTheme.js";
10
+ import { useT } from "../frame/hooks.js";
11
+ import { formatNumber, t, tx } from "../frame/i18n.js";
12
+ import { ThemeDots } from "../frame/PaneTheme.js";
13
+ import { DERIVED_ROLES, autoFix, contrastReport, draftFrom, modeOf, paletteFrom, pinnedRoles, record, redo, startHistory, themeJson, undo, uniqueId, wcagLevel, } from "./builderModel.js";
14
+ import { Button, ColorField, Segmented, Select, Slider, Toggle } from "./controls.js";
15
+ import { FontRoles } from "./fonts/FontRoles.js";
16
+ import { panelSite, panelThemes } from "./site.js";
17
+ import { useThemeState } from "./themes.js";
18
+ import './builder.css';
19
+ /** Swatches for the three base colors when the app names none. */
20
+ const BASE_SWATCHES = {
21
+ bg: ['#000000', '#0b0d12', '#15202b', '#1a1b26', '#2e3440', '#ffffff', '#fbf8f1', '#fdf6e3'],
22
+ text: ['#e7e9ea', '#eef0f7', '#ffffff', '#c0caf5', '#0f1419', '#2a241d', '#073642', '#000000'],
23
+ accent: ['#1d9bf0', '#5b8cff', '#7856ff', '#bd93f9', '#f91880', '#ff7a00', '#00ba7c', '#3dff7a'],
24
+ };
25
+ const ROLE_LABEL = { surface: 'wb.builder.role.surface', elevated: 'wb.builder.role.elevated', border: 'wb.builder.role.border', muted: 'wb.builder.role.muted', inverse: 'wb.builder.role.inverse', onInverse: 'wb.builder.role.onInverse', page: 'wb.builder.role.page' };
26
+ const px = (v) => t('wb.appearance.px', { value: v });
27
+ const pct = (v) => t('wb.appearance.percent', { value: v / 100 });
28
+ const PATTERNS = ['dots', 'grid', 'diagonal', 'scanlines', 'paper', 'clouds'];
29
+ export function ThemeBuilder({ notify }) {
30
+ const t = useT();
31
+ const themes = panelThemes();
32
+ const { allThemes, missingFonts, setChoice, setPreview, themeState } = themes.store;
33
+ const resolveTheme = themes.catalog.resolve;
34
+ const ThemePreview = themes.Preview;
35
+ const draftSite = { colors: themes.draftColors, siteTheme: themes.catalog.defaultChoice.preset };
36
+ const swatches = themes.baseSwatches ?? BASE_SWATCHES;
37
+ const { ready, choice } = useThemeState();
38
+ const [history, setHistory] = useState(null);
39
+ const [live, setLive] = useState(true);
40
+ const dragFrom = useRef(null);
41
+ // Start from the theme that is on now.
42
+ useEffect(() => { if (ready && !history)
43
+ setHistory(startHistory(draftFrom(resolveTheme(choice), draftSite))); }, [ready]);
44
+ const draft = history?.present ?? null;
45
+ // Live on the real site panes and the chrome (debounced), until the builder closes.
46
+ useEffect(() => {
47
+ if (!draft)
48
+ return;
49
+ const timer = setTimeout(() => void setPreview(live ? draft : null), 120);
50
+ return () => clearTimeout(timer);
51
+ }, [draft, live]);
52
+ useEffect(() => () => { void setPreview(null); }, []);
53
+ /** Applies a change; `commit: false` while a slider drags (one undo step per drag). */
54
+ const change = useCallback((next, commit = true) => {
55
+ setHistory(current => {
56
+ if (!current)
57
+ return current;
58
+ if (!commit) {
59
+ dragFrom.current ??= current.present;
60
+ return record(current, next, { commit: false });
61
+ }
62
+ const from = dragFrom.current ?? undefined;
63
+ dragFrom.current = null;
64
+ return record(current, next, { from });
65
+ });
66
+ }, []);
67
+ // Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y anywhere while the builder is open, except inside text fields.
68
+ useEffect(() => {
69
+ const onKey = (event) => {
70
+ const target = event.target;
71
+ if (target && (target.isContentEditable || (/^(input|textarea)$/i.test(target.tagName) && !/^(range|color|checkbox)$/.test(target.type))))
72
+ return;
73
+ if (!(event.ctrlKey || event.metaKey) || event.altKey)
74
+ return;
75
+ const key = event.key.toLowerCase();
76
+ if (key === 'z' && !event.shiftKey) {
77
+ event.preventDefault();
78
+ setHistory(h => h && undo(h));
79
+ }
80
+ else if ((key === 'z' && event.shiftKey) || key === 'y') {
81
+ event.preventDefault();
82
+ setHistory(h => h && redo(h));
83
+ }
84
+ };
85
+ window.addEventListener('keydown', onKey);
86
+ return () => window.removeEventListener('keydown', onKey);
87
+ }, []);
88
+ if (!draft || !history)
89
+ return _jsx("div", { className: "wb-builder is-loading", "aria-busy": "true" });
90
+ const colors = draft.colors;
91
+ const set = (key, value, commit = true) => change({ ...draft, [key]: value }, commit);
92
+ const setColors = (next, commit = true) => change({ ...draft, colors: next, mode: modeOf(next) }, commit);
93
+ const setBase = (role, value) => {
94
+ const base = { bg: colors.bg, text: colors.text, accent: colors.accent, [role]: value };
95
+ // A new base re-derives every other role (hand-set roles belong to the old base).
96
+ setColors(paletteFrom(base));
97
+ };
98
+ const setFont = (patch, commit = true) => set('font', sanitizeSpec({ name: 'x', font: { ...draft.font, ...patch } }).font, commit);
99
+ const setRole = (role, next, commit = true) => setFont({ roles: { ...draft.font.roles, [role]: next } }, commit);
100
+ const setShape = (patch, commit = true) => set('shape', { ...draft.shape, ...patch }, commit);
101
+ const setLayout = (patch, commit = true) => set('layout', { ...draft.layout, ...patch }, commit);
102
+ const setEffects = (patch, commit = true) => set('effects', { ...draft.effects, ...patch }, commit);
103
+ const startFrom = (id) => {
104
+ const theme = allThemes(choice).find(item => item.id === id);
105
+ if (!theme)
106
+ return;
107
+ change(draftFrom(id === choice.preset ? resolveTheme(choice) : theme, draftSite));
108
+ notify(t('wb.builder.startedFrom', { name: theme.name }));
109
+ };
110
+ async function save() {
111
+ const state = themeState();
112
+ const missing = missingFonts(draft);
113
+ const id = uniqueId(draft.name, [...themes.catalog.builtins, ...state.choice.themes].map(theme => theme.id));
114
+ const theme = sanitizeSpec({ ...draft, id });
115
+ try {
116
+ await setChoice({ ...state.choice, themes: [...state.choice.themes, theme], preset: id, overrides: {}, accent: null });
117
+ notify(`${t('wb.builder.saved', { name: theme.name })}${missing.length ? ` ${t('wb.builder.savedMissing', { fonts: missing.join(', '), count: missing.length })}` : ''}`);
118
+ }
119
+ catch (error) {
120
+ notify(error instanceof Error ? error.message : String(error), true);
121
+ }
122
+ }
123
+ function exportFile() {
124
+ const url = URL.createObjectURL(new Blob([themeJson(draft)], { type: 'application/json' }));
125
+ const anchor = document.createElement('a');
126
+ anchor.href = url;
127
+ anchor.download = `${draft.id}${themes.fileSuffix ?? '.theme.json'}`;
128
+ anchor.click();
129
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
130
+ }
131
+ async function share() {
132
+ try {
133
+ await navigator.clipboard.writeText(themeJson(draft));
134
+ notify(t('wb.builder.shared'));
135
+ }
136
+ catch {
137
+ notify(t('wb.builder.copyFailed'), true);
138
+ }
139
+ }
140
+ const report = contrastReport(colors);
141
+ const failing = report.filter(check => !check.pass).length;
142
+ const options = allThemes(choice).map(theme => ({ value: theme.id, label: theme.name, icon: _jsx(ThemeDots, { theme: theme }) }));
143
+ return _jsxs("div", { className: "wb-builder", children: [_jsxs("div", { className: "wb-builder-bar", role: "toolbar", "aria-label": t('wb.panel.section.builder'), children: [_jsx("input", { className: "wb-builder-name", "aria-label": t('wb.builder.name'), value: draft.name, maxLength: 60, spellCheck: false, onChange: event => set('name', event.target.value, false), onBlur: event => set('name', event.target.value.trim() || t('wb.builder.untitled')) }), _jsxs("div", { className: "wb-builder-tools", children: [_jsx(Select, { label: t('wb.builder.startFrom'), value: null, placeholder: t('wb.builder.startFromPlaceholder'), options: options, width: 176, onChange: startFrom }), _jsx("span", { className: "wb-divider", "aria-hidden": "true" }), _jsx(IconButton, { label: t('wb.builder.undo'), disabled: !history.past.length, onClick: () => setHistory(h => h && undo(h)), d: "M6 4 3 7l3 3M3 7h7a4 4 0 0 1 0 8H8" }), _jsx(IconButton, { label: t('wb.builder.redo'), disabled: !history.future.length, onClick: () => setHistory(h => h && redo(h)), d: "m10 4 3 3-3 3M13 7H6a4 4 0 0 0 0 8h2" }), _jsx("span", { className: "wb-divider", "aria-hidden": "true" }), _jsxs("label", { className: "wb-live", children: [_jsx(Toggle, { label: t('wb.builder.previewLive'), checked: live, onChange: setLive }), _jsx("span", { children: t('wb.builder.liveOnSite') })] }), _jsx(Button, { size: "sm", tone: "ghost", onClick: () => void share(), children: t('wb.builder.share') }), _jsx(Button, { size: "sm", tone: "ghost", onClick: exportFile, children: t('wb.common.export') }), _jsx(Button, { size: "sm", tone: "primary", onClick: () => void save(), children: t('wb.appearance.saveAsTheme') })] })] }), _jsxs("div", { className: "wb-builder-grid", children: [_jsxs("div", { className: "wb-builder-controls", children: [_jsxs(Card, { title: t('wb.builder.colors'), hint: t('wb.builder.colorsHint'), children: [_jsx("div", { className: "wb-base", children: ['bg', 'text', 'accent'].map(role => _jsxs("div", { className: "wb-base-item", children: [_jsxs("div", { className: "wb-base-swatch", style: { background: colors[role] }, children: [_jsx("span", { style: { color: role === 'bg' ? colors.text : colors.bg }, children: role === 'bg' ? t('wb.appearance.background') : role === 'text' ? t('wb.builder.text') : t('wb.appearance.accent') }), _jsx("code", { children: colors[role] })] }), _jsx(ColorField, { label: role === 'bg' ? t('wb.builder.backgroundColor') : role === 'text' ? t('wb.builder.textColor') : t('wb.appearance.accentColor'), value: colors[role], swatches: swatches[role], onChange: value => value && setBase(role, value) })] }, role)) }), _jsx(Palette, { colors: colors, onChange: setColors })] }), _jsx(Card, { title: t('wb.builder.contrast'), hint: t('wb.builder.contrastHint'), action: failing ? _jsx(Button, { size: "sm", tone: "primary", onClick: () => { setColors(autoFix(colors)); notify(t('wb.builder.adjusted', { count: failing })); }, children: t('wb.builder.autoFix', { count: failing }) }) : _jsx("span", { className: "wb-ok", children: t('wb.builder.allPass') }), children: _jsx("ul", { className: "wb-contrast", children: report.map(check => _jsxs("li", { className: check.pass ? 'is-pass' : 'is-fail', children: [_jsx("span", { className: "wb-contrast-sample", style: { color: check.fg, background: check.bg }, children: "Aa" }), _jsx("span", { className: "wb-contrast-label", children: tx(`wb.builder.contrast.${check.id}`, undefined, check.label) }), _jsxs("span", { className: "wb-contrast-ratio", children: [_jsx("b", { children: formatNumber(check.ratio, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }), ":1"] }), _jsx("span", { className: "wb-contrast-need", children: t('wb.builder.needs', { ratio: check.need }) }), _jsx("span", { className: `wb-contrast-badge ${check.pass ? 'is-pass' : 'is-fail'}`, children: check.pass ? wcagLevel(check.ratio) : t('wb.builder.tooLow') })] }, check.id)) }) }), _jsxs(Card, { title: t('wb.builder.type'), hint: t('wb.builder.typeHint'), children: [_jsx(FontRoles, { font: draft.font, onRole: setRole }), _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.appearance.textSize'), children: _jsx(Slider, { label: t('wb.appearance.textSize'), min: 85, max: 120, value: Math.round(draft.font.scale * 100), format: pct, onChange: v => setFont({ scale: v / 100 }, false), onCommit: v => setFont({ scale: v / 100 }) }) }), _jsx(Field, { label: t('wb.builder.regularWeight'), children: _jsx(Slider, { label: t('wb.builder.regularWeight'), min: 300, max: 500, step: 10, value: draft.font.weight, format: String, onChange: v => setFont({ weight: v }, false), onCommit: v => setFont({ weight: v }) }) }), _jsx(Field, { label: t('wb.appearance.bold'), children: _jsx(Slider, { label: t('wb.appearance.bold'), min: 500, max: 800, step: 10, value: draft.font.bold, format: String, onChange: v => setFont({ bold: v }, false), onCommit: v => setFont({ bold: v }) }) }), _jsx(Field, { label: t('wb.builder.tracking'), children: _jsx(Slider, { label: t('wb.builder.tracking'), min: -30, max: 60, step: 2, value: Math.round(draft.font.tracking * 1000), format: v => `${formatNumber(v / 1000, { minimumFractionDigits: 3, maximumFractionDigits: 3 })} em`, onChange: v => setFont({ tracking: v / 1000 }, false), onCommit: v => setFont({ tracking: v / 1000 }) }) }), _jsx(Field, { label: t('wb.builder.leading'), children: _jsx(Slider, { label: t('wb.builder.leading'), min: 115, max: 180, step: 5, value: draft.font.leading ? Math.round(draft.font.leading * 100) : 115, format: v => v === 115 ? t('wb.builder.leadingSite') : formatNumber(v / 100, { minimumFractionDigits: 2, maximumFractionDigits: 2 }), onChange: v => setFont({ leading: v === 115 ? 0 : v / 100 }, false), onCommit: v => setFont({ leading: v === 115 ? 0 : v / 100 }) }) })] })] }), _jsx(Card, { title: t('wb.builder.shape'), children: _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.builder.cardCorners'), children: _jsx(Slider, { label: t('wb.builder.cardCorners'), min: 0, max: 28, value: draft.shape.radius, format: px, onChange: v => setShape({ radius: v }, false), onCommit: v => setShape({ radius: v }) }) }), _jsx(Field, { label: t('wb.builder.buttons'), children: _jsx(Segmented, { label: t('wb.builder.buttonShape'), size: "sm", value: draft.shape.button >= 100 ? 'pill' : draft.shape.button === 0 ? 'square' : 'soft', onChange: v => setShape({ button: v === 'pill' ? 9999 : v === 'square' ? 0 : Math.max(4, Math.min(12, draft.shape.radius)) }), options: [{ value: 'square', label: t('wb.appearance.corners.square') }, { value: 'soft', label: t('wb.appearance.corners.soft') }, { value: 'pill', label: t('wb.builder.pill') }] }) }), _jsx(Field, { label: t('wb.appearance.avatars'), children: _jsx(Segmented, { label: t('wb.appearance.avatars'), size: "sm", value: draft.shape.avatar, onChange: avatar => setShape({ avatar }), options: [{ value: 'circle', label: t('wb.appearance.avatars.circle') }, { value: 'rounded', label: t('wb.appearance.avatars.rounded') }, { value: 'square', label: t('wb.appearance.corners.square') }] }) }), _jsx(Field, { label: t('wb.appearance.density'), children: _jsx(Segmented, { label: t('wb.appearance.density'), size: "sm", value: draft.layout.density, onChange: density => setLayout({ density }), options: [{ value: 'compact', label: t('wb.appearance.density.compact') }, { value: 'default', label: t('wb.appearance.density.default') }, { value: 'comfortable', label: t('wb.appearance.density.roomy') }] }) }), _jsx(Field, { label: t('wb.appearance.timeline'), children: _jsx(Segmented, { label: t('wb.appearance.timelineStyle'), size: "sm", value: draft.layout.cards ? 'cards' : draft.layout.frame ? 'framed' : 'flat', onChange: v => setLayout({ cards: v === 'cards', frame: v === 'framed' }), options: [{ value: 'flat', label: t('wb.appearance.timeline.flat') }, { value: 'framed', label: t('wb.appearance.timeline.framed') }, { value: 'cards', label: t('wb.appearance.timeline.cards') }] }) }), _jsx(Field, { label: t('wb.appearance.timelineWidth'), children: _jsx(Slider, { label: t('wb.appearance.timelineWidth'), min: 520, max: 820, step: 10, value: draft.layout.column, format: px, onChange: column => setLayout({ column }, false), onCommit: column => setLayout({ column }) }) }), _jsx(Field, { label: t('wb.appearance.sidebarWidth'), children: _jsx(Slider, { label: t('wb.appearance.sidebarWidth'), min: 290, max: 400, step: 10, value: draft.layout.sidebar, format: px, onChange: sidebar => setLayout({ sidebar }, false), onCommit: sidebar => setLayout({ sidebar }) }) })] }) }), _jsxs(Card, { title: t('wb.builder.backgroundEffects'), children: [_jsx(BackgroundEditor, { background: draft.background, colors: colors, notify: notify, onChange: (background, commit) => set('background', background, commit) }), _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.appearance.motion'), children: _jsx(Slider, { label: t('wb.appearance.motion'), min: 0, max: 400, step: 10, value: draft.effects.motion, format: v => v ? t('wb.builder.ms', { value: v }) : t('wb.common.off'), onChange: motion => setEffects({ motion }, false), onCommit: motion => setEffects({ motion }) }) }), _jsx(Field, { label: t('wb.appearance.hover'), children: _jsx(Segmented, { label: t('wb.appearance.hoverEffect'), size: "sm", value: draft.effects.hover, onChange: hover => setEffects({ hover }), options: [{ value: 'none', label: t('wb.appearance.hover.none') }, { value: 'tint', label: t('wb.appearance.hover.tint') }, { value: 'lift', label: t('wb.appearance.hover.lift') }, { value: 'glow', label: t('wb.appearance.bg.glow') }] }) }), _jsx(Field, { label: t('wb.builder.shadow'), children: _jsx(Segmented, { label: t('wb.builder.shadow'), size: "sm", value: draft.effects.shadow, onChange: shadow => setEffects({ shadow }), options: [{ value: 'none', label: t('wb.appearance.hover.none') }, { value: 'soft', label: t('wb.appearance.corners.soft') }, { value: 'deep', label: t('wb.builder.deep') }] }) }), _jsx(Field, { label: t('wb.appearance.crt'), children: _jsx(Toggle, { label: t('wb.appearance.crt'), checked: draft.effects.crt, onChange: crt => setEffects({ crt }) }) })] })] }), _jsx(Card, { title: t('wb.appearance.themeCss'), hint: t('wb.builder.cssHint'), children: _jsxs("div", { className: "bt-code is-compact", children: [_jsx("textarea", { "aria-label": t('wb.appearance.themeCss'), spellCheck: false, value: draft.css, maxLength: MAX_CSS_CHARS, placeholder: panelSite().cssExamples?.builder ?? '/* CSS that travels with this theme */', onChange: event => set('css', event.target.value, false), onBlur: event => set('css', event.target.value) }), _jsx("div", { className: "bt-code-bar", children: _jsx("small", { children: t('wb.builder.cssLines', { count: draft.css.split('\n').length }) }) })] }) })] }), _jsxs("aside", { className: "wb-builder-preview", "aria-label": t('wb.builder.preview'), children: [_jsxs("div", { className: "wb-preview-frame", children: [_jsx(ChromePreview, { theme: draft }), _jsx(ThemePreview, { theme: draft })] }), _jsx("p", { className: "wb-preview-note", children: live ? _jsxs(_Fragment, { children: [_jsx("i", { className: "wb-live-dot" }), t('wb.builder.liveNote')] }) : t('wb.builder.liveOff') }), _jsxs("div", { className: "wb-meta", children: [_jsxs("label", { children: [_jsx("span", { children: t('wb.builder.author') }), _jsx("input", { value: draft.author, maxLength: 60, onChange: event => set('author', event.target.value, false), onBlur: event => set('author', event.target.value.trim()) })] }), _jsxs("label", { children: [_jsx("span", { children: t('wb.builder.description') }), _jsx("textarea", { rows: 2, value: draft.description, maxLength: 200, onChange: event => set('description', event.target.value, false), onBlur: event => set('description', event.target.value.trim()) })] })] })] })] })] });
144
+ }
145
+ function Card({ title, hint, action, children }) {
146
+ return _jsxs("section", { className: "wb-card", "aria-label": title, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h3", { children: title }), hint && _jsx("p", { children: hint })] }), action] }), children] });
147
+ }
148
+ const Field = ({ label, children }) => _jsxs("div", { className: "wb-field", children: [_jsx("span", { children: label }), children] });
149
+ function IconButton({ label, d, onClick, disabled }) {
150
+ return _jsx("button", { type: "button", className: "wb-icon-button", "aria-label": label, title: label, disabled: disabled, onClick: onClick, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: d, fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) });
151
+ }
152
+ /** Every derived role as a swatch; a click opens its color field, "Auto" un-pins it. */
153
+ function Palette({ colors, onChange }) {
154
+ const t = useT();
155
+ const [editing, setEditing] = useState(null);
156
+ const pinned = pinnedRoles(colors);
157
+ const base = { bg: colors.bg, text: colors.text, accent: colors.accent };
158
+ return _jsxs("div", { className: "wb-palette", children: [_jsx("div", { className: "wb-palette-row", role: "list", "aria-label": t('wb.builder.paletteRoles'), children: DERIVED_ROLES.map(role => _jsxs("button", { type: "button", role: "listitem", className: `wb-chip ${editing === role ? 'is-on' : ''}`, "aria-expanded": editing === role, onClick: () => setEditing(editing === role ? null : role), children: [_jsx("span", { className: "wb-chip-swatch", style: { background: colors[role] } }), _jsxs("span", { className: "wb-chip-copy", children: [_jsx("b", { children: t(ROLE_LABEL[role]) }), _jsxs("small", { children: [pinned[role] ? t('wb.builder.setByHand') : t('wb.builder.derived'), " \u00B7 ", colors[role]] })] })] }, role)) }), editing && _jsxs("div", { className: "wb-palette-edit", children: [_jsx("span", { children: t(ROLE_LABEL[editing]) }), _jsx(ColorField, { label: t(ROLE_LABEL[editing]), value: pinned[editing] ? colors[editing] : null, autoLabel: t('wb.builder.auto'), swatches: [], onChange: value => {
159
+ const next = { ...pinned };
160
+ if (value && isHex(value))
161
+ next[editing] = value;
162
+ else
163
+ delete next[editing];
164
+ onChange(paletteFrom(base, next));
165
+ } })] })] });
166
+ }
167
+ function BackgroundEditor({ background, colors, notify, onChange }) {
168
+ const t = useT();
169
+ const file = useRef(null);
170
+ const kind = background.kind;
171
+ const page = colors.page ?? colors.bg;
172
+ const switchTo = (next) => {
173
+ if (next === 'none')
174
+ onChange({ kind: 'none' });
175
+ else if (next === 'gradient')
176
+ onChange({ kind: 'gradient', from: page, to: page, angle: 180, glow: colors.accent });
177
+ else if (next === 'pattern')
178
+ onChange({ kind: 'pattern', pattern: 'dots', ink: colors.text, opacity: 0.12, size: 22 });
179
+ else
180
+ file.current?.click();
181
+ };
182
+ async function pick(input) {
183
+ if (!input)
184
+ return;
185
+ if (!/^image\/(png|jpeg|webp|gif|avif)$/.test(input.type)) {
186
+ notify(t('wb.appearance.imageType'), true);
187
+ return;
188
+ }
189
+ const url = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(String(reader.result)); reader.onerror = () => reject(reader.error); reader.readAsDataURL(input); });
190
+ if (url.length > MAX_IMAGE_CHARS) {
191
+ notify(t('wb.appearance.imageTooLarge'), true);
192
+ return;
193
+ }
194
+ onChange({ kind: 'image', url, fit: 'cover', dim: modeOf(colors) === 'light' ? 0.55 : 0.6 });
195
+ }
196
+ return _jsxs("div", { className: "wb-bg", children: [_jsx(Segmented, { label: t('wb.appearance.background'), size: "sm", value: kind, onChange: switchTo, options: [{ value: 'none', label: t('wb.appearance.bg.none') }, { value: 'gradient', label: t('wb.builder.gradient') }, { value: 'pattern', label: t('wb.builder.pattern') }, { value: 'image', label: t('wb.appearance.bg.image') }] }), _jsx("input", { ref: file, type: "file", hidden: true, accept: "image/png,image/jpeg,image/webp,image/gif,image/avif", onChange: event => { void pick(event.target.files?.[0]); event.target.value = ''; } }), background.kind === 'gradient' && _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.builder.from'), children: _jsx(ColorField, { label: t('wb.builder.gradientStart'), value: background.from, swatches: [page, colors.bg, colors.surface], onChange: v => v && onChange({ ...background, from: v }) }) }), _jsx(Field, { label: t('wb.builder.to'), children: _jsx(ColorField, { label: t('wb.builder.gradientEnd'), value: background.to, swatches: [page, colors.bg, colors.elevated], onChange: v => v && onChange({ ...background, to: v }) }) }), _jsx(Field, { label: t('wb.appearance.bg.glow'), children: _jsx(ColorField, { label: t('wb.appearance.bg.glow'), value: background.glow ?? null, autoLabel: t('wb.appearance.hover.none'), swatches: [colors.accent], onChange: v => onChange({ ...background, glow: v ?? undefined }) }) }), _jsx(Field, { label: t('wb.builder.angle'), children: _jsx(Slider, { label: t('wb.builder.gradientAngle'), min: 0, max: 360, step: 5, value: background.angle, format: v => `${formatNumber(v)}°`, onChange: angle => onChange({ ...background, angle }, false), onCommit: angle => onChange({ ...background, angle }) }) })] }), background.kind === 'pattern' && _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.builder.pattern'), children: _jsx(Select, { label: t('wb.builder.pattern'), value: background.pattern, width: 160, onChange: pattern => onChange({ ...background, pattern }), options: PATTERNS.map(value => ({ value, label: tx(`wb.appearance.bg.${value}`, undefined, value) })) }) }), _jsx(Field, { label: t('wb.builder.ink'), children: _jsx(ColorField, { label: t('wb.builder.patternInk'), value: background.ink, swatches: [colors.text, colors.accent, '#ffffff'], onChange: v => v && onChange({ ...background, ink: v }) }) }), _jsx(Field, { label: t('wb.builder.strength'), children: _jsx(Slider, { label: t('wb.builder.patternStrength'), min: 0, max: 60, value: Math.round(background.opacity * 100), format: pct, onChange: v => onChange({ ...background, opacity: v / 100 }, false), onCommit: v => onChange({ ...background, opacity: v / 100 }) }) }), _jsx(Field, { label: t('wb.builder.scale'), children: _jsx(Slider, { label: t('wb.builder.patternScale'), min: 2, max: 400, value: background.size, format: px, onChange: size => onChange({ ...background, size }, false), onCommit: size => onChange({ ...background, size }) }) })] }), background.kind === 'image' && _jsxs("div", { className: "wb-fields", children: [_jsx(Field, { label: t('wb.builder.dimming'), children: _jsx(Slider, { label: t('wb.appearance.dim'), min: 35, max: 95, value: Math.round(background.dim * 100), format: pct, onChange: v => onChange({ ...background, dim: v / 100 }, false), onCommit: v => onChange({ ...background, dim: v / 100 }) }) }), _jsx(Field, { label: t('wb.builder.fit'), children: _jsx(Segmented, { label: t('wb.builder.photoFit'), size: "sm", value: background.fit, onChange: fit => onChange({ ...background, fit }), options: [{ value: 'cover', label: t('wb.builder.cover') }, { value: 'tile', label: t('wb.builder.tile') }] }) }), _jsx(Field, { label: t('wb.builder.photo'), children: _jsx(Button, { size: "sm", onClick: () => file.current?.click(), children: t('wb.builder.replace') }) })] })] });
197
+ }
198
+ /** The app's window in the draft: a tab strip and an address bar drawn with the chrome tokens. */
199
+ function ChromePreview({ theme }) {
200
+ const themes = panelThemes();
201
+ const vars = useMemo(() => chromeVars(themes.store.adapter.chrome(theme)), [theme]);
202
+ const sample = themes.chromePreview ?? { tabs: ['Home', '@waybetter', panelSite().brand.name], chip: panelSite().brand.name, page: 'Home' };
203
+ return _jsxs("div", { className: "wb-chrome-preview", style: vars, "aria-hidden": "true", children: [_jsxs("div", { className: "wb-cp-tabs", children: [_jsxs("span", { className: "wb-cp-tab is-on", children: [_jsx("i", {}), sample.tabs[0]] }), _jsxs("span", { className: "wb-cp-tab", children: [_jsx("i", {}), sample.tabs[1]] }), _jsxs("span", { className: "wb-cp-tab", children: [_jsx("i", {}), sample.tabs[2]] })] }), _jsxs("div", { className: "wb-cp-bar", children: [_jsx("span", { className: "wb-cp-dot" }), _jsxs("span", { className: "wb-cp-omni", children: [_jsx("b", { children: sample.chip }), _jsx("em", { children: "/" }), sample.page] }), _jsx("span", { className: "wb-cp-brand" })] })] });
204
+ }
205
+ //# sourceMappingURL=ThemeBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeBuilder.js","sourceRoot":"","sources":["../../../../../../shell/src/panel/ThemeBuilder.tsx"],"names":[],"mappings":"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","sourcesContent":["// The Theme Builder: a full editor for a theme document with a live preview on the real site panes (a\n// native, unsaved preview; closing the builder gives every tab its own theme back), the local\n// miniature and the chrome. Three base colors derive the whole palette; a contrast report shows every\n// pair the site draws and can fix them; fonts per role with the Google Fonts browser; shape, layout,\n// background, effects and theme CSS. Undo/redo (Ctrl+Z / Ctrl+Shift+Z), Save as theme, Export, Share.\nimport { useCallback, useEffect, useMemo, useRef, useState, type CSSProperties, type ReactNode } from 'react';\nimport {\n MAX_CSS_CHARS, MAX_IMAGE_CHARS, isHex, sanitizeSpec,\n type Background, type EffectsSpec, type FontRole, type FontRoleName, type FontSpec, type LayoutSpec, type Pattern, type ShapeSpec, type ThemeColors, type ThemeSpec,\n} from '../../../runtime/src/themeSpec.ts';\nimport { chromeVars } from '../frame/chromeTheme.ts';\nimport { useT } from '../frame/hooks.ts';\nimport { formatNumber, t, tx } from '../frame/i18n.ts';\nimport { ThemeDots } from '../frame/PaneTheme.tsx';\nimport {\n DERIVED_ROLES, autoFix, contrastReport, draftFrom, modeOf, paletteFrom, pinnedRoles, record, redo, startHistory, themeJson, undo, uniqueId, wcagLevel,\n type DerivedRole, type DraftSite, type History,\n} from './builderModel.ts';\nimport { Button, ColorField, Segmented, Select, Slider, Toggle, type Option } from './controls.tsx';\nimport { FontRoles } from './fonts/FontRoles.tsx';\nimport { panelSite, panelThemes, type Notify } from './site.ts';\nimport { useThemeState } from './themes.ts';\nimport './builder.css';\n\n/** Swatches for the three base colors when the app names none. */\nconst BASE_SWATCHES = {\n bg: ['#000000', '#0b0d12', '#15202b', '#1a1b26', '#2e3440', '#ffffff', '#fbf8f1', '#fdf6e3'],\n text: ['#e7e9ea', '#eef0f7', '#ffffff', '#c0caf5', '#0f1419', '#2a241d', '#073642', '#000000'],\n accent: ['#1d9bf0', '#5b8cff', '#7856ff', '#bd93f9', '#f91880', '#ff7a00', '#00ba7c', '#3dff7a'],\n};\nconst ROLE_LABEL: Record<DerivedRole, string> = { surface: 'wb.builder.role.surface', elevated: 'wb.builder.role.elevated', border: 'wb.builder.role.border', muted: 'wb.builder.role.muted', inverse: 'wb.builder.role.inverse', onInverse: 'wb.builder.role.onInverse', page: 'wb.builder.role.page' };\nconst px = (v: number) => t('wb.appearance.px', { value: v });\nconst pct = (v: number) => t('wb.appearance.percent', { value: v / 100 });\nconst PATTERNS: Pattern[] = ['dots', 'grid', 'diagonal', 'scanlines', 'paper', 'clouds'];\ntype BackgroundKind = 'none' | 'gradient' | 'pattern' | 'image';\n\nexport function ThemeBuilder({ notify }: { notify: Notify }) {\n const t = useT();\n const themes = panelThemes();\n const { allThemes, missingFonts, setChoice, setPreview, themeState } = themes.store;\n const resolveTheme = themes.catalog.resolve;\n const ThemePreview = themes.Preview;\n const draftSite: DraftSite = { colors: themes.draftColors, siteTheme: themes.catalog.defaultChoice.preset };\n const swatches = themes.baseSwatches ?? BASE_SWATCHES;\n const { ready, choice } = useThemeState();\n const [history, setHistory] = useState<History | null>(null);\n const [live, setLive] = useState(true);\n const dragFrom = useRef<ThemeSpec | null>(null);\n\n // Start from the theme that is on now.\n useEffect(() => { if (ready && !history) setHistory(startHistory(draftFrom(resolveTheme(choice), draftSite))); }, [ready]);\n const draft = history?.present ?? null;\n\n // Live on the real site panes and the chrome (debounced), until the builder closes.\n useEffect(() => {\n if (!draft) return;\n const timer = setTimeout(() => void setPreview(live ? draft : null), 120);\n return () => clearTimeout(timer);\n }, [draft, live]);\n useEffect(() => () => { void setPreview(null); }, []);\n\n /** Applies a change; `commit: false` while a slider drags (one undo step per drag). */\n const change = useCallback((next: ThemeSpec, commit = true) => {\n setHistory(current => {\n if (!current) return current;\n if (!commit) { dragFrom.current ??= current.present; return record(current, next, { commit: false }); }\n const from = dragFrom.current ?? undefined;\n dragFrom.current = null;\n return record(current, next, { from });\n });\n }, []);\n\n // Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y anywhere while the builder is open, except inside text fields.\n useEffect(() => {\n const onKey = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (target && (target.isContentEditable || (/^(input|textarea)$/i.test(target.tagName) && !/^(range|color|checkbox)$/.test((target as HTMLInputElement).type)))) return;\n if (!(event.ctrlKey || event.metaKey) || event.altKey) return;\n const key = event.key.toLowerCase();\n if (key === 'z' && !event.shiftKey) { event.preventDefault(); setHistory(h => h && undo(h)); }\n else if ((key === 'z' && event.shiftKey) || key === 'y') { event.preventDefault(); setHistory(h => h && redo(h)); }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n if (!draft || !history) return <div className=\"wb-builder is-loading\" aria-busy=\"true\"/>;\n const colors = draft.colors!;\n const set = <K extends keyof ThemeSpec>(key: K, value: ThemeSpec[K], commit = true) => change({ ...draft, [key]: value }, commit);\n const setColors = (next: ThemeColors, commit = true) => change({ ...draft, colors: next, mode: modeOf(next) }, commit);\n const setBase = (role: 'bg' | 'text' | 'accent', value: string) => {\n const base = { bg: colors.bg, text: colors.text, accent: colors.accent, [role]: value };\n // A new base re-derives every other role (hand-set roles belong to the old base).\n setColors(paletteFrom(base));\n };\n const setFont = (patch: Partial<FontSpec>, commit = true) => set('font', sanitizeSpec({ name: 'x', font: { ...draft.font, ...patch } }).font, commit);\n const setRole = (role: FontRoleName, next: FontRole, commit = true) => setFont({ roles: { ...draft.font.roles, [role]: next } }, commit);\n const setShape = (patch: Partial<ShapeSpec>, commit = true) => set('shape', { ...draft.shape, ...patch }, commit);\n const setLayout = (patch: Partial<LayoutSpec>, commit = true) => set('layout', { ...draft.layout, ...patch }, commit);\n const setEffects = (patch: Partial<EffectsSpec>, commit = true) => set('effects', { ...draft.effects, ...patch }, commit);\n\n const startFrom = (id: string) => {\n const theme = allThemes(choice).find(item => item.id === id);\n if (!theme) return;\n change(draftFrom(id === choice.preset ? resolveTheme(choice) : theme, draftSite));\n notify(t('wb.builder.startedFrom', { name: theme.name }));\n };\n\n async function save() {\n const state = themeState();\n const missing = missingFonts(draft!);\n const id = uniqueId(draft!.name, [...themes.catalog.builtins, ...state.choice.themes].map(theme => theme.id));\n const theme = sanitizeSpec({ ...draft!, id });\n try {\n await setChoice({ ...state.choice, themes: [...state.choice.themes, theme], preset: id, overrides: {}, accent: null });\n notify(`${t('wb.builder.saved', { name: theme.name })}${missing.length ? ` ${t('wb.builder.savedMissing', { fonts: missing.join(', '), count: missing.length })}` : ''}`);\n } catch (error) { notify(error instanceof Error ? error.message : String(error), true); }\n }\n function exportFile() {\n const url = URL.createObjectURL(new Blob([themeJson(draft!)], { type: 'application/json' }));\n const anchor = document.createElement('a');\n anchor.href = url; anchor.download = `${draft!.id}${themes.fileSuffix ?? '.theme.json'}`; anchor.click();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n async function share() {\n try { await navigator.clipboard.writeText(themeJson(draft!)); notify(t('wb.builder.shared')); }\n catch { notify(t('wb.builder.copyFailed'), true); }\n }\n\n const report = contrastReport(colors);\n const failing = report.filter(check => !check.pass).length;\n const options: Array<Option<string>> = allThemes(choice).map(theme => ({ value: theme.id, label: theme.name, icon: <ThemeDots theme={theme}/> }));\n\n return <div className=\"wb-builder\">\n <div className=\"wb-builder-bar\" role=\"toolbar\" aria-label={t('wb.panel.section.builder')}>\n <input className=\"wb-builder-name\" aria-label={t('wb.builder.name')} value={draft.name} maxLength={60} spellCheck={false}\n onChange={event => set('name', event.target.value, false)} onBlur={event => set('name', event.target.value.trim() || t('wb.builder.untitled'))}/>\n <div className=\"wb-builder-tools\">\n <Select label={t('wb.builder.startFrom')} value={null} placeholder={t('wb.builder.startFromPlaceholder')} options={options} width={176} onChange={startFrom}/>\n <span className=\"wb-divider\" aria-hidden=\"true\"/>\n <IconButton label={t('wb.builder.undo')} disabled={!history.past.length} onClick={() => setHistory(h => h && undo(h))} d=\"M6 4 3 7l3 3M3 7h7a4 4 0 0 1 0 8H8\"/>\n <IconButton label={t('wb.builder.redo')} disabled={!history.future.length} onClick={() => setHistory(h => h && redo(h))} d=\"m10 4 3 3-3 3M13 7H6a4 4 0 0 0 0 8h2\"/>\n <span className=\"wb-divider\" aria-hidden=\"true\"/>\n <label className=\"wb-live\"><Toggle label={t('wb.builder.previewLive')} checked={live} onChange={setLive}/><span>{t('wb.builder.liveOnSite')}</span></label>\n <Button size=\"sm\" tone=\"ghost\" onClick={() => void share()}>{t('wb.builder.share')}</Button>\n <Button size=\"sm\" tone=\"ghost\" onClick={exportFile}>{t('wb.common.export')}</Button>\n <Button size=\"sm\" tone=\"primary\" onClick={() => void save()}>{t('wb.appearance.saveAsTheme')}</Button>\n </div>\n </div>\n\n <div className=\"wb-builder-grid\">\n <div className=\"wb-builder-controls\">\n <Card title={t('wb.builder.colors')} hint={t('wb.builder.colorsHint')}>\n <div className=\"wb-base\">\n {(['bg', 'text', 'accent'] as const).map(role => <div key={role} className=\"wb-base-item\">\n <div className=\"wb-base-swatch\" style={{ background: colors[role] }}><span style={{ color: role === 'bg' ? colors.text : colors.bg }}>{role === 'bg' ? t('wb.appearance.background') : role === 'text' ? t('wb.builder.text') : t('wb.appearance.accent')}</span><code>{colors[role]}</code></div>\n <ColorField label={role === 'bg' ? t('wb.builder.backgroundColor') : role === 'text' ? t('wb.builder.textColor') : t('wb.appearance.accentColor')} value={colors[role]} swatches={swatches[role]} onChange={value => value && setBase(role, value)}/>\n </div>)}\n </div>\n <Palette colors={colors} onChange={setColors}/>\n </Card>\n\n <Card title={t('wb.builder.contrast')} hint={t('wb.builder.contrastHint')}\n action={failing ? <Button size=\"sm\" tone=\"primary\" onClick={() => { setColors(autoFix(colors)); notify(t('wb.builder.adjusted', { count: failing })); }}>{t('wb.builder.autoFix', { count: failing })}</Button> : <span className=\"wb-ok\">{t('wb.builder.allPass')}</span>}>\n <ul className=\"wb-contrast\">\n {report.map(check => <li key={check.id} className={check.pass ? 'is-pass' : 'is-fail'}>\n <span className=\"wb-contrast-sample\" style={{ color: check.fg, background: check.bg }}>Aa</span>\n <span className=\"wb-contrast-label\">{tx(`wb.builder.contrast.${check.id}`, undefined, check.label)}</span>\n <span className=\"wb-contrast-ratio\"><b>{formatNumber(check.ratio, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</b>:1</span>\n <span className=\"wb-contrast-need\">{t('wb.builder.needs', { ratio: check.need })}</span>\n <span className={`wb-contrast-badge ${check.pass ? 'is-pass' : 'is-fail'}`}>{check.pass ? wcagLevel(check.ratio) : t('wb.builder.tooLow')}</span>\n </li>)}\n </ul>\n </Card>\n\n <Card title={t('wb.builder.type')} hint={t('wb.builder.typeHint')}>\n <FontRoles font={draft.font} onRole={setRole}/>\n <div className=\"wb-fields\">\n <Field label={t('wb.appearance.textSize')}><Slider label={t('wb.appearance.textSize')} min={85} max={120} value={Math.round(draft.font.scale * 100)} format={pct} onChange={v => setFont({ scale: v / 100 }, false)} onCommit={v => setFont({ scale: v / 100 })}/></Field>\n <Field label={t('wb.builder.regularWeight')}><Slider label={t('wb.builder.regularWeight')} min={300} max={500} step={10} value={draft.font.weight} format={String} onChange={v => setFont({ weight: v }, false)} onCommit={v => setFont({ weight: v })}/></Field>\n <Field label={t('wb.appearance.bold')}><Slider label={t('wb.appearance.bold')} min={500} max={800} step={10} value={draft.font.bold} format={String} onChange={v => setFont({ bold: v }, false)} onCommit={v => setFont({ bold: v })}/></Field>\n <Field label={t('wb.builder.tracking')}><Slider label={t('wb.builder.tracking')} min={-30} max={60} step={2} value={Math.round(draft.font.tracking * 1000)} format={v => `${formatNumber(v / 1000, { minimumFractionDigits: 3, maximumFractionDigits: 3 })} em`} onChange={v => setFont({ tracking: v / 1000 }, false)} onCommit={v => setFont({ tracking: v / 1000 })}/></Field>\n <Field label={t('wb.builder.leading')}><Slider label={t('wb.builder.leading')} min={115} max={180} step={5} value={draft.font.leading ? Math.round(draft.font.leading * 100) : 115} format={v => v === 115 ? t('wb.builder.leadingSite') : formatNumber(v / 100, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} onChange={v => setFont({ leading: v === 115 ? 0 : v / 100 }, false)} onCommit={v => setFont({ leading: v === 115 ? 0 : v / 100 })}/></Field>\n </div>\n </Card>\n\n <Card title={t('wb.builder.shape')}>\n <div className=\"wb-fields\">\n <Field label={t('wb.builder.cardCorners')}><Slider label={t('wb.builder.cardCorners')} min={0} max={28} value={draft.shape.radius} format={px} onChange={v => setShape({ radius: v }, false)} onCommit={v => setShape({ radius: v })}/></Field>\n <Field label={t('wb.builder.buttons')}><Segmented label={t('wb.builder.buttonShape')} size=\"sm\" value={draft.shape.button >= 100 ? 'pill' : draft.shape.button === 0 ? 'square' : 'soft'}\n onChange={v => setShape({ button: v === 'pill' ? 9999 : v === 'square' ? 0 : Math.max(4, Math.min(12, draft.shape.radius)) })}\n options={[{ value: 'square', label: t('wb.appearance.corners.square') }, { value: 'soft', label: t('wb.appearance.corners.soft') }, { value: 'pill', label: t('wb.builder.pill') }]}/></Field>\n <Field label={t('wb.appearance.avatars')}><Segmented label={t('wb.appearance.avatars')} size=\"sm\" value={draft.shape.avatar} onChange={avatar => setShape({ avatar })}\n options={[{ value: 'circle', label: t('wb.appearance.avatars.circle') }, { value: 'rounded', label: t('wb.appearance.avatars.rounded') }, { value: 'square', label: t('wb.appearance.corners.square') }]}/></Field>\n <Field label={t('wb.appearance.density')}><Segmented label={t('wb.appearance.density')} size=\"sm\" value={draft.layout.density} onChange={density => setLayout({ density })}\n options={[{ value: 'compact', label: t('wb.appearance.density.compact') }, { value: 'default', label: t('wb.appearance.density.default') }, { value: 'comfortable', label: t('wb.appearance.density.roomy') }]}/></Field>\n <Field label={t('wb.appearance.timeline')}><Segmented label={t('wb.appearance.timelineStyle')} size=\"sm\" value={draft.layout.cards ? 'cards' : draft.layout.frame ? 'framed' : 'flat'}\n onChange={v => setLayout({ cards: v === 'cards', frame: v === 'framed' })} options={[{ value: 'flat', label: t('wb.appearance.timeline.flat') }, { value: 'framed', label: t('wb.appearance.timeline.framed') }, { value: 'cards', label: t('wb.appearance.timeline.cards') }]}/></Field>\n <Field label={t('wb.appearance.timelineWidth')}><Slider label={t('wb.appearance.timelineWidth')} min={520} max={820} step={10} value={draft.layout.column} format={px} onChange={column => setLayout({ column }, false)} onCommit={column => setLayout({ column })}/></Field>\n <Field label={t('wb.appearance.sidebarWidth')}><Slider label={t('wb.appearance.sidebarWidth')} min={290} max={400} step={10} value={draft.layout.sidebar} format={px} onChange={sidebar => setLayout({ sidebar }, false)} onCommit={sidebar => setLayout({ sidebar })}/></Field>\n </div>\n </Card>\n\n <Card title={t('wb.builder.backgroundEffects')}>\n <BackgroundEditor background={draft.background} colors={colors} notify={notify} onChange={(background, commit) => set('background', background, commit)}/>\n <div className=\"wb-fields\">\n <Field label={t('wb.appearance.motion')}><Slider label={t('wb.appearance.motion')} min={0} max={400} step={10} value={draft.effects.motion} format={v => v ? t('wb.builder.ms', { value: v }) : t('wb.common.off')} onChange={motion => setEffects({ motion }, false)} onCommit={motion => setEffects({ motion })}/></Field>\n <Field label={t('wb.appearance.hover')}><Segmented label={t('wb.appearance.hoverEffect')} size=\"sm\" value={draft.effects.hover} onChange={hover => setEffects({ hover })}\n options={[{ value: 'none', label: t('wb.appearance.hover.none') }, { value: 'tint', label: t('wb.appearance.hover.tint') }, { value: 'lift', label: t('wb.appearance.hover.lift') }, { value: 'glow', label: t('wb.appearance.bg.glow') }]}/></Field>\n <Field label={t('wb.builder.shadow')}><Segmented label={t('wb.builder.shadow')} size=\"sm\" value={draft.effects.shadow} onChange={shadow => setEffects({ shadow })}\n options={[{ value: 'none', label: t('wb.appearance.hover.none') }, { value: 'soft', label: t('wb.appearance.corners.soft') }, { value: 'deep', label: t('wb.builder.deep') }]}/></Field>\n <Field label={t('wb.appearance.crt')}><Toggle label={t('wb.appearance.crt')} checked={draft.effects.crt} onChange={crt => setEffects({ crt })}/></Field>\n </div>\n </Card>\n\n <Card title={t('wb.appearance.themeCss')} hint={t('wb.builder.cssHint')}>\n <div className=\"bt-code is-compact\">\n <textarea aria-label={t('wb.appearance.themeCss')} spellCheck={false} value={draft.css} maxLength={MAX_CSS_CHARS} placeholder={panelSite().cssExamples?.builder ?? '/* CSS that travels with this theme */'}\n onChange={event => set('css', event.target.value, false)} onBlur={event => set('css', event.target.value)}/>\n <div className=\"bt-code-bar\"><small>{t('wb.builder.cssLines', { count: draft.css.split('\\n').length })}</small></div>\n </div>\n </Card>\n </div>\n\n <aside className=\"wb-builder-preview\" aria-label={t('wb.builder.preview')}>\n <div className=\"wb-preview-frame\">\n <ChromePreview theme={draft}/>\n <ThemePreview theme={draft}/>\n </div>\n <p className=\"wb-preview-note\">{live ? <><i className=\"wb-live-dot\"/>{t('wb.builder.liveNote')}</> : t('wb.builder.liveOff')}</p>\n <div className=\"wb-meta\">\n <label><span>{t('wb.builder.author')}</span><input value={draft.author} maxLength={60} onChange={event => set('author', event.target.value, false)} onBlur={event => set('author', event.target.value.trim())}/></label>\n <label><span>{t('wb.builder.description')}</span><textarea rows={2} value={draft.description} maxLength={200} onChange={event => set('description', event.target.value, false)} onBlur={event => set('description', event.target.value.trim())}/></label>\n </div>\n </aside>\n </div>\n </div>;\n}\n\nfunction Card({ title, hint, action, children }: { title: string; hint?: string; action?: ReactNode; children: ReactNode }) {\n return <section className=\"wb-card\" aria-label={title}>\n <header><div><h3>{title}</h3>{hint && <p>{hint}</p>}</div>{action}</header>\n {children}\n </section>;\n}\nconst Field = ({ label, children }: { label: string; children: ReactNode }) => <div className=\"wb-field\"><span>{label}</span>{children}</div>;\n\nfunction IconButton({ label, d, onClick, disabled }: { label: string; d: string; onClick(): void; disabled?: boolean }) {\n return <button type=\"button\" className=\"wb-icon-button\" aria-label={label} title={label} disabled={disabled} onClick={onClick}>\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d={d} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>\n </button>;\n}\n\n/** Every derived role as a swatch; a click opens its color field, \"Auto\" un-pins it. */\nfunction Palette({ colors, onChange }: { colors: ThemeColors; onChange(next: ThemeColors): void }) {\n const t = useT();\n const [editing, setEditing] = useState<DerivedRole | null>(null);\n const pinned = pinnedRoles(colors);\n const base = { bg: colors.bg, text: colors.text, accent: colors.accent };\n return <div className=\"wb-palette\">\n <div className=\"wb-palette-row\" role=\"list\" aria-label={t('wb.builder.paletteRoles')}>\n {DERIVED_ROLES.map(role => <button key={role} type=\"button\" role=\"listitem\" className={`wb-chip ${editing === role ? 'is-on' : ''}`} aria-expanded={editing === role} onClick={() => setEditing(editing === role ? null : role)}>\n <span className=\"wb-chip-swatch\" style={{ background: colors[role] }}/>\n <span className=\"wb-chip-copy\"><b>{t(ROLE_LABEL[role])}</b><small>{pinned[role] ? t('wb.builder.setByHand') : t('wb.builder.derived')} · {colors[role]}</small></span>\n </button>)}\n </div>\n {editing && <div className=\"wb-palette-edit\">\n <span>{t(ROLE_LABEL[editing])}</span>\n <ColorField label={t(ROLE_LABEL[editing])} value={pinned[editing] ? colors[editing]! : null} autoLabel={t('wb.builder.auto')} swatches={[]}\n onChange={value => {\n const next = { ...pinned } as Partial<Record<DerivedRole, string>>;\n if (value && isHex(value)) next[editing] = value; else delete next[editing];\n onChange(paletteFrom(base, next));\n }}/>\n </div>}\n </div>;\n}\n\nfunction BackgroundEditor({ background, colors, notify, onChange }: { background: Background; colors: ThemeColors; notify: Notify; onChange(next: Background, commit?: boolean): void }) {\n const t = useT();\n const file = useRef<HTMLInputElement>(null);\n const kind: BackgroundKind = background.kind;\n const page = colors.page ?? colors.bg;\n const switchTo = (next: BackgroundKind) => {\n if (next === 'none') onChange({ kind: 'none' });\n else if (next === 'gradient') onChange({ kind: 'gradient', from: page, to: page, angle: 180, glow: colors.accent });\n else if (next === 'pattern') onChange({ kind: 'pattern', pattern: 'dots', ink: colors.text, opacity: 0.12, size: 22 });\n else file.current?.click();\n };\n async function pick(input: File | undefined) {\n if (!input) return;\n if (!/^image\\/(png|jpeg|webp|gif|avif)$/.test(input.type)) { notify(t('wb.appearance.imageType'), true); return; }\n const url = await new Promise<string>((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(String(reader.result)); reader.onerror = () => reject(reader.error); reader.readAsDataURL(input); });\n if (url.length > MAX_IMAGE_CHARS) { notify(t('wb.appearance.imageTooLarge'), true); return; }\n onChange({ kind: 'image', url, fit: 'cover', dim: modeOf(colors) === 'light' ? 0.55 : 0.6 });\n }\n return <div className=\"wb-bg\">\n <Segmented<BackgroundKind> label={t('wb.appearance.background')} size=\"sm\" value={kind} onChange={switchTo}\n options={[{ value: 'none', label: t('wb.appearance.bg.none') }, { value: 'gradient', label: t('wb.builder.gradient') }, { value: 'pattern', label: t('wb.builder.pattern') }, { value: 'image', label: t('wb.appearance.bg.image') }]}/>\n <input ref={file} type=\"file\" hidden accept=\"image/png,image/jpeg,image/webp,image/gif,image/avif\" onChange={event => { void pick(event.target.files?.[0]); event.target.value = ''; }}/>\n {background.kind === 'gradient' && <div className=\"wb-fields\">\n <Field label={t('wb.builder.from')}><ColorField label={t('wb.builder.gradientStart')} value={background.from} swatches={[page, colors.bg, colors.surface]} onChange={v => v && onChange({ ...background, from: v })}/></Field>\n <Field label={t('wb.builder.to')}><ColorField label={t('wb.builder.gradientEnd')} value={background.to} swatches={[page, colors.bg, colors.elevated]} onChange={v => v && onChange({ ...background, to: v })}/></Field>\n <Field label={t('wb.appearance.bg.glow')}><ColorField label={t('wb.appearance.bg.glow')} value={background.glow ?? null} autoLabel={t('wb.appearance.hover.none')} swatches={[colors.accent]} onChange={v => onChange({ ...background, glow: v ?? undefined })}/></Field>\n <Field label={t('wb.builder.angle')}><Slider label={t('wb.builder.gradientAngle')} min={0} max={360} step={5} value={background.angle} format={v => `${formatNumber(v)}°`} onChange={angle => onChange({ ...background, angle }, false)} onCommit={angle => onChange({ ...background, angle })}/></Field>\n </div>}\n {background.kind === 'pattern' && <div className=\"wb-fields\">\n <Field label={t('wb.builder.pattern')}><Select<Pattern> label={t('wb.builder.pattern')} value={background.pattern} width={160} onChange={pattern => onChange({ ...background, pattern })} options={PATTERNS.map(value => ({ value, label: tx(`wb.appearance.bg.${value}`, undefined, value) }))}/></Field>\n <Field label={t('wb.builder.ink')}><ColorField label={t('wb.builder.patternInk')} value={background.ink} swatches={[colors.text, colors.accent, '#ffffff']} onChange={v => v && onChange({ ...background, ink: v })}/></Field>\n <Field label={t('wb.builder.strength')}><Slider label={t('wb.builder.patternStrength')} min={0} max={60} value={Math.round(background.opacity * 100)} format={pct} onChange={v => onChange({ ...background, opacity: v / 100 }, false)} onCommit={v => onChange({ ...background, opacity: v / 100 })}/></Field>\n <Field label={t('wb.builder.scale')}><Slider label={t('wb.builder.patternScale')} min={2} max={400} value={background.size} format={px} onChange={size => onChange({ ...background, size }, false)} onCommit={size => onChange({ ...background, size })}/></Field>\n </div>}\n {background.kind === 'image' && <div className=\"wb-fields\">\n <Field label={t('wb.builder.dimming')}><Slider label={t('wb.appearance.dim')} min={35} max={95} value={Math.round(background.dim * 100)} format={pct} onChange={v => onChange({ ...background, dim: v / 100 }, false)} onCommit={v => onChange({ ...background, dim: v / 100 })}/></Field>\n <Field label={t('wb.builder.fit')}><Segmented label={t('wb.builder.photoFit')} size=\"sm\" value={background.fit} onChange={fit => onChange({ ...background, fit })} options={[{ value: 'cover', label: t('wb.builder.cover') }, { value: 'tile', label: t('wb.builder.tile') }]}/></Field>\n <Field label={t('wb.builder.photo')}><Button size=\"sm\" onClick={() => file.current?.click()}>{t('wb.builder.replace')}</Button></Field>\n </div>}\n </div>;\n}\n\n/** The app's window in the draft: a tab strip and an address bar drawn with the chrome tokens. */\nfunction ChromePreview({ theme }: { theme: ThemeSpec }) {\n const themes = panelThemes();\n const vars = useMemo(() => chromeVars(themes.store.adapter.chrome(theme)), [theme]);\n const sample = themes.chromePreview ?? { tabs: ['Home', '@waybetter', panelSite().brand.name] as [string, string, string], chip: panelSite().brand.name, page: 'Home' };\n return <div className=\"wb-chrome-preview\" style={vars as CSSProperties} aria-hidden=\"true\">\n <div className=\"wb-cp-tabs\">\n <span className=\"wb-cp-tab is-on\"><i/>{sample.tabs[0]}</span><span className=\"wb-cp-tab\"><i/>{sample.tabs[1]}</span><span className=\"wb-cp-tab\"><i/>{sample.tabs[2]}</span>\n </div>\n <div className=\"wb-cp-bar\"><span className=\"wb-cp-dot\"/><span className=\"wb-cp-omni\"><b>{sample.chip}</b><em>/</em>{sample.page}</span><span className=\"wb-cp-brand\"/></div>\n </div>;\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /* Settings → Backup & sync and Developer (BackupPanel.tsx, DeveloperPanel.tsx). Panel tokens (panel.css). */
2
+
3
+ .btb-check { display: inline-flex; align-items: center; gap: 7px; color: var(--c-text); font-size: 12.5px; cursor: pointer; user-select: none; }
4
+ .btb-check input, .btb-row input { width: 15px; height: 15px; margin: 0; accent-color: var(--c-accent); cursor: pointer; }
5
+ .btb-loading { padding: 14px 16px; color: var(--c-muted); font-size: 12.5px; }
6
+ .btb-path { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--f-mono); font-size: 11.5px; }
7
+
8
+ /* Import preview: one row per section. */
9
+ .btb-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px 16px; border-top: 1px solid var(--c-line-soft); cursor: pointer; }
10
+ .btb-row:first-child { border-top: 0; }
11
+ .btb-row input { margin-top: 2px; flex: none; }
12
+ .btb-row:hover { background: rgba(127, 127, 127, .05); }
13
+ .btb-row.is-same .btb-row-title { color: var(--c-muted); }
14
+ .btb-row-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
15
+ .btb-row-title { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 13px; }
16
+ .btb-row-line { color: var(--c-muted); font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; }
17
+ .btb-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 12px 16px; border-top: 1px solid var(--c-line-soft); }
18
+ .btb-actions-note { color: var(--c-muted); font-size: 12px; }
19
+
20
+ /* Sync */
21
+ .btb-pass { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
22
+ .btb-pass .bt-input { width: 200px; }
23
+ .btb-error { color: #ff8a80; font-size: 12px; }
24
+ .btb-snapshots { display: flex; flex-direction: column; gap: 6px; width: 100%; }
25
+ .btb-snapshot { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 9px; background: rgba(127, 127, 127, .06); }
26
+ .btb-snapshot.is-fresh { background: rgb(var(--c-accent-rgb) / .1); box-shadow: inset 0 0 0 1px rgb(var(--c-accent-rgb) / .3); }
27
+ .btb-snapshot-device { font-weight: 600; font-size: 12.5px; }
28
+ .btb-snapshot-when { flex: 1; color: var(--c-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
29
+
30
+ /* Developer: load errors */
31
+ .btd-error { display: flex; flex-direction: column; gap: 4px; padding: 11px 16px; border-top: 1px solid var(--c-line-soft); border-inline-start: 3px solid var(--c-danger); }
32
+ .btd-error:first-child { border-top: 0; }
33
+ .btd-where { font: 600 12px/1.3 var(--f-mono); color: #ffb4ab; overflow-wrap: anywhere; }
34
+ .btd-message { font: 12.5px/1.45 var(--f-mono); color: var(--c-text); overflow-wrap: anywhere; }