@eifi1/ui-kit 0.32.2 → 0.33.1

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 (400) hide show
  1. package/README.md +17 -9
  2. package/dist/account/delete-account-setting.d.ts +11 -10
  3. package/dist/account/delete-account-setting.js +2 -1
  4. package/dist/account/delete-account-setting.js.map +1 -1
  5. package/dist/account/email-change-setting.d.ts +5 -0
  6. package/dist/account/email-change-setting.js +4 -3
  7. package/dist/account/email-change-setting.js.map +1 -1
  8. package/dist/account/sessions-setting.d.ts +4 -0
  9. package/dist/account/sessions-setting.js +3 -2
  10. package/dist/account/sessions-setting.js.map +1 -1
  11. package/dist/admin/admin-action-confirm.d.ts +11 -10
  12. package/dist/admin/admin-action-confirm.js.map +1 -1
  13. package/dist/admin/invitations-panel.d.ts +11 -10
  14. package/dist/admin/invitations-panel.js +4 -3
  15. package/dist/admin/invitations-panel.js.map +1 -1
  16. package/dist/admin/plan-change.d.ts +101 -0
  17. package/dist/admin/plan-change.js +210 -0
  18. package/dist/admin/plan-change.js.map +1 -0
  19. package/dist/admin/reviewer-scope-editor.d.ts +11 -10
  20. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  21. package/dist/admin/role-select.d.ts +8 -7
  22. package/dist/admin/role-select.js.map +1 -1
  23. package/dist/admin/transfer-ownership-dialog.d.ts +11 -10
  24. package/dist/admin/user-roster.d.ts +8 -7
  25. package/dist/admin/user-roster.js +2 -2
  26. package/dist/admin/user-roster.js.map +1 -1
  27. package/dist/auth/auth-errors.d.ts +13 -2
  28. package/dist/auth/auth-errors.js +5 -1
  29. package/dist/auth/auth-errors.js.map +1 -1
  30. package/dist/auth/complete-name-dialog.d.ts +4 -1
  31. package/dist/auth/complete-name-dialog.js +2 -1
  32. package/dist/auth/complete-name-dialog.js.map +1 -1
  33. package/dist/auth/register-form.d.ts +11 -10
  34. package/dist/billing/billing-banner.d.ts +14 -11
  35. package/dist/billing/billing-banner.js.map +1 -1
  36. package/dist/billing/billing-labels.d.ts +11 -10
  37. package/dist/billing/billing-labels.js +10 -1
  38. package/dist/billing/billing-labels.js.map +1 -1
  39. package/dist/billing/billing-lock.d.ts +40 -12
  40. package/dist/billing/billing-lock.js +9 -3
  41. package/dist/billing/billing-lock.js.map +1 -1
  42. package/dist/billing/billing-overview.d.ts +155 -0
  43. package/dist/billing/billing-overview.js +2 -0
  44. package/dist/billing/billing-overview.js.map +1 -0
  45. package/dist/billing/billing-standing.d.ts +11 -10
  46. package/dist/billing/checkout-processing.d.ts +218 -0
  47. package/dist/billing/checkout-processing.js +198 -0
  48. package/dist/billing/checkout-processing.js.map +1 -0
  49. package/dist/billing/checkout-return.d.ts +51 -0
  50. package/dist/billing/checkout-return.js +43 -0
  51. package/dist/billing/checkout-return.js.map +1 -0
  52. package/dist/billing/pay-page.d.ts +215 -0
  53. package/dist/billing/pay-page.js +113 -0
  54. package/dist/billing/pay-page.js.map +1 -0
  55. package/dist/billing/plan-card.d.ts +11 -10
  56. package/dist/billing/plan-limit-notice.d.ts +11 -10
  57. package/dist/billing/plan-limit-toast.d.ts +144 -0
  58. package/dist/billing/plan-limit-toast.js +40 -0
  59. package/dist/billing/plan-limit-toast.js.map +1 -0
  60. package/dist/billing/subscription-actions.d.ts +39 -15
  61. package/dist/billing/subscription-actions.js +9 -2
  62. package/dist/billing/subscription-actions.js.map +1 -1
  63. package/dist/billing/subscription-status-chip.d.ts +10 -9
  64. package/dist/bin/eifi1-pay-page.mjs +166 -0
  65. package/dist/chart.d.ts +11 -10
  66. package/dist/components/account-chips.d.ts +6 -1
  67. package/dist/components/account-settings.d.ts +4 -1
  68. package/dist/components/account-settings.js +2 -1
  69. package/dist/components/account-settings.js.map +1 -1
  70. package/dist/components/amount-input.d.ts +11 -10
  71. package/dist/components/autocomplete.d.ts +2 -1
  72. package/dist/components/autocomplete.js +5 -3
  73. package/dist/components/autocomplete.js.map +1 -1
  74. package/dist/components/button-group.d.ts +11 -10
  75. package/dist/components/button-group.js +1 -1
  76. package/dist/components/button-group.js.map +1 -1
  77. package/dist/components/calculator.d.ts +11 -10
  78. package/dist/components/calculator.js +3 -3
  79. package/dist/components/calculator.js.map +1 -1
  80. package/dist/components/checkbox-group.d.ts +2 -1
  81. package/dist/components/checkbox-group.js.map +1 -1
  82. package/dist/components/checkbox.d.ts +2 -1
  83. package/dist/components/checkbox.js.map +1 -1
  84. package/dist/components/chip.d.ts +2 -1
  85. package/dist/components/chip.js +19 -17
  86. package/dist/components/chip.js.map +1 -1
  87. package/dist/components/choice-card.d.ts +3 -1
  88. package/dist/components/choice-card.js +1 -1
  89. package/dist/components/choice-card.js.map +1 -1
  90. package/dist/components/combobox-core.js +2 -1
  91. package/dist/components/combobox-core.js.map +1 -1
  92. package/dist/components/combobox.d.ts +4 -3
  93. package/dist/components/combobox.js +2 -2
  94. package/dist/components/combobox.js.map +1 -1
  95. package/dist/components/confirm-dialog.d.ts +11 -10
  96. package/dist/components/confirm-dialog.js +6 -3
  97. package/dist/components/confirm-dialog.js.map +1 -1
  98. package/dist/components/copy-button.d.ts +12 -11
  99. package/dist/components/country-select.d.ts +2 -1
  100. package/dist/components/country-select.js.map +1 -1
  101. package/dist/components/danger-confirm.d.ts +11 -10
  102. package/dist/components/danger-confirm.js.map +1 -1
  103. package/dist/components/data-table-cells.d.ts +12 -1
  104. package/dist/components/data-table-filter-popover.d.ts +12 -1
  105. package/dist/components/data-table-filters.d.ts +12 -1
  106. package/dist/components/data-table-labels.d.ts +12 -1
  107. package/dist/components/data-table-pagination.d.ts +12 -1
  108. package/dist/components/data-table.d.ts +12 -1
  109. package/dist/components/data-table.js +3 -3
  110. package/dist/components/data-table.js.map +1 -1
  111. package/dist/components/date-picker.js +6 -4
  112. package/dist/components/date-picker.js.map +1 -1
  113. package/dist/components/dropdown.js +9 -1
  114. package/dist/components/dropdown.js.map +1 -1
  115. package/dist/components/entity-combobox.d.ts +3 -2
  116. package/dist/components/entity-combobox.js.map +1 -1
  117. package/dist/components/facing-pair.d.ts +11 -10
  118. package/dist/components/field-parts.d.ts +32 -4
  119. package/dist/components/field-parts.js +54 -19
  120. package/dist/components/field-parts.js.map +1 -1
  121. package/dist/components/file-button.d.ts +11 -10
  122. package/dist/components/file-button.js +3 -2
  123. package/dist/components/file-button.js.map +1 -1
  124. package/dist/components/file-dropzone.d.ts +12 -11
  125. package/dist/components/file-dropzone.js.map +1 -1
  126. package/dist/components/floating-panel.js +5 -5
  127. package/dist/components/floating-panel.js.map +1 -1
  128. package/dist/components/form-actions.d.ts +10 -9
  129. package/dist/components/form-actions.js +3 -3
  130. package/dist/components/form-actions.js.map +1 -1
  131. package/dist/components/full-bleed-dialog.js.map +1 -1
  132. package/dist/components/iban-input.d.ts +11 -10
  133. package/dist/components/inline-edit-field.d.ts +2 -1
  134. package/dist/components/inline-edit-field.js +6 -6
  135. package/dist/components/inline-edit-field.js.map +1 -1
  136. package/dist/components/language-select.d.ts +11 -10
  137. package/dist/components/legal-page.d.ts +11 -10
  138. package/dist/components/legal.d.ts +11 -10
  139. package/dist/components/list.d.ts +2 -1
  140. package/dist/components/list.js +4 -5
  141. package/dist/components/list.js.map +1 -1
  142. package/dist/components/modal.js.map +1 -1
  143. package/dist/components/money-field.d.ts +11 -10
  144. package/dist/components/month-picker.js +54 -44
  145. package/dist/components/month-picker.js.map +1 -1
  146. package/dist/components/multi-entity-combobox.d.ts +3 -2
  147. package/dist/components/multi-entity-combobox.js.map +1 -1
  148. package/dist/components/number-field.d.ts +18 -10
  149. package/dist/components/number-field.js.map +1 -1
  150. package/dist/components/number-input.d.ts +37 -10
  151. package/dist/components/number-input.js +27 -12
  152. package/dist/components/number-input.js.map +1 -1
  153. package/dist/components/numpad-sheet.d.ts +11 -10
  154. package/dist/components/numpad-sheet.js +2 -2
  155. package/dist/components/numpad-sheet.js.map +1 -1
  156. package/dist/components/phone-input.d.ts +11 -10
  157. package/dist/components/popover.js +6 -2
  158. package/dist/components/popover.js.map +1 -1
  159. package/dist/components/row-actions.d.ts +6 -5
  160. package/dist/components/row-actions.js +130 -32
  161. package/dist/components/row-actions.js.map +1 -1
  162. package/dist/components/series-chart.d.ts +11 -10
  163. package/dist/components/settings-fields.d.ts +11 -10
  164. package/dist/components/share-card.d.ts +8 -7
  165. package/dist/components/share-card.js +26 -10
  166. package/dist/components/share-card.js.map +1 -1
  167. package/dist/components/skeleton.d.ts +10 -2
  168. package/dist/components/skeleton.js.map +1 -1
  169. package/dist/components/status-dot.d.ts +1 -0
  170. package/dist/components/status-dot.js +2 -2
  171. package/dist/components/status-dot.js.map +1 -1
  172. package/dist/components/swatch-picker.d.ts +2 -1
  173. package/dist/components/swatch-picker.js.map +1 -1
  174. package/dist/components/swipeable-row.d.ts +88 -17
  175. package/dist/components/swipeable-row.js +46 -9
  176. package/dist/components/swipeable-row.js.map +1 -1
  177. package/dist/components/switch.d.ts +2 -1
  178. package/dist/components/switch.js.map +1 -1
  179. package/dist/components/table.d.ts +2 -1
  180. package/dist/components/table.js +6 -0
  181. package/dist/components/table.js.map +1 -1
  182. package/dist/components/text-link.d.ts +10 -9
  183. package/dist/components/time-input.d.ts +11 -10
  184. package/dist/components/toggle-group.d.ts +2 -1
  185. package/dist/components/toggle-group.js +1 -1
  186. package/dist/components/toggle-group.js.map +1 -1
  187. package/dist/components/translation-review-editor.d.ts +4 -0
  188. package/dist/components/translation-review-editor.js +4 -3
  189. package/dist/components/translation-review-editor.js.map +1 -1
  190. package/dist/components/translation-review-parts.d.ts +1 -0
  191. package/dist/components/translation-review.d.ts +1 -0
  192. package/dist/components/translation-review.js +15 -18
  193. package/dist/components/translation-review.js.map +1 -1
  194. package/dist/components/ui.d.ts +10 -9
  195. package/dist/components/ui.js +47 -27
  196. package/dist/components/ui.js.map +1 -1
  197. package/dist/components/use-table-state.d.ts +12 -1
  198. package/dist/components/user-avatar.d.ts +1 -0
  199. package/dist/components/write-lock.d.ts +101 -13
  200. package/dist/components/write-lock.js +37 -13
  201. package/dist/components/write-lock.js.map +1 -1
  202. package/dist/{data-table-labels-kpAAVi6g.d.ts → data-table-labels-BJ5JE_X2.d.ts} +17 -0
  203. package/dist/data-table.d.ts +12 -1
  204. package/dist/{delete-account-setting-Dy4kJgUm.d.ts → delete-account-setting-DAgGBrbn.d.ts} +393 -42
  205. package/dist/feedback/feedback-attachment.d.ts +11 -10
  206. package/dist/feedback/feedback-attachment.js +7 -7
  207. package/dist/feedback/feedback-attachment.js.map +1 -1
  208. package/dist/feedback/feedback-context.d.ts +11 -10
  209. package/dist/feedback/feedback-crash.d.ts +11 -10
  210. package/dist/feedback/feedback-dialog.d.ts +11 -10
  211. package/dist/feedback/feedback-inbox.d.ts +10 -9
  212. package/dist/feedback/feedback-inbox.js +7 -3
  213. package/dist/feedback/feedback-inbox.js.map +1 -1
  214. package/dist/feedback/feedback-labels.d.ts +11 -10
  215. package/dist/feedback/feedback-menu.d.ts +4 -3
  216. package/dist/feedback/feedback-record.d.ts +11 -10
  217. package/dist/feedback/feedback-row-detail.d.ts +11 -10
  218. package/dist/feedback/feedback-row-detail.js.map +1 -1
  219. package/dist/feedback/feedback-status-undo.d.ts +11 -10
  220. package/dist/feedback/feedback-submit.d.ts +11 -10
  221. package/dist/feedback/feedback-swipe.d.ts +11 -10
  222. package/dist/feedback/feedback-swipe.js +3 -6
  223. package/dist/feedback/feedback-swipe.js.map +1 -1
  224. package/dist/feedback/feedback-table.d.ts +11 -10
  225. package/dist/feedback/feedback-table.js.map +1 -1
  226. package/dist/feedback/feedback-thread.d.ts +11 -10
  227. package/dist/feedback/feedback-thread.js +5 -1
  228. package/dist/feedback/feedback-thread.js.map +1 -1
  229. package/dist/feedback.d.ts +11 -10
  230. package/dist/hooks/use-anchored-panel.d.ts +37 -7
  231. package/dist/hooks/use-anchored-panel.js +6 -7
  232. package/dist/hooks/use-anchored-panel.js.map +1 -1
  233. package/dist/hooks/use-file-drop.d.ts +11 -10
  234. package/dist/hooks/use-focus-trap.d.ts +8 -0
  235. package/dist/hooks/use-focus-trap.js +17 -11
  236. package/dist/hooks/use-focus-trap.js.map +1 -1
  237. package/dist/i18n/defaults.d.ts +11 -10
  238. package/dist/i18n/defaults.js +2 -0
  239. package/dist/i18n/defaults.js.map +1 -1
  240. package/dist/i18n/german.d.ts +11 -10
  241. package/dist/i18n/german.js +37 -1
  242. package/dist/i18n/german.js.map +1 -1
  243. package/dist/i18n/kit-labels.d.ts +5 -4
  244. package/dist/i18n/kit-labels.js.map +1 -1
  245. package/dist/i18n/languages.d.ts +11 -10
  246. package/dist/i18n/locales/de-CH.d.ts +11 -10
  247. package/dist/i18n/locales/en.d.ts +11 -10
  248. package/dist/i18n/locales/es.d.ts +11 -10
  249. package/dist/i18n/locales/es.js +35 -1
  250. package/dist/i18n/locales/es.js.map +1 -1
  251. package/dist/i18n/locales/fr.d.ts +11 -10
  252. package/dist/i18n/locales/fr.js +37 -1
  253. package/dist/i18n/locales/fr.js.map +1 -1
  254. package/dist/i18n/locales/hu.d.ts +11 -10
  255. package/dist/i18n/locales/hu.js +38 -1
  256. package/dist/i18n/locales/hu.js.map +1 -1
  257. package/dist/i18n/locales/it.d.ts +11 -10
  258. package/dist/i18n/locales/it.js +35 -1
  259. package/dist/i18n/locales/it.js.map +1 -1
  260. package/dist/i18n/locales/zh.d.ts +11 -10
  261. package/dist/i18n/locales/zh.js +35 -1
  262. package/dist/i18n/locales/zh.js.map +1 -1
  263. package/dist/i18n/plurals.d.ts +20 -1
  264. package/dist/i18n/plurals.js +11 -0
  265. package/dist/i18n/plurals.js.map +1 -1
  266. package/dist/i18n/review.d.ts +11 -10
  267. package/dist/i18n/review.js +8 -1
  268. package/dist/i18n/review.js.map +1 -1
  269. package/dist/index.d.ts +11 -6
  270. package/dist/index.js +40 -2
  271. package/dist/index.js.map +1 -1
  272. package/dist/landing/landing-actions.d.ts +11 -10
  273. package/dist/landing/landing-sections.d.ts +11 -10
  274. package/dist/landing/public-header.d.ts +11 -10
  275. package/dist/landing/routing.d.ts +11 -10
  276. package/dist/pay/.well-known/apple-developer-merchantid-domain-association +1 -0
  277. package/dist/pay/index.html +30 -0
  278. package/dist/pay/pay.css +126 -0
  279. package/dist/pay/pay.js +198 -0
  280. package/dist/rhf/fields.d.ts +11 -10
  281. package/dist/rhf/form.d.ts +11 -10
  282. package/dist/rhf.d.ts +11 -10
  283. package/dist/settings/settings-section.d.ts +11 -10
  284. package/dist/shell/app-shell.d.ts +10 -9
  285. package/dist/shell/top-bar-brand.d.ts +11 -10
  286. package/dist/shell/topbar-action-menu.d.ts +1 -0
  287. package/dist/shell.d.ts +11 -10
  288. package/dist/testing/css-variables.d.ts +74 -0
  289. package/dist/testing/css-variables.generated.d.ts +7 -0
  290. package/dist/testing/css-variables.generated.js +8 -0
  291. package/dist/testing/css-variables.generated.js.map +1 -0
  292. package/dist/testing/css-variables.js +93 -0
  293. package/dist/testing/css-variables.js.map +1 -0
  294. package/dist/testing/index.d.ts +1 -0
  295. package/dist/testing/index.js +12 -0
  296. package/dist/testing/index.js.map +1 -0
  297. package/dist/theme/contrast-tokens.d.ts +44 -1
  298. package/dist/theme/contrast-tokens.js +21 -0
  299. package/dist/theme/contrast-tokens.js.map +1 -1
  300. package/dist/theme/contrast.d.ts +2 -2
  301. package/dist/theme/palette-derive.js +60 -11
  302. package/dist/theme/palette-derive.js.map +1 -1
  303. package/dist/theme/palette-presets.js +45 -43
  304. package/dist/theme/palette-presets.js.map +1 -1
  305. package/dist/wizard/stepper-nav.d.ts +12 -11
  306. package/dist/wizard/stepper-nav.js.map +1 -1
  307. package/dist/wizard.d.ts +11 -10
  308. package/package.json +10 -2
  309. package/src/account/delete-account-setting.tsx +6 -1
  310. package/src/account/email-change-setting.tsx +9 -3
  311. package/src/account/sessions-setting.tsx +7 -2
  312. package/src/admin/admin-action-confirm.tsx +2 -1
  313. package/src/admin/invitations-panel.tsx +9 -3
  314. package/src/admin/plan-change.tsx +487 -0
  315. package/src/admin/reviewer-scope-editor.tsx +2 -1
  316. package/src/admin/role-select.tsx +2 -1
  317. package/src/admin/user-roster.tsx +5 -3
  318. package/src/auth/auth-errors.ts +25 -2
  319. package/src/auth/complete-name-dialog.tsx +6 -2
  320. package/src/billing/billing-banner.tsx +3 -1
  321. package/src/billing/billing-labels.ts +45 -0
  322. package/src/billing/billing-lock.ts +36 -3
  323. package/src/billing/billing-overview.ts +58 -0
  324. package/src/billing/checkout-processing.ts +391 -0
  325. package/src/billing/checkout-return.ts +90 -0
  326. package/src/billing/pay-page.ts +246 -0
  327. package/src/billing/plan-limit-toast.tsx +91 -0
  328. package/src/billing/subscription-actions.tsx +41 -8
  329. package/src/components/account-settings.tsx +6 -2
  330. package/src/components/autocomplete.tsx +10 -4
  331. package/src/components/button-group.tsx +4 -1
  332. package/src/components/calculator.tsx +10 -6
  333. package/src/components/checkbox-group.tsx +2 -2
  334. package/src/components/checkbox.tsx +2 -1
  335. package/src/components/chip.tsx +37 -32
  336. package/src/components/choice-card.tsx +4 -2
  337. package/src/components/combobox-core.tsx +5 -2
  338. package/src/components/combobox.tsx +8 -6
  339. package/src/components/confirm-dialog.tsx +13 -6
  340. package/src/components/country-select.tsx +2 -2
  341. package/src/components/danger-confirm.tsx +2 -2
  342. package/src/components/data-table.tsx +20 -9
  343. package/src/components/date-picker.tsx +10 -7
  344. package/src/components/dropdown.tsx +12 -2
  345. package/src/components/entity-combobox.tsx +3 -3
  346. package/src/components/field-parts.tsx +61 -14
  347. package/src/components/file-button.tsx +5 -4
  348. package/src/components/file-dropzone.tsx +2 -2
  349. package/src/components/floating-panel.tsx +7 -5
  350. package/src/components/form-actions.tsx +12 -5
  351. package/src/components/full-bleed-dialog.tsx +6 -0
  352. package/src/components/inline-edit-field.tsx +13 -13
  353. package/src/components/list.tsx +10 -9
  354. package/src/components/modal.tsx +5 -0
  355. package/src/components/month-picker.tsx +8 -2
  356. package/src/components/multi-entity-combobox.tsx +3 -3
  357. package/src/components/number-field.tsx +7 -0
  358. package/src/components/number-input.tsx +71 -11
  359. package/src/components/numpad-sheet.tsx +8 -4
  360. package/src/components/popover.tsx +6 -2
  361. package/src/components/row-actions.tsx +208 -58
  362. package/src/components/share-card.tsx +67 -13
  363. package/src/components/skeleton.tsx +10 -2
  364. package/src/components/status-dot.tsx +7 -7
  365. package/src/components/swatch-picker.tsx +2 -2
  366. package/src/components/swipeable-row.tsx +138 -27
  367. package/src/components/switch.tsx +2 -1
  368. package/src/components/table.tsx +8 -1
  369. package/src/components/toggle-group.tsx +5 -3
  370. package/src/components/translation-review-editor.tsx +8 -3
  371. package/src/components/translation-review.tsx +18 -22
  372. package/src/components/ui.tsx +92 -43
  373. package/src/components/write-lock.tsx +150 -24
  374. package/src/feedback/feedback-attachment.tsx +13 -9
  375. package/src/feedback/feedback-inbox.tsx +10 -6
  376. package/src/feedback/feedback-row-detail.tsx +3 -2
  377. package/src/feedback/feedback-swipe.tsx +6 -11
  378. package/src/feedback/feedback-table.tsx +2 -1
  379. package/src/feedback/feedback-thread.tsx +20 -1
  380. package/src/hooks/use-anchored-panel.ts +60 -14
  381. package/src/hooks/use-focus-trap.ts +55 -12
  382. package/src/i18n/defaults.ts +2 -0
  383. package/src/i18n/german.ts +41 -0
  384. package/src/i18n/kit-labels.tsx +4 -0
  385. package/src/i18n/locales/es.ts +35 -0
  386. package/src/i18n/locales/fr.ts +41 -0
  387. package/src/i18n/locales/hu.ts +39 -0
  388. package/src/i18n/locales/it.ts +36 -0
  389. package/src/i18n/locales/zh.ts +34 -0
  390. package/src/i18n/plurals.ts +29 -0
  391. package/src/i18n/review.ts +7 -0
  392. package/src/index.ts +51 -5
  393. package/src/testing/css-variables.generated.ts +112 -0
  394. package/src/testing/css-variables.ts +191 -0
  395. package/src/testing/index.ts +13 -0
  396. package/src/theme/contrast-tokens.ts +53 -2
  397. package/src/theme/palette-derive.ts +87 -10
  398. package/src/theme/palette-presets.ts +45 -43
  399. package/src/wizard/stepper-nav.tsx +2 -1
  400. package/tokens.css +324 -46
