@helixui/library 3.1.0-next.72 → 3.2.0-next.100

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 (254) hide show
  1. package/custom-elements.json +165 -328
  2. package/dist/components/hx-accordion/hx-accordion-item.styles.d.ts.map +1 -1
  3. package/dist/components/hx-accordion/index.js +1 -1
  4. package/dist/components/hx-alert/index.js +1 -1
  5. package/dist/components/hx-banner/index.js +1 -1
  6. package/dist/components/hx-breadcrumb/hx-breadcrumb-item.styles.d.ts.map +1 -1
  7. package/dist/components/hx-breadcrumb/index.js +1 -1
  8. package/dist/components/hx-button/hx-button.d.ts +44 -49
  9. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  10. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  11. package/dist/components/hx-button/index.js +1 -1
  12. package/dist/components/hx-card/hx-card.styles.d.ts.map +1 -1
  13. package/dist/components/hx-card/index.js +1 -1
  14. package/dist/components/hx-carousel/index.js +1 -1
  15. package/dist/components/hx-checkbox/index.js +1 -1
  16. package/dist/components/hx-clinical-status/hx-clinical-status.styles.d.ts.map +1 -1
  17. package/dist/components/hx-clinical-status/index.js +1 -1
  18. package/dist/components/hx-code-snippet/hx-code-snippet.styles.d.ts.map +1 -1
  19. package/dist/components/hx-code-snippet/index.js +1 -1
  20. package/dist/components/hx-color-picker/hx-color-picker.styles.d.ts.map +1 -1
  21. package/dist/components/hx-color-picker/index.js +1 -1
  22. package/dist/components/hx-combobox/index.js +1 -1
  23. package/dist/components/hx-data-table/hx-data-table.styles.d.ts.map +1 -1
  24. package/dist/components/hx-data-table/index.js +1 -1
  25. package/dist/components/hx-date-picker/index.js +1 -1
  26. package/dist/components/hx-dialog/hx-dialog.styles.d.ts.map +1 -1
  27. package/dist/components/hx-dialog/index.js +1 -1
  28. package/dist/components/hx-drawer/hx-drawer.styles.d.ts.map +1 -1
  29. package/dist/components/hx-drawer/index.js +1 -1
  30. package/dist/components/hx-file-upload/hx-file-upload.styles.d.ts.map +1 -1
  31. package/dist/components/hx-file-upload/index.js +1 -1
  32. package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
  33. package/dist/components/hx-icon-button/index.js +1 -1
  34. package/dist/components/hx-link/index.js +1 -1
  35. package/dist/components/hx-menu/hx-menu-item.styles.d.ts.map +1 -1
  36. package/dist/components/hx-menu/index.js +1 -1
  37. package/dist/components/hx-meter/hx-meter.styles.d.ts.map +1 -1
  38. package/dist/components/hx-meter/index.js +1 -1
  39. package/dist/components/hx-nav/hx-nav.styles.d.ts.map +1 -1
  40. package/dist/components/hx-nav/index.js +1 -1
  41. package/dist/components/hx-overflow-menu/hx-overflow-menu.styles.d.ts.map +1 -1
  42. package/dist/components/hx-overflow-menu/index.js +1 -1
  43. package/dist/components/hx-pagination/hx-pagination.styles.d.ts.map +1 -1
  44. package/dist/components/hx-pagination/index.js +1 -1
  45. package/dist/components/hx-phi-field/hx-phi-field.styles.d.ts.map +1 -1
  46. package/dist/components/hx-phi-field/index.js +1 -1
  47. package/dist/components/hx-popover/hx-popover.styles.d.ts.map +1 -1
  48. package/dist/components/hx-popover/index.js +1 -1
  49. package/dist/components/hx-radio-group/index.js +1 -1
  50. package/dist/components/hx-rating/index.js +1 -1
  51. package/dist/components/hx-select/hx-select.styles.d.ts.map +1 -1
  52. package/dist/components/hx-select/index.js +1 -1
  53. package/dist/components/hx-side-nav/hx-nav-item.d.ts +7 -5
  54. package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
  55. package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
  56. package/dist/components/hx-side-nav/hx-side-nav.d.ts +9 -23
  57. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  58. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  59. package/dist/components/hx-side-nav/index.js +1 -1
  60. package/dist/components/hx-slider/index.js +1 -1
  61. package/dist/components/hx-split-button/hx-split-button.d.ts +1 -1
  62. package/dist/components/hx-split-button/index.js +1 -1
  63. package/dist/components/hx-split-panel/hx-split-panel.styles.d.ts.map +1 -1
  64. package/dist/components/hx-split-panel/index.js +1 -1
  65. package/dist/components/hx-steps/hx-step.styles.d.ts.map +1 -1
  66. package/dist/components/hx-steps/index.js +1 -1
  67. package/dist/components/hx-switch/index.js +1 -1
  68. package/dist/components/hx-table/hx-table.styles.d.ts.map +1 -1
  69. package/dist/components/hx-table/index.js +1 -1
  70. package/dist/components/hx-tabs/index.js +1 -1
  71. package/dist/components/hx-text-input/hx-text-input.d.ts +18 -35
  72. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  73. package/dist/components/hx-text-input/index.js +1 -1
  74. package/dist/components/hx-textarea/index.js +1 -1
  75. package/dist/components/hx-time-picker/index.js +1 -1
  76. package/dist/components/hx-toast/hx-toast.d.ts +12 -8
  77. package/dist/components/hx-toast/hx-toast.d.ts.map +1 -1
  78. package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
  79. package/dist/components/hx-toast/index.js +1 -1
  80. package/dist/components/hx-toggle-button/index.js +1 -1
  81. package/dist/components/hx-top-nav/hx-top-nav.styles.d.ts.map +1 -1
  82. package/dist/components/hx-top-nav/index.js +1 -1
  83. package/dist/components/hx-tree-view/hx-tree-item.styles.d.ts.map +1 -1
  84. package/dist/components/hx-tree-view/index.js +1 -1
  85. package/dist/css/helix-all.css +289 -237
  86. package/dist/css/helix-core.css +147 -53
  87. package/dist/css/helix-data.css +9 -14
  88. package/dist/css/helix-feedback.css +30 -20
  89. package/dist/css/helix-forms.css +53 -73
  90. package/dist/css/helix-layout.css +2 -8
  91. package/dist/css/helix-media.css +3 -3
  92. package/dist/css/helix-navigation.css +34 -41
  93. package/dist/css/helix-overlay.css +3 -12
  94. package/dist/css/helix-tokens.css +60 -5
  95. package/dist/css/helix-utility.css +5 -5
  96. package/dist/css/hx-alert.css +1 -1
  97. package/dist/css/hx-banner.css +2 -2
  98. package/dist/css/hx-button.css +143 -43
  99. package/dist/css/hx-card.css +1 -4
  100. package/dist/css/hx-carousel.css +3 -3
  101. package/dist/css/hx-checkbox.css +2 -2
  102. package/dist/css/hx-clinical-status.css +2 -4
  103. package/dist/css/hx-code-snippet.css +6 -4
  104. package/dist/css/hx-color-picker.css +3 -13
  105. package/dist/css/hx-combobox.css +7 -7
  106. package/dist/css/hx-data-table.css +2 -8
  107. package/dist/css/hx-date-picker.css +7 -7
  108. package/dist/css/hx-dialog.css +1 -4
  109. package/dist/css/hx-drawer.css +1 -4
  110. package/dist/css/hx-file-upload.css +4 -13
  111. package/dist/css/hx-icon-button.css +2 -5
  112. package/dist/css/hx-link.css +1 -1
  113. package/dist/css/hx-meter.css +1 -2
  114. package/dist/css/hx-nav.css +2 -8
  115. package/dist/css/hx-overflow-menu.css +2 -8
  116. package/dist/css/hx-pagination.css +2 -8
  117. package/dist/css/hx-phi-field.css +1 -4
  118. package/dist/css/hx-popover.css +1 -4
  119. package/dist/css/hx-rating.css +3 -3
  120. package/dist/css/hx-select.css +3 -4
  121. package/dist/css/hx-side-nav.css +26 -12
  122. package/dist/css/hx-slider.css +4 -4
  123. package/dist/css/hx-split-button.css +5 -5
  124. package/dist/css/hx-split-panel.css +2 -8
  125. package/dist/css/hx-switch.css +3 -3
  126. package/dist/css/hx-table.css +1 -2
  127. package/dist/css/hx-text-input.css +8 -8
  128. package/dist/css/hx-textarea.css +2 -2
  129. package/dist/css/hx-time-picker.css +3 -3
  130. package/dist/css/hx-toast.css +26 -15
  131. package/dist/css/hx-toggle-button.css +4 -4
  132. package/dist/css/hx-top-nav.css +1 -4
  133. package/dist/css/hx-tree-view.css +1 -1
  134. package/dist/css/index.css +1 -1
  135. package/dist/css/manifest.json +60 -46
  136. package/dist/index.js +44 -44
  137. package/dist/shared/{hx-accordion-cnKg4_la.js → hx-accordion-ZVzgDzTG.js} +4 -5
  138. package/dist/shared/hx-accordion-ZVzgDzTG.js.map +1 -0
  139. package/dist/shared/{hx-alert-BZH8iHQf.js → hx-alert-C597yHpD.js} +2 -2
  140. package/dist/shared/{hx-alert-BZH8iHQf.js.map → hx-alert-C597yHpD.js.map} +1 -1
  141. package/dist/shared/{hx-banner-DT7Zn9Bo.js → hx-banner-Cxd7eFUP.js} +3 -3
  142. package/dist/shared/{hx-banner-DT7Zn9Bo.js.map → hx-banner-Cxd7eFUP.js.map} +1 -1
  143. package/dist/shared/{hx-breadcrumb-item-COeYcB2x.js → hx-breadcrumb-item-3tKppF9h.js} +2 -5
  144. package/dist/shared/{hx-breadcrumb-item-COeYcB2x.js.map → hx-breadcrumb-item-3tKppF9h.js.map} +1 -1
  145. package/dist/shared/{hx-button-modUSOpY.js → hx-button-9OUjJnk7.js} +167 -68
  146. package/dist/shared/hx-button-9OUjJnk7.js.map +1 -0
  147. package/dist/shared/{hx-card-CU1QnjNb.js → hx-card-qNAM2QNV.js} +6 -9
  148. package/dist/shared/hx-card-qNAM2QNV.js.map +1 -0
  149. package/dist/shared/{hx-carousel-item-BaE4hpLl.js → hx-carousel-item-z1Lc24op.js} +4 -4
  150. package/dist/shared/hx-carousel-item-z1Lc24op.js.map +1 -0
  151. package/dist/shared/{hx-checkbox-C46TyXhM.js → hx-checkbox-DBD-gMoz.js} +3 -3
  152. package/dist/shared/{hx-checkbox-C46TyXhM.js.map → hx-checkbox-DBD-gMoz.js.map} +1 -1
  153. package/dist/shared/{hx-clinical-status-BmSjfSEN.js → hx-clinical-status-D3XQIOqX.js} +3 -5
  154. package/dist/shared/hx-clinical-status-D3XQIOqX.js.map +1 -0
  155. package/dist/shared/{hx-code-snippet-CJ0FbQYG.js → hx-code-snippet-B26RM1_C.js} +10 -8
  156. package/dist/shared/{hx-code-snippet-CJ0FbQYG.js.map → hx-code-snippet-B26RM1_C.js.map} +1 -1
  157. package/dist/shared/{hx-color-picker-DiDLZyvK.js → hx-color-picker-uRc865FJ.js} +23 -33
  158. package/dist/shared/hx-color-picker-uRc865FJ.js.map +1 -0
  159. package/dist/shared/{hx-combobox-DaA5dBC4.js → hx-combobox-ClhNRAS5.js} +8 -8
  160. package/dist/shared/hx-combobox-ClhNRAS5.js.map +1 -0
  161. package/dist/shared/{hx-data-table-Cq3t86Ic.js → hx-data-table-CLqVqdxr.js} +3 -9
  162. package/dist/shared/hx-data-table-CLqVqdxr.js.map +1 -0
  163. package/dist/shared/{hx-date-picker-DMqRQNSB.js → hx-date-picker-BJm7Yrda.js} +8 -8
  164. package/dist/shared/{hx-date-picker-DMqRQNSB.js.map → hx-date-picker-BJm7Yrda.js.map} +1 -1
  165. package/dist/shared/{hx-dialog-eIS8tcDm.js → hx-dialog-DRN_1-Y-.js} +2 -5
  166. package/dist/shared/hx-dialog-DRN_1-Y-.js.map +1 -0
  167. package/dist/shared/{hx-drawer-DDhDz7RI.js → hx-drawer-Y1Ui2IWJ.js} +2 -5
  168. package/dist/shared/hx-drawer-Y1Ui2IWJ.js.map +1 -0
  169. package/dist/shared/{hx-file-upload-zTDbjsRw.js → hx-file-upload-D3rKROK5.js} +17 -26
  170. package/dist/shared/hx-file-upload-D3rKROK5.js.map +1 -0
  171. package/dist/shared/{hx-icon-button-BmV97nqz.js → hx-icon-button-CGNdQSFM.js} +3 -6
  172. package/dist/shared/hx-icon-button-CGNdQSFM.js.map +1 -0
  173. package/dist/shared/{hx-link-DmiV-mPw.js → hx-link-9Ig2DW6L.js} +5 -5
  174. package/dist/shared/{hx-link-DmiV-mPw.js.map → hx-link-9Ig2DW6L.js.map} +1 -1
  175. package/dist/shared/{hx-menu-divider-j__TZjH2.js → hx-menu-divider-C2omnPtj.js} +2 -5
  176. package/dist/shared/hx-menu-divider-C2omnPtj.js.map +1 -0
  177. package/dist/shared/{hx-meter-Cm7k_Ro8.js → hx-meter-BPscsw5t.js} +2 -3
  178. package/dist/shared/hx-meter-BPscsw5t.js.map +1 -0
  179. package/dist/shared/{hx-nav-item-D8xHLVOs.js → hx-nav-item-CqbO5-T5.js} +140 -90
  180. package/dist/shared/hx-nav-item-CqbO5-T5.js.map +1 -0
  181. package/dist/shared/{hx-nav-LoyEKZQC.js → hx-nav-ldFM3Fle.js} +37 -43
  182. package/dist/shared/hx-nav-ldFM3Fle.js.map +1 -0
  183. package/dist/shared/{hx-overflow-menu-BmKyAp5D.js → hx-overflow-menu-DCLsdIBy.js} +3 -9
  184. package/dist/shared/hx-overflow-menu-DCLsdIBy.js.map +1 -0
  185. package/dist/shared/{hx-pagination-Dqw5dorC.js → hx-pagination-C7y8GVyU.js} +54 -60
  186. package/dist/shared/hx-pagination-C7y8GVyU.js.map +1 -0
  187. package/dist/shared/{hx-phi-field-Bf9TdtC1.js → hx-phi-field-C19oxlrr.js} +2 -5
  188. package/dist/shared/hx-phi-field-C19oxlrr.js.map +1 -0
  189. package/dist/shared/{hx-popover-B93rTAfr.js → hx-popover-B-FP3-wW.js} +8 -11
  190. package/dist/shared/hx-popover-B-FP3-wW.js.map +1 -0
  191. package/dist/shared/{hx-radio-N8xgDd_5.js → hx-radio-dFjUAost.js} +4 -4
  192. package/dist/shared/{hx-radio-N8xgDd_5.js.map → hx-radio-dFjUAost.js.map} +1 -1
  193. package/dist/shared/{hx-rating-i2FL1WUN.js → hx-rating-CGtsejNf.js} +4 -4
  194. package/dist/shared/{hx-rating-i2FL1WUN.js.map → hx-rating-CGtsejNf.js.map} +1 -1
  195. package/dist/shared/{hx-select-vgaBo1Ai.js → hx-select-Bf4usFts.js} +4 -5
  196. package/dist/shared/hx-select-Bf4usFts.js.map +1 -0
  197. package/dist/shared/{hx-slider-ydBamYhd.js → hx-slider-m0aEClH1.js} +5 -5
  198. package/dist/shared/{hx-slider-ydBamYhd.js.map → hx-slider-m0aEClH1.js.map} +1 -1
  199. package/dist/shared/{hx-split-button-BeMsmS6N.js → hx-split-button-BxDFfx4D.js} +6 -6
  200. package/dist/shared/{hx-split-button-BeMsmS6N.js.map → hx-split-button-BxDFfx4D.js.map} +1 -1
  201. package/dist/shared/{hx-split-panel-BVG1VWNT.js → hx-split-panel-B-u0Z3mm.js} +3 -9
  202. package/dist/shared/hx-split-panel-B-u0Z3mm.js.map +1 -0
  203. package/dist/shared/{hx-step-DL3PbOzm.js → hx-step-R2rjp1fT.js} +2 -5
  204. package/dist/shared/hx-step-R2rjp1fT.js.map +1 -0
  205. package/dist/shared/{hx-switch-Dougzsgp.js → hx-switch-DvAW4YY-.js} +4 -4
  206. package/dist/shared/{hx-switch-Dougzsgp.js.map → hx-switch-DvAW4YY-.js.map} +1 -1
  207. package/dist/shared/{hx-tab-panel-CbkO9VKu.js → hx-tab-panel-SWOEHuJc.js} +3 -3
  208. package/dist/shared/{hx-tab-panel-CbkO9VKu.js.map → hx-tab-panel-SWOEHuJc.js.map} +1 -1
  209. package/dist/shared/{hx-td-1zwTFLRw.js → hx-td-DnnEMIuA.js} +2 -3
  210. package/dist/shared/hx-td-DnnEMIuA.js.map +1 -0
  211. package/dist/shared/{hx-text-input-B-caO5fI.js → hx-text-input-Bn7Gn8CI.js} +24 -25
  212. package/dist/shared/hx-text-input-Bn7Gn8CI.js.map +1 -0
  213. package/dist/shared/{hx-textarea-D9O4U8cb.js → hx-textarea-Jx1xnhgv.js} +7 -7
  214. package/dist/shared/{hx-textarea-D9O4U8cb.js.map → hx-textarea-Jx1xnhgv.js.map} +1 -1
  215. package/dist/shared/{hx-time-picker-m0z4nFB-.js → hx-time-picker-BoEIZwzv.js} +4 -4
  216. package/dist/shared/{hx-time-picker-m0z4nFB-.js.map → hx-time-picker-BoEIZwzv.js.map} +1 -1
  217. package/dist/shared/{hx-toggle-button-Dd8clXB4.js → hx-toggle-button-DPAIh_Xo.js} +24 -24
  218. package/dist/shared/{hx-toggle-button-Dd8clXB4.js.map → hx-toggle-button-DPAIh_Xo.js.map} +1 -1
  219. package/dist/shared/{hx-top-nav-CchPYaiV.js → hx-top-nav-DP6OFS8C.js} +11 -14
  220. package/dist/shared/hx-top-nav-DP6OFS8C.js.map +1 -0
  221. package/dist/shared/{hx-tree-item-DtMC3DTa.js → hx-tree-item-Dt0Ozqyr.js} +4 -10
  222. package/dist/shared/hx-tree-item-Dt0Ozqyr.js.map +1 -0
  223. package/dist/shared/{toast-factory-DvDRAh0l.js → toast-factory-YSznocIV.js} +66 -56
  224. package/dist/shared/toast-factory-YSznocIV.js.map +1 -0
  225. package/figma-inventory.json +292 -444
  226. package/package.json +2 -2
  227. package/dist/shared/hx-accordion-cnKg4_la.js.map +0 -1
  228. package/dist/shared/hx-button-modUSOpY.js.map +0 -1
  229. package/dist/shared/hx-card-CU1QnjNb.js.map +0 -1
  230. package/dist/shared/hx-carousel-item-BaE4hpLl.js.map +0 -1
  231. package/dist/shared/hx-clinical-status-BmSjfSEN.js.map +0 -1
  232. package/dist/shared/hx-color-picker-DiDLZyvK.js.map +0 -1
  233. package/dist/shared/hx-combobox-DaA5dBC4.js.map +0 -1
  234. package/dist/shared/hx-data-table-Cq3t86Ic.js.map +0 -1
  235. package/dist/shared/hx-dialog-eIS8tcDm.js.map +0 -1
  236. package/dist/shared/hx-drawer-DDhDz7RI.js.map +0 -1
  237. package/dist/shared/hx-file-upload-zTDbjsRw.js.map +0 -1
  238. package/dist/shared/hx-icon-button-BmV97nqz.js.map +0 -1
  239. package/dist/shared/hx-menu-divider-j__TZjH2.js.map +0 -1
  240. package/dist/shared/hx-meter-Cm7k_Ro8.js.map +0 -1
  241. package/dist/shared/hx-nav-LoyEKZQC.js.map +0 -1
  242. package/dist/shared/hx-nav-item-D8xHLVOs.js.map +0 -1
  243. package/dist/shared/hx-overflow-menu-BmKyAp5D.js.map +0 -1
  244. package/dist/shared/hx-pagination-Dqw5dorC.js.map +0 -1
  245. package/dist/shared/hx-phi-field-Bf9TdtC1.js.map +0 -1
  246. package/dist/shared/hx-popover-B93rTAfr.js.map +0 -1
  247. package/dist/shared/hx-select-vgaBo1Ai.js.map +0 -1
  248. package/dist/shared/hx-split-panel-BVG1VWNT.js.map +0 -1
  249. package/dist/shared/hx-step-DL3PbOzm.js.map +0 -1
  250. package/dist/shared/hx-td-1zwTFLRw.js.map +0 -1
  251. package/dist/shared/hx-text-input-B-caO5fI.js.map +0 -1
  252. package/dist/shared/hx-top-nav-CchPYaiV.js.map +0 -1
  253. package/dist/shared/hx-tree-item-DtMC3DTa.js.map +0 -1
  254. package/dist/shared/toast-factory-DvDRAh0l.js.map +0 -1
