@helixui/library 3.2.0-next.76 → 3.2.0-next.81

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 (43) hide show
  1. package/custom-elements.json +390 -375
  2. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  3. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  4. package/dist/components/hx-button/index.js +1 -1
  5. package/dist/components/hx-side-nav/hx-nav-item.d.ts +7 -5
  6. package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
  7. package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
  8. package/dist/components/hx-side-nav/hx-side-nav.d.ts +5 -4
  9. package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
  10. package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
  11. package/dist/components/hx-side-nav/index.js +1 -1
  12. package/dist/components/hx-text-input/hx-text-input.d.ts +5 -5
  13. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  14. package/dist/components/hx-text-input/index.js +1 -1
  15. package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
  16. package/dist/components/hx-toast/index.js +1 -1
  17. package/dist/css/helix-all.css +95 -65
  18. package/dist/css/helix-core.css +56 -36
  19. package/dist/css/helix-feedback.css +18 -13
  20. package/dist/css/helix-forms.css +4 -4
  21. package/dist/css/helix-navigation.css +17 -12
  22. package/dist/css/helix-tokens.css +43 -0
  23. package/dist/css/hx-button.css +56 -36
  24. package/dist/css/hx-side-nav.css +17 -12
  25. package/dist/css/hx-text-input.css +4 -4
  26. package/dist/css/hx-toast.css +18 -13
  27. package/dist/css/index.css +1 -1
  28. package/dist/css/manifest.json +27 -16
  29. package/dist/index.js +4 -4
  30. package/dist/shared/{hx-button-modUSOpY.js → hx-button-kWxjKqo-.js} +79 -60
  31. package/dist/shared/hx-button-kWxjKqo-.js.map +1 -0
  32. package/dist/shared/{hx-nav-item-D8xHLVOs.js → hx-nav-item-CMyMv5Gv.js} +129 -88
  33. package/dist/shared/hx-nav-item-CMyMv5Gv.js.map +1 -0
  34. package/dist/shared/{hx-text-input-B-caO5fI.js → hx-text-input-ClrrmoE1.js} +20 -21
  35. package/dist/shared/hx-text-input-ClrrmoE1.js.map +1 -0
  36. package/dist/shared/{toast-factory-DvDRAh0l.js → toast-factory-CIiZDZGZ.js} +59 -54
  37. package/dist/shared/toast-factory-CIiZDZGZ.js.map +1 -0
  38. package/figma-inventory.json +80 -44
  39. package/package.json +2 -2
  40. package/dist/shared/hx-button-modUSOpY.js.map +0 -1
  41. package/dist/shared/hx-nav-item-D8xHLVOs.js.map +0 -1
  42. package/dist/shared/hx-text-input-B-caO5fI.js.map +0 -1
  43. package/dist/shared/toast-factory-DvDRAh0l.js.map +0 -1
@@ -8,7 +8,7 @@
8
8
  and evaluates their text against the page white background, producing
9
9
  false-positive color-contrast violations (WCAG 2.1 AA). */
10
10
  background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));
11
- color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ebeee9));
11
+ color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));
12
12
  }
13
13
 
14
14
  * {
@@ -23,11 +23,11 @@
23
23
  height: 100%;
24
24
  width: var(--hx-side-nav-width, 16rem);
25
25
  background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));
26
- color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ebeee9));
26
+ color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));
27
27
  transition: width var(--hx-transition-normal, 300ms) ease;
28
28
  overflow: hidden;
29
29
  border-inline-end: var(--hx-border-width-thin, 1px) solid
