@eifi1/ui-kit 0.31.0 → 0.32.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 (565) hide show
  1. package/README.md +53 -30
  2. package/dist/account/delete-account-setting.d.ts +8 -3
  3. package/dist/admin/admin-action-confirm.d.ts +8 -3
  4. package/dist/admin/admin-parts.d.ts +8 -1
  5. package/dist/admin/admin-parts.js +1 -1
  6. package/dist/admin/admin-parts.js.map +1 -1
  7. package/dist/admin/invitations-panel.d.ts +8 -3
  8. package/dist/admin/invitations-panel.js +29 -26
  9. package/dist/admin/invitations-panel.js.map +1 -1
  10. package/dist/admin/reviewer-scope-editor.d.ts +8 -3
  11. package/dist/admin/role-select.d.ts +10 -5
  12. package/dist/admin/transfer-ownership-dialog.d.ts +8 -3
  13. package/dist/admin/user-roster.d.ts +10 -5
  14. package/dist/admin/user-roster.js +8 -47
  15. package/dist/admin/user-roster.js.map +1 -1
  16. package/dist/auth/auth-errors.d.ts +43 -8
  17. package/dist/auth/auth-errors.js +24 -1
  18. package/dist/auth/auth-errors.js.map +1 -1
  19. package/dist/auth/register-form.d.ts +8 -3
  20. package/dist/auth/reset-password-form.d.ts +1 -1
  21. package/dist/auth/reset-password-form.js +2 -1
  22. package/dist/auth/reset-password-form.js.map +1 -1
  23. package/dist/auth/verify-email.d.ts +4 -0
  24. package/dist/auth/verify-email.js +3 -2
  25. package/dist/auth/verify-email.js.map +1 -1
  26. package/dist/billing/billing-banner.d.ts +184 -0
  27. package/dist/billing/billing-banner.js +98 -0
  28. package/dist/billing/billing-banner.js.map +1 -0
  29. package/dist/billing/billing-labels.d.ts +100 -0
  30. package/dist/billing/billing-labels.js +74 -0
  31. package/dist/billing/billing-labels.js.map +1 -0
  32. package/dist/billing/billing-lock.d.ts +158 -0
  33. package/dist/billing/billing-lock.js +17 -0
  34. package/dist/billing/billing-lock.js.map +1 -0
  35. package/dist/billing/billing-standing.d.ts +149 -0
  36. package/dist/billing/billing-standing.js +28 -0
  37. package/dist/billing/billing-standing.js.map +1 -0
  38. package/dist/billing/plan-card.d.ts +248 -0
  39. package/dist/billing/plan-card.js +248 -0
  40. package/dist/billing/plan-card.js.map +1 -0
  41. package/dist/billing/plan-limit-notice.d.ts +156 -0
  42. package/dist/billing/plan-limit-notice.js +76 -0
  43. package/dist/billing/plan-limit-notice.js.map +1 -0
  44. package/dist/billing/plan-limit.d.ts +34 -0
  45. package/dist/billing/plan-limit.js +20 -0
  46. package/dist/billing/plan-limit.js.map +1 -0
  47. package/dist/billing/plan-price.d.ts +61 -0
  48. package/dist/billing/plan-price.js +45 -0
  49. package/dist/billing/plan-price.js.map +1 -0
  50. package/dist/billing/subscription-actions.d.ts +133 -0
  51. package/dist/billing/subscription-actions.js +28 -0
  52. package/dist/billing/subscription-actions.js.map +1 -0
  53. package/dist/billing/subscription-status-chip.d.ts +149 -0
  54. package/dist/billing/subscription-status-chip.js +48 -0
  55. package/dist/billing/subscription-status-chip.js.map +1 -0
  56. package/dist/chart.d.ts +9 -3
  57. package/dist/components/account-chips.d.ts +16 -4
  58. package/dist/components/account-chips.js +21 -3
  59. package/dist/components/account-chips.js.map +1 -1
  60. package/dist/components/alert-banner.d.ts +6 -1
  61. package/dist/components/alert-banner.js +4 -3
  62. package/dist/components/alert-banner.js.map +1 -1
  63. package/dist/components/amount-input.d.ts +8 -3
  64. package/dist/components/amount-input.js +5 -5
  65. package/dist/components/amount-input.js.map +1 -1
  66. package/dist/components/appearance-labels.d.ts +32 -0
  67. package/dist/components/appearance-labels.js +18 -0
  68. package/dist/components/appearance-labels.js.map +1 -0
  69. package/dist/components/autocomplete.js +2 -2
  70. package/dist/components/autocomplete.js.map +1 -1
  71. package/dist/components/breadcrumbs.js +3 -2
  72. package/dist/components/breadcrumbs.js.map +1 -1
  73. package/dist/components/bulk-action-bar.d.ts +2 -2
  74. package/dist/components/bulk-action-bar.js +7 -12
  75. package/dist/components/bulk-action-bar.js.map +1 -1
  76. package/dist/components/button-group.d.ts +8 -3
  77. package/dist/components/calculator.d.ts +8 -3
  78. package/dist/components/calculator.js +4 -3
  79. package/dist/components/calculator.js.map +1 -1
  80. package/dist/components/calendar-heatmap.js +5 -5
  81. package/dist/components/calendar-heatmap.js.map +1 -1
  82. package/dist/components/chart-height.d.ts +23 -0
  83. package/dist/components/chart-height.js +15 -0
  84. package/dist/components/chart-height.js.map +1 -0
  85. package/dist/components/chart-zoom.js +6 -1
  86. package/dist/components/chart-zoom.js.map +1 -1
  87. package/dist/components/checkbox-group.js +2 -2
  88. package/dist/components/checkbox-group.js.map +1 -1
  89. package/dist/components/checkbox.d.ts +10 -0
  90. package/dist/components/checkbox.js +25 -10
  91. package/dist/components/checkbox.js.map +1 -1
  92. package/dist/components/chip.d.ts +19 -3
  93. package/dist/components/chip.js +47 -21
  94. package/dist/components/chip.js.map +1 -1
  95. package/dist/components/choice-card.d.ts +1 -1
  96. package/dist/components/choice-card.js +8 -7
  97. package/dist/components/choice-card.js.map +1 -1
  98. package/dist/components/column-mapper.js +1 -1
  99. package/dist/components/column-mapper.js.map +1 -1
  100. package/dist/components/combobox-core.js +8 -7
  101. package/dist/components/combobox-core.js.map +1 -1
  102. package/dist/components/combobox.js +8 -8
  103. package/dist/components/combobox.js.map +1 -1
  104. package/dist/components/confirm-dialog.d.ts +8 -3
  105. package/dist/components/confirm-dialog.js +7 -1
  106. package/dist/components/confirm-dialog.js.map +1 -1
  107. package/dist/components/copy-button.d.ts +10 -5
  108. package/dist/components/country-select.js +1 -1
  109. package/dist/components/country-select.js.map +1 -1
  110. package/dist/components/currency-select.js +3 -3
  111. package/dist/components/currency-select.js.map +1 -1
  112. package/dist/components/danger-confirm.d.ts +8 -3
  113. package/dist/components/data-table-cells.d.ts +1 -1
  114. package/dist/components/data-table-filter-popover.d.ts +1 -1
  115. package/dist/components/data-table-filter-popover.js +4 -1
  116. package/dist/components/data-table-filter-popover.js.map +1 -1
  117. package/dist/components/data-table-filters.d.ts +1 -1
  118. package/dist/components/data-table-labels.d.ts +1 -1
  119. package/dist/components/data-table-pagination.d.ts +1 -1
  120. package/dist/components/data-table.d.ts +1 -1
  121. package/dist/components/data-table.js +123 -52
  122. package/dist/components/data-table.js.map +1 -1
  123. package/dist/components/date-picker.d.ts +1 -1
  124. package/dist/components/date-picker.js +7 -5
  125. package/dist/components/date-picker.js.map +1 -1
  126. package/dist/components/description-list.js +2 -2
  127. package/dist/components/description-list.js.map +1 -1
  128. package/dist/components/dialog-frame.js +2 -1
  129. package/dist/components/dialog-frame.js.map +1 -1
  130. package/dist/components/disclosure.js +3 -2
  131. package/dist/components/disclosure.js.map +1 -1
  132. package/dist/components/dropdown.d.ts +1 -1
  133. package/dist/components/dropdown.js +7 -1
  134. package/dist/components/dropdown.js.map +1 -1
  135. package/dist/components/facing-pair.d.ts +19 -6
  136. package/dist/components/facing-pair.js +3 -2
  137. package/dist/components/facing-pair.js.map +1 -1
  138. package/dist/components/field-parts.d.ts +102 -6
  139. package/dist/components/field-parts.js +81 -6
  140. package/dist/components/field-parts.js.map +1 -1
  141. package/dist/components/field-sync.d.ts +4 -1
  142. package/dist/components/field-sync.js +12 -2
  143. package/dist/components/field-sync.js.map +1 -1
  144. package/dist/components/field.js +2 -2
  145. package/dist/components/field.js.map +1 -1
  146. package/dist/components/file-button.d.ts +8 -3
  147. package/dist/components/file-dropzone.d.ts +8 -3
  148. package/dist/components/floating-panel.js +7 -4
  149. package/dist/components/floating-panel.js.map +1 -1
  150. package/dist/components/focus-ring.d.ts +12 -0
  151. package/dist/components/focus-ring.js +8 -0
  152. package/dist/components/focus-ring.js.map +1 -0
  153. package/dist/components/form-actions.d.ts +8 -3
  154. package/dist/components/form-actions.js +33 -19
  155. package/dist/components/form-actions.js.map +1 -1
  156. package/dist/components/full-bleed-dialog.d.ts +11 -1
  157. package/dist/components/full-bleed-dialog.js +3 -1
  158. package/dist/components/full-bleed-dialog.js.map +1 -1
  159. package/dist/components/iban-input.d.ts +8 -3
  160. package/dist/components/image-grid.js +1 -1
  161. package/dist/components/image-grid.js.map +1 -1
  162. package/dist/components/inline-edit-field.js +6 -3
  163. package/dist/components/inline-edit-field.js.map +1 -1
  164. package/dist/components/language-select.d.ts +8 -3
  165. package/dist/components/legal-page.d.ts +26 -5
  166. package/dist/components/legal-page.js +3 -1
  167. package/dist/components/legal-page.js.map +1 -1
  168. package/dist/components/legal.d.ts +8 -3
  169. package/dist/components/legal.js +2 -1
  170. package/dist/components/legal.js.map +1 -1
  171. package/dist/components/lightbox.js +24 -2
  172. package/dist/components/lightbox.js.map +1 -1
  173. package/dist/components/line-items.js +2 -1
  174. package/dist/components/line-items.js.map +1 -1
  175. package/dist/components/list.d.ts +5 -0
  176. package/dist/components/list.js +13 -9
  177. package/dist/components/list.js.map +1 -1
  178. package/dist/components/measured-grid.d.ts +3 -1
  179. package/dist/components/measured-grid.js +38 -20
  180. package/dist/components/measured-grid.js.map +1 -1
  181. package/dist/components/menu-item.js +2 -1
  182. package/dist/components/menu-item.js.map +1 -1
  183. package/dist/components/mini-calendar.js +8 -4
  184. package/dist/components/mini-calendar.js.map +1 -1
  185. package/dist/components/money-field.d.ts +8 -3
  186. package/dist/components/month-picker.js +9 -5
  187. package/dist/components/month-picker.js.map +1 -1
  188. package/dist/components/nav-pills.js +1 -1
  189. package/dist/components/nav-pills.js.map +1 -1
  190. package/dist/components/number-field.d.ts +8 -3
  191. package/dist/components/number-input.d.ts +11 -4
  192. package/dist/components/number-input.js +8 -6
  193. package/dist/components/number-input.js.map +1 -1
  194. package/dist/components/numpad-sheet.d.ts +8 -3
  195. package/dist/components/numpad-sheet.js +2 -1
  196. package/dist/components/numpad-sheet.js.map +1 -1
  197. package/dist/components/one-time-code-input.js +2 -2
  198. package/dist/components/one-time-code-input.js.map +1 -1
  199. package/dist/components/page-contents.js +2 -2
  200. package/dist/components/page-contents.js.map +1 -1
  201. package/dist/components/phone-input.d.ts +8 -3
  202. package/dist/components/phone-input.js +2 -2
  203. package/dist/components/phone-input.js.map +1 -1
  204. package/dist/components/pie-chart.d.ts +8 -2
  205. package/dist/components/pie-chart.js +11 -7
  206. package/dist/components/pie-chart.js.map +1 -1
  207. package/dist/components/popover.d.ts +9 -1
  208. package/dist/components/popover.js +8 -4
  209. package/dist/components/popover.js.map +1 -1
  210. package/dist/components/row-actions.d.ts +100 -0
  211. package/dist/components/row-actions.js +165 -0
  212. package/dist/components/row-actions.js.map +1 -0
  213. package/dist/components/scroll-area.js +1 -1
  214. package/dist/components/scroll-area.js.map +1 -1
  215. package/dist/components/search-field.js +3 -2
  216. package/dist/components/search-field.js.map +1 -1
  217. package/dist/components/series-chart-budget.d.ts +30 -7
  218. package/dist/components/series-chart-budget.js +12 -4
  219. package/dist/components/series-chart-budget.js.map +1 -1
  220. package/dist/components/series-chart-ticks.d.ts +7 -1
  221. package/dist/components/series-chart-ticks.js +6 -0
  222. package/dist/components/series-chart-ticks.js.map +1 -1
  223. package/dist/components/series-chart.d.ts +58 -28
  224. package/dist/components/series-chart.js +42 -32
  225. package/dist/components/series-chart.js.map +1 -1
  226. package/dist/components/settings-fields.d.ts +51 -6
  227. package/dist/components/settings-fields.js +37 -0
  228. package/dist/components/settings-fields.js.map +1 -1
  229. package/dist/components/share-card.d.ts +11 -6
  230. package/dist/components/share-card.js +2 -0
  231. package/dist/components/share-card.js.map +1 -1
  232. package/dist/components/sign-chip.d.ts +4 -0
  233. package/dist/components/sign-chip.js +17 -4
  234. package/dist/components/sign-chip.js.map +1 -1
  235. package/dist/components/signature-pad.d.ts +3 -1
  236. package/dist/components/signature-pad.js +8 -5
  237. package/dist/components/signature-pad.js.map +1 -1
  238. package/dist/components/slider.js +7 -6
  239. package/dist/components/slider.js.map +1 -1
  240. package/dist/components/sparkline.d.ts +5 -1
  241. package/dist/components/sparkline.js +4 -2
  242. package/dist/components/sparkline.js.map +1 -1
  243. package/dist/components/stat-tile.d.ts +17 -1
  244. package/dist/components/stat-tile.js +48 -20
  245. package/dist/components/stat-tile.js.map +1 -1
  246. package/dist/components/status-dot.d.ts +4 -0
  247. package/dist/components/swipeable-row.js +2 -1
  248. package/dist/components/swipeable-row.js.map +1 -1
  249. package/dist/components/switch.d.ts +21 -7
  250. package/dist/components/switch.js +24 -11
  251. package/dist/components/switch.js.map +1 -1
  252. package/dist/components/table.js +2 -2
  253. package/dist/components/table.js.map +1 -1
  254. package/dist/components/text-link.d.ts +8 -3
  255. package/dist/components/text-link.js +1 -1
  256. package/dist/components/text-link.js.map +1 -1
  257. package/dist/components/text.d.ts +7 -2
  258. package/dist/components/text.js +5 -5
  259. package/dist/components/text.js.map +1 -1
  260. package/dist/components/tile-radio.js +2 -1
  261. package/dist/components/tile-radio.js.map +1 -1
  262. package/dist/components/time-input.d.ts +8 -3
  263. package/dist/components/toast.d.ts +18 -2
  264. package/dist/components/toast.js +8 -5
  265. package/dist/components/toast.js.map +1 -1
  266. package/dist/components/toggle-group.d.ts +16 -1
  267. package/dist/components/toggle-group.js +40 -11
  268. package/dist/components/toggle-group.js.map +1 -1
  269. package/dist/components/toggle-legend.d.ts +10 -1
  270. package/dist/components/toggle-legend.js +21 -7
  271. package/dist/components/toggle-legend.js.map +1 -1
  272. package/dist/components/translation-review-parts.d.ts +4 -0
  273. package/dist/components/translation-review.d.ts +4 -0
  274. package/dist/components/translation-review.js +3 -3
  275. package/dist/components/translation-review.js.map +1 -1
  276. package/dist/components/tree-view.js +3 -2
  277. package/dist/components/tree-view.js.map +1 -1
  278. package/dist/components/treemap.d.ts +5 -2
  279. package/dist/components/treemap.js +33 -16
  280. package/dist/components/treemap.js.map +1 -1
  281. package/dist/components/ui.d.ts +8 -3
  282. package/dist/components/ui.js +202 -114
  283. package/dist/components/ui.js.map +1 -1
  284. package/dist/components/use-table-state.d.ts +1 -1
  285. package/dist/components/user-avatar.d.ts +5 -1
  286. package/dist/components/user-avatar.js +1 -1
  287. package/dist/components/user-avatar.js.map +1 -1
  288. package/dist/{data-table-labels-DUELeXpa.d.ts → data-table-labels-kpAAVi6g.d.ts} +26 -2
  289. package/dist/data-table.d.ts +1 -1
  290. package/dist/{delete-account-setting-DCFS5Vof.d.ts → delete-account-setting-BvdQdbv3.d.ts} +613 -58
  291. package/dist/demo/demo-banner.js +1 -0
  292. package/dist/demo/demo-banner.js.map +1 -1
  293. package/dist/feedback/feedback-attachment.d.ts +8 -3
  294. package/dist/feedback/feedback-context.d.ts +8 -3
  295. package/dist/feedback/feedback-crash.d.ts +8 -3
  296. package/dist/feedback/feedback-dialog.d.ts +8 -3
  297. package/dist/feedback/feedback-dialog.js +3 -3
  298. package/dist/feedback/feedback-dialog.js.map +1 -1
  299. package/dist/feedback/feedback-inbox.d.ts +8 -3
  300. package/dist/feedback/feedback-inbox.js +2 -2
  301. package/dist/feedback/feedback-inbox.js.map +1 -1
  302. package/dist/feedback/feedback-labels.d.ts +8 -3
  303. package/dist/feedback/feedback-menu.d.ts +9 -4
  304. package/dist/feedback/feedback-record.d.ts +8 -3
  305. package/dist/feedback/feedback-row-detail.d.ts +8 -3
  306. package/dist/feedback/feedback-status-undo.d.ts +8 -3
  307. package/dist/feedback/feedback-submit.d.ts +8 -3
  308. package/dist/feedback/feedback-swipe.d.ts +8 -3
  309. package/dist/feedback/feedback-table.d.ts +8 -3
  310. package/dist/feedback/feedback-thread.d.ts +8 -3
  311. package/dist/feedback/feedback-thread.js +3 -3
  312. package/dist/feedback/feedback-thread.js.map +1 -1
  313. package/dist/feedback.d.ts +8 -3
  314. package/dist/hooks/use-anchored-panel.d.ts +32 -3
  315. package/dist/hooks/use-anchored-panel.js +21 -3
  316. package/dist/hooks/use-anchored-panel.js.map +1 -1
  317. package/dist/hooks/use-breakpoint.d.ts +77 -0
  318. package/dist/hooks/use-breakpoint.js +50 -0
  319. package/dist/hooks/use-breakpoint.js.map +1 -0
  320. package/dist/hooks/use-file-drop.d.ts +8 -3
  321. package/dist/hooks/use-large-text.d.ts +29 -0
  322. package/dist/hooks/use-large-text.js +20 -0
  323. package/dist/hooks/use-large-text.js.map +1 -0
  324. package/dist/hooks/use-windowed-rows.d.ts +52 -8
  325. package/dist/hooks/use-windowed-rows.js +94 -5
  326. package/dist/hooks/use-windowed-rows.js.map +1 -1
  327. package/dist/i18n/defaults.d.ts +8 -3
  328. package/dist/i18n/defaults.js +8 -0
  329. package/dist/i18n/defaults.js.map +1 -1
  330. package/dist/i18n/german.d.ts +8 -3
  331. package/dist/i18n/german.js +91 -3
  332. package/dist/i18n/german.js.map +1 -1
  333. package/dist/i18n/kit-labels.d.ts +8 -3
  334. package/dist/i18n/kit-labels.js.map +1 -1
  335. package/dist/i18n/languages.d.ts +10 -5
  336. package/dist/i18n/locales/de-CH.d.ts +8 -3
  337. package/dist/i18n/locales/en.d.ts +8 -3
  338. package/dist/i18n/locales/es.d.ts +8 -3
  339. package/dist/i18n/locales/es.js +86 -3
  340. package/dist/i18n/locales/es.js.map +1 -1
  341. package/dist/i18n/locales/fr.d.ts +8 -3
  342. package/dist/i18n/locales/fr.js +88 -3
  343. package/dist/i18n/locales/fr.js.map +1 -1
  344. package/dist/i18n/locales/hu.d.ts +8 -3
  345. package/dist/i18n/locales/hu.js +88 -3
  346. package/dist/i18n/locales/hu.js.map +1 -1
  347. package/dist/i18n/locales/it.d.ts +8 -3
  348. package/dist/i18n/locales/it.js +89 -3
  349. package/dist/i18n/locales/it.js.map +1 -1
  350. package/dist/i18n/locales/zh.d.ts +8 -3
  351. package/dist/i18n/locales/zh.js +86 -3
  352. package/dist/i18n/locales/zh.js.map +1 -1
  353. package/dist/i18n/review.d.ts +8 -3
  354. package/dist/i18n/review.js +16 -1
  355. package/dist/i18n/review.js.map +1 -1
  356. package/dist/index.d.ts +29 -13
  357. package/dist/index.js +77 -5
  358. package/dist/index.js.map +1 -1
  359. package/dist/landing/landing-actions.d.ts +12 -5
  360. package/dist/landing/landing-actions.js +1 -1
  361. package/dist/landing/landing-actions.js.map +1 -1
  362. package/dist/landing/landing-sections.d.ts +8 -3
  363. package/dist/landing/public-header.d.ts +9 -4
  364. package/dist/landing/public-header.js +3 -3
  365. package/dist/landing/public-header.js.map +1 -1
  366. package/dist/landing/routing.d.ts +27 -9
  367. package/dist/landing/routing.js +5 -2
  368. package/dist/landing/routing.js.map +1 -1
  369. package/dist/lib/cn.js +3 -2
  370. package/dist/lib/cn.js.map +1 -1
  371. package/dist/rhf/fields.d.ts +8 -3
  372. package/dist/rhf/fields.js +1 -1
  373. package/dist/rhf/fields.js.map +1 -1
  374. package/dist/rhf/form.d.ts +8 -3
  375. package/dist/rhf/form.js +2 -2
  376. package/dist/rhf/form.js.map +1 -1
  377. package/dist/rhf.d.ts +8 -3
  378. package/dist/search/command-palette.d.ts +1 -1
  379. package/dist/search/command-palette.js +9 -8
  380. package/dist/search/command-palette.js.map +1 -1
  381. package/dist/settings/settings-labels.d.ts +8 -1
  382. package/dist/settings/settings-labels.js +7 -2
  383. package/dist/settings/settings-labels.js.map +1 -1
  384. package/dist/settings/settings-layout.js +2 -1
  385. package/dist/settings/settings-layout.js.map +1 -1
  386. package/dist/settings/settings-section.d.ts +8 -3
  387. package/dist/settings/use-account-appearance.d.ts +92 -0
  388. package/dist/settings/use-account-appearance.js +63 -0
  389. package/dist/settings/use-account-appearance.js.map +1 -0
  390. package/dist/settings/use-settings-route.d.ts +1 -1
  391. package/dist/settings/use-settings-route.js +2 -3
  392. package/dist/settings/use-settings-route.js.map +1 -1
  393. package/dist/shell/app-shell.d.ts +12 -171
  394. package/dist/shell/app-shell.js +144 -28
  395. package/dist/shell/app-shell.js.map +1 -1
  396. package/dist/shell/auth-layout.js +1 -1
  397. package/dist/shell/auth-layout.js.map +1 -1
  398. package/dist/shell/option-switcher-menu.js +1 -1
  399. package/dist/shell/option-switcher-menu.js.map +1 -1
  400. package/dist/shell/top-bar-brand.d.ts +8 -3
  401. package/dist/shell/top-bar-brand.js +3 -1
  402. package/dist/shell/top-bar-brand.js.map +1 -1
  403. package/dist/shell/topbar-action-menu.d.ts +4 -0
  404. package/dist/shell/topbar-action-menu.js +3 -3
  405. package/dist/shell/topbar-action-menu.js.map +1 -1
  406. package/dist/shell/topbar-controls.js +4 -4
  407. package/dist/shell/topbar-controls.js.map +1 -1
  408. package/dist/shell.d.ts +10 -6
  409. package/dist/shell.js.map +1 -1
  410. package/dist/theme/contrast-tokens.d.ts +41 -0
  411. package/dist/theme/contrast-tokens.js +59 -0
  412. package/dist/theme/contrast-tokens.js.map +1 -0
  413. package/dist/theme/contrast.d.ts +109 -0
  414. package/dist/theme/contrast.js +128 -0
  415. package/dist/theme/contrast.js.map +1 -0
  416. package/dist/theme/palette-presets.d.ts +12 -1
  417. package/dist/theme/palette-presets.js +9 -4
  418. package/dist/theme/palette-presets.js.map +1 -1
  419. package/dist/theme/palette-store.js.map +1 -1
  420. package/dist/theme/text-size.d.ts +157 -0
  421. package/dist/theme/text-size.js +121 -0
  422. package/dist/theme/text-size.js.map +1 -0
  423. package/dist/wizard/stepper-nav.d.ts +8 -3
  424. package/dist/wizard.d.ts +8 -3
  425. package/package.json +1 -1
  426. package/src/admin/admin-parts.ts +9 -2
  427. package/src/admin/invitations-panel.tsx +36 -29
  428. package/src/admin/user-roster.tsx +17 -72
  429. package/src/auth/auth-errors.ts +68 -7
  430. package/src/auth/reset-password-form.tsx +6 -2
  431. package/src/auth/verify-email.tsx +14 -2
  432. package/src/billing/billing-banner.tsx +205 -0
  433. package/src/billing/billing-labels.ts +224 -0
  434. package/src/billing/billing-lock.ts +75 -0
  435. package/src/billing/billing-standing.ts +72 -0
  436. package/src/billing/plan-card.tsx +458 -0
  437. package/src/billing/plan-limit-notice.tsx +145 -0
  438. package/src/billing/plan-limit.ts +53 -0
  439. package/src/billing/plan-price.ts +101 -0
  440. package/src/billing/subscription-actions.tsx +76 -0
  441. package/src/billing/subscription-status-chip.tsx +95 -0
  442. package/src/components/account-chips.tsx +36 -10
  443. package/src/components/alert-banner.tsx +11 -6
  444. package/src/components/amount-input.tsx +5 -5
  445. package/src/components/appearance-labels.ts +40 -0
  446. package/src/components/autocomplete.tsx +2 -2
  447. package/src/components/breadcrumbs.tsx +3 -3
  448. package/src/components/bulk-action-bar.tsx +11 -14
  449. package/src/components/calculator.tsx +4 -3
  450. package/src/components/calendar-heatmap.tsx +5 -5
  451. package/src/components/chart-height.ts +30 -0
  452. package/src/components/chart-zoom.tsx +6 -1
  453. package/src/components/checkbox-group.tsx +2 -2
  454. package/src/components/checkbox.tsx +62 -20
  455. package/src/components/chip.tsx +105 -24
  456. package/src/components/choice-card.tsx +15 -10
  457. package/src/components/column-mapper.tsx +1 -1
  458. package/src/components/combobox-core.tsx +8 -7
  459. package/src/components/combobox.tsx +8 -8
  460. package/src/components/confirm-dialog.tsx +20 -1
  461. package/src/components/country-select.tsx +1 -1
  462. package/src/components/currency-select.tsx +3 -3
  463. package/src/components/data-table-filter-popover.tsx +7 -1
  464. package/src/components/data-table.tsx +160 -43
  465. package/src/components/date-picker.tsx +12 -9
  466. package/src/components/description-list.tsx +2 -2
  467. package/src/components/dialog-frame.tsx +2 -1
  468. package/src/components/disclosure.tsx +3 -2
  469. package/src/components/dropdown.tsx +10 -2
  470. package/src/components/facing-pair.ts +12 -5
  471. package/src/components/field-parts.tsx +190 -7
  472. package/src/components/field-sync.tsx +17 -3
  473. package/src/components/field.tsx +2 -2
  474. package/src/components/floating-panel.tsx +7 -4
  475. package/src/components/focus-ring.ts +12 -0
  476. package/src/components/form-actions.tsx +55 -18
  477. package/src/components/full-bleed-dialog.tsx +18 -4
  478. package/src/components/image-grid.tsx +1 -1
  479. package/src/components/inline-edit-field.tsx +6 -3
  480. package/src/components/legal-page.tsx +28 -2
  481. package/src/components/legal.tsx +19 -1
  482. package/src/components/lightbox.tsx +24 -2
  483. package/src/components/line-items.tsx +7 -1
  484. package/src/components/list.tsx +36 -10
  485. package/src/components/measured-grid.tsx +49 -24
  486. package/src/components/menu-item.tsx +2 -2
  487. package/src/components/mini-calendar.tsx +8 -4
  488. package/src/components/month-picker.tsx +9 -5
  489. package/src/components/nav-pills.tsx +1 -1
  490. package/src/components/number-input.tsx +14 -7
  491. package/src/components/numpad-sheet.tsx +2 -2
  492. package/src/components/one-time-code-input.tsx +2 -2
  493. package/src/components/page-contents.tsx +2 -2
  494. package/src/components/phone-input.tsx +2 -2
  495. package/src/components/pie-chart.tsx +19 -9
  496. package/src/components/popover.tsx +22 -5
  497. package/src/components/row-actions.tsx +344 -0
  498. package/src/components/scroll-area.tsx +1 -1
  499. package/src/components/search-field.tsx +4 -2
  500. package/src/components/series-chart-budget.ts +40 -8
  501. package/src/components/series-chart-ticks.ts +10 -0
  502. package/src/components/series-chart.tsx +123 -72
  503. package/src/components/settings-fields.tsx +81 -2
  504. package/src/components/share-card.tsx +10 -0
  505. package/src/components/sign-chip.tsx +28 -4
  506. package/src/components/signature-pad.tsx +13 -7
  507. package/src/components/slider.tsx +22 -9
  508. package/src/components/sparkline.tsx +11 -3
  509. package/src/components/stat-tile.tsx +70 -14
  510. package/src/components/swipeable-row.tsx +2 -1
  511. package/src/components/switch.tsx +57 -23
  512. package/src/components/table.tsx +2 -2
  513. package/src/components/text-link.tsx +1 -1
  514. package/src/components/text.tsx +11 -6
  515. package/src/components/tile-radio.tsx +4 -1
  516. package/src/components/toast.tsx +27 -7
  517. package/src/components/toggle-group.tsx +99 -12
  518. package/src/components/toggle-legend.tsx +53 -8
  519. package/src/components/translation-review.tsx +10 -5
  520. package/src/components/tree-view.tsx +3 -2
  521. package/src/components/treemap.tsx +27 -10
  522. package/src/components/ui.tsx +331 -145
  523. package/src/components/user-avatar.tsx +1 -1
  524. package/src/demo/demo-banner.tsx +5 -0
  525. package/src/feedback/feedback-dialog.tsx +3 -3
  526. package/src/feedback/feedback-inbox.tsx +2 -2
  527. package/src/feedback/feedback-thread.tsx +3 -3
  528. package/src/hooks/use-anchored-panel.ts +67 -5
  529. package/src/hooks/use-breakpoint.ts +121 -0
  530. package/src/hooks/use-large-text.ts +41 -0
  531. package/src/hooks/use-windowed-rows.ts +168 -12
  532. package/src/i18n/defaults.ts +8 -0
  533. package/src/i18n/german.ts +105 -1
  534. package/src/i18n/kit-labels.tsx +12 -0
  535. package/src/i18n/locales/es.ts +96 -1
  536. package/src/i18n/locales/fr.ts +100 -1
  537. package/src/i18n/locales/hu.ts +98 -1
  538. package/src/i18n/locales/it.ts +101 -1
  539. package/src/i18n/locales/zh.ts +92 -1
  540. package/src/i18n/review.ts +15 -0
  541. package/src/index.ts +82 -8
  542. package/src/landing/landing-actions.tsx +9 -5
  543. package/src/landing/public-header.tsx +4 -4
  544. package/src/landing/routing.tsx +22 -5
  545. package/src/lib/cn.ts +13 -2
  546. package/src/rhf/fields.tsx +1 -1
  547. package/src/rhf/form.tsx +2 -2
  548. package/src/search/command-palette.tsx +10 -9
  549. package/src/settings/settings-labels.ts +13 -1
  550. package/src/settings/settings-layout.tsx +2 -1
  551. package/src/settings/use-account-appearance.ts +148 -0
  552. package/src/settings/use-settings-route.ts +3 -4
  553. package/src/shell/app-shell.tsx +278 -54
  554. package/src/shell/auth-layout.tsx +1 -1
  555. package/src/shell/option-switcher-menu.tsx +1 -1
  556. package/src/shell/top-bar-brand.tsx +3 -1
  557. package/src/shell/topbar-action-menu.tsx +3 -3
  558. package/src/shell/topbar-controls.tsx +4 -4
  559. package/src/shell.ts +7 -1
  560. package/src/theme/contrast-tokens.ts +112 -0
  561. package/src/theme/contrast.ts +224 -0
  562. package/src/theme/palette-presets.ts +24 -4
  563. package/src/theme/palette-store.ts +6 -1
  564. package/src/theme/text-size.ts +267 -0
  565. package/tokens.css +143 -1