@@ -395,10 +395,7 @@
395
395
 
396
396
  .button:focus-visible {
397
397
  outline: var(--hx-focus-ring-width, 2px) solid
398
- var(
399
- --hx-button-focus-ring-color,
400
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
401
- );
398
+ var(--hx-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
402
399
  outline-offset: var(--hx-focus-ring-offset, 2px);
403
400
  }
404
401
 
@@ -436,21 +433,24 @@
436
433
  /* ─── Style Variants ─── */
437
434
 
438
435
  .button--primary {
439
- --hx-button-bg: var(--hx-color-primary-500, #429797);
440
- --hx-button-color: var(--hx-color-text-on-primary, #ffffff);
436
+ --hx-button-bg: var(--hx-color-action-primary-bg, #429797);
437
+ /* Inline #0d1825 matches text.on-primary's resolved primitive (neutral-900);
438
+ cold-start without the semantic still paints AA-tuned dark-on-primary
439
+ rather than white-on-primary (3.43:1 fail). */
440
+ --hx-button-color: var(--hx-color-text-on-primary, #0d1825);
441
441
  --hx-button-border-color: transparent;
442
442
  }
443
443
 
444
444
  .button--secondary {
445
445
  --hx-button-bg: transparent;
446
- /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
447
- primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
448
- --hx-button-color: var(--hx-color-primary-600, #0f7078);
449
- --hx-button-border-color: var(--hx-color-primary-600, #0f7078);
446
+ /* primary-500 (#429797) text on white surface = 3.44:1 — fails AA.
447
+ primary-600 (#0F7078) on white = 5.82:1 — AA pass. */
448
+ --hx-button-color: var(--hx-color-action-secondary-fg, #0f7078);
449
+ --hx-button-border-color: var(--hx-color-action-secondary-border, #0f7078);
450
450
  }
451
451
 
452
452
  .button--secondary:hover {
453
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));
453
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-secondary-bg-hover, #ebf8f8));
454
454
  }
455
455
 
456
456
  .button--tertiary {
@@ -464,36 +464,52 @@
464
464
  }
465
465
 
466
466
  .button--danger {
467
- --hx-button-bg: var(--hx-color-error-500, #e5493e);
468
- --hx-button-color: var(--hx-color-text-on-error, #ffffff);
467
+ --hx-button-bg: var(--hx-color-action-danger-bg, #e5493e);
468
+ /* Inline #0d1825 matches text.on-error's resolved primitive (neutral-900);
469
+ cold-start without the semantic still paints AA-tuned dark-on-error
470
+ rather than white-on-error (3.92:1 fail). */
471
+ --hx-button-color: var(--hx-color-text-on-error, #0d1825);
469
472
  --hx-button-border-color: transparent;
470
473
  }
471
474
 
472
475
  /* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).
473
- error-600 (#C92A2A) drops that to 2.25:1 — AA fail. Hold fg at neutral-0
474
- directly so darker hover fills stay legible. Mirrors hx-toast precedent
475
- (commit 300e21ab0). */
476
+ error-600 (#C92A2A) drops that to 3.28:1 — AA fail. text.on-error-strong
477
+ resolves to neutral-0 across modes (no dark flip) so the darker hover fill
478
+ stays legible. Mirrors hx-toast precedent (commit 300e21ab0); routed
479
+ through the semantic tier in 3.2.1 token-cascade remediation. */
476
480
  .button--danger:hover {
477
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-error-600, #c92a2a));
478
- --hx-button-color: var(--hx-color-neutral-0, #ffffff);
481
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-hover, #c92a2a));
482
+ --hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);
483
+ }
484
+
485
+ /* Pressed state binds explicitly to action.danger.bg-active (error-700,
486
+ #A21312) + text.on-error-strong (neutral-0) = 7.96:1 AA. Base
487
+ .button:active filter:brightness(0.8) would compound on top of bg-hover
488
+ (#C92A2A) and produce ~3.3:1 sub-AA on the bound colors. Override the
489
+ filter to none. HC override on action.danger.bg-active flips to HC
490
+ error-500 so the on-error-strong (HC = #000) pair is AA in HC too. */
491
+ .button--danger:active {
492
+ --hx-button-bg: var(--hx-button-active-bg, var(--hx-color-action-danger-bg-active, #a21312));
493
+ --hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);
494
+ filter: none;
479
495
  }
480
496
 
481
497
  .button--ghost {
482
498
  --hx-button-bg: transparent;
483
- /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
484
- primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
485
- --hx-button-color: var(--hx-color-primary-600, #0f7078);
499
+ /* primary-500 (#429797) text on white surface = 3.44:1 — fails AA.
500
+ primary-600 (#0F7078) on white = 5.82:1 — AA pass. */
501
+ --hx-button-color: var(--hx-color-action-ghost-fg, #0f7078);
486
502
  --hx-button-border-color: transparent;
487
503
  }
488
504
 
489
505
  .button--ghost:hover {
490
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));
506
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-ghost-bg-hover, #ebf8f8));
491
507
  }
492
508
 
493
509
  .button--outline {
494
510
  --hx-button-bg: transparent;
495
511
  --hx-button-color: var(--hx-color-text-primary, #0d1825);
496
- --hx-button-border-color: var(--hx-color-border-strong, #8e9c98);
512
+ --hx-button-border-color: var(--hx-color-border-strong, #66787b);
497
513
  }
498
514
 
499
515
  .button--outline:hover {
@@ -501,12 +517,24 @@
501
517
  }
502
518
 
503
519
  /* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.
504
- primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. Pin fg at
505
- neutral-0 for the darker hover fill. Mirrors hx-toast precedent
506
- (commit 300e21ab0). */
520
+ primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. text.on-primary-strong
521
+ resolves to neutral-0 across modes (no dark flip) for the darker hover fill.
522
+ Mirrors hx-toast precedent (commit 300e21ab0); routed through the semantic
523
+ tier in 3.2.1 token-cascade remediation. */
507
524
  .button--primary:hover {
508
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-primary-600, #0f7078));
509
- --hx-button-color: var(--hx-color-neutral-0, #ffffff);
525
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-hover, #0f7078));
526
+ --hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);
527
+ }
528
+
529
+ /* Pressed state binds explicitly to action.primary.bg-active (primary-700,
530
+ #0F6363) + text.on-primary-strong (neutral-0) = 7.03:1 AA. The base
531
+ .button:active filter:brightness(0.8) would compound on top of bg-hover
532
+ (#0F7078) and produce ~3.7:1 sub-AA on the bound colors. Override the
533
+ filter to none so the action.*.bg-active token is what actually paints. */
534
+ .button--primary:active {
535
+ --hx-button-bg: var(--hx-button-active-bg, var(--hx-color-action-primary-bg-active, #0f6363));
536
+ --hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);
537
+ filter: none;
510
538
  }
511
539
 
512
540
  /* ─── Disabled ─── */
@@ -550,9 +578,19 @@
550
578
 
551
579
  /* ─── Inverted Mode ─── */
552
580
 
581
+ /* Inline-fallback contract for --hx-color-border-on-dark-* in this section:
582
+ the literal rgba(255, 255, 255, 0.X) arms are a LIGHT-MODE-only last
583
+ resort (cold-start, CSS-not-loaded). At runtime, hx-theme injects
584
+ dark.color.border.on-dark-* as overlay-black-* so dark-mode inverted
585
+ buttons stay visible on the now-light surface.inverse (#EBEEE9). The
586
+ inline white overlays would render invisible (≈1.1:1) on a light surface,
587
+ but they never paint when the theme is mounted. If a future change moves
588
+ these into a context where hx-theme is not guaranteed, replace with
589
+ mode-aware tokens. */
590
+
553
591
  /* Override text color and filter-based hover/active for all variants */
554
592
  :host([inverted]) .button {
555
- color: var(--hx-button-inverted-color, var(--hx-color-neutral-0, #ffffff));
593
+ color: var(--hx-button-inverted-color, var(--hx-color-text-inverse, #ffffff));
556
594
  filter: none;
557
595
  }
558
596
 
@@ -565,37 +603,89 @@
565
603
  }
566
604
 
567
605
  :host([inverted]) .button:focus-visible {
606
+ /* WCAG 1.4.11: focus indicator needs ≥3:1 against adjacent colors.
607
+ border-on-dark-default (overlay-white-30) ≈ 2.7:1 on neutral-900 — fails.
608
+ border-on-dark-strong (overlay-white-70) ≈ 5:1 — passes. */
568
609
  outline-color: var(
569
610
  --hx-button-inverted-focus-ring-color,
570
- var(--hx-overlay-white-50, rgba(255, 255, 255, 0.5))
611
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))
571
612
  );
572
613
  }
573
614
 
574
- /* Primary inverted — slight transparent white overlay on hover */
575
- :host([inverted]) .button--primary:hover {
576
- --hx-button-bg: var(--hx-color-primary-400, #6ab1b1);
615
+ /* Primary inverted — resting bg routes through action.primary.bg-inverted-rest
616
+ so dark mode can flip the fill to primary-600. surface.inverse becomes light
617
+ (#EBEEE9) in dark mode; primary-500 on #EBEEE9 = 2.94:1 (sub-3:1 UI floor
618
+ fail for the inverted-button boundary). primary-600 on #EBEEE9 = 4.97:1
619
+ (AA pass). Light mode tracks action.primary.bg (primary-500, 5.20:1 on
620
+ dark surface.inverse). */
621
+ :host([inverted]) .button--primary {
622
+ --hx-button-bg: var(--hx-color-action-primary-bg-inverted-rest, #429797);
623
+ }
624
+
625
+ /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover
626
+ (primary-400, light teal). The base :host([inverted]) .button rule binds
627
+ color to text.inverse, which flips by mode (neutral-0 in light, neutral-900
628
+ in dark). On a permanent light-teal fill, white text drops to 2.4:1 in
629
+ light mode (AA fail). Pin color to text.on-primary (neutral-900, no
630
+ dark-mode flip) for both hover and active so the foreground is dark in
631
+ both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).
632
+ Pressed === hover visually in inverted mode is acceptable UX (the
633
+ transient absence of pointer over the button signals release).
634
+ The fallback chain wraps --hx-button-active-bg (highest precedence) and
635
+ --hx-button-hover-bg so consumer overrides on either prop apply under
636
+ :host([inverted]) — the two share a paint here, so either knob is
637
+ honored, with active-bg winning when both are set. */
638
+ :host([inverted]) .button--primary:hover,
639
+ :host([inverted]) .button--primary:active {
640
+ --hx-button-bg: var(
641
+ --hx-button-active-bg,
642
+ var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))
643
+ );
644
+ color: var(
645
+ --hx-button-inverted-primary-interactive-color,
646
+ var(--hx-color-text-on-primary, #0d1825)
647
+ );
577
648
  }
578
649
 
579
- /* Secondary inverted — white border and text */
650
+ /* Danger inverted — sister to primary. Hover/pressed lift to
651
+ action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground
652
+ contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);
653
+ pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both
654
+ modes. Same active-bg → hover-bg → semantic fallback chain as primary. */
655
+ :host([inverted]) .button--danger:hover,
656
+ :host([inverted]) .button--danger:active {
657
+ --hx-button-bg: var(
658
+ --hx-button-active-bg,
659
+ var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))
660
+ );
661
+ color: var(
662
+ --hx-button-inverted-danger-interactive-color,
663
+ var(--hx-color-text-on-error, #0d1825)
664
+ );
665
+ }
666
+
667
+ /* Secondary inverted — white border and translucent hover fill */
580
668
  :host([inverted]) .button--secondary {
581
- --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));
669
+ --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
582
670
  }
583
671
 
584
672
  :host([inverted]) .button--secondary:hover {
585
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
673
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
586
674
  }
587
675
 
588
- /* Tertiary inverted */
676
+ /* Tertiary inverted — resting at subtle (10%) lifts to default (30%) on hover
677
+ so the runtime hover delta is visually distinct, not collapsed onto a
678
+ single token. */
589
679
  :host([inverted]) .button--tertiary {
590
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
680
+ --hx-button-bg: var(--hx-color-border-on-dark-subtle, rgba(255, 255, 255, 0.1));
591
681
  --hx-button-border-color: transparent;
592
682
  }
593
683
 
594
684
  :host([inverted]) .button--tertiary:hover {
595
- --hx-button-bg: var(--hx-overlay-white-25, rgba(255, 255, 255, 0.25));
685
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
596
686
  }
597
687
 
598
- /* Ghost inverted — transparent base, white hover bg */
688
+ /* Ghost inverted — transparent base, translucent hover bg */
599
689
  :host([inverted]) .button--ghost {
600
690
  --hx-button-bg: transparent;
601
691
  --hx-button-border-color: transparent;
@@ -604,17 +694,17 @@
604
694
  :host([inverted]) .button--ghost:hover {
605
695
  --hx-button-bg: var(
606
696
  --hx-button-inverted-ghost-hover-bg,
607
- var(--hx-overlay-white-20, rgba(255, 255, 255, 0.2))
697
+ var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3))
608
698
  );
609
699
  }
610
700
 
611
701
  /* Outline inverted — white border */
612
702
  :host([inverted]) .button--outline {
613
- --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));
703
+ --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
614
704
  }
615
705
 
616
706
  :host([inverted]) .button--outline:hover {
617
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
707
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
618
708
  }
619
709
 
620
710
  /* ─── Prefix / Suffix / Label ─── */
@@ -642,6 +732,16 @@
642
732
  border: 2px solid ButtonText;
643
733
  }
644
734
 
735
+ .button:hover {
736
+ /* Hover affordance must survive in HC. Highlight/HighlightText is the
737
+ OS-level "selected" pair, mirroring the forcedColorsInteractive mixin's
738
+ hover contract — kept inline since this component owns its bespoke HC
739
+ block (XOR rule). */
740
+ background-color: Highlight;
741
+ color: HighlightText;
742
+ border-color: Highlight;
743
+ }
744
+
645
745
  .button:focus-visible {
646
746
  outline: 3px solid Highlight;
647
747
  outline-offset: 2px;
@@ -870,10 +970,7 @@
870
970
 
871
971
  .card--interactive:focus-visible {
872
972
  outline: var(--hx-focus-ring-width, 2px) solid
873
- var(
874
- --hx-card-focus-ring-color,
875
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
876
- );
973
+ var(--hx-card-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
877
974
  outline-offset: var(--hx-focus-ring-offset, 2px);
878
975
  }
879
976
 
@@ -1179,10 +1276,7 @@
1179
1276
 
1180
1277
  .button:focus-visible {
1181
1278
  outline: var(--hx-focus-ring-width, 2px) solid
1182
- var(
1183
- --hx-icon-button-focus-ring-color,
1184
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
1185
- );
1279
+ var(--hx-icon-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
1186
1280
  outline-offset: var(--hx-focus-ring-offset, 2px);
1187
1281
  }
1188
1282
 
@@ -1252,7 +1346,7 @@
1252
1346
  .button--tertiary {
1253
1347
  --hx-icon-button-bg: transparent;
1254
1348
  --hx-icon-button-color: var(--hx-color-text-strong, #202b39);
1255
- --hx-icon-button-border-color: var(--hx-color-border-strong, #8e9c98);
1349
+ --hx-icon-button-border-color: var(--hx-color-border-strong, #66787b);
1256
1350
  }
1257
1351
 
1258
1352
  .button--tertiary:hover {
@@ -1427,7 +1521,7 @@
1427
1521
  outline: var(--hx-focus-ring-width, 2px) solid
1428
1522
  var(
1429
1523
  --hx-link-focus-ring-color,
1430
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
1524
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
1431
1525
  );
1432
1526
  outline-offset: var(--hx-focus-ring-offset, 2px);
1433
1527
  border-radius: var(--hx-border-radius-sm, 0.25rem);
@@ -80,7 +80,8 @@
80
80
  min-width: var(--hx-touch-target-min, 2.75rem);
81
81
  min-height: var(--hx-touch-target-min, 2.75rem);
82
82
  padding: var(--hx-space-1, 0.25rem) var(--hx-space-2, 0.5rem);
83
- border: var(--hx-border-width-thin, 1px) solid var(--hx-color-border-strong, #8e9c98);
83
+ border: var(--hx-border-width-thin, 1px) solid
84
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
84
85
  border-radius: var(--hx-border-radius-sm, 0.25rem);
85
86
  /* Copy button sits on the always-dark block snippet surface; uses inverse family for contrast on the terminal background. */
86
87
  background-color: var(--hx-color-surface-inverse, #0d1825);
@@ -106,7 +107,7 @@
106
107
 
107
108
  .code-snippet__copy-button:focus-visible {
108
109
  outline: var(--hx-focus-ring-width, 2px) solid
109
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1));
110
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078));
110
111
  outline-offset: var(--hx-focus-ring-offset, 2px);
111
112
  }
112
113
 
@@ -125,7 +126,8 @@
125
126
  min-height: var(--hx-touch-target-min, 2.75rem);
126
127
  padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);
127
128
  border: none;
128
- border-top: var(--hx-border-width-thin, 1px) solid var(--hx-color-border-strong, #8e9c98);
129
+ border-top: var(--hx-border-width-thin, 1px) solid
130
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
129
131
  /* Expand button is attached to the always-dark block snippet — inverse family maintains the terminal aesthetic. */
130
132
  background-color: var(--hx-color-surface-inverse, #0d1825);
131
133
  color: var(--hx-color-text-inverse, #ffffff);
@@ -147,7 +149,7 @@
147
149
 
148
150
  .code-snippet__expand-button:focus-visible {
149
151
  outline: var(--hx-focus-ring-width, 2px) solid
150
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1));
152
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078));
151
153
  outline-offset: var(--hx-focus-ring-offset, 2px);
152
154
  }
153
155
 
@@ -301,10 +303,7 @@
301
303
 
302
304
  .sort-btn:focus-visible {
303
305
  outline: var(--hx-focus-ring-width, 2px) solid
304
- var(
305
- --hx-data-table-focus-ring-color,
306
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
307
- );
306
+ var(--hx-data-table-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
308
307
  outline-offset: var(--hx-focus-ring-offset, 2px);
309
308
  border-radius: var(--hx-border-radius-sm, 2px);
310
309
  }
@@ -406,10 +405,7 @@
406
405
  [part~='td']:focus-visible,
407
406
  [part~='th']:focus-visible {
408
407
  outline: var(--hx-focus-ring-width, 2px) solid
409
- var(
410
- --hx-data-table-focus-ring-color,
411
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
412
- );
408
+ var(--hx-data-table-focus-ring-color, var(--hx-focus-ring-color, #0f7078));
413
409
  outline-offset: var(--hx-focus-ring-offset, -2px);
414
410
  border-radius: var(--hx-border-radius-sm, 2px);
415
411
  }
@@ -679,8 +675,7 @@ export const helixStructuredListRowStyles = css`
679
675
  /* ─── Focus ─── */
680
676
 
681
677
  ::slotted(:focus-visible) {
682
- outline: var(--hx-focus-ring-width, 2px) solid
683
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797));
678
+ outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #0f7078);
684
679
  outline-offset: var(--hx-focus-ring-offset, -2px);
685
680
  }
686
681
 
@@ -162,7 +162,7 @@
162
162
  outline: var(--hx-focus-ring-width, 2px) solid
163
163
  var(
164
164
  --hx-alert-close-btn-focus-ring-color,
165
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
165
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
166
166
  );
167
167
  outline-offset: var(--hx-focus-ring-offset, 2px);
168
168
  opacity: 1;
@@ -338,7 +338,7 @@
338
338
  outline: var(--hx-focus-ring-width, 2px) solid
339
339
  var(
340
340
  --hx-banner-action-focus-ring-color,
341
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
341
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
342
342
  );
343
343
  outline-offset: var(--hx-focus-ring-offset, 2px);
344
344
  border-radius: var(--hx-border-radius-sm, 0.25rem);
@@ -382,7 +382,7 @@
382
382
  outline: var(--hx-focus-ring-width, 2px) solid
383
383
  var(
384
384
  --hx-banner-close-btn-focus-ring-color,
385
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
385
+ var(--hx-focus-ring-color, var(--hx-color-primary-600, #0f7078))
386
386
  );
387
387
  outline-offset: var(--hx-focus-ring-offset, 2px);
388
388
  opacity: 1;
@@ -481,8 +481,7 @@
481
481
  }
482
482
 
483
483
  .meter:focus-visible {
484
- outline: var(--hx-focus-ring-width, 2px) solid
485
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797));
484
+ outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, #0f7078);
486
485
  outline-offset: var(--hx-focus-ring-offset, 2px);
487
486
  }
488
487
 
@@ -1233,33 +1232,38 @@
1233
1232
  * error-600) because the lighter -500 fills can't pass AA against white
1234
1233
  * text in the precision-cool palette. The neutral-900 on-{role} tokens
1235
1234
  * are tuned for the lighter -500 surfaces and would fail here (e.g.
1236
- * neutral-900 on primary-600 = 3.07:1), so we hold fg at neutral-0
1237
- * directly for primary/success/danger.
1238
- * - neutral-0 on primary-600 (#0F7078) = 5.39:1 — AA pass
1239
- * - neutral-0 on success-700 (#146831) = 6.88:1 — AA pass
1240
- * (success-600 #0E8A4A on white = 4.41:1 — drifts under AA at 14px)
1241
- * - neutral-0 on error-600 (#C92A2A) = 5.92:1 — AA pass
1242
- * - neutral-900 on warning-500 (#C2711C) = 4.83:1 — AA pass
1235
+ * neutral-900 on primary-600 = 3.07:1), so the on-{role}-strong tokens
1236
+ * (neutral-0, no dark-mode flip) keep fg legible on the darker fills.
1237
+ * - text.on-primary-strong on info.bg-strong (primary-600, #0F7078) = 5.82:1
1238
+ * - text.on-success-strong on success.bg-strong (success-700, #146831) = 6.88:1
1239
+ * (success-600 #0E8A4A on white = 4.42:1 — drifts under AA at 14px)
1240
+ * - text.on-error-strong on danger.bg-strong (error-600, #C92A2A) = 5.46:1
1241
+ * - text.on-warning on warning.bg-strong (warning-500, #C2711C) = 4.83:1
1243
1242
  * (warning stays on the lighter -500 surface so on-warning works)
1243
+ *
1244
+ * 3.2.1 token-cascade: bg variants now route through surface.{role}-strong
1245
+ * semantics; fg variants route through text.on-{role}-strong (or on-warning
1246
+ * for the warning variant). Component-tier tokens are NOT bypassed — the
1247
+ * --hx-toast-bg / --hx-toast-color slots remain the single override point.
1244
1248
  */
1245
1249
  .toast--success {
1246
- --hx-toast-bg: var(--hx-color-success-700, #146831);
1247
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
1250
+ --hx-toast-bg: var(--hx-color-surface-success-strong, #146831);
1251
+ --hx-toast-color: var(--hx-color-text-on-success-strong, #ffffff);
1248
1252
  }
1249
1253
 
1250
1254
  .toast--warning {
1251
- --hx-toast-bg: var(--hx-color-warning-500, #c2711c);
1255
+ --hx-toast-bg: var(--hx-color-surface-warning-strong, #c2711c);
1252
1256
  --hx-toast-color: var(--hx-color-text-on-warning, #0d1825);
1253
1257
  }
1254
1258
 
1255
1259
  .toast--danger {
1256
- --hx-toast-bg: var(--hx-color-error-600, #c92a2a);
1257
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
1260
+ --hx-toast-bg: var(--hx-color-surface-danger-strong, #c92a2a);
1261
+ --hx-toast-color: var(--hx-color-text-on-error-strong, #ffffff);
1258
1262
  }
1259
1263
 
1260
1264
  .toast--info {
1261
- --hx-toast-bg: var(--hx-color-primary-600, #0f7078);
1262
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
1265
+ --hx-toast-bg: var(--hx-color-surface-info-strong, #0f7078);
1266
+ --hx-toast-color: var(--hx-color-text-on-primary-strong, #ffffff);
1263
1267
  }
1264
1268
 
1265
1269
  /* ─── Severity Label (WCAG 1.4.1) ─── */
@@ -1352,10 +1356,16 @@
1352
1356
  }
1353
1357
 
1354
1358
  /* ─── Forced Colors (Windows High Contrast) ─── */
1355
- /* Belt-and-suspenders: rich per-class HC overrides PLUS the forcedColorsSurface mixin. */
1359
+ /* Sole owner: bespoke per-class HC overrides on .toast and .toast__close.
1360
+ The shared forcedColorsSurface mixin was dropped in 3.2.1 (XOR rule);
1361
+ this block now carries the surface contract the mixin used to provide
1362
+ (background:Canvas + color:CanvasText + border:1px solid CanvasText)
1363
+ plus the per-class affordances the mixin never touched. */
1356
1364
 
1357
1365
  @media (forced-colors: active) {
1358
1366
  .toast {
1367
+ background: Canvas;
1368
+ color: CanvasText;
1359
1369
  border: 1px solid CanvasText;
1360
1370
  }
1361
1371