30
- var(--hx-side-nav-border-color, var(--hx-color-border-strong, #313e4b));
30
+ var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
31
31
  }
32
32
 
33
33
  /* ─── Collapsed State ─── */
@@ -45,7 +45,7 @@
45
45
  flex-shrink: 0;
46
46
  min-height: var(--hx-space-14, 3.5rem);
47
47
  border-bottom: var(--hx-border-width-thin, 1px) solid
48
- var(--hx-side-nav-border-color, var(--hx-color-border-strong, #313e4b));
48
+ var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
49
49
  overflow: hidden;
50
50
  }
51
51
 
@@ -72,7 +72,7 @@
72
72
  flex-shrink: 0;
73
73
  min-height: var(--hx-space-14, 3.5rem);
74
74
  border-top: var(--hx-border-width-thin, 1px) solid
75
- var(--hx-side-nav-border-color, var(--hx-color-border-strong, #313e4b));
75
+ var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
76
76
  overflow: hidden;
77
77
  }
78
78
 
@@ -95,7 +95,7 @@
95
95
  border: none;
96
96
  border-radius: var(--hx-border-radius-sm, 0.25rem);
97
97
  background: transparent;
98
- color: var(--hx-side-nav-toggle-color, var(--hx-color-text-inverse, #b6bfb9));
98
+ color: var(--hx-side-nav-toggle-color, var(--hx-color-text-inverse, #ffffff));
99
99
  cursor: pointer;
100
100
  transition:
101
101
  background-color var(--hx-transition-fast, 150ms) ease,
@@ -104,10 +104,10 @@
104
104
 
105
105
  .side-nav__toggle:hover {
106
106
  background-color: var(
107
- --hx-overlay-white-10,
107
+ --hx-color-border-on-dark-subtle,
108
108
  rgba(255, 255, 255, 0.1)
109
109
  ); /* fallback for browsers without color-mix() */
110
- color: var(--hx-color-text-inverse, #ebeee9);
110
+ color: var(--hx-side-nav-toggle-hover-color, var(--hx-color-text-inverse, #ffffff));
111
111
  }
112
112
 
113
113
  @supports (color: color-mix(in srgb, red 50%, blue)) {
@@ -118,10 +118,7 @@
118
118
 
119
119
  .side-nav__toggle:focus-visible {
120
120
  outline: var(--hx-focus-ring-width, 2px) solid
121
- var(
122
- --hx-side-nav-focus-ring-color,
123
- var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
124
- );
121
+ var(--hx-side-nav-focus-ring-color, var(--hx-focus-ring-color, #6ab1b1));
125
122
  outline-offset: var(--hx-focus-ring-offset, 2px);
126
123
  }
127
124
 
@@ -167,10 +164,18 @@
167
164
  }
168
165
 
169
166
  .side-nav__toggle {
167
+ forced-color-adjust: none;
168
+ background-color: ButtonFace;
170
169
  color: ButtonText;
171
170
  border: 1px solid ButtonText;
172
171
  }
173
172
 
173
+ .side-nav__toggle:hover {
174
+ background-color: Highlight;
175
+ color: HighlightText;
176
+ border-color: Highlight;
177
+ }
178
+
174
179
  .side-nav__toggle:focus-visible {
175
180
  outline: 3px solid Highlight;
176
181
  outline-offset: 2px;
@@ -291,10 +291,10 @@
291
291
 
292
292
  /* ─── High Contrast Mode (forced-colors) ───
293
293
  *
294
- * Component-specific overrides that complement the shared forcedColorsField
295
- * mixin (composed in static styles). The mixin handles the input/wrapper
296
- * core; the rules below extend it to the label / error / help-text /
297
- * disabled-host surfaces unique to hx-text-input.
294
+ * Bespoke block sole owner of forced-colors deference for hx-text-input.
295
+ * Covers wrapper/input/placeholder/focus/disabled/error/label/help-text;
296
+ * strictly more than forcedColorsField. The mixin is intentionally NOT
297
+ * composed (XOR rule see styles/forced-colors.ts COMPOSITION RULES).
298
298
  */
299
299
 
300
300
  @media (forced-colors: active) {
@@ -49,33 +49,38 @@
49
49
  * error-600) because the lighter -500 fills can't pass AA against white
50
50
  * text in the precision-cool palette. The neutral-900 on-{role} tokens
51
51
  * are tuned for the lighter -500 surfaces and would fail here (e.g.
52
- * neutral-900 on primary-600 = 3.07:1), so we hold fg at neutral-0
53
- * directly for primary/success/danger.
54
- * - neutral-0 on primary-600 (#0F7078) = 5.39:1 — AA pass
55
- * - neutral-0 on success-700 (#146831) = 6.88:1 — AA pass
52
+ * neutral-900 on primary-600 = 3.07:1), so the on-{role}-strong tokens
53
+ * (neutral-0, no dark-mode flip) keep fg legible on the darker fills.
54
+ * - text.on-primary-strong on info.bg-strong (primary-600, #0F7078) = 5.39:1
55
+ * - text.on-success-strong on success.bg-strong (success-700, #146831) = 6.88:1
56
56
  * (success-600 #0E8A4A on white = 4.41:1 — drifts under AA at 14px)
57
- * - neutral-0 on error-600 (#C92A2A) = 5.92:1 — AA pass
58
- * - neutral-900 on warning-500 (#C2711C) = 4.83:1 — AA pass
57
+ * - text.on-error-strong on danger.bg-strong (error-600, #C92A2A) = 5.92:1
58
+ * - text.on-warning on warning.bg-strong (warning-500, #C2711C) = 4.83:1
59
59
  * (warning stays on the lighter -500 surface so on-warning works)
60
+ *
61
+ * 3.2.1 token-cascade: bg variants now route through surface.{role}-strong
62
+ * semantics; fg variants route through text.on-{role}-strong (or on-warning
63
+ * for the warning variant). Component-tier tokens are NOT bypassed — the
64
+ * --hx-toast-bg / --hx-toast-color slots remain the single override point.
60
65
  */
61
66
  .toast--success {
62
- --hx-toast-bg: var(--hx-color-success-700, #146831);
63
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
67
+ --hx-toast-bg: var(--hx-color-surface-success-strong, #146831);
68
+ --hx-toast-color: var(--hx-color-text-on-success-strong, #ffffff);
64
69
  }
65
70
 
66
71
  .toast--warning {
67
- --hx-toast-bg: var(--hx-color-warning-500, #c2711c);
72
+ --hx-toast-bg: var(--hx-color-surface-warning-strong, #c2711c);
68
73
  --hx-toast-color: var(--hx-color-text-on-warning, #0d1825);
69
74
  }
70
75
 
71
76
  .toast--danger {
72
- --hx-toast-bg: var(--hx-color-error-600, #c92a2a);
73
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
77
+ --hx-toast-bg: var(--hx-color-surface-danger-strong, #c92a2a);
78
+ --hx-toast-color: var(--hx-color-text-on-error-strong, #ffffff);
74
79
  }
75
80
 
76
81
  .toast--info {
77
- --hx-toast-bg: var(--hx-color-primary-600, #0f7078);
78
- --hx-toast-color: var(--hx-color-neutral-0, #ffffff);
82
+ --hx-toast-bg: var(--hx-color-surface-info-strong, #0f7078);
83
+ --hx-toast-color: var(--hx-color-text-on-primary-strong, #ffffff);
79
84
  }
80
85
 
81
86
  /* ─── Severity Label (WCAG 1.4.1) ─── */
@@ -1,4 +1,4 @@
1
- /* index.css — generated 2026-04-25T17:34:50.957Z */
1
+ /* index.css — generated 2026-04-25T20:44:53.981Z */
2
2
  /* Imports all per-component CSS files for Drupal asset pipeline */
3
3
 
4
4
  @import './hx-accordion.css';
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-04-25T17:34:50.956Z",
2
+ "generated": "2026-04-25T20:44:53.980Z",
3
3
  "components": [
4
4
  {
5
5
  "name": "hx-accordion",
@@ -255,21 +255,34 @@
255
255
  "--hx-button-border-color",
256
256
  "--hx-button-border-radius",
257
257
  "--hx-button-color",
258
+ "--hx-button-focus-ring-color",
258
259
  "--hx-button-font-family",
259
260
  "--hx-button-font-weight",
260
261
  "--hx-button-hover-bg",
261
262
  "--hx-button-inverted-color",
263
+ "--hx-color-action-danger-bg",
264
+ "--hx-color-action-danger-bg-hover",
265
+ "--hx-color-action-ghost-bg-hover",
266
+ "--hx-color-action-ghost-fg",
267
+ "--hx-color-action-primary-bg",
268
+ "--hx-color-action-primary-bg-hover",
269
+ "--hx-color-action-primary-bg-inverted-hover",
270
+ "--hx-color-action-secondary-bg-hover",
271
+ "--hx-color-action-secondary-border",
272
+ "--hx-color-action-secondary-fg",
273
+ "--hx-color-border-on-dark-default",
274
+ "--hx-color-border-on-dark-strong",
275
+ "--hx-color-border-on-dark-subtle",
262
276
  "--hx-color-border-strong",
263
- "--hx-color-error-500",
264
- "--hx-color-error-600",
265
277
  "--hx-color-neutral-0",
266
- "--hx-color-primary-400",
267
278
  "--hx-color-primary-500",
268
- "--hx-color-primary-600",
269
279
  "--hx-color-surface-raised",
270
280
  "--hx-color-surface-sunken",
281
+ "--hx-color-text-inverse",
271
282
  "--hx-color-text-on-error",
283
+ "--hx-color-text-on-error-strong",
272
284
  "--hx-color-text-on-primary",
285
+ "--hx-color-text-on-primary-strong",
273
286
  "--hx-color-text-primary",
274
287
  "--hx-duration-spinner",
275
288
  "--hx-filter-brightness-active",
@@ -285,11 +298,6 @@
285
298
  "--hx-line-height-tight",
286
299
  "--hx-opacity-disabled",
287
300
  "--hx-opacity-muted",
288
- "--hx-overlay-white-15",
289
- "--hx-overlay-white-20",
290
- "--hx-overlay-white-25",
291
- "--hx-overlay-white-50",
292
- "--hx-overlay-white-70",
293
301
  "--hx-size-10",
294
302
  "--hx-size-12",
295
303
  "--hx-space-1",
@@ -1756,7 +1764,6 @@
1756
1764
  "--hx-border-radius-sm",
1757
1765
  "--hx-border-width-thin",
1758
1766
  "--hx-color-border-strong",
1759
- "--hx-color-primary-400",
1760
1767
  "--hx-color-surface-inverse",
1761
1768
  "--hx-color-text-inverse",
1762
1769
  "--hx-focus-ring-color",
@@ -1766,9 +1773,11 @@
1766
1773
  "--hx-side-nav-border-color",
1767
1774
  "--hx-side-nav-collapsed-width",
1768
1775
  "--hx-side-nav-color",
1776
+ "--hx-side-nav-focus-ring-color",
1769
1777
  "--hx-side-nav-footer-padding",
1770
1778
  "--hx-side-nav-header-padding",
1771
1779
  "--hx-side-nav-toggle-color",
1780
+ "--hx-side-nav-toggle-hover-color",
1772
1781
  "--hx-side-nav-width",
1773
1782
  "--hx-space-14",
1774
1783
  "--hx-space-2",
@@ -2453,14 +2462,16 @@
2453
2462
  "tokens": [
2454
2463
  "--hx-border-radius-md",
2455
2464
  "--hx-border-radius-sm",
2456
- "--hx-color-error-600",
2457
- "--hx-color-neutral-0",
2458
- "--hx-color-primary-600",
2459
- "--hx-color-success-700",
2465
+ "--hx-color-surface-danger-strong",
2466
+ "--hx-color-surface-info-strong",
2460
2467
  "--hx-color-surface-inverse",
2468
+ "--hx-color-surface-success-strong",
2469
+ "--hx-color-surface-warning-strong",
2461
2470
  "--hx-color-text-inverse",
2471
+ "--hx-color-text-on-error-strong",
2472
+ "--hx-color-text-on-primary-strong",
2473
+ "--hx-color-text-on-success-strong",
2462
2474
  "--hx-color-text-on-warning",
2463
- "--hx-color-warning-500",
2464
2475
  "--hx-focus-ring-offset",
2465
2476
  "--hx-focus-ring-width",
2466
2477
  "--hx-font-family-sans",
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { H as v } from "./shared/hx-avatar-C9hOmlAb.js";
6
6
  import { H as E } from "./shared/hx-badge-CQXgOXJM.js";
7
7
  import { H as k } from "./shared/hx-banner-DT7Zn9Bo.js";
8
8
  import { H as B, a as P } from "./shared/hx-breadcrumb-item-COeYcB2x.js";
9
- import { H as M } from "./shared/hx-button-modUSOpY.js";
9
+ import { H as M } from "./shared/hx-button-kWxjKqo-.js";
10
10
  import { H as N } from "./shared/hx-button-group-BI-QBqmO.js";
11
11
  import { H as A } from "./shared/hx-card-CU1QnjNb.js";
12
12
  import { H as G, a as U } from "./shared/hx-carousel-item-BaE4hpLl.js";
@@ -53,7 +53,7 @@ import { H as So } from "./shared/hx-prose-BThYcASV.js";
53
53
  import { H as To, a as bo } from "./shared/hx-radio-N8xgDd_5.js";
54
54
  import { H as go } from "./shared/hx-rating-i2FL1WUN.js";
55
55
  import { H as vo } from "./shared/hx-select-vgaBo1Ai.js";
56
- import { H as Eo, a as Do } from "./shared/hx-nav-item-D8xHLVOs.js";
56
+ import { H as Eo, a as Do } from "./shared/hx-nav-item-CMyMv5Gv.js";
57
57
  import { H as wo } from "./shared/hx-skeleton-Cnieh5Uc.js";
58
58
  import { H as Po } from "./shared/hx-slider-ydBamYhd.js";
59
59
  import { H as Mo } from "./shared/hx-spinner-DL5AYr16.js";
@@ -70,11 +70,11 @@ import { H as tt, a as rt, b as at, c as it, d as st, e as xt, f as Ht } from ".
70
70
  import { H as nt, a as pt, b as mt } from "./shared/hx-tab-panel-CbkO9VKu.js";
71
71
  import { H as ct } from "./shared/hx-tag-CNSmdyaK.js";
72
72
  import { H as ht } from "./shared/hx-text-Bz_9fJ3J.js";
73
- import { F as St, H as yt } from "./shared/hx-text-input-B-caO5fI.js";
73
+ import { F as St, H as yt } from "./shared/hx-text-input-ClrrmoE1.js";
74
74
  import { H as bt } from "./shared/hx-textarea-D9O4U8cb.js";
75
75
  import { H as gt } from "./shared/hx-theme-BiyQ7UUK.js";
76
76
  import { H as vt } from "./shared/hx-time-picker-m0z4nFB-.js";
77
- import { H as Et, a as Dt, t as kt } from "./shared/toast-factory-DvDRAh0l.js";
77
+ import { H as Et, a as Dt, t as kt } from "./shared/toast-factory-CIiZDZGZ.js";
78
78
  import { H as Bt } from "./shared/hx-toggle-button-Dd8clXB4.js";
79
79
  import { H as Ft } from "./shared/hx-tooltip-nYOv9OLu.js";
80
80
  import { H as Lt } from "./shared/hx-top-nav-CchPYaiV.js";
@@ -1,12 +1,11 @@
1
- import { css as f, html as u, nothing as s } from "lit";
1
+ import { css as f, html as d, nothing as s } from "lit";
2
2
  import { property as a, customElement as v } from "lit/decorators.js";
3
- import { classMap as d } from "lit/directives/class-map.js";
3
+ import { classMap as b } from "lit/directives/class-map.js";
4
4
  import { ifDefined as c } from "lit/directives/if-defined.js";
5
- import { f as p } from "./forced-colors-CTEDFRGa.js";
6
- import { d as x } from "./dev-warn-YlwPHjtX.js";
7
- import { m } from "./aria-delegation-Doq6RRUy.js";
5
+ import { d as p } from "./dev-warn-YlwPHjtX.js";
6
+ import { m as x } from "./aria-delegation-Doq6RRUy.js";
8
7
  import { H as g } from "./helix-element-BNEYeiys.js";
9
- const y = f`
8
+ const m = f`
10
9
  :host {
11
10
  display: inline-block;
12
11
  }
@@ -54,10 +53,7 @@ const y = f`
54
53
 
55
54
  .button:focus-visible {
56
55
  outline: var(--hx-focus-ring-width, 2px) solid
57
- var(
58
- --hx-button-focus-ring-color,
59
- var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
60
- );
56
+ var(--hx-button-focus-ring-color, var(--hx-focus-ring-color, #6ab1b1));
61
57
  outline-offset: var(--hx-focus-ring-offset, 2px);
62
58
  }
63
59
 
@@ -95,8 +91,11 @@ const y = f`
95
91
  /* ─── Style Variants ─── */
96
92
 
97
93
  .button--primary {
98
- --hx-button-bg: var(--hx-color-primary-500, #429797);
99
- --hx-button-color: var(--hx-color-text-on-primary, #ffffff);
94
+ --hx-button-bg: var(--hx-color-action-primary-bg, #429797);
95
+ /* Inline #0d1825 matches text.on-primary's resolved primitive (neutral-900);
96
+ cold-start without the semantic still paints AA-tuned dark-on-primary
97
+ rather than white-on-primary (3.43:1 fail). */
98
+ --hx-button-color: var(--hx-color-text-on-primary, #0d1825);
100
99
  --hx-button-border-color: transparent;
101
100
  }
102
101
 
@@ -104,12 +103,12 @@ const y = f`
104
103
  --hx-button-bg: transparent;
105
104
  /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
106
105
  primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
107
- --hx-button-color: var(--hx-color-primary-600, #0f7078);
108
- --hx-button-border-color: var(--hx-color-primary-600, #0f7078);
106
+ --hx-button-color: var(--hx-color-action-secondary-fg, #0f7078);
107
+ --hx-button-border-color: var(--hx-color-action-secondary-border, #0f7078);
109
108
  }
110
109
 
111
110
  .button--secondary:hover {
112
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));
111
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-secondary-bg-hover, #ebf8f8));
113
112
  }
114
113
 
115
114
  .button--tertiary {
@@ -123,30 +122,34 @@ const y = f`
123
122
  }
124
123
 
125
124
  .button--danger {
126
- --hx-button-bg: var(--hx-color-error-500, #e5493e);
127
- --hx-button-color: var(--hx-color-text-on-error, #ffffff);
125
+ --hx-button-bg: var(--hx-color-action-danger-bg, #e5493e);
126
+ /* Inline #0d1825 matches text.on-error's resolved primitive (neutral-900);
127
+ cold-start without the semantic still paints AA-tuned dark-on-error
128
+ rather than white-on-error (3.92:1 fail). */
129
+ --hx-button-color: var(--hx-color-text-on-error, #0d1825);
128
130
  --hx-button-border-color: transparent;
129
131
  }
130
132
 
131
133
  /* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).
132
- error-600 (#C92A2A) drops that to 2.25:1 — AA fail. Hold fg at neutral-0
133
- directly so darker hover fills stay legible. Mirrors hx-toast precedent
134
- (commit 300e21ab0). */
134
+ error-600 (#C92A2A) drops that to 2.25:1 — AA fail. text.on-error-strong
135
+ resolves to neutral-0 across modes (no dark flip) so the darker hover fill
136
+ stays legible. Mirrors hx-toast precedent (commit 300e21ab0); routed
137
+ through the semantic tier in 3.2.1 token-cascade remediation. */
135
138
  .button--danger:hover {
136
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-error-600, #c92a2a));
137
- --hx-button-color: var(--hx-color-neutral-0, #ffffff);
139
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-hover, #c92a2a));
140
+ --hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);
138
141
  }
139
142
 
140
143
  .button--ghost {
141
144
  --hx-button-bg: transparent;
142
145
  /* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
143
146
  primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
144
- --hx-button-color: var(--hx-color-primary-600, #0f7078);
147
+ --hx-button-color: var(--hx-color-action-ghost-fg, #0f7078);
145
148
  --hx-button-border-color: transparent;
146
149
  }
147
150
 
148
151
  .button--ghost:hover {
149
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));
152
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-ghost-bg-hover, #ebf8f8));
150
153
  }
151
154
 
152
155
  .button--outline {
@@ -160,12 +163,13 @@ const y = f`
160
163
  }
161
164
 
162
165
  /* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.
163
- primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. Pin fg at
164
- neutral-0 for the darker hover fill. Mirrors hx-toast precedent
165
- (commit 300e21ab0). */
166
+ primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. text.on-primary-strong
167
+ resolves to neutral-0 across modes (no dark flip) for the darker hover fill.
168
+ Mirrors hx-toast precedent (commit 300e21ab0); routed through the semantic
169
+ tier in 3.2.1 token-cascade remediation. */
166
170
  .button--primary:hover {
167
- --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-primary-600, #0f7078));
168
- --hx-button-color: var(--hx-color-neutral-0, #ffffff);
171
+ --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-hover, #0f7078));
172
+ --hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);
169
173
  }
170
174
 
171
175
  /* ─── Disabled ─── */
@@ -211,7 +215,7 @@ const y = f`
211
215
 
212
216
  /* Override text color and filter-based hover/active for all variants */
213
217
  :host([inverted]) .button {
214
- color: var(--hx-button-inverted-color, var(--hx-color-neutral-0, #ffffff));
218
+ color: var(--hx-button-inverted-color, var(--hx-color-text-inverse, #ffffff));
215
219
  filter: none;
216
220
  }
217
221
 
@@ -224,37 +228,42 @@ const y = f`
224
228
  }
225
229
 
226
230
  :host([inverted]) .button:focus-visible {
231
+ /* WCAG 1.4.11: focus indicator needs ≥3:1 against adjacent colors.
232
+ border-on-dark-default (overlay-white-30) ≈ 2.7:1 on neutral-900 — fails.
233
+ border-on-dark-strong (overlay-white-70) ≈ 5:1 — passes. */
227
234
  outline-color: var(
228
235
  --hx-button-inverted-focus-ring-color,
229
- var(--hx-overlay-white-50, rgba(255, 255, 255, 0.5))
236
+ var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))
230
237
  );
231
238
  }
232
239
 
233
240
  /* Primary inverted — slight transparent white overlay on hover */
234
241
  :host([inverted]) .button--primary:hover {
235
- --hx-button-bg: var(--hx-color-primary-400, #6ab1b1);
242
+ --hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
236
243
  }
237
244
 
238
- /* Secondary inverted — white border and text */
245
+ /* Secondary inverted — white border and translucent hover fill */
239
246
  :host([inverted]) .button--secondary {
240
- --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));
247
+ --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
241
248
  }
242
249
 
243
250
  :host([inverted]) .button--secondary:hover {
244
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
251
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
245
252
  }
246
253
 
247
- /* Tertiary inverted */
254
+ /* Tertiary inverted — resting at subtle (10%) lifts to default (30%) on hover
255
+ so the runtime hover delta is visually distinct, not collapsed onto a
256
+ single token. */
248
257
  :host([inverted]) .button--tertiary {
249
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
258
+ --hx-button-bg: var(--hx-color-border-on-dark-subtle, rgba(255, 255, 255, 0.1));
250
259
  --hx-button-border-color: transparent;
251
260
  }
252
261
 
253
262
  :host([inverted]) .button--tertiary:hover {
254
- --hx-button-bg: var(--hx-overlay-white-25, rgba(255, 255, 255, 0.25));
263
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
255
264
  }
256
265
 
257
- /* Ghost inverted — transparent base, white hover bg */
266
+ /* Ghost inverted — transparent base, translucent hover bg */
258
267
  :host([inverted]) .button--ghost {
259
268
  --hx-button-bg: transparent;
260
269
  --hx-button-border-color: transparent;
@@ -263,17 +272,17 @@ const y = f`
263
272
  :host([inverted]) .button--ghost:hover {
264
273
  --hx-button-bg: var(
265
274
  --hx-button-inverted-ghost-hover-bg,
266
- var(--hx-overlay-white-20, rgba(255, 255, 255, 0.2))
275
+ var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3))
267
276
  );
268
277
  }
269
278
 
270
279
  /* Outline inverted — white border */
271
280
  :host([inverted]) .button--outline {
272
- --hx-button-border-color: var(--hx-overlay-white-70, rgba(255, 255, 255, 0.7));
281
+ --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
273
282
  }
274
283
 
275
284
  :host([inverted]) .button--outline:hover {
276
- --hx-button-bg: var(--hx-overlay-white-15, rgba(255, 255, 255, 0.15));
285
+ --hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
277
286
  }
278
287
 
279
288
  /* ─── Prefix / Suffix / Label ─── */
@@ -301,6 +310,16 @@ const y = f`
301
310
  border: 2px solid ButtonText;
302
311
  }
303
312
 
313
+ .button:hover {
314
+ /* Hover affordance must survive in HC. Highlight/HighlightText is the
315
+ OS-level "selected" pair, mirroring the forcedColorsInteractive mixin's
316
+ hover contract — kept inline since this component owns its bespoke HC
317
+ block (XOR rule). */
318
+ background-color: Highlight;
319
+ color: HighlightText;
320
+ border-color: Highlight;
321
+ }
322
+
304
323
  .button:focus-visible {
305
324
  outline: 3px solid Highlight;
306
325
  outline-offset: 2px;
@@ -323,12 +342,12 @@ const y = f`
323
342
  }
324
343
  }
325
344
  `;
326
- var _ = Object.defineProperty, w = Object.getOwnPropertyDescriptor, n = (t, r, h, i) => {
327
- for (var o = i > 1 ? void 0 : i ? w(r, h) : r, l = t.length - 1, b; l >= 0; l--)
328
- (b = t[l]) && (o = (i ? b(r, h, o) : b(o)) || o);
329
- return i && o && _(r, h, o), o;
345
+ var y = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, n = (t, r, l, i) => {
346
+ for (var o = i > 1 ? void 0 : i ? _(r, l) : r, h = t.length - 1, u; h >= 0; h--)
347
+ (u = t[h]) && (o = (i ? u(r, l, o) : u(o)) || o);
348
+ return i && o && y(r, l, o), o;
330
349
  };
331
- let e = class extends m(g) {
350
+ let e = class extends x(g) {
332
351
  constructor() {
333
352
  super(...arguments), this.variant = "primary", this.size = "md", this.disabled = !1, this.loading = !1, this.type = "button", this.href = void 0, this.target = void 0, this.name = void 0, this.value = void 0, this.full = !1, this.inverted = !1, this.accessibleLabel = "", this._emptySlotWarnEmitted = !1;
334
353
  }
@@ -351,15 +370,15 @@ let e = class extends m(g) {
351
370
  const r = (i = this.shadowRoot) == null ? void 0 : i.querySelector("slot:not([name])");
352
371
  !((r == null ? void 0 : r.assignedNodes({ flatten: !0 })) ?? []).some(
353
372
  (o) => {
354
- var l;
355
- return o.nodeType !== Node.TEXT_NODE || (((l = o.textContent) == null ? void 0 : l.trim().length) ?? 0) > 0;
373
+ var h;
374
+ return o.nodeType !== Node.TEXT_NODE || (((h = o.textContent) == null ? void 0 : h.trim().length) ?? 0) > 0;
356
375
  }
357
376
  ) && !this._effectiveLabel && (this._emptySlotWarnEmitted = !0);
358
377
  }
359
378
  updated(t) {
360
379
  if (super.updated(t), t.has("variant")) {
361
380
  const r = [...e._VALID_VARIANTS];
362
- r.includes(this.variant) || (x(
381
+ r.includes(this.variant) || (p(
363
382
  "hx-button",
364
383
  `Invalid variant "${this.variant}". Expected one of: ${r.join(", ")}. Clamping to "primary".`
365
384
  ), this.variant = "primary");
@@ -368,11 +387,11 @@ let e = class extends m(g) {
368
387
  // ─── Slot Handlers ───
369
388
  /** @internal */
370
389
  _handleDefaultSlotChange(t) {
371
- const h = t.target.assignedNodes({ flatten: !0 }).some((i) => {
390
+ const l = t.target.assignedNodes({ flatten: !0 }).some((i) => {
372
391
  var o;
373
392
  return i.nodeType !== Node.TEXT_NODE || (((o = i.textContent) == null ? void 0 : o.trim().length) ?? 0) > 0;
374
393
  });
375
- !h && !this._effectiveLabel && this._emptySlotWarnEmitted, h && (this._emptySlotWarnEmitted = !1);
394
+ !l && !this._effectiveLabel && this._emptySlotWarnEmitted, l && (this._emptySlotWarnEmitted = !1);
376
395
  }
377
396
  // ─── Event Handling ───
378
397
  /**
@@ -398,7 +417,7 @@ let e = class extends m(g) {
398
417
  * @internal
399
418
  */
400
419
  _renderSpinner() {
401
- return u`
420
+ return d`
402
421
  <svg
403
422
  class="button__spinner"
404
423
  part="spinner"
@@ -430,7 +449,7 @@ let e = class extends m(g) {
430
449
  * @internal
431
450
  */
432
451
  _renderInner() {
433
- return u`
452
+ return d`
434
453
  ${this.loading ? this._renderSpinner() : s}
435
454
  <span part="prefix" class="button__prefix">
436
455
  <slot name="prefix"></slot>
@@ -451,10 +470,10 @@ let e = class extends m(g) {
451
470
  [`button--${this.size}`]: !0,
452
471
  "button--loading": this.loading
453
472
  };
454
- return this.href !== void 0 ? u`
473
+ return this.href !== void 0 ? d`
455
474
  <a
456
475
  part="button"
457
- class=${d(t)}
476
+ class=${b(t)}
458
477
  href=${this.disabled || this.loading ? s : c(this.href)}
459
478
  target=${c(this.target)}
460
479
  rel=${this.target === "_blank" ? "noopener noreferrer" : s}
@@ -466,10 +485,10 @@ let e = class extends m(g) {
466
485
  >
467
486
  ${this._renderInner()}
468
487
  </a>
469
- ` : u`
488
+ ` : d`
470
489
  <button
471
490
  part="button"
472
- class=${d(t)}
491
+ class=${b(t)}
473
492
  ?disabled=${this.disabled}
474
493
  type=${this.type}
475
494
  aria-label=${this._effectiveLabel || s}
@@ -481,7 +500,7 @@ let e = class extends m(g) {
481
500
  `;
482
501
  }
483
502
  };
484
- e.styles = [y, p];
503
+ e.styles = [m];
485
504
  e.formAssociated = !0;
486
505
  e._VALID_VARIANTS = [
487
506
  "primary",
@@ -533,4 +552,4 @@ e = n([
533
552
  export {
534
553
  e as H
535
554
  };
536
- //# sourceMappingURL=hx-button-modUSOpY.js.map
555
+ //# sourceMappingURL=hx-button-kWxjKqo-.js.map