@@ -49,8 +49,9 @@ function toLab(hex: string): Lab | null {
49
49
 
50
50
  /** `color-mix(in oklab, a p, b)` as a hex — the same formula tokens.css's derived roles
51
51
  * use, so a stepped value sits where the stylesheet would have put it. A colour that is
52
- * not hex (a consumer's own token set) comes back unmixed. */
53
- function mix(a: string, b: string, p: number): string {
52
+ * not hex (a consumer's own token set) comes back unmixed. The deriver mixes with it
53
+ * too (`--bg-hover`, `--brand-muted`, `--brand-bg`, `--brand-bg-hover`). */
54
+ export function mix(a: string, b: string, p: number): string {
54
55
  const A = toLab(a);
55
56
  const B = toLab(b);
56
57
  if (!A || !B) return a;
@@ -62,6 +63,56 @@ function mix(a: string, b: string, p: number): string {
62
63
  return toHex(oklchToRgb({ l, c, h }));
63
64
  }
64
65
 
66
+ /**
67
+ * `--bg-hover` in tokens.css: this share of `--text-primary` mixed into `--bg-surface`.
68
+ *
69
+ * 5.5 %, down from 7 % in 0.33 (docs/colour-roles-harmonization.md §12.10): a hovered row
70
+ * on a card is the darkest fill (in dark, the lightest) that text sits on, and at 7 % the
71
+ * light status colours, the money colours and Ink/Moss/Plum's muted text fell to
72
+ * 4.25–4.49:1 on it. The status literals are fixed, the same in every preset, so the
73
+ * hover moved instead: text wins over the hover's step. At 5.5 % the step from the card
74
+ * is still 1.09–1.13:1, above the 1.08:1 the kit's hover rule asks (§12.2). The deriver
75
+ * solves the money colours against this fill, and tokens-css-audit.test.ts measures
76
+ * every text role on it in every shipped preset, so the two cannot part.
77
+ */
78
+ export const HOVER_INK = 0.055;
79
+
80
+ /** The card's hover fill (`--bg-hover`) for `t`, as tokens.css mixes it. */
81
+ export function hoverFill(t: Pick<TokenSet, "textPrimary" | "bgSurface">): string {
82
+ return mix(t.textPrimary, t.bgSurface, HOVER_INK);
83
+ }
84
+
85
+ /**
86
+ * `--brand-muted` in tokens.css: this share of `--brand` mixed into `--text-primary`.
87
+ *
88
+ * 62 %, down from 70 % in 0.33 (docs/colour-roles-harmonization.md §12.11): the brand as
89
+ * text sits on its soft chip HOVERED too (`--brand-bg-hover` — ButtonGroupLink's current
90
+ * page, a selected day), and at 70 % it read 4.08–4.42:1 there in Default and Moss light
91
+ * and in Ink, Moss, Plum and Contrast dark. The brand could not move instead: the dark
92
+ * brands would have flipped their white label to the dark ink. Nor could the chip's hover
93
+ * lighten: by the time the text cleared 4.5:1 the hover sat 1.00:1 from the chip it
94
+ * hovers. So the text moves toward the ink, as `--bg-hover` moved for its text.
95
+ */
96
+ export const BRAND_MUTED_SHARE = 0.62;
97
+ /** `--brand-bg` and `--brand-bg-hover` in tokens.css: these shares of `--brand` mixed
98
+ * into `--bg-surface`. */
99
+ export const BRAND_BG_SHARE = 0.14;
100
+ export const BRAND_BG_HOVER_SHARE = 0.24;
101
+
102
+ /** `--brand-muted`, `--brand-bg` and `--brand-bg-hover` for `t`, as tokens.css mixes them.
103
+ * tokens-css-audit.test.ts holds the three shares equal to the stylesheet's. */
104
+ export function brandSoft(t: Pick<TokenSet, "brand" | "textPrimary" | "bgSurface">): {
105
+ brandMuted: string;
106
+ brandBg: string;
107
+ brandBgHover: string;
108
+ } {
109
+ return {
110
+ brandMuted: mix(t.brand, t.textPrimary, BRAND_MUTED_SHARE),
111
+ brandBg: mix(t.brand, t.bgSurface, BRAND_BG_SHARE),
112
+ brandBgHover: mix(t.brand, t.bgSurface, BRAND_BG_HOVER_SHARE),
113
+ };
114
+ }
115
+
65
116
  /** WCAG 1.4.11 for a component's boundary. */
66
117
  const BORDER_TARGET = 3;
67
118
  /** `--border-strong` in tokens.css: 55 % border, 45 % text. */
@@ -13,6 +13,7 @@ import {
13
13
  solveLightness,
14
14
  } from "./color";
15
15
  import type { CvdType, Oklch } from "./color";
16
+ import { brandSoft, hoverFill } from "./contrast-tokens";
16
17
 
17
18
  /**
18
19
  * Build a whole palette from one brand colour, plus any number of colours pinned by
@@ -161,7 +162,14 @@ function placeHue(home: number, slack: number, taken: number[]): number {
161
162
  const SURFACE_L = {
162
163
  // Light: the PAGE is slightly darker than the cards on it, so a card reads as raised
163
164
  // without needing a shadow to say so. Matches the shipped presets' relationship.
164
- light: { page: 0.912, surface: 0.945, surface2: 0.929 },
165
+ //
166
+ // The light WELL is the page itself (0.33, docs/colour-roles-harmonization.md §5.3,
167
+ // k26). Between the card and the page it sat 1.02–1.05:1 from the card it is inset
168
+ // in, which is no well at all; at the page's lightness it stands out from the card
169
+ // exactly as far as the card does from the page, and nothing re-solves, because the
170
+ // page is already the surface every text role is solved against. Dark keeps its
171
+ // well a step lighter than the card (1.11–1.13:1).
172
+ light: { page: 0.912, surface: 0.945, surface2: 0.912 },
165
173
  dark: { page: 0.158, surface: 0.206, surface2: 0.249 },
166
174
  } as const;
167
175
 
@@ -272,6 +280,19 @@ export function derivePalette({
272
280
  const textSecondary = solveAgainst(brand.h, textChroma, targets.secondary, worstSurface, mode);
273
281
  const textMuted = solveAgainst(brand.h, textChroma, targets.muted, worstSurface, mode);
274
282
 
283
+ // The darkest fill text sits on (the lightest, in dark): the worst surface, or a
284
+ // hovered row on the card (`--bg-hover`), which in light is a shade darker than the
285
+ // page. The colours that are solved exactly to 4.5:1 — money, the semantic text — are
286
+ // solved against this, so they hold on a hovered row too (0.33, §12.10). The text
287
+ // roles above keep their margin (4.6:1 and up) and need no second solve.
288
+ const hover = hoverFill({ textPrimary, bgSurface: surfaces.bgSurface });
289
+ const worstText = [worstSurface, hover].reduce((a, b) =>
290
+ contrast(a, mode === "light" ? "#000000" : "#ffffff") <
291
+ contrast(b, mode === "light" ? "#000000" : "#ffffff")
292
+ ? a
293
+ : b,
294
+ );
295
+
275
296
  // ── Brand. Keep the hue the caller asked for; move only the lightness, and only as
276
297
  // far as 3:1 against the worst surface — WCAG 1.4.11, since a brand-filled control is
277
298
  // a graphical object whose boundary has to be perceivable.
@@ -280,7 +301,7 @@ export function derivePalette({
280
301
  // NORMALISED, never the caller's raw string. `parseHex` accepts "4f46e5" and "#abc",
281
302
  // and passing either through unchanged put a value in the TokenSet that is not a CSS
282
303
  // colour — it then fails silently at paint time, three layers from here.
283
- const brandHex =
304
+ let brandHex =
284
305
  brandRatio >= 3
285
306
  ? toHex(parseHex(anchors.brand)!)
286
307
  : solveAgainst(brand.h, brandChroma, 3, worstSurface, mode);
@@ -291,13 +312,39 @@ export function derivePalette({
291
312
  `${brandHex}; hue and chroma are unchanged.`,
292
313
  );
293
314
  }
315
+ // `--brand-muted` is the brand AS TEXT — a soft brand chip's label, an outline chip, a
316
+ // current link — and tokens.css derives it: 62 % brand into the ink. A brand solved
317
+ // to 3:1 left it at 4.43–4.51:1 in three dark presets (0.33, §5.5), so it gets the
318
+ // text floor here: the brand moves away from the surfaces, a step at a time, until its
319
+ // muted form clears 4.5:1 on the worst fill and on its own soft chip, at rest
320
+ // (`--brand-bg`) and hovered (`--brand-bg-hover`, the harder of the two: §12.11).
321
+ const brandMutedWorst = (hex: string) => {
322
+ const soft = brandSoft({ brand: hex, textPrimary, bgSurface: surfaces.bgSurface });
323
+ return Math.min(
324
+ contrast(soft.brandMuted, worstText),
325
+ contrast(soft.brandMuted, soft.brandBg),
326
+ contrast(soft.brandMuted, soft.brandBgHover),
327
+ );
328
+ };
329
+ for (let i = 0; i < 40 && brandMutedWorst(brandHex) < 4.5; i++) {
330
+ const lch = hexToOklch(brandHex)!;
331
+ brandHex = oklchToHex({ ...lch, l: mode === "light" ? lch.l - 0.005 : lch.l + 0.005 });
332
+ }
333
+ if (brandMutedWorst(brandHex) < 4.5) {
334
+ warnings.push(
335
+ `the brand as text (--brand-muted) reaches only ${brandMutedWorst(brandHex).toFixed(2)}:1 ` +
336
+ `against the ${mode} surfaces (needs 4.5:1).`,
337
+ );
338
+ }
294
339
  const brandLch = hexToOklch(brandHex)!;
340
+ const brandContrast = contrastOn(brandHex);
295
341
  const brandHover = oklchToHex({
296
342
  ...brandLch,
297
- // Hover moves AWAY from the page in both themes: darker on light, lighter on dark.
298
- l: mode === "light" ? brandLch.l - 0.06 : brandLch.l + 0.06,
343
+ // Hover moves AWAY from the colour of the text on it (0.33, §5.5): darker under
344
+ // white, lighter under a dark ink. It used to move away from the page, which in dark
345
+ // lightened a fill that carries WHITE text, toward its own label: 4.07:1.
346
+ l: brandContrast === "#ffffff" ? brandLch.l - 0.06 : brandLch.l + 0.06,
299
347
  });
300
- const brandContrast = contrastOn(brandHex);
301
348
  const onBrand = contrast(brandHex, brandContrast);
302
349
  if (onBrand < 4.5) {
303
350
  warnings.push(
@@ -352,7 +399,7 @@ export function derivePalette({
352
399
  const bg = tintOn(hue, chroma, surfaces.bgSurface, mode);
353
400
  const onSurface = solveLightness(
354
401
  4.5,
355
- parseHex(worstSurface)!,
402
+ parseHex(worstText)!,
356
403
  hue,
357
404
  chroma,
358
405
  mode === "light" ? "darker" : "lighter",
@@ -425,11 +472,19 @@ export function derivePalette({
425
472
  // red/green pair — which is why the shipped presets use teal/amber/violet. Derived
426
473
  // here at fixed hues rather than from the brand, for the same reason `--danger` is:
427
474
  // a consumer who rebrands does not thereby change what "money out" looks like.
428
- const money = (hue: number, target: number) => solveAgainst(hue, 0.12, target, worstSurface, mode);
475
+ const money = (hue: number, target: number) => solveAgainst(hue, 0.12, target, worstText, mode);
429
476
  const moneyIncome = money(175, 4.5);
430
477
  const moneyExpense = money(70, 4.5);
431
478
  const moneyNet = money(300, 4.5);
432
- const moneyNeutral = oklchToHex({ l: mode === "light" ? 0.52 : 0.72, c: 0.012, h: brand.h });
479
+ // "No money has moved": a quiet grey at a fixed lightness, but printed as TEXT (the
480
+ // numpad's sign, a future row's figure), so it gets the text floor too (0.33). The
481
+ // fixed lightness left it at 4.24:1 on four light pages.
482
+ const neutralFloor = solveLightness(4.5, parseHex(worstText)!, brand.h, 0.012, mode === "light" ? "darker" : "lighter");
483
+ const moneyNeutral = oklchToHex({
484
+ l: mode === "light" ? Math.min(0.52, neutralFloor) : Math.max(0.72, neutralFloor),
485
+ c: 0.012,
486
+ h: brand.h,
487
+ });
433
488
 
434
489
  const tokens: TokenSet = {
435
490
  ...surfaces,
@@ -498,6 +553,13 @@ export function auditPalette(t: TokenSet, semantic?: SemanticTokens): ContrastRe
498
553
  ["bgSurface", t.bgSurface],
499
554
  ["bgSurface2", t.bgSurface2],
500
555
  ];
556
+ // A hovered row on the card (`--bg-hover`) carries the same text as the card, and in
557
+ // light it is the darkest fill that text sits on (0.33, §12.10). Text is measured on
558
+ // it; the brand fill and the hairline, which are not text, are not.
559
+ const hover = hoverFill(t);
560
+ const textGrounds: Array<[string, string]> = [...surfaces, ["bgHover", hover]];
561
+ // `--brand-muted`, `--brand-bg` and `--brand-bg-hover`, mixed as tokens.css mixes them.
562
+ const { brandMuted, brandBg, brandBgHover } = brandSoft(t);
501
563
 
502
564
  const add = (pair: string, fg: string, bg: string, required: number, rule: string) => {
503
565
  const ratio = contrast(fg, bg);
@@ -505,21 +567,35 @@ export function auditPalette(t: TokenSet, semantic?: SemanticTokens): ContrastRe
505
567
  };
506
568
 
507
569
  for (const [name, bg] of surfaces) {
570
+ add(`brand on ${name}`, t.brand, bg, 3, "WCAG 1.4.11 graphical object");
571
+ add(`border on ${name}`, t.border, bg, 1.1, "house rule: a hairline must be findable");
572
+ }
573
+ for (const [name, bg] of textGrounds) {
508
574
  add(`textPrimary on ${name}`, t.textPrimary, bg, 7, "WCAG 1.4.6 AAA body text");
509
575
  add(`textSecondary on ${name}`, t.textSecondary, bg, 4.5, "WCAG 1.4.3 AA body text");
510
576
  add(`textMuted on ${name}`, t.textMuted, bg, 4.5, "WCAG 1.4.3 AA body text");
511
- add(`brand on ${name}`, t.brand, bg, 3, "WCAG 1.4.11 graphical object");
512
- add(`border on ${name}`, t.border, bg, 1.1, "house rule: a hairline must be findable");
577
+ add(`brandMuted on ${name}`, brandMuted, bg, 4.5, "WCAG 1.4.3 — the brand as text");
513
578
  for (const [key, hex] of [
514
579
  ["moneyIncome", t.moneyIncome],
515
580
  ["moneyExpense", t.moneyExpense],
516
581
  ["moneyNet", t.moneyNet],
582
+ // Not a figure's colour but still printed as one (the numpad's sign, a future
583
+ // row's amount) — measured since 0.33, when it was found at 4.24:1.
584
+ ["moneyNeutral", t.moneyNeutral],
517
585
  ] as const) {
518
586
  add(`${key} on ${name}`, hex, bg, 4.5, "WCAG 1.4.3 — these are rendered as TEXT");
519
587
  }
520
588
  }
521
589
 
522
590
  add("brandContrast on brand", t.brandContrast, t.brand, 4.5, "WCAG 1.4.3 AA body text");
591
+ // A hovered brand button carries the same label (0.33): the derived dark presets
592
+ // lightened the hover toward their white label and left it at 4.07:1.
593
+ add("brandContrast on brandHover", t.brandContrast, t.brandHover, 4.5, "WCAG 1.4.3 AA body text");
594
+ add("brandMuted on brandBg", brandMuted, brandBg, 4.5, "WCAG 1.4.3 — a soft brand chip's label");
595
+ // The same label on the chip hovered (§12.11): a current link, a selected day. At 70 %
596
+ // brand the muted text read 4.08–4.42:1 here (Default and Moss light; Ink, Moss, Plum
597
+ // and Contrast dark).
598
+ add("brandMuted on brandBgHover", brandMuted, brandBgHover, 4.5, "WCAG 1.4.3 — a hovered soft brand chip's label");
523
599
 
524
600
  if (semantic) {
525
601
  for (const [name, fg] of [
@@ -529,6 +605,7 @@ export function auditPalette(t: TokenSet, semantic?: SemanticTokens): ContrastRe
529
605
  ["success", semantic.success],
530
606
  ] as const) {
531
607
  add(`${name} on bgSurface`, fg, t.bgSurface, 4.5, "WCAG 1.4.3 — rendered as text");
608
+ add(`${name} on bgHover`, fg, hover, 4.5, "WCAG 1.4.3 — rendered as text, on a hovered row");
532
609
  }
533
610
  add("danger on dangerBg", semantic.danger, semantic.dangerBg, 4.5, "WCAG 1.4.3 — badge text");
534
611
  add("warning on warningBg", semantic.warning, semantic.warningBg, 4.5, "WCAG 1.4.3 — badge text");
@@ -70,7 +70,9 @@ export const DEFAULT_PRESET: PalettePreset = {
70
70
  // Solar Dusk (light) surfaces, with the brand unified to indigo (see above).
71
71
  bgPage: "#ede3cf",
72
72
  bgSurface: "#f6ecd9",
73
- bgSurface2: "#f3ead6",
73
+ // The well is the page in light (0.33, k26): #f3ead6 stood 1.02:1 from the card it
74
+ // is inset in. Every light preset does the same; see SURFACE_L in palette-derive.ts.
75
+ bgSurface2: "#ede3cf",
74
76
  border: "#e2d6bd",
75
77
  textPrimary: "#463f33",
76
78
  textSecondary: "#50493c",
@@ -134,7 +136,7 @@ export const ALTERNATIVE_PRESETS: PalettePreset[] = [
134
136
  light: {
135
137
  bgPage: "#ece5d6",
136
138
  bgSurface: "#f5efe3",
137
- bgSurface2: "#efe9dc",
139
+ bgSurface2: "#ece5d6",
138
140
  border: "#e2dcce",
139
141
  textPrimary: "#2b2622",
140
142
  textSecondary: "#4f4a44",
@@ -189,7 +191,7 @@ export const ALTERNATIVE_PRESETS: PalettePreset[] = [
189
191
  light: {
190
192
  bgPage: "#e2e7ef",
191
193
  bgSurface: "#f0f3f8",
192
- bgSurface2: "#e1e6ee",
194
+ bgSurface2: "#e2e7ef",
193
195
  border: "#d3dae6",
194
196
  textPrimary: "#2e3440",
195
197
  textSecondary: "#454b56",
@@ -244,7 +246,7 @@ export const ALTERNATIVE_PRESETS: PalettePreset[] = [
244
246
  light: {
245
247
  bgPage: "#e8eaf2",
246
248
  bgSurface: "#f6f7fb",
247
- bgSurface2: "#eef1f8",
249
+ bgSurface2: "#e8eaf2",
248
250
  border: "#dadfeb",
249
251
  textPrimary: "#1b1f2e",
250
252
  textSecondary: "#494d5a",
@@ -300,7 +302,7 @@ export const ALTERNATIVE_PRESETS: PalettePreset[] = [
300
302
  light: {
301
303
  bgPage: "#ede3cf",
302
304
  bgSurface: "#f6ecd9",
303
- bgSurface2: "#f3ead6",
305
+ bgSurface2: "#ede3cf",
304
306
  border: "#e2d6bd",
305
307
  textPrimary: "#463f33",
306
308
  textSecondary: "#50493c",
@@ -355,7 +357,7 @@ export const ALTERNATIVE_PRESETS: PalettePreset[] = [
355
357
  light: {
356
358
  bgPage: "#ececec",
357
359
  bgSurface: "#f7f7f7",
358
- bgSurface2: "#f4f4f5",
360
+ bgSurface2: "#ececec",
359
361
  border: "#e4e4e7",
360
362
  textPrimary: "#18181b",
361
363
  textSecondary: "#4e4e50",
@@ -508,7 +510,7 @@ export const DERIVED_PRESETS: PalettePreset[] = [
508
510
  light: {
509
511
  bgPage: "#dce2ef",
510
512
  bgSurface: "#e6edfa",
511
- bgSurface2: "#e1e8f5",
513
+ bgSurface2: "#dce2ef",
512
514
  border: "#b0bace",
513
515
  textPrimary: "#2e3139",
514
516
  textSecondary: "#454950",
@@ -516,14 +518,14 @@ export const DERIVED_PRESETS: PalettePreset[] = [
516
518
  brand: "#2f5fd0",
517
519
  brandHover: "#1f4cbc",
518
520
  brandContrast: "#ffffff",
519
- moneyIncome: "#00735f",
521
+ moneyIncome: "#00725e",
520
522
  moneyExpense: "#8e5900",
521
523
  moneyNet: "#7356a2",
522
- moneyNeutral: "#656970",
524
+ moneyNeutral: "#61656c",
523
525
  chart: PAUL_TOL.light,
524
526
  heat: {
525
- neutral: "#e1e8f5",
526
- under: "#00735f",
527
+ neutral: "#dce2ef",
528
+ under: "#00725e",
527
529
  over: "#8e5900",
528
530
  seqLow: "#fee3c5",
529
531
  seqHigh: "#8e5900",
@@ -538,8 +540,8 @@ export const DERIVED_PRESETS: PalettePreset[] = [
538
540
  textPrimary: "#c7ccd5",
539
541
  textSecondary: "#a7abb4",
540
542
  textMuted: "#858992",
541
- brand: "#3364d5",
542
- brandHover: "#4477ea",
543
+ brand: "#3466d7",
544
+ brandHover: "#2353c3",
543
545
  brandContrast: "#ffffff",
544
546
  moneyIncome: "#00997f",
545
547
  moneyExpense: "#b77b29",
@@ -563,7 +565,7 @@ export const DERIVED_PRESETS: PalettePreset[] = [
563
565
  light: {
564
566
  bgPage: "#d8e6dd",
565
567
  bgSurface: "#e3f1e8",
566
- bgSurface2: "#deece3",
568
+ bgSurface2: "#d8e6dd",
567
569
  border: "#abbfb2",
568
570
  textPrimary: "#2c342e",
569
571
  textSecondary: "#434b45",
@@ -572,16 +574,16 @@ export const DERIVED_PRESETS: PalettePreset[] = [
572
574
  brandHover: "#196842",
573
575
  brandContrast: "#ffffff",
574
576
  moneyIncome: "#00735f",
575
- moneyExpense: "#8f5a00",
576
- moneyNet: "#7457a3",
577
- moneyNeutral: "#646b66",
577
+ moneyExpense: "#8e5900",
578
+ moneyNet: "#7356a2",
579
+ moneyNeutral: "#5f6762",
578
580
  chart: PAUL_TOL.light,
579
581
  heat: {
580
- neutral: "#deece3",
582
+ neutral: "#d8e6dd",
581
583
  under: "#00735f",
582
- over: "#8f5a00",
583
- seqLow: "#fee3c4",
584
- seqHigh: "#8f5a00",
584
+ over: "#8e5900",
585
+ seqLow: "#fee3c5",
586
+ seqHigh: "#8e5900",
585
587
  empty: "rgba(120,110,95,0.14)",
586
588
  },
587
589
  },
@@ -593,8 +595,8 @@ export const DERIVED_PRESETS: PalettePreset[] = [
593
595
  textPrimary: "#c5cfc9",
594
596
  textSecondary: "#a4aea8",
595
597
  textMuted: "#838c86",
596
- brand: "#2f7a52",
597
- brandHover: "#428c63",
598
+ brand: "#317b53",
599
+ brandHover: "#1c6943",
598
600
  brandContrast: "#ffffff",
599
601
  moneyIncome: "#009a80",
600
602
  moneyExpense: "#b87b2a",
@@ -618,7 +620,7 @@ export const DERIVED_PRESETS: PalettePreset[] = [
618
620
  light: {
619
621
  bgPage: "#e7dfea",
620
622
  bgSurface: "#f2e9f5",
621
- bgSurface2: "#ece4ef",
623
+ bgSurface2: "#e7dfea",
622
624
  border: "#c2b6c6",
623
625
  textPrimary: "#342f36",
624
626
  textSecondary: "#4c474e",
@@ -627,16 +629,16 @@ export const DERIVED_PRESETS: PalettePreset[] = [
627
629
  brandHover: "#692d7d",
628
630
  brandContrast: "#ffffff",
629
631
  moneyIncome: "#00725e",
630
- moneyExpense: "#8e5900",
631
- moneyNet: "#7356a2",
632
- moneyNeutral: "#6c676e",
632
+ moneyExpense: "#8d5900",
633
+ moneyNet: "#7355a2",
634
+ moneyNeutral: "#676369",
633
635
  chart: PAUL_TOL.light,
634
636
  heat: {
635
- neutral: "#ece4ef",
637
+ neutral: "#e7dfea",
636
638
  under: "#00725e",
637
- over: "#8e5900",
638
- seqLow: "#fee3c5",
639
- seqHigh: "#8e5900",
639
+ over: "#8d5900",
640
+ seqLow: "#fee3c4",
641
+ seqHigh: "#8d5900",
640
642
  empty: "rgba(120,110,95,0.14)",
641
643
  },
642
644
  },
@@ -648,8 +650,8 @@ export const DERIVED_PRESETS: PalettePreset[] = [
648
650
  textPrimary: "#d0cad3",
649
651
  textSecondary: "#afa9b1",
650
652
  textMuted: "#8d878f",
651
- brand: "#8f52a4",
652
- brandHover: "#a264b7",
653
+ brand: "#9153a6",
654
+ brandHover: "#7f4193",
653
655
  brandContrast: "#ffffff",
654
656
  moneyIncome: "#00997f",
655
657
  moneyExpense: "#b77b29",
@@ -673,7 +675,7 @@ export const DERIVED_PRESETS: PalettePreset[] = [
673
675
  light: {
674
676
  bgPage: "#e0e2e5",
675
677
  bgSurface: "#ebedef",
676
- bgSurface2: "#e6e8ea",
678
+ bgSurface2: "#e0e2e5",
677
679
  border: "#b7babe",
678
680
  textPrimary: "#191d24",
679
681
  textSecondary: "#373c44",
@@ -681,17 +683,17 @@ export const DERIVED_PRESETS: PalettePreset[] = [
681
683
  brand: "#1f2937",
682
684
  brandHover: "#111b28",
683
685
  brandContrast: "#ffffff",
684
- moneyIncome: "#00735f",
685
- moneyExpense: "#8e5900",
686
- moneyNet: "#7456a2",
687
- moneyNeutral: "#656970",
686
+ moneyIncome: "#00715d",
687
+ moneyExpense: "#8d5800",
688
+ moneyNet: "#7255a1",
689
+ moneyNeutral: "#5f646b",
688
690
  chart: PAUL_TOL.light,
689
691
  heat: {
690
- neutral: "#e6e8ea",
691
- under: "#00735f",
692
- over: "#8e5900",
692
+ neutral: "#e0e2e5",
693
+ under: "#00715d",
694
+ over: "#8d5800",
693
695
  seqLow: "#fee3c5",
694
- seqHigh: "#8e5900",
696
+ seqHigh: "#8d5800",
695
697
  empty: "rgba(120,110,95,0.14)",
696
698
  },
697
699
  },
@@ -704,7 +706,7 @@ export const DERIVED_PRESETS: PalettePreset[] = [
704
706
  textSecondary: "#b7bdc5",
705
707
  textMuted: "#9197a0",
706
708
  brand: "#546c8d",
707
- brandHover: "#657e9f",
709
+ brandHover: "#445b7b",
708
710
  brandContrast: "#ffffff",
709
711
  moneyIncome: "#00997f",
710
712
  moneyExpense: "#b77b29",
@@ -10,6 +10,7 @@ import { WizardContextProvider } from "./wizard-context";
10
10
  import { DEFAULT_WIZARD_LABELS } from "./types";
11
11
  import { useKitLabels } from "../i18n/kit-labels";
12
12
  import type { UseWizardReturn, WizardLabels } from "./types";
13
+ import type { CommitScope } from "../components/write-lock";
13
14
 
14
15
  /**
15
16
  * The chrome around a wizard: the step indicator, the step content, and the
@@ -74,7 +75,7 @@ export function StepperNav<TData extends Record<string, unknown>>({
74
75
  * with five buttons would not say which one saves — and would read like `useWizard`'s
75
76
  * `commits`, which is a step's policy, not a lock.
76
77
  */
77
- finishCommit?: boolean;
78
+ finishCommit?: CommitScope;
78
79
  /**
79
80
  * Why Finish is not available — {@link Button}'s `disabledReason` on the Finish button:
80
81
  * `aria-disabled` and focusable, the reason in the kit Tooltip and on the button's