@@ -1,19 +1,21 @@
1
1
  import * as react from 'react';
2
2
  import { ComponentPropsWithoutRef, ReactNode } from 'react';
3
- import { dY as LegalFooterProps } from '../delete-account-setting-DCFS5Vof.js';
3
+ import { e8 as LegalFooterProps } from '../delete-account-setting-BvdQdbv3.js';
4
4
  import { LandingActionsProps } from './landing-actions.js';
5
5
  import { LandingLabels } from './landing-labels.js';
6
6
  import '../components/tooltip.js';
7
7
  import '../hooks/use-anchored-rect.js';
8
8
  import '../lib/clipping.js';
9
- import '../data-table-labels-DUELeXpa.js';
9
+ import '../data-table-labels-kpAAVi6g.js';
10
10
  import '../components/data-table-sort.js';
11
11
  import '../components/swipeable-row.js';
12
12
  import '../components/mini-calendar.js';
13
13
  import '../components/calendar-heatmap.js';
14
14
  import '../components/popover.js';
15
+ import '../hooks/use-breakpoint.js';
15
16
  import '../components/chip.js';
16
17
  import 'lucide-react';
18
+ import '../components/field-parts.js';
17
19
  import '../components/field-sync.js';
18
20
  import '../wizard/types.js';
19
21
  import '../tour/tour.js';
@@ -81,6 +83,9 @@ import '../admin/admin-parts.js';
81
83
  import '../admin/admin-action-log.js';
82
84
  import '../settings/settings-labels.js';
83
85
  import '../demo/demo-labels.js';
86
+ import '../components/appearance-labels.js';
87
+ import '../theme/contrast.js';
88
+ import '../theme/text-size.js';
84
89
  import '../components/reauth-dialog.js';
85
90
  import '../components/server-wake.js';
86
91
  import '../lib/server-wake.js';
@@ -94,7 +99,7 @@ import '../components/sign-chip.js';
94
99
  import '../components/column-mapper.js';
95
100
  import '../lib/column-mapping.js';
96
101
  import '../lib/table-text.js';
97
- import '../components/field-parts.js';
102
+ import '../components/focus-ring.js';
98
103
 
99
104
  /**
100
105
  * The sections of the public landing page (docs/landing-demo-harmonization.md §4.1),
@@ -4,18 +4,20 @@ import { TopBarProps } from '../shell/top-bar.js';
4
4
  import { AccessChoice } from './access.js';
5
5
  import { LandingLabels } from './landing-labels.js';
6
6
  import { LandingSession } from './landing-actions.js';
7
- import '../delete-account-setting-DCFS5Vof.js';
7
+ import '../delete-account-setting-BvdQdbv3.js';
8
8
  import '../components/tooltip.js';
9
9
  import '../hooks/use-anchored-rect.js';
10
10
  import '../lib/clipping.js';
11
- import '../data-table-labels-DUELeXpa.js';
11
+ import '../data-table-labels-kpAAVi6g.js';
12
12
  import '../components/data-table-sort.js';
13
13
  import '../components/swipeable-row.js';
14
14
  import '../components/mini-calendar.js';
15
15
  import '../components/calendar-heatmap.js';
16
16
  import '../components/popover.js';
17
+ import '../hooks/use-breakpoint.js';
17
18
  import '../components/chip.js';
18
19
  import 'lucide-react';
20
+ import '../components/field-parts.js';
19
21
  import '../components/field-sync.js';
20
22
  import '../wizard/types.js';
21
23
  import '../tour/tour.js';
@@ -82,6 +84,9 @@ import '../admin/admin-parts.js';
82
84
  import '../admin/admin-action-log.js';
83
85
  import '../settings/settings-labels.js';
84
86
  import '../demo/demo-labels.js';
87
+ import '../components/appearance-labels.js';
88
+ import '../theme/contrast.js';
89
+ import '../theme/text-size.js';
85
90
  import '../components/reauth-dialog.js';
86
91
  import '../components/server-wake.js';
87
92
  import '../lib/server-wake.js';
@@ -95,7 +100,7 @@ import '../components/sign-chip.js';
95
100
  import '../components/column-mapper.js';
96
101
  import '../lib/column-mapping.js';
97
102
  import '../lib/table-text.js';
98
- import '../components/field-parts.js';
103
+ import '../components/focus-ring.js';
99
104
 
100
105
  /** The header's brand: what `TopBarBrand` draws. */
101
106
  interface PublicHeaderBrand {
@@ -139,7 +144,7 @@ interface PublicHeaderProps extends Omit<TopBarProps, "brand" | "actions" | "chi
139
144
  * | user | **Open app** (primary) |
140
145
  *
141
146
  * A demo session is not "signed in" here: it is still offered access, which is the point
142
- * of the demo (§5.6). On a phone (`PHONE_QUERY`) the actions take the kit's `sm` size, so
147
+ * of the demo (§5.6). In the phone layout (`usePhoneLayout()`) the actions take the kit's `sm` size, so
143
148
  * the brand mark, the two controls and two actions fit 390px; "Sign in" gives way below
144
149
  * `sm` as in keksdose — the sign-in page is one tap away from "Request access" anyway.
145
150
  */
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { Button, PHONE_QUERY } from "../components/ui.js";
4
- import { useMediaQuery } from "../hooks/use-media-query.js";
3
+ import { Button } from "../components/ui.js";
4
+ import { usePhoneLayout } from "../hooks/use-breakpoint.js";
5
5
  import { TopBar } from "../shell/top-bar.js";
6
6
  import { TopBarBrand } from "../shell/top-bar-brand.js";
7
7
  import { useAccessAction } from "./access.js";
@@ -22,7 +22,7 @@ function PublicHeader({
22
22
  }) {
23
23
  const labels = useLandingLabels(labelsProp);
24
24
  const accessLink = useAccessAction(access, labelsProp);
25
- const phone = useMediaQuery(PHONE_QUERY, false);
25
+ const phone = usePhoneLayout();
26
26
  const size = phone ? "sm" : "md";
27
27
  const home = homeHref ?? (session === "none" ? "/" : "/welcome");
28
28
  const actions = session === "user" ? /* @__PURE__ */ jsx(Button, { href: openAppHref, variant: "brand", size, children: labels.openApp }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/landing/public-header.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { Button, PHONE_QUERY } from \"../components/ui\";\nimport { useMediaQuery } from \"../hooks/use-media-query\";\nimport { TopBar } from \"../shell/top-bar\";\nimport type { TopBarProps } from \"../shell/top-bar\";\nimport { TopBarBrand } from \"../shell/top-bar-brand\";\nimport { useAccessAction } from \"./access\";\nimport type { AccessChoice } from \"./access\";\nimport { useLandingLabels } from \"./landing-labels\";\nimport type { LandingLabels } from \"./landing-labels\";\nimport type { LandingSession } from \"./landing-actions\";\n\n/** The header's brand: what `TopBarBrand` draws. */\nexport interface PublicHeaderBrand {\n /** The brand mark — an SVG or an `<img alt=\"\">`. */\n logo: ReactNode;\n /** The product name beside it, and the link's accessible name. */\n name: ReactNode;\n /** See `TopBarBrand`. Default `sm`: the logo alone on a phone. */\n collapseBelow?: \"sm\" | \"md\" | false;\n}\n\nexport interface PublicHeaderProps extends Omit<TopBarProps, \"brand\" | \"actions\" | \"children\"> {\n brand: PublicHeaderBrand;\n /** Where the brand links. Default `/` without a session and `/welcome` with one —\n * `/` would resume into the app, `/welcome` is always the landing (§3.1). */\n homeHref?: string;\n session: LandingSession;\n access: AccessChoice;\n /** \"Sign in\". Default `/login`. */\n signInHref?: string;\n /** \"Open app\" for a real session — the resume target. Default `/`, which resumes\n * through `RootEntry`. */\n openAppHref?: string;\n /** \"Continue the demo\" for a demo session. Default `/demo`, which continues a live\n * demo (§3.1). */\n demoHref?: string;\n /** The app's `LanguageMenu`, before the actions. */\n languageMenu?: ReactNode;\n /** The app's `ThemeToggle`, before the language menu. */\n themeToggle?: ReactNode;\n labels?: Partial<LandingLabels>;\n}\n\n/**\n * The header of every public page (docs/landing-demo-harmonization.md §4.1): the\n * landing, the auth pages, the legal pages and the 404 — keksdose's `LandingHeader`, on\n * the kit's `TopBar` and `TopBarBrand`, with its hard-coded teal turned into `--brand`.\n *\n * | session | actions |\n * |---|---|\n * | none | Sign in (secondary, hidden below `sm`), **Request access** (primary) |\n * | demo | Continue the demo (secondary), **Request access** (primary) |\n * | user | **Open app** (primary) |\n *\n * A demo session is not \"signed in\" here: it is still offered access, which is the point\n * of the demo (§5.6). On a phone (`PHONE_QUERY`) the actions take the kit's `sm` size, so\n * the brand mark, the two controls and two actions fit 390px; \"Sign in\" gives way below\n * `sm` as in keksdose — the sign-in page is one tap away from \"Request access\" anyway.\n */\nexport function PublicHeader({\n brand,\n homeHref,\n session,\n access,\n signInHref = \"/login\",\n openAppHref = \"/\",\n demoHref = \"/demo\",\n languageMenu,\n themeToggle,\n labels: labelsProp,\n className,\n ...rest\n}: PublicHeaderProps) {\n const labels = useLandingLabels(labelsProp);\n const accessLink = useAccessAction(access, labelsProp);\n const phone = useMediaQuery(PHONE_QUERY, false);\n const size = phone ? \"sm\" : \"md\";\n const home = homeHref ?? (session === \"none\" ? \"/\" : \"/welcome\");\n\n const actions =\n session === \"user\" ? (\n <Button href={openAppHref} variant=\"brand\" size={size}>\n {labels.openApp}\n </Button>\n ) : (\n <>\n {session === \"demo\" ? (\n <Button href={demoHref} variant=\"secondary\" size={size}>\n {labels.continueDemo}\n </Button>\n ) : (\n <Button href={signInHref} variant=\"secondary\" size={size} className=\"max-sm:hidden\">\n {labels.signIn}\n </Button>\n )}\n <Button href={accessLink.href} variant=\"brand\" size={size}>\n {accessLink.label}\n </Button>\n </>\n );\n\n return (\n <TopBar\n {...rest}\n className={className}\n brand={<TopBarBrand logo={brand.logo} name={brand.name} to={home} collapseBelow={brand.collapseBelow} />}\n actions={\n <>\n {themeToggle}\n {languageMenu}\n <span data-slot=\"public-header-actions\" className=\"ms-1 flex items-center gap-1.5 sm:gap-2\">\n {actions}\n </span>\n </>\n }\n />\n );\n}\n"],"mappings":";AAmFM,SAIA,UAJA,KAIA,YAJA;AAjFN,SAAS,QAAQ,mBAAmB;AACpC,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AAEvB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAEhC,SAAS,wBAAwB;AAoD1B,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,SAAS,iBAAiB,UAAU;AAC1C,QAAM,aAAa,gBAAgB,QAAQ,UAAU;AACrD,QAAM,QAAQ,cAAc,aAAa,KAAK;AAC9C,QAAM,OAAO,QAAQ,OAAO;AAC5B,QAAM,OAAO,aAAa,YAAY,SAAS,MAAM;AAErD,QAAM,UACJ,YAAY,SACV,oBAAC,UAAO,MAAM,aAAa,SAAQ,SAAQ,MACxC,iBAAO,SACV,IAEA,iCACG;AAAA,gBAAY,SACX,oBAAC,UAAO,MAAM,UAAU,SAAQ,aAAY,MACzC,iBAAO,cACV,IAEA,oBAAC,UAAO,MAAM,YAAY,SAAQ,aAAY,MAAY,WAAU,iBACjE,iBAAO,QACV;AAAA,IAEF,oBAAC,UAAO,MAAM,WAAW,MAAM,SAAQ,SAAQ,MAC5C,qBAAW,OACd;AAAA,KACF;AAGJ,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,OAAO,oBAAC,eAAY,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,MAAM,eAAe,MAAM,eAAe;AAAA,MACtG,SACE,iCACG;AAAA;AAAA,QACA;AAAA,QACD,oBAAC,UAAK,aAAU,yBAAwB,WAAU,2CAC/C,mBACH;AAAA,SACF;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/landing/public-header.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { Button } from \"../components/ui\";\nimport { usePhoneLayout } from \"../hooks/use-breakpoint\";\nimport { TopBar } from \"../shell/top-bar\";\nimport type { TopBarProps } from \"../shell/top-bar\";\nimport { TopBarBrand } from \"../shell/top-bar-brand\";\nimport { useAccessAction } from \"./access\";\nimport type { AccessChoice } from \"./access\";\nimport { useLandingLabels } from \"./landing-labels\";\nimport type { LandingLabels } from \"./landing-labels\";\nimport type { LandingSession } from \"./landing-actions\";\n\n/** The header's brand: what `TopBarBrand` draws. */\nexport interface PublicHeaderBrand {\n /** The brand mark — an SVG or an `<img alt=\"\">`. */\n logo: ReactNode;\n /** The product name beside it, and the link's accessible name. */\n name: ReactNode;\n /** See `TopBarBrand`. Default `sm`: the logo alone on a phone. */\n collapseBelow?: \"sm\" | \"md\" | false;\n}\n\nexport interface PublicHeaderProps extends Omit<TopBarProps, \"brand\" | \"actions\" | \"children\"> {\n brand: PublicHeaderBrand;\n /** Where the brand links. Default `/` without a session and `/welcome` with one —\n * `/` would resume into the app, `/welcome` is always the landing (§3.1). */\n homeHref?: string;\n session: LandingSession;\n access: AccessChoice;\n /** \"Sign in\". Default `/login`. */\n signInHref?: string;\n /** \"Open app\" for a real session — the resume target. Default `/`, which resumes\n * through `RootEntry`. */\n openAppHref?: string;\n /** \"Continue the demo\" for a demo session. Default `/demo`, which continues a live\n * demo (§3.1). */\n demoHref?: string;\n /** The app's `LanguageMenu`, before the actions. */\n languageMenu?: ReactNode;\n /** The app's `ThemeToggle`, before the language menu. */\n themeToggle?: ReactNode;\n labels?: Partial<LandingLabels>;\n}\n\n/**\n * The header of every public page (docs/landing-demo-harmonization.md §4.1): the\n * landing, the auth pages, the legal pages and the 404 — keksdose's `LandingHeader`, on\n * the kit's `TopBar` and `TopBarBrand`, with its hard-coded teal turned into `--brand`.\n *\n * | session | actions |\n * |---|---|\n * | none | Sign in (secondary, hidden below `sm`), **Request access** (primary) |\n * | demo | Continue the demo (secondary), **Request access** (primary) |\n * | user | **Open app** (primary) |\n *\n * A demo session is not \"signed in\" here: it is still offered access, which is the point\n * of the demo (§5.6). In the phone layout (`usePhoneLayout()`) the actions take the kit's `sm` size, so\n * the brand mark, the two controls and two actions fit 390px; \"Sign in\" gives way below\n * `sm` as in keksdose — the sign-in page is one tap away from \"Request access\" anyway.\n */\nexport function PublicHeader({\n brand,\n homeHref,\n session,\n access,\n signInHref = \"/login\",\n openAppHref = \"/\",\n demoHref = \"/demo\",\n languageMenu,\n themeToggle,\n labels: labelsProp,\n className,\n ...rest\n}: PublicHeaderProps) {\n const labels = useLandingLabels(labelsProp);\n const accessLink = useAccessAction(access, labelsProp);\n const phone = usePhoneLayout();\n const size = phone ? \"sm\" : \"md\";\n const home = homeHref ?? (session === \"none\" ? \"/\" : \"/welcome\");\n\n const actions =\n session === \"user\" ? (\n <Button href={openAppHref} variant=\"brand\" size={size}>\n {labels.openApp}\n </Button>\n ) : (\n <>\n {session === \"demo\" ? (\n <Button href={demoHref} variant=\"secondary\" size={size}>\n {labels.continueDemo}\n </Button>\n ) : (\n <Button href={signInHref} variant=\"secondary\" size={size} className=\"max-sm:hidden\">\n {labels.signIn}\n </Button>\n )}\n <Button href={accessLink.href} variant=\"brand\" size={size}>\n {accessLink.label}\n </Button>\n </>\n );\n\n return (\n <TopBar\n {...rest}\n className={className}\n brand={<TopBarBrand logo={brand.logo} name={brand.name} to={home} collapseBelow={brand.collapseBelow} />}\n actions={\n <>\n {themeToggle}\n {languageMenu}\n <span data-slot=\"public-header-actions\" className=\"ms-1 flex items-center gap-1.5 sm:gap-2\">\n {actions}\n </span>\n </>\n }\n />\n );\n}\n"],"mappings":";AAmFM,SAIA,UAJA,KAIA,YAJA;AAjFN,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AAEvB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAEhC,SAAS,wBAAwB;AAoD1B,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,SAAS,iBAAiB,UAAU;AAC1C,QAAM,aAAa,gBAAgB,QAAQ,UAAU;AACrD,QAAM,QAAQ,eAAe;AAC7B,QAAM,OAAO,QAAQ,OAAO;AAC5B,QAAM,OAAO,aAAa,YAAY,SAAS,MAAM;AAErD,QAAM,UACJ,YAAY,SACV,oBAAC,UAAO,MAAM,aAAa,SAAQ,SAAQ,MACxC,iBAAO,SACV,IAEA,iCACG;AAAA,gBAAY,SACX,oBAAC,UAAO,MAAM,UAAU,SAAQ,aAAY,MACzC,iBAAO,cACV,IAEA,oBAAC,UAAO,MAAM,YAAY,SAAQ,aAAY,MAAY,WAAU,iBACjE,iBAAO,QACV;AAAA,IAEF,oBAAC,UAAO,MAAM,WAAW,MAAM,SAAQ,SAAQ,MAC5C,qBAAW,OACd;AAAA,KACF;AAGJ,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,OAAO,oBAAC,eAAY,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,MAAM,eAAe,MAAM,eAAe;AAAA,MACtG,SACE,iCACG;AAAA;AAAA,QACA;AAAA,QACD,oBAAC,UAAK,aAAU,yBAAwB,WAAU,2CAC/C,mBACH;AAAA,SACF;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -1,18 +1,20 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { LandingSession } from './landing-actions.js';
4
- import '../delete-account-setting-DCFS5Vof.js';
4
+ import '../delete-account-setting-BvdQdbv3.js';
5
5
  import '../components/tooltip.js';
6
6
  import '../hooks/use-anchored-rect.js';
7
7
  import '../lib/clipping.js';
8
- import '../data-table-labels-DUELeXpa.js';
8
+ import '../data-table-labels-kpAAVi6g.js';
9
9
  import '../components/data-table-sort.js';
10
10
  import '../components/swipeable-row.js';
11
11
  import '../components/mini-calendar.js';
12
12
  import '../components/calendar-heatmap.js';
13
13
  import '../components/popover.js';
14
+ import '../hooks/use-breakpoint.js';
14
15
  import '../components/chip.js';
15
16
  import 'lucide-react';
17
+ import '../components/field-parts.js';
16
18
  import '../components/field-sync.js';
17
19
  import '../wizard/types.js';
18
20
  import '../tour/tour.js';
@@ -81,6 +83,9 @@ import '../admin/admin-parts.js';
81
83
  import '../admin/admin-action-log.js';
82
84
  import '../settings/settings-labels.js';
83
85
  import '../demo/demo-labels.js';
86
+ import '../components/appearance-labels.js';
87
+ import '../theme/contrast.js';
88
+ import '../theme/text-size.js';
84
89
  import '../components/reauth-dialog.js';
85
90
  import '../components/server-wake.js';
86
91
  import '../lib/server-wake.js';
@@ -94,8 +99,15 @@ import '../components/sign-chip.js';
94
99
  import '../components/column-mapper.js';
95
100
  import '../lib/column-mapping.js';
96
101
  import '../lib/table-text.js';
97
- import '../components/field-parts.js';
102
+ import '../components/focus-ring.js';
98
103
 
104
+ /**
105
+ * 0.31.1: a session that is still being restored — an app whose access token lives in
106
+ * memory reads it back from its refresh token first (kastlan's 0.31 adoption). Until
107
+ * then `/` neither shows the landing nor resumes, and a public page neither shows nor
108
+ * redirects: both render `loading` instead.
109
+ */
110
+ type RoutingSession = LandingSession | "loading";
99
111
  /**
100
112
  * The public routes' logic (docs/landing-demo-harmonization.md §3): what `/` shows,
101
113
  * which pages a session skips, and the page a session resumes on — keksdose's
@@ -167,8 +179,11 @@ declare function readLastVisitedPage(key: string, fallback?: null): string | nul
167
179
  * resume on the previous one's page. */
168
180
  declare function clearLastVisitedPage(key: string): void;
169
181
  interface RootEntryProps {
170
- /** Without a session `/` is the landing; with one (real or demo) it resumes. */
171
- session: LandingSession;
182
+ /** Without a session `/` is the landing; with one (real or demo) it resumes;
183
+ * `"loading"` while the app restores one. */
184
+ session: RoutingSession;
185
+ /** What shows while `session` is `"loading"`. Default: the kit's `LoadingState`. */
186
+ loading?: ReactNode;
172
187
  /** The remembered page — `readLastVisitedPage(key)`. */
173
188
  resumePath?: string | null;
174
189
  /** The landing page element. */
@@ -186,9 +201,12 @@ interface RootEntryProps {
186
201
  * home instead, because a session at `/` came to use the app. The landing stays one tap
187
202
  * away at `/welcome`, where the signed-in brand link points.
188
203
  */
189
- declare function RootEntry({ session, resumePath, landing, home }: RootEntryProps): react.JSX.Element;
204
+ declare function RootEntry({ session, resumePath, landing, home, loading }: RootEntryProps): react.JSX.Element;
190
205
  interface RedirectIfAuthedProps {
191
- session: LandingSession;
206
+ /** `"loading"` while the app restores a session: neither the page nor a redirect. */
207
+ session: RoutingSession;
208
+ /** What shows while `session` is `"loading"`. Default: the kit's `LoadingState`. */
209
+ loading?: ReactNode;
192
210
  /**
193
211
  * Let a DEMO session through (§5.6): on `/login`, `/register` and the app's invitation
194
212
  * pages, so a demo visitor can sign in or accept an invitation — a successful one
@@ -213,6 +231,6 @@ interface RedirectIfAuthedProps {
213
231
  * `allowDemo` around `/login`, `/register` and the invitation pages, and one without
214
232
  * around `/demo` (and `/forgot-password`).
215
233
  */
216
- declare function RedirectIfAuthed({ session, allowDemo, fallback, children }: RedirectIfAuthedProps): react.JSX.Element;
234
+ declare function RedirectIfAuthed({ session, allowDemo, fallback, children, loading }: RedirectIfAuthedProps): react.JSX.Element;
217
235
 
218
- export { DEFAULT_LAST_VISITED_EXCLUDES, type LastVisitedPageOptions, NEXT_PARAM, type PathPattern, RedirectIfAuthed, type RedirectIfAuthedProps, RootEntry, type RootEntryProps, clearLastVisitedPage, readLastVisitedPage, safeNextPath, useLastVisitedPage };
236
+ export { DEFAULT_LAST_VISITED_EXCLUDES, type LastVisitedPageOptions, NEXT_PARAM, type PathPattern, RedirectIfAuthed, type RedirectIfAuthedProps, RootEntry, type RootEntryProps, type RoutingSession, clearLastVisitedPage, readLastVisitedPage, safeNextPath, useLastVisitedPage };
@@ -3,6 +3,7 @@ import { Fragment, jsx } from "react/jsx-runtime";
3
3
  import { useEffect } from "react";
4
4
  import { Navigate, Outlet, useLocation } from "react-router";
5
5
  import { readStored, writeStored } from "../lib/safe-storage.js";
6
+ import { LoadingState } from "../components/loading-state.js";
6
7
  const NEXT_PARAM = "next";
7
8
  function safeNextPath(raw) {
8
9
  if (!raw) return null;
@@ -55,13 +56,15 @@ function clearLastVisitedPage(key) {
55
56
  } catch {
56
57
  }
57
58
  }
58
- function RootEntry({ session, resumePath, landing, home }) {
59
+ function RootEntry({ session, resumePath, landing, home, loading }) {
60
+ if (session === "loading") return /* @__PURE__ */ jsx(Fragment, { children: loading ?? /* @__PURE__ */ jsx(LoadingState, {}) });
59
61
  if (session === "none") return /* @__PURE__ */ jsx(Fragment, { children: landing });
60
62
  const resume = safeNextPath(resumePath);
61
63
  return /* @__PURE__ */ jsx(Navigate, { to: resume && resume !== "/" ? resume : home, replace: true });
62
64
  }
63
- function RedirectIfAuthed({ session, allowDemo = false, fallback, children }) {
65
+ function RedirectIfAuthed({ session, allowDemo = false, fallback, children, loading }) {
64
66
  const { search } = useLocation();
67
+ if (session === "loading") return /* @__PURE__ */ jsx(Fragment, { children: loading ?? /* @__PURE__ */ jsx(LoadingState, {}) });
65
68
  if (session === "none" || session === "demo" && allowDemo) {
66
69
  return children === void 0 ? /* @__PURE__ */ jsx(Outlet, {}) : /* @__PURE__ */ jsx(Fragment, { children });
67
70
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/landing/routing.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Navigate, Outlet, useLocation } from \"react-router\";\n\nimport { readStored, writeStored } from \"../lib/safe-storage\";\nimport type { LandingSession } from \"./landing-actions\";\n\n/**\n * The public routes' logic (docs/landing-demo-harmonization.md §3): what `/` shows,\n * which pages a session skips, and the page a session resumes on — keksdose's\n * `RootEntry`, `RedirectIfAuthed` and use-last-visited-page.ts, for every app.\n * Router-aware (react-router), so they belong to the `./shell` entry.\n */\n\n/* ── ?next= ──────────────────────────────────────────────────────────────── */\n\n/** The query parameter that carries \"where I was actually trying to go\" through the\n * sign-in bounce (keksdose's `NEXT_PARAM`). */\nexport const NEXT_PARAM = \"next\";\n\n/**\n * A `?next=` value that is safe to navigate to, or null.\n *\n * Same-origin PATHS only, decided by the URL PARSER rather than by string prefix —\n * this is the open-redirect check, and it is the reason this lives in one place\n * instead of at each call site.\n *\n * The prefix version (\"starts with `/`, does not start with `//`\") let two shapes\n * through that the browser resolves cross-origin, because the WHATWG parser does not\n * read them as text: a backslash after the leading slash counts as a second slash for\n * a special scheme, so `/\\evil.example` resolves to `https://evil.example/`; and tab,\n * LF and CR are STRIPPED anywhere in the input before parsing, so `/<TAB>/evil.example`\n * becomes `//evil.example`. Asking the same parser the browser will use closes every\n * such shape at once, including ones nobody has thought of yet, and it normalises what\n * comes back instead of echoing the caller's spelling.\n *\n * keksdose's (shared/hooks/use-last-visited-page.ts), verbatim but for the fallback\n * origin.\n */\nexport function safeNextPath(raw: string | null | undefined): string | null {\n if (!raw) return null;\n const base = typeof window !== \"undefined\" ? window.location.origin : \"https://kit.invalid\";\n try {\n const url = new URL(raw, base);\n if (url.origin !== base) return null;\n return `${url.pathname}${url.search}${url.hash}`;\n } catch {\n return null;\n }\n}\n\n/* ── The last visited page (§3.2) ────────────────────────────────────────── */\n\n/** A path to leave out: a string is the path and everything under it (`/demo` is\n * `/demo` and `/demo/ended`; `/` is only `/`), a RegExp is tested on the pathname. */\nexport type PathPattern = string | RegExp;\n\n/**\n * The pages never recorded as a resume target (§3.2): the landing (`/`, `/welcome`), the\n * auth pages, the demo's own (`/demo*`) and the legal pages. The 404 has no path of its\n * own — call {@link useLastVisitedPage} inside the signed-in layout, as keksdose does,\n * and it never sees one. The app adds its own one-shot routes (keksdose:\n * `/banks/callback`, `/join`, `/share-target`) through `exclude`.\n */\nexport const DEFAULT_LAST_VISITED_EXCLUDES: readonly PathPattern[] = Object.freeze([\n \"/\",\n \"/welcome\",\n \"/login\",\n \"/register\",\n \"/forgot-password\",\n \"/reset-password\",\n \"/verify-email\",\n \"/demo\",\n \"/impressum\",\n \"/privacy\",\n \"/terms\",\n]);\n\nfunction matchesPath(pathname: string, pattern: PathPattern): boolean {\n if (typeof pattern !== \"string\") return new RegExp(pattern.source, pattern.flags.replace(\"g\", \"\")).test(pathname);\n if (pattern === \"/\") return pathname === \"/\";\n const base = pattern.endsWith(\"/\") ? pattern.slice(0, -1) : pattern;\n return pathname === base || pathname.startsWith(`${base}/`);\n}\n\n/** Whether `pathname` is one of the defaults or the app's `exclude`. */\nfunction isExcluded(pathname: string, exclude: readonly PathPattern[]): boolean {\n return [...DEFAULT_LAST_VISITED_EXCLUDES, ...exclude].some((pattern) => matchesPath(pathname, pattern));\n}\n\nexport interface LastVisitedPageOptions {\n /** The device key: `<app>.lastVisitedPage` (§3.2), one per app on the origin. */\n key: string;\n /** The app's own paths to leave out, ON TOP of {@link DEFAULT_LAST_VISITED_EXCLUDES}. */\n exclude?: readonly PathPattern[];\n /** `false` records nothing — while the session is still being restored, say. */\n enabled?: boolean;\n}\n\n/**\n * Remember the page a session is on (path and query), on every navigation, so `/` — a\n * revisit, a fresh sign-in, the installed PWA, whose `start_url` is `/` — resumes there\n * (§3.2, keksdose feedback #59). Device-local, in `localStorage` under `key`; a blocked\n * storage records nothing.\n *\n * Call it once in the signed-in layout. The excluded paths are never written, so a\n * one-shot page (a bank callback, an invitation link) never becomes the place the next\n * launch opens on.\n */\nexport function useLastVisitedPage({ key, exclude = [], enabled = true }: LastVisitedPageOptions): void {\n const { pathname, search } = useLocation();\n // Decided here, so the effect depends on the answer and not on an `exclude` array the\n // caller likely builds inline.\n const skip = !enabled || isExcluded(pathname, exclude);\n useEffect(() => {\n if (skip) return;\n writeStored(key, pathname + search);\n }, [key, pathname, search, skip]);\n}\n\n/**\n * The page {@link useLastVisitedPage} remembered under `key` — checked by\n * {@link safeNextPath}, so a value someone planted in storage cannot leave the origin —\n * or `fallback` (default `null`) when there is none or storage is blocked. A string\n * fallback narrows the answer to a string, for react-router's `to`.\n */\nexport function readLastVisitedPage(key: string, fallback: string): string;\nexport function readLastVisitedPage(key: string, fallback?: null): string | null;\nexport function readLastVisitedPage(key: string, fallback: string | null = null): string | null {\n return safeNextPath(readStored(key)) ?? fallback;\n}\n\n/** Forget the remembered page — on an explicit sign-out, so the next account does not\n * resume on the previous one's page. */\nexport function clearLastVisitedPage(key: string): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.removeItem(key);\n } catch {\n // storage blocked: there is nothing to forget\n }\n}\n\n/* ── RootEntry ───────────────────────────────────────────────────────────── */\n\nexport interface RootEntryProps {\n /** Without a session `/` is the landing; with one (real or demo) it resumes. */\n session: LandingSession;\n /** The remembered page — `readLastVisitedPage(key)`. */\n resumePath?: string | null;\n /** The landing page element. */\n landing: ReactNode;\n /** The app's home: where a session goes with nothing to resume (keksdose `/budget`,\n * kastlan and Kurvenschmiede `/dashboard`). */\n home: string;\n}\n\n/**\n * The `/` route (§3.1): the landing for a visitor, and for a session — real or demo —\n * the last visited page, else the app's home. Indexed and canonical `/` for the visitor;\n * a crawler never has a session, so for it `/` is stable.\n *\n * keksdose showed a session with nothing remembered the landing; the contract sends it\n * home instead, because a session at `/` came to use the app. The landing stays one tap\n * away at `/welcome`, where the signed-in brand link points.\n */\nexport function RootEntry({ session, resumePath, landing, home }: RootEntryProps) {\n if (session === \"none\") return <>{landing}</>;\n const resume = safeNextPath(resumePath);\n return <Navigate to={resume && resume !== \"/\" ? resume : home} replace />;\n}\n\n/* ── RedirectIfAuthed ────────────────────────────────────────────────────── */\n\nexport interface RedirectIfAuthedProps {\n session: LandingSession;\n /**\n * Let a DEMO session through (§5.6): on `/login`, `/register` and the app's invitation\n * pages, so a demo visitor can sign in or accept an invitation — a successful one\n * replaces the demo session. Default `false`: on `/demo` a live demo continues instead\n * of starting a second one (§5.2), and on `/forgot-password` a demo has no password.\n */\n allowDemo?: boolean;\n /** Where a redirected session goes: the resume target —\n * `readLastVisitedPage(key, home)`. A safe `?next=` goes first. */\n fallback: string;\n /** The page. Left out, an `<Outlet />`: the component is a layout route around the\n * public pages, as in keksdose. */\n children?: ReactNode;\n}\n\n/**\n * Public pages a session skips (§3.1): a signed-in visitor at `/login` goes back into\n * the app, to a safe `?next=` when the URL carries one (a share invitation or a push\n * deep link opened with a live session in another tab — keksdose) and else to\n * `fallback`.\n *\n * A demo session passes where `allowDemo` says so (§5.6). Mount one wrapper with\n * `allowDemo` around `/login`, `/register` and the invitation pages, and one without\n * around `/demo` (and `/forgot-password`).\n */\nexport function RedirectIfAuthed({ session, allowDemo = false, fallback, children }: RedirectIfAuthedProps) {\n const { search } = useLocation();\n if (session === \"none\" || (session === \"demo\" && allowDemo)) {\n return children === undefined ? <Outlet /> : <>{children}</>;\n }\n const next = safeNextPath(new URLSearchParams(search).get(NEXT_PARAM));\n return <Navigate to={next ?? fallback} replace />;\n}\n"],"mappings":";AAuKiC;AAvKjC,SAAS,iBAAiB;AAE1B,SAAS,UAAU,QAAQ,mBAAmB;AAE9C,SAAS,YAAY,mBAAmB;AAcjC,MAAM,aAAa;AAqBnB,SAAS,aAAa,KAA+C;AAC1E,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,OAAO,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AACtE,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK,IAAI;AAC7B,QAAI,IAAI,WAAW,KAAM,QAAO;AAChC,WAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeO,MAAM,gCAAwD,OAAO,OAAO;AAAA,EACjF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,YAAY,UAAkB,SAA+B;AACpE,MAAI,OAAO,YAAY,SAAU,QAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC,EAAE,KAAK,QAAQ;AAChH,MAAI,YAAY,IAAK,QAAO,aAAa;AACzC,QAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC5D,SAAO,aAAa,QAAQ,SAAS,WAAW,GAAG,IAAI,GAAG;AAC5D;AAGA,SAAS,WAAW,UAAkB,SAA0C;AAC9E,SAAO,CAAC,GAAG,+BAA+B,GAAG,OAAO,EAAE,KAAK,CAAC,YAAY,YAAY,UAAU,OAAO,CAAC;AACxG;AAqBO,SAAS,mBAAmB,EAAE,KAAK,UAAU,CAAC,GAAG,UAAU,KAAK,GAAiC;AACtG,QAAM,EAAE,UAAU,OAAO,IAAI,YAAY;AAGzC,QAAM,OAAO,CAAC,WAAW,WAAW,UAAU,OAAO;AACrD,YAAU,MAAM;AACd,QAAI,KAAM;AACV,gBAAY,KAAK,WAAW,MAAM;AAAA,EACpC,GAAG,CAAC,KAAK,UAAU,QAAQ,IAAI,CAAC;AAClC;AAUO,SAAS,oBAAoB,KAAa,WAA0B,MAAqB;AAC9F,SAAO,aAAa,WAAW,GAAG,CAAC,KAAK;AAC1C;AAIO,SAAS,qBAAqB,KAAmB;AACtD,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI;AACF,WAAO,aAAa,WAAW,GAAG;AAAA,EACpC,QAAQ;AAAA,EAER;AACF;AAyBO,SAAS,UAAU,EAAE,SAAS,YAAY,SAAS,KAAK,GAAmB;AAChF,MAAI,YAAY,OAAQ,QAAO,gCAAG,mBAAQ;AAC1C,QAAM,SAAS,aAAa,UAAU;AACtC,SAAO,oBAAC,YAAS,IAAI,UAAU,WAAW,MAAM,SAAS,MAAM,SAAO,MAAC;AACzE;AA+BO,SAAS,iBAAiB,EAAE,SAAS,YAAY,OAAO,UAAU,SAAS,GAA0B;AAC1G,QAAM,EAAE,OAAO,IAAI,YAAY;AAC/B,MAAI,YAAY,UAAW,YAAY,UAAU,WAAY;AAC3D,WAAO,aAAa,SAAY,oBAAC,UAAO,IAAK,gCAAG,UAAS;AAAA,EAC3D;AACA,QAAM,OAAO,aAAa,IAAI,gBAAgB,MAAM,EAAE,IAAI,UAAU,CAAC;AACrE,SAAO,oBAAC,YAAS,IAAI,QAAQ,UAAU,SAAO,MAAC;AACjD;","names":[]}
1
+ {"version":3,"sources":["../../src/landing/routing.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Navigate, Outlet, useLocation } from \"react-router\";\n\nimport { readStored, writeStored } from \"../lib/safe-storage\";\nimport type { LandingSession } from \"./landing-actions\";\nimport { LoadingState } from \"../components/loading-state\";\n\n/**\n * 0.31.1: a session that is still being restored — an app whose access token lives in\n * memory reads it back from its refresh token first (kastlan's 0.31 adoption). Until\n * then `/` neither shows the landing nor resumes, and a public page neither shows nor\n * redirects: both render `loading` instead.\n */\nexport type RoutingSession = LandingSession | \"loading\";\n\n/**\n * The public routes' logic (docs/landing-demo-harmonization.md §3): what `/` shows,\n * which pages a session skips, and the page a session resumes on — keksdose's\n * `RootEntry`, `RedirectIfAuthed` and use-last-visited-page.ts, for every app.\n * Router-aware (react-router), so they belong to the `./shell` entry.\n */\n\n/* ── ?next= ──────────────────────────────────────────────────────────────── */\n\n/** The query parameter that carries \"where I was actually trying to go\" through the\n * sign-in bounce (keksdose's `NEXT_PARAM`). */\nexport const NEXT_PARAM = \"next\";\n\n/**\n * A `?next=` value that is safe to navigate to, or null.\n *\n * Same-origin PATHS only, decided by the URL PARSER rather than by string prefix —\n * this is the open-redirect check, and it is the reason this lives in one place\n * instead of at each call site.\n *\n * The prefix version (\"starts with `/`, does not start with `//`\") let two shapes\n * through that the browser resolves cross-origin, because the WHATWG parser does not\n * read them as text: a backslash after the leading slash counts as a second slash for\n * a special scheme, so `/\\evil.example` resolves to `https://evil.example/`; and tab,\n * LF and CR are STRIPPED anywhere in the input before parsing, so `/<TAB>/evil.example`\n * becomes `//evil.example`. Asking the same parser the browser will use closes every\n * such shape at once, including ones nobody has thought of yet, and it normalises what\n * comes back instead of echoing the caller's spelling.\n *\n * keksdose's (shared/hooks/use-last-visited-page.ts), verbatim but for the fallback\n * origin.\n */\nexport function safeNextPath(raw: string | null | undefined): string | null {\n if (!raw) return null;\n const base = typeof window !== \"undefined\" ? window.location.origin : \"https://kit.invalid\";\n try {\n const url = new URL(raw, base);\n if (url.origin !== base) return null;\n return `${url.pathname}${url.search}${url.hash}`;\n } catch {\n return null;\n }\n}\n\n/* ── The last visited page (§3.2) ────────────────────────────────────────── */\n\n/** A path to leave out: a string is the path and everything under it (`/demo` is\n * `/demo` and `/demo/ended`; `/` is only `/`), a RegExp is tested on the pathname. */\nexport type PathPattern = string | RegExp;\n\n/**\n * The pages never recorded as a resume target (§3.2): the landing (`/`, `/welcome`), the\n * auth pages, the demo's own (`/demo*`) and the legal pages. The 404 has no path of its\n * own — call {@link useLastVisitedPage} inside the signed-in layout, as keksdose does,\n * and it never sees one. The app adds its own one-shot routes (keksdose:\n * `/banks/callback`, `/join`, `/share-target`) through `exclude`.\n */\nexport const DEFAULT_LAST_VISITED_EXCLUDES: readonly PathPattern[] = Object.freeze([\n \"/\",\n \"/welcome\",\n \"/login\",\n \"/register\",\n \"/forgot-password\",\n \"/reset-password\",\n \"/verify-email\",\n \"/demo\",\n \"/impressum\",\n \"/privacy\",\n \"/terms\",\n]);\n\nfunction matchesPath(pathname: string, pattern: PathPattern): boolean {\n if (typeof pattern !== \"string\") return new RegExp(pattern.source, pattern.flags.replace(\"g\", \"\")).test(pathname);\n if (pattern === \"/\") return pathname === \"/\";\n const base = pattern.endsWith(\"/\") ? pattern.slice(0, -1) : pattern;\n return pathname === base || pathname.startsWith(`${base}/`);\n}\n\n/** Whether `pathname` is one of the defaults or the app's `exclude`. */\nfunction isExcluded(pathname: string, exclude: readonly PathPattern[]): boolean {\n return [...DEFAULT_LAST_VISITED_EXCLUDES, ...exclude].some((pattern) => matchesPath(pathname, pattern));\n}\n\nexport interface LastVisitedPageOptions {\n /** The device key: `<app>.lastVisitedPage` (§3.2), one per app on the origin. */\n key: string;\n /** The app's own paths to leave out, ON TOP of {@link DEFAULT_LAST_VISITED_EXCLUDES}. */\n exclude?: readonly PathPattern[];\n /** `false` records nothing — while the session is still being restored, say. */\n enabled?: boolean;\n}\n\n/**\n * Remember the page a session is on (path and query), on every navigation, so `/` — a\n * revisit, a fresh sign-in, the installed PWA, whose `start_url` is `/` — resumes there\n * (§3.2, keksdose feedback #59). Device-local, in `localStorage` under `key`; a blocked\n * storage records nothing.\n *\n * Call it once in the signed-in layout. The excluded paths are never written, so a\n * one-shot page (a bank callback, an invitation link) never becomes the place the next\n * launch opens on.\n */\nexport function useLastVisitedPage({ key, exclude = [], enabled = true }: LastVisitedPageOptions): void {\n const { pathname, search } = useLocation();\n // Decided here, so the effect depends on the answer and not on an `exclude` array the\n // caller likely builds inline.\n const skip = !enabled || isExcluded(pathname, exclude);\n useEffect(() => {\n if (skip) return;\n writeStored(key, pathname + search);\n }, [key, pathname, search, skip]);\n}\n\n/**\n * The page {@link useLastVisitedPage} remembered under `key` — checked by\n * {@link safeNextPath}, so a value someone planted in storage cannot leave the origin —\n * or `fallback` (default `null`) when there is none or storage is blocked. A string\n * fallback narrows the answer to a string, for react-router's `to`.\n */\nexport function readLastVisitedPage(key: string, fallback: string): string;\nexport function readLastVisitedPage(key: string, fallback?: null): string | null;\nexport function readLastVisitedPage(key: string, fallback: string | null = null): string | null {\n return safeNextPath(readStored(key)) ?? fallback;\n}\n\n/** Forget the remembered page — on an explicit sign-out, so the next account does not\n * resume on the previous one's page. */\nexport function clearLastVisitedPage(key: string): void {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.removeItem(key);\n } catch {\n // storage blocked: there is nothing to forget\n }\n}\n\n/* ── RootEntry ───────────────────────────────────────────────────────────── */\n\nexport interface RootEntryProps {\n /** Without a session `/` is the landing; with one (real or demo) it resumes;\n * `\"loading\"` while the app restores one. */\n session: RoutingSession;\n /** What shows while `session` is `\"loading\"`. Default: the kit's `LoadingState`. */\n loading?: ReactNode;\n /** The remembered page — `readLastVisitedPage(key)`. */\n resumePath?: string | null;\n /** The landing page element. */\n landing: ReactNode;\n /** The app's home: where a session goes with nothing to resume (keksdose `/budget`,\n * kastlan and Kurvenschmiede `/dashboard`). */\n home: string;\n}\n\n/**\n * The `/` route (§3.1): the landing for a visitor, and for a session — real or demo —\n * the last visited page, else the app's home. Indexed and canonical `/` for the visitor;\n * a crawler never has a session, so for it `/` is stable.\n *\n * keksdose showed a session with nothing remembered the landing; the contract sends it\n * home instead, because a session at `/` came to use the app. The landing stays one tap\n * away at `/welcome`, where the signed-in brand link points.\n */\nexport function RootEntry({ session, resumePath, landing, home, loading }: RootEntryProps) {\n if (session === \"loading\") return <>{loading ?? <LoadingState />}</>;\n if (session === \"none\") return <>{landing}</>;\n const resume = safeNextPath(resumePath);\n return <Navigate to={resume && resume !== \"/\" ? resume : home} replace />;\n}\n\n/* ── RedirectIfAuthed ────────────────────────────────────────────────────── */\n\nexport interface RedirectIfAuthedProps {\n /** `\"loading\"` while the app restores a session: neither the page nor a redirect. */\n session: RoutingSession;\n /** What shows while `session` is `\"loading\"`. Default: the kit's `LoadingState`. */\n loading?: ReactNode;\n /**\n * Let a DEMO session through (§5.6): on `/login`, `/register` and the app's invitation\n * pages, so a demo visitor can sign in or accept an invitation — a successful one\n * replaces the demo session. Default `false`: on `/demo` a live demo continues instead\n * of starting a second one (§5.2), and on `/forgot-password` a demo has no password.\n */\n allowDemo?: boolean;\n /** Where a redirected session goes: the resume target —\n * `readLastVisitedPage(key, home)`. A safe `?next=` goes first. */\n fallback: string;\n /** The page. Left out, an `<Outlet />`: the component is a layout route around the\n * public pages, as in keksdose. */\n children?: ReactNode;\n}\n\n/**\n * Public pages a session skips (§3.1): a signed-in visitor at `/login` goes back into\n * the app, to a safe `?next=` when the URL carries one (a share invitation or a push\n * deep link opened with a live session in another tab — keksdose) and else to\n * `fallback`.\n *\n * A demo session passes where `allowDemo` says so (§5.6). Mount one wrapper with\n * `allowDemo` around `/login`, `/register` and the invitation pages, and one without\n * around `/demo` (and `/forgot-password`).\n */\nexport function RedirectIfAuthed({ session, allowDemo = false, fallback, children, loading }: RedirectIfAuthedProps) {\n const { search } = useLocation();\n if (session === \"loading\") return <>{loading ?? <LoadingState />}</>;\n if (session === \"none\" || (session === \"demo\" && allowDemo)) {\n return children === undefined ? <Outlet /> : <>{children}</>;\n }\n const next = safeNextPath(new URLSearchParams(search).get(NEXT_PARAM));\n return <Navigate to={next ?? fallback} replace />;\n}\n"],"mappings":";AAmLoC,mBAAc,WAAd;AAnLpC,SAAS,iBAAiB;AAE1B,SAAS,UAAU,QAAQ,mBAAmB;AAE9C,SAAS,YAAY,mBAAmB;AAExC,SAAS,oBAAoB;AAqBtB,MAAM,aAAa;AAqBnB,SAAS,aAAa,KAA+C;AAC1E,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,OAAO,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AACtE,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK,IAAI;AAC7B,QAAI,IAAI,WAAW,KAAM,QAAO;AAChC,WAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeO,MAAM,gCAAwD,OAAO,OAAO;AAAA,EACjF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,YAAY,UAAkB,SAA+B;AACpE,MAAI,OAAO,YAAY,SAAU,QAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC,EAAE,KAAK,QAAQ;AAChH,MAAI,YAAY,IAAK,QAAO,aAAa;AACzC,QAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC5D,SAAO,aAAa,QAAQ,SAAS,WAAW,GAAG,IAAI,GAAG;AAC5D;AAGA,SAAS,WAAW,UAAkB,SAA0C;AAC9E,SAAO,CAAC,GAAG,+BAA+B,GAAG,OAAO,EAAE,KAAK,CAAC,YAAY,YAAY,UAAU,OAAO,CAAC;AACxG;AAqBO,SAAS,mBAAmB,EAAE,KAAK,UAAU,CAAC,GAAG,UAAU,KAAK,GAAiC;AACtG,QAAM,EAAE,UAAU,OAAO,IAAI,YAAY;AAGzC,QAAM,OAAO,CAAC,WAAW,WAAW,UAAU,OAAO;AACrD,YAAU,MAAM;AACd,QAAI,KAAM;AACV,gBAAY,KAAK,WAAW,MAAM;AAAA,EACpC,GAAG,CAAC,KAAK,UAAU,QAAQ,IAAI,CAAC;AAClC;AAUO,SAAS,oBAAoB,KAAa,WAA0B,MAAqB;AAC9F,SAAO,aAAa,WAAW,GAAG,CAAC,KAAK;AAC1C;AAIO,SAAS,qBAAqB,KAAmB;AACtD,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI;AACF,WAAO,aAAa,WAAW,GAAG;AAAA,EACpC,QAAQ;AAAA,EAER;AACF;AA4BO,SAAS,UAAU,EAAE,SAAS,YAAY,SAAS,MAAM,QAAQ,GAAmB;AACzF,MAAI,YAAY,UAAW,QAAO,gCAAG,qBAAW,oBAAC,gBAAa,GAAG;AACjE,MAAI,YAAY,OAAQ,QAAO,gCAAG,mBAAQ;AAC1C,QAAM,SAAS,aAAa,UAAU;AACtC,SAAO,oBAAC,YAAS,IAAI,UAAU,WAAW,MAAM,SAAS,MAAM,SAAO,MAAC;AACzE;AAkCO,SAAS,iBAAiB,EAAE,SAAS,YAAY,OAAO,UAAU,UAAU,QAAQ,GAA0B;AACnH,QAAM,EAAE,OAAO,IAAI,YAAY;AAC/B,MAAI,YAAY,UAAW,QAAO,gCAAG,qBAAW,oBAAC,gBAAa,GAAG;AACjE,MAAI,YAAY,UAAW,YAAY,UAAU,WAAY;AAC3D,WAAO,aAAa,SAAY,oBAAC,UAAO,IAAK,gCAAG,UAAS;AAAA,EAC3D;AACA,QAAM,OAAO,aAAa,IAAI,gBAAgB,MAAM,EAAE,IAAI,UAAU,CAAC;AACrE,SAAO,oBAAC,YAAS,IAAI,QAAQ,UAAU,SAAO,MAAC;AACjD;","names":[]}
package/dist/lib/cn.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
  import { clsx } from "clsx";
3
- import { twMerge } from "tailwind-merge";
4
- const cn = (...inputs) => twMerge(clsx(inputs));
3
+ import { extendTailwindMerge } from "tailwind-merge";
4
+ const merge = extendTailwindMerge({ extend: { theme: { text: ["micro", "caption"] } } });
5
+ const cn = (...inputs) => merge(clsx(inputs));
5
6
  export {
6
7
  cn
7
8
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Merge class lists with Tailwind conflict resolution (later wins). */\nexport const cn = (...inputs: Parameters<typeof clsx>) => twMerge(clsx(inputs));\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,eAAe;AAGjB,MAAM,KAAK,IAAI,WAAoC,QAAQ,KAAK,MAAM,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * tailwind-merge, told about the kit's own font sizes (docs/text-size-harmonization.md\n * §3.2): `text-micro` and `text-caption` are `@theme` sizes in tokens.css, which\n * tailwind-merge cannot see. Unknown, a `text-<word>` is taken for a COLOUR, so\n * `cn(\"text-caption text-[var(--text-muted)]\")` dropped the size — the later colour\n * \"won\" over it — and `cn(\"text-xs\", \"text-caption\")` kept both sizes. Registered as\n * sizes, they merge like `text-xs`: a later size replaces an earlier one, a colour sits\n * beside them.\n */\nconst merge = extendTailwindMerge({ extend: { theme: { text: [\"micro\", \"caption\"] } } });\n\n/** Merge class lists with Tailwind conflict resolution (later wins). */\nexport const cn = (...inputs: Parameters<typeof clsx>) => merge(clsx(inputs));\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,2BAA2B;AAWpC,MAAM,QAAQ,oBAAoB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,SAAS,EAAE,EAAE,EAAE,CAAC;AAGhF,MAAM,KAAK,IAAI,WAAoC,MAAM,KAAK,MAAM,CAAC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { FieldValues, FieldPath, ControllerProps, ControllerRenderProps, ControllerFieldState } from 'react-hook-form';
4
- import { dt as IbanInputProps, eg as PhoneInputProps, eD as SelectProps, dD as InputProps, eY as TextareaProps } from '../delete-account-setting-DCFS5Vof.js';
4
+ import { dE as IbanInputProps, es as PhoneInputProps, eY as SelectProps, dO as InputProps, fj as TextareaProps } from '../delete-account-setting-BvdQdbv3.js';
5
5
  import { NumberFieldProps } from '../components/number-field.js';
6
6
  import { DatePickerProps, DateRangePickerProps } from '../components/date-picker.js';
7
7
  import { TimeInputProps } from '../components/time-input.js';
@@ -15,14 +15,16 @@ import { ComboClearValue } from '../components/combobox-core.js';
15
15
  import '../components/tooltip.js';
16
16
  import '../hooks/use-anchored-rect.js';
17
17
  import '../lib/clipping.js';
18
- import '../data-table-labels-DUELeXpa.js';
18
+ import '../data-table-labels-kpAAVi6g.js';
19
19
  import '../components/data-table-sort.js';
20
20
  import '../components/swipeable-row.js';
21
21
  import '../components/mini-calendar.js';
22
22
  import '../components/calendar-heatmap.js';
23
23
  import '../components/popover.js';
24
+ import '../hooks/use-breakpoint.js';
24
25
  import '../components/chip.js';
25
26
  import 'lucide-react';
27
+ import '../components/field-parts.js';
26
28
  import '../components/field-sync.js';
27
29
  import '../wizard/types.js';
28
30
  import '../tour/tour.js';
@@ -90,6 +92,9 @@ import '../admin/admin-parts.js';
90
92
  import '../admin/admin-action-log.js';
91
93
  import '../settings/settings-labels.js';
92
94
  import '../demo/demo-labels.js';
95
+ import '../components/appearance-labels.js';
96
+ import '../theme/contrast.js';
97
+ import '../theme/text-size.js';
93
98
  import '../components/reauth-dialog.js';
94
99
  import '../components/server-wake.js';
95
100
  import '../lib/server-wake.js';
@@ -102,7 +107,7 @@ import '../components/sign-chip.js';
102
107
  import '../components/column-mapper.js';
103
108
  import '../lib/column-mapping.js';
104
109
  import '../lib/table-text.js';
105
- import '../components/field-parts.js';
110
+ import '../components/focus-ring.js';
106
111
  import '../components/number-input.js';
107
112
  import '../components/calculator.js';
108
113
  import '../components/numpad-sheet.js';
@@ -519,7 +519,7 @@ function RangeBody({
519
519
  {
520
520
  id: messageIds[i],
521
521
  "data-slot": "form-message",
522
- className: "text-[11px] leading-tight text-[var(--danger)]",
522
+ className: "text-caption leading-tight text-[var(--danger)]",
523
523
  children: message
524
524
  },
525
525
  message