@helixui/library 3.2.0-next.89 → 3.2.0-next.91

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.
@@ -2831,9 +2831,13 @@
2831
2831
  "default": "var(--hx-color-action-primary-bg)"
2832
2832
  },
2833
2833
  {
2834
- "description": "Hover background override; when set, overrides the variant default hover background from outside the shadow DOM.",
2834
+ "description": "Hover background override (primary and danger variants only). Other variants (secondary/outline, ghost) keep their hover fills routed through their semantic action.* tokens and do not consume this hook. Under [inverted] for primary/danger, hover and active share a paint (combined :hover, :active rule), so this override applies to both states unless --hx-button-active-bg also takes precedence.",
2835
2835
  "name": "--hx-button-hover-bg"
2836
2836
  },
2837
+ {
2838
+ "description": "Pressed/active background override (primary and danger variants only, including their inverted modes). Takes precedence over --hx-button-hover-bg in the fallback chain. Standard-mode primary/danger default to action.{primary,danger}.bg-active (with filter:none) for AA-pinned pressed contrast. Inverted-mode primary/danger reuse action.{primary,danger}.bg-inverted-hover (combined :hover, :active rule); setting --hx-button-active-bg under [inverted] therefore overrides the lifted hover fill as well as the pressed fill — the two share a paint in inverted mode. Other variants do not consume this hook.",
2839
+ "name": "--hx-button-active-bg"
2840
+ },
2837
2841
  {
2838
2842
  "description": "Button text color (variants route through text.on-{role} / text.on-{role}-strong).",
2839
2843
  "name": "--hx-button-color",
@@ -2869,6 +2873,16 @@
2869
2873
  "name": "--hx-button-inverted-color",
2870
2874
  "default": "var(--hx-color-text-inverse)"
2871
2875
  },
2876
+ {
2877
+ "description": "Foreground override for inverted primary hover and pressed (combined :hover, :active rule). Defaults to text.on-primary (neutral-900, no dark-mode flip) so dark text rides the lifted primary-400 fill — text.inverse on light teal collapses to ~2.4:1 in light mode.",
2878
+ "name": "--hx-button-inverted-primary-interactive-color",
2879
+ "default": "var(--hx-color-text-on-primary)"
2880
+ },
2881
+ {
2882
+ "description": "Foreground override for inverted danger hover and pressed (combined :hover, :active rule). Defaults to text.on-error (neutral-900); same rationale as the primary override.",
2883
+ "name": "--hx-button-inverted-danger-interactive-color",
2884
+ "default": "var(--hx-color-text-on-error)"
2885
+ },
2872
2886
  {
2873
2887
  "description": "Ghost hover bg when inverted (overlay-white-30 ≈ 5:1 vs neutral-900).",
2874
2888
  "name": "--hx-button-inverted-ghost-hover-bg",
@@ -2892,15 +2906,15 @@
2892
2906
  "name": "--hx-color-action-primary-bg-active"
2893
2907
  },
2894
2908
  {
2895
- "description": "Secondary/outline variant fg (resolves to primary-600 light, primary-400 dark).",
2909
+ "description": "Secondary/outline variant fg (resolves to primary-600 light, primary-400 dark). Consumed only by .button--secondary; the actual border/surface paint for outline currently routes through --hx-color-border-strong / --hx-color-surface-raised in styles, with this token reserved for the foreground.",
2896
2910
  "name": "--hx-color-action-secondary-fg"
2897
2911
  },
2898
2912
  {
2899
- "description": "Secondary/outline variant border.",
2913
+ "description": "Secondary/outline variant border (3.2.1 semantic; outline still routes through --hx-color-border-strong by default).",
2900
2914
  "name": "--hx-color-action-secondary-border"
2901
2915
  },
2902
2916
  {
2903
- "description": "Secondary/outline variant hover fill.",
2917
+ "description": "Secondary/outline variant hover fill (3.2.1 semantic; outline still routes through --hx-color-surface-raised by default).",
2904
2918
  "name": "--hx-color-action-secondary-bg-hover"
2905
2919
  },
2906
2920
  {
@@ -2923,6 +2937,14 @@
2923
2937
  "description": "Danger variant active fill.",
2924
2938
  "name": "--hx-color-action-danger-bg-active"
2925
2939
  },
2940
+ {
2941
+ "description": "Primary variant hover/pressed fill on dark/inverted surface (resolves to primary-400, 7.27:1 on neutral-900).",
2942
+ "name": "--hx-color-action-primary-bg-inverted-hover"
2943
+ },
2944
+ {
2945
+ "description": "Danger variant hover/pressed fill on dark/inverted surface (resolves to error-400, 6.58:1 on neutral-900).",
2946
+ "name": "--hx-color-action-danger-bg-inverted-hover"
2947
+ },
2926
2948
  {
2927
2949
  "description": "Foreground for primary fill (resolves to neutral-900 — AA-tuned for primary-500).",
2928
2950
  "name": "--hx-color-text-on-primary"
@@ -3113,7 +3135,7 @@
3113
3135
  "text": "boolean"
3114
3136
  },
3115
3137
  "default": "false",
3116
- "description": "When true, flips button colors for placement on dark or gradient backgrounds.\nForces text to white and adjusts hover/focus ring colors across all variants.",
3138
+ "description": "When true, flips button colors for placement on dark or gradient backgrounds.\nForces text to white and adjusts hover/focus ring colors across all variants.\n\n**Mode scope:** `[inverted]` is validated for placement on a dark *region*\nwithin a light-mode-active page (hero banners, gradient sections, dark\ncards). It is NOT validated for use within a dark-mode-active root\ncontext: in dark mode, `surface.inverse` flips to a light surface\n(neutral-100), and the lifted `-400` hover/active fills lose UI-floor\ncontrast against it (primary 2.10:1, danger 2.32:1 vs WCAG 1.4.11's 3:1\nfloor). Mode-aware fill stops + foreground for the dark-mode-inverted\ncombination are tracked as a 3.2.x follow-up.",
3117
3139
  "attribute": "inverted",
3118
3140
  "reflects": true
3119
3141
  },
@@ -3271,7 +3293,7 @@
3271
3293
  "text": "boolean"
3272
3294
  },
3273
3295
  "default": "false",
3274
- "description": "When true, flips button colors for placement on dark or gradient backgrounds.\nForces text to white and adjusts hover/focus ring colors across all variants.",
3296
+ "description": "When true, flips button colors for placement on dark or gradient backgrounds.\nForces text to white and adjusts hover/focus ring colors across all variants.\n\n**Mode scope:** `[inverted]` is validated for placement on a dark *region*\nwithin a light-mode-active page (hero banners, gradient sections, dark\ncards). It is NOT validated for use within a dark-mode-active root\ncontext: in dark mode, `surface.inverse` flips to a light surface\n(neutral-100), and the lifted `-400` hover/active fills lose UI-floor\ncontrast against it (primary 2.10:1, danger 2.32:1 vs WCAG 1.4.11's 3:1\nfloor). Mode-aware fill stops + foreground for the dark-mode-inverted\ncombination are tracked as a 3.2.x follow-up.",
3275
3297
  "fieldName": "inverted",
3276
3298
  "attribute": "inverted"
3277
3299
  },
@@ -29740,7 +29762,7 @@
29740
29762
  "name": "--hx-color-error-text"
29741
29763
  },
29742
29764
  {
29743
- "description": "Error border primitive fallback inside the focus-state cascade.",
29765
+ "description": "Error border primitive fallback inside the invalid-state cascade.",
29744
29766
  "name": "--hx-color-error-600"
29745
29767
  }
29746
29768
  ],
@@ -28,7 +28,8 @@ declare const HelixButton_base: typeof HelixElement;
28
28
  * @csspart spinner - The loading spinner SVG element.
29
29
  *
30
30
  * @cssprop [--hx-button-bg=var(--hx-color-action-primary-bg)] - Button background color (3.2.1 cascade — variant rules route through action.{primary,secondary,ghost,danger}.bg).
31
- * @cssprop [--hx-button-hover-bg] - Hover background override; when set, overrides the variant default hover background from outside the shadow DOM.
31
+ * @cssprop [--hx-button-hover-bg] - Hover background override (primary and danger variants only). Other variants (secondary/outline, ghost) keep their hover fills routed through their semantic action.* tokens and do not consume this hook. Under [inverted] for primary/danger, hover and active share a paint (combined :hover, :active rule), so this override applies to both states unless --hx-button-active-bg also takes precedence.
32
+ * @cssprop [--hx-button-active-bg] - Pressed/active background override (primary and danger variants only, including their inverted modes). Takes precedence over --hx-button-hover-bg in the fallback chain. Standard-mode primary/danger default to action.{primary,danger}.bg-active (with filter:none) for AA-pinned pressed contrast. Inverted-mode primary/danger reuse action.{primary,danger}.bg-inverted-hover (combined :hover, :active rule); setting --hx-button-active-bg under [inverted] therefore overrides the lifted hover fill as well as the pressed fill — the two share a paint in inverted mode. Other variants do not consume this hook.
32
33
  * @cssprop [--hx-button-color=var(--hx-color-text-on-primary)] - Button text color (variants route through text.on-{role} / text.on-{role}-strong).
33
34
  * @cssprop [--hx-button-border-color=transparent] - Button border color (secondary/outline variants route through action.secondary.border).
34
35
  * @cssprop [--hx-button-border-radius=var(--hx-border-radius-md)] - Button border radius.
@@ -37,20 +38,24 @@ declare const HelixButton_base: typeof HelixElement;
37
38
  * @cssprop [--hx-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.
38
39
  *
39
40
  * @cssprop [--hx-button-inverted-color=var(--hx-color-text-inverse)] - Text color when inverted (resolves to neutral-0).
41
+ * @cssprop [--hx-button-inverted-primary-interactive-color=var(--hx-color-text-on-primary)] - Foreground override for inverted primary hover and pressed (combined :hover, :active rule). Defaults to text.on-primary (neutral-900, no dark-mode flip) so dark text rides the lifted primary-400 fill — text.inverse on light teal collapses to ~2.4:1 in light mode.
42
+ * @cssprop [--hx-button-inverted-danger-interactive-color=var(--hx-color-text-on-error)] - Foreground override for inverted danger hover and pressed (combined :hover, :active rule). Defaults to text.on-error (neutral-900); same rationale as the primary override.
40
43
  * @cssprop [--hx-button-inverted-ghost-hover-bg=var(--hx-color-border-on-dark-default)] - Ghost hover bg when inverted (overlay-white-30 ≈ 5:1 vs neutral-900).
41
44
  * @cssprop [--hx-button-inverted-focus-ring-color=var(--hx-color-border-on-dark-strong)] - Focus ring color when inverted (overlay-white-70 = ~5:1 vs neutral-900).
42
45
  *
43
46
  * @cssprop [--hx-color-action-primary-bg] - Primary variant resting fill (3.2.1 semantic action layer).
44
47
  * @cssprop [--hx-color-action-primary-bg-hover] - Primary variant hover fill.
45
48
  * @cssprop [--hx-color-action-primary-bg-active] - Primary variant active/pressed fill.
46
- * @cssprop [--hx-color-action-secondary-fg] - Secondary/outline variant fg (resolves to primary-600 light, primary-400 dark).
47
- * @cssprop [--hx-color-action-secondary-border] - Secondary/outline variant border.
48
- * @cssprop [--hx-color-action-secondary-bg-hover] - Secondary/outline variant hover fill.
49
+ * @cssprop [--hx-color-action-secondary-fg] - Secondary/outline variant fg (resolves to primary-600 light, primary-400 dark). Consumed only by .button--secondary; the actual border/surface paint for outline currently routes through --hx-color-border-strong / --hx-color-surface-raised in styles, with this token reserved for the foreground.
50
+ * @cssprop [--hx-color-action-secondary-border] - Secondary/outline variant border (3.2.1 semantic; outline still routes through --hx-color-border-strong by default).
51
+ * @cssprop [--hx-color-action-secondary-bg-hover] - Secondary/outline variant hover fill (3.2.1 semantic; outline still routes through --hx-color-surface-raised by default).
49
52
  * @cssprop [--hx-color-action-ghost-fg] - Ghost variant fg.
50
53
  * @cssprop [--hx-color-action-ghost-bg-hover] - Ghost variant hover fill.
51
54
  * @cssprop [--hx-color-action-danger-bg] - Danger variant resting fill.
52
55
  * @cssprop [--hx-color-action-danger-bg-hover] - Danger variant hover fill.
53
56
  * @cssprop [--hx-color-action-danger-bg-active] - Danger variant active fill.
57
+ * @cssprop [--hx-color-action-primary-bg-inverted-hover] - Primary variant hover/pressed fill on dark/inverted surface (resolves to primary-400, 7.27:1 on neutral-900).
58
+ * @cssprop [--hx-color-action-danger-bg-inverted-hover] - Danger variant hover/pressed fill on dark/inverted surface (resolves to error-400, 6.58:1 on neutral-900).
54
59
  * @cssprop [--hx-color-text-on-primary] - Foreground for primary fill (resolves to neutral-900 — AA-tuned for primary-500).
55
60
  * @cssprop [--hx-color-text-on-primary-strong] - Foreground for primary-hover fill (resolves to neutral-0 across modes).
56
61
  * @cssprop [--hx-color-text-on-error] - Foreground for danger fill (resolves to neutral-900).
@@ -121,6 +126,16 @@ export declare class HelixButton extends HelixButton_base {
121
126
  /**
122
127
  * When true, flips button colors for placement on dark or gradient backgrounds.
123
128
  * Forces text to white and adjusts hover/focus ring colors across all variants.
129
+ *
130
+ * **Mode scope:** `[inverted]` is validated for placement on a dark *region*
131
+ * within a light-mode-active page (hero banners, gradient sections, dark
132
+ * cards). It is NOT validated for use within a dark-mode-active root
133
+ * context: in dark mode, `surface.inverse` flips to a light surface
134
+ * (neutral-100), and the lifted `-400` hover/active fills lose UI-floor
135
+ * contrast against it (primary 2.10:1, danger 2.32:1 vs WCAG 1.4.11's 3:1
136
+ * floor). Mode-aware fill stops + foreground for the dark-mode-inverted
137
+ * combination are tracked as a 3.2.x follow-up.
138
+ *
124
139
  * @attr inverted
125
140
  */
126
141
  inverted: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"hx-button.d.ts","sourceRoot":"","sources":["../../../src/components/hx-button/hx-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC9E,OAAO,4CAA4C,CAAC;AAIpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKnD,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,UAAU,CAAC;CAC3B;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,qBACa,WAAY,SAAQ,gBAAgC;IAM/D,OAAgB,MAAM,4BAAuB;IAI7C,gBAAgB;IAChB,OAAgB,cAAc,UAAQ;IAItC;;;OAGG;IAEH,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAa;IAE3F;;;OAGG;IAEH,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEhC;;;OAGG;IAEH,QAAQ,UAAS;IAEjB;;;;OAIG;IAEH,OAAO,UAAS;IAEhB;;;OAGG;IAEH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAY;IAE/C;;;OAGG;IAEH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAa;IAErC;;;OAGG;IAEH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAa;IAEvC;;;OAGG;IAEH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAa;IAErC;;;OAGG;IAEH,KAAK,EAAE,MAAM,GAAG,SAAS,CAAa;IAEtC;;;;OAIG;IAEH,IAAI,UAAS;IAEb;;;;OAIG;IAEH,QAAQ,UAAS;IAEjB;;;;;;;;OAQG;IAEH,eAAe,EAAE,MAAM,CAAM;IAE7B;;;;OAIG;IACH,OAAO,KAAK,eAAe,GAE1B;cAIkB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAM3D,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAO5B;IAGX,OAAO,CAAC,qBAAqB,CAAS;IAE7B,YAAY,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAe3D,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAgB/D,gBAAgB;IAChB,OAAO,CAAC,wBAAwB;IAoBhC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAgCpB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA6BtB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAiBX,MAAM;CAyChB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,WAAW,CAAC;KAC1B;IACD,UAAU,mBAAmB;QAC3B,UAAU,EAAE,WAAW,CAAC;YAAE,aAAa,EAAE,UAAU,CAAA;SAAE,CAAC,CAAC;KACxD;CACF"}
1
+ {"version":3,"file":"hx-button.d.ts","sourceRoot":"","sources":["../../../src/components/hx-button/hx-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC9E,OAAO,4CAA4C,CAAC;AAIpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKnD,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,UAAU,CAAC;CAC3B;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,qBACa,WAAY,SAAQ,gBAAgC;IAM/D,OAAgB,MAAM,4BAAuB;IAI7C,gBAAgB;IAChB,OAAgB,cAAc,UAAQ;IAItC;;;OAGG;IAEH,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAa;IAE3F;;;OAGG;IAEH,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAEhC;;;OAGG;IAEH,QAAQ,UAAS;IAEjB;;;;OAIG;IAEH,OAAO,UAAS;IAEhB;;;OAGG;IAEH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAY;IAE/C;;;OAGG;IAEH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAa;IAErC;;;OAGG;IAEH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAa;IAEvC;;;OAGG;IAEH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAa;IAErC;;;OAGG;IAEH,KAAK,EAAE,MAAM,GAAG,SAAS,CAAa;IAEtC;;;;OAIG;IAEH,IAAI,UAAS;IAEb;;;;;;;;;;;;;;OAcG;IAEH,QAAQ,UAAS;IAEjB;;;;;;;;OAQG;IAEH,eAAe,EAAE,MAAM,CAAM;IAE7B;;;;OAIG;IACH,OAAO,KAAK,eAAe,GAE1B;cAIkB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAM3D,gBAAgB;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAO5B;IAGX,OAAO,CAAC,qBAAqB,CAAS;IAE7B,YAAY,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAe3D,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAgB/D,gBAAgB;IAChB,OAAO,CAAC,wBAAwB;IAoBhC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAgCpB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA6BtB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAiBX,MAAM;CAyChB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,WAAW,CAAC;KAC1B;IACD,UAAU,mBAAmB;QAC3B,UAAU,EAAE,WAAW,CAAC;YAAE,aAAa,EAAE,UAAU,CAAA;SAAE,CAAC,CAAC;KACxD;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"hx-button.styles.d.ts","sourceRoot":"","sources":["../../../src/components/hx-button/hx-button.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,yBAuW7B,CAAC"}
1
+ {"version":3,"file":"hx-button.styles.d.ts","sourceRoot":"","sources":["../../../src/components/hx-button/hx-button.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,yBA4Y7B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { H as e } from "../../shared/hx-button-D3Royxqp.js";
1
+ import { H as e } from "../../shared/hx-button-ebUV8KhT.js";
2
2
  export {
3
3
  e as HelixButton
4
4
  };
@@ -1,4 +1,4 @@
1
- import { H as i, a as x } from "../../shared/hx-nav-item-C9zXD1zK.js";
1
+ import { H as i, a as x } from "../../shared/hx-nav-item-CvTxO3Sa.js";
2
2
  export {
3
3
  i as HelixNavItem,
4
4
  x as HelixSideNav
@@ -53,7 +53,7 @@ declare const HelixTextInput_base: typeof HelixElement & (new (...args: any[]) =
53
53
  * @cssprop [--hx-color-text-strong] - Resting input text + label color (semantic).
54
54
  * @cssprop [--hx-color-border-strong] - Resting border color (semantic).
55
55
  * @cssprop [--hx-color-error-text] - Error state text + border color (semantic).
56
- * @cssprop [--hx-color-error-600] - Error border primitive fallback inside the focus-state cascade.
56
+ * @cssprop [--hx-color-error-600] - Error border primitive fallback inside the invalid-state cascade.
57
57
  */
58
58
  export declare class HelixTextInput extends HelixTextInput_base {
59
59
  static styles: import('lit').CSSResult[];
@@ -1279,9 +1279,46 @@
1279
1279
  );
1280
1280
  }
1281
1281
 
1282
- /* Primary inverted — slight transparent white overlay on hover */
1283
- :host([inverted]) .button--primary:hover {
1284
- --hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
1282
+ /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover
1283
+ (primary-400, light teal). The base :host([inverted]) .button rule binds
1284
+ color to text.inverse, which flips by mode (neutral-0 in light, neutral-900
1285
+ in dark). On a permanent light-teal fill, white text drops to 2.4:1 in
1286
+ light mode (AA fail). Pin color to text.on-primary (neutral-900, no
1287
+ dark-mode flip) for both hover and active so the foreground is dark in
1288
+ both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).
1289
+ Pressed === hover visually in inverted mode is acceptable UX (the
1290
+ transient absence of pointer over the button signals release).
1291
+ The fallback chain wraps --hx-button-active-bg (highest precedence) and
1292
+ --hx-button-hover-bg so consumer overrides on either prop apply under
1293
+ :host([inverted]) — the two share a paint here, so either knob is
1294
+ honored, with active-bg winning when both are set. */
1295
+ :host([inverted]) .button--primary:hover,
1296
+ :host([inverted]) .button--primary:active {
1297
+ --hx-button-bg: var(
1298
+ --hx-button-active-bg,
1299
+ var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))
1300
+ );
1301
+ color: var(
1302
+ --hx-button-inverted-primary-interactive-color,
1303
+ var(--hx-color-text-on-primary, #0d1825)
1304
+ );
1305
+ }
1306
+
1307
+ /* Danger inverted — sister to primary. Hover/pressed lift to
1308
+ action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground
1309
+ contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);
1310
+ pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both
1311
+ modes. Same active-bg → hover-bg → semantic fallback chain as primary. */
1312
+ :host([inverted]) .button--danger:hover,
1313
+ :host([inverted]) .button--danger:active {
1314
+ --hx-button-bg: var(
1315
+ --hx-button-active-bg,
1316
+ var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))
1317
+ );
1318
+ color: var(
1319
+ --hx-button-inverted-danger-interactive-color,
1320
+ var(--hx-color-text-on-error, #0d1825)
1321
+ );
1285
1322
  }
1286
1323
 
1287
1324
  /* Secondary inverted — white border and translucent hover fill */
@@ -602,9 +602,46 @@
602
602
  );
603
603
  }
604
604
 
605
- /* Primary inverted — slight transparent white overlay on hover */
606
- :host([inverted]) .button--primary:hover {
607
- --hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
605
+ /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover
606
+ (primary-400, light teal). The base :host([inverted]) .button rule binds
607
+ color to text.inverse, which flips by mode (neutral-0 in light, neutral-900
608
+ in dark). On a permanent light-teal fill, white text drops to 2.4:1 in
609
+ light mode (AA fail). Pin color to text.on-primary (neutral-900, no
610
+ dark-mode flip) for both hover and active so the foreground is dark in
611
+ both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).
612
+ Pressed === hover visually in inverted mode is acceptable UX (the
613
+ transient absence of pointer over the button signals release).
614
+ The fallback chain wraps --hx-button-active-bg (highest precedence) and
615
+ --hx-button-hover-bg so consumer overrides on either prop apply under
616
+ :host([inverted]) — the two share a paint here, so either knob is
617
+ honored, with active-bg winning when both are set. */
618
+ :host([inverted]) .button--primary:hover,
619
+ :host([inverted]) .button--primary:active {
620
+ --hx-button-bg: var(
621
+ --hx-button-active-bg,
622
+ var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))
623
+ );
624
+ color: var(
625
+ --hx-button-inverted-primary-interactive-color,
626
+ var(--hx-color-text-on-primary, #0d1825)
627
+ );
628
+ }
629
+
630
+ /* Danger inverted — sister to primary. Hover/pressed lift to
631
+ action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground
632
+ contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);
633
+ pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both
634
+ modes. Same active-bg → hover-bg → semantic fallback chain as primary. */
635
+ :host([inverted]) .button--danger:hover,
636
+ :host([inverted]) .button--danger:active {
637
+ --hx-button-bg: var(
638
+ --hx-button-active-bg,
639
+ var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))
640
+ );
641
+ color: var(
642
+ --hx-button-inverted-danger-interactive-color,
643
+ var(--hx-color-text-on-error, #0d1825)
644
+ );
608
645
  }
609
646
 
610
647
  /* Secondary inverted — white border and translucent hover fill */
@@ -141,6 +141,7 @@
141
141
  --hx-color-action-danger-bg: var(--hx-color-error-500);
142
142
  --hx-color-action-danger-bg-hover: var(--hx-color-error-600);
143
143
  --hx-color-action-danger-bg-active: var(--hx-color-error-700);
144
+ --hx-color-action-danger-bg-inverted-hover: var(--hx-color-error-400);
144
145
  --hx-body-bg: var(--hx-color-surface-default);
145
146
  --hx-body-color: var(--hx-color-text-primary);
146
147
  --hx-body-font-family: var(--hx-font-family-sans);
@@ -253,9 +253,46 @@
253
253
  );
254
254
  }
255
255
 
256
- /* Primary inverted — slight transparent white overlay on hover */
257
- :host([inverted]) .button--primary:hover {
258
- --hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
256
+ /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover
257
+ (primary-400, light teal). The base :host([inverted]) .button rule binds
258
+ color to text.inverse, which flips by mode (neutral-0 in light, neutral-900
259
+ in dark). On a permanent light-teal fill, white text drops to 2.4:1 in
260
+ light mode (AA fail). Pin color to text.on-primary (neutral-900, no
261
+ dark-mode flip) for both hover and active so the foreground is dark in
262
+ both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).
263
+ Pressed === hover visually in inverted mode is acceptable UX (the
264
+ transient absence of pointer over the button signals release).
265
+ The fallback chain wraps --hx-button-active-bg (highest precedence) and
266
+ --hx-button-hover-bg so consumer overrides on either prop apply under
267
+ :host([inverted]) — the two share a paint here, so either knob is
268
+ honored, with active-bg winning when both are set. */
269
+ :host([inverted]) .button--primary:hover,
270
+ :host([inverted]) .button--primary:active {
271
+ --hx-button-bg: var(
272
+ --hx-button-active-bg,
273
+ var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))
274
+ );
275
+ color: var(
276
+ --hx-button-inverted-primary-interactive-color,
277
+ var(--hx-color-text-on-primary, #0d1825)
278
+ );
279
+ }
280
+
281
+ /* Danger inverted — sister to primary. Hover/pressed lift to
282
+ action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground
283
+ contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);
284
+ pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both
285
+ modes. Same active-bg → hover-bg → semantic fallback chain as primary. */
286
+ :host([inverted]) .button--danger:hover,
287
+ :host([inverted]) .button--danger:active {
288
+ --hx-button-bg: var(
289
+ --hx-button-active-bg,
290
+ var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))
291
+ );
292
+ color: var(
293
+ --hx-button-inverted-danger-interactive-color,
294
+ var(--hx-color-text-on-error, #0d1825)
295
+ );
259
296
  }
260
297
 
261
298
  /* Secondary inverted — white border and translucent hover fill */
@@ -1,4 +1,4 @@
1
- /* index.css — generated 2026-04-25T23:24:47.443Z */
1
+ /* index.css — generated 2026-04-26T02:36:59.940Z */
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-25T23:24:47.443Z",
2
+ "generated": "2026-04-26T02:36:59.939Z",
3
3
  "components": [
4
4
  {
5
5
  "name": "hx-accordion",
@@ -264,6 +264,7 @@
264
264
  "--hx-color-action-danger-bg",
265
265
  "--hx-color-action-danger-bg-active",
266
266
  "--hx-color-action-danger-bg-hover",
267
+ "--hx-color-action-danger-bg-inverted-hover",
267
268
  "--hx-color-action-ghost-bg-hover",
268
269
  "--hx-color-action-ghost-fg",
269
270
  "--hx-color-action-primary-bg",
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-D3Royxqp.js";
9
+ import { H as M } from "./shared/hx-button-ebUV8KhT.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-C9zXD1zK.js";
56
+ import { H as Eo, a as Do } from "./shared/hx-nav-item-CvTxO3Sa.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";
@@ -1,11 +1,11 @@
1
- import { css as f, html as d, nothing as s } from "lit";
2
- import { property as a, customElement as v } from "lit/decorators.js";
3
- import { classMap as u } from "lit/directives/class-map.js";
4
- import { ifDefined as c } from "lit/directives/if-defined.js";
1
+ import { css as v, html as d, nothing as s } from "lit";
2
+ import { property as a, customElement as f } from "lit/decorators.js";
3
+ import { classMap as c } from "lit/directives/class-map.js";
4
+ import { ifDefined as u } from "lit/directives/if-defined.js";
5
5
  import { d as p } from "./dev-warn-YlwPHjtX.js";
6
- import { m as x } from "./aria-delegation-Doq6RRUy.js";
7
- import { H as g } from "./helix-element-BNEYeiys.js";
8
- const m = f`
6
+ import { m as g } from "./aria-delegation-Doq6RRUy.js";
7
+ import { H as x } from "./helix-element-BNEYeiys.js";
8
+ const m = v`
9
9
  :host {
10
10
  display: inline-block;
11
11
  }
@@ -260,9 +260,46 @@ const m = f`
260
260
  );
261
261
  }
262
262
 
263
- /* Primary inverted — slight transparent white overlay on hover */
264
- :host([inverted]) .button--primary:hover {
265
- --hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
263
+ /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover
264
+ (primary-400, light teal). The base :host([inverted]) .button rule binds
265
+ color to text.inverse, which flips by mode (neutral-0 in light, neutral-900
266
+ in dark). On a permanent light-teal fill, white text drops to 2.4:1 in
267
+ light mode (AA fail). Pin color to text.on-primary (neutral-900, no
268
+ dark-mode flip) for both hover and active so the foreground is dark in
269
+ both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).
270
+ Pressed === hover visually in inverted mode is acceptable UX (the
271
+ transient absence of pointer over the button signals release).
272
+ The fallback chain wraps --hx-button-active-bg (highest precedence) and
273
+ --hx-button-hover-bg so consumer overrides on either prop apply under
274
+ :host([inverted]) — the two share a paint here, so either knob is
275
+ honored, with active-bg winning when both are set. */
276
+ :host([inverted]) .button--primary:hover,
277
+ :host([inverted]) .button--primary:active {
278
+ --hx-button-bg: var(
279
+ --hx-button-active-bg,
280
+ var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))
281
+ );
282
+ color: var(
283
+ --hx-button-inverted-primary-interactive-color,
284
+ var(--hx-color-text-on-primary, #0d1825)
285
+ );
286
+ }
287
+
288
+ /* Danger inverted — sister to primary. Hover/pressed lift to
289
+ action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground
290
+ contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);
291
+ pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both
292
+ modes. Same active-bg → hover-bg → semantic fallback chain as primary. */
293
+ :host([inverted]) .button--danger:hover,
294
+ :host([inverted]) .button--danger:active {
295
+ --hx-button-bg: var(
296
+ --hx-button-active-bg,
297
+ var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))
298
+ );
299
+ color: var(
300
+ --hx-button-inverted-danger-interactive-color,
301
+ var(--hx-color-text-on-error, #0d1825)
302
+ );
266
303
  }
267
304
 
268
305
  /* Secondary inverted — white border and translucent hover fill */
@@ -365,12 +402,12 @@ const m = f`
365
402
  }
366
403
  }
367
404
  `;
368
- var y = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, n = (t, r, l, i) => {
369
- for (var o = i > 1 ? void 0 : i ? _(r, l) : r, h = t.length - 1, b; h >= 0; h--)
370
- (b = t[h]) && (o = (i ? b(r, l, o) : b(o)) || o);
371
- return i && o && y(r, l, o), o;
405
+ var y = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, n = (t, r, h, i) => {
406
+ for (var o = i > 1 ? void 0 : i ? _(r, h) : r, l = t.length - 1, b; l >= 0; l--)
407
+ (b = t[l]) && (o = (i ? b(r, h, o) : b(o)) || o);
408
+ return i && o && y(r, h, o), o;
372
409
  };
373
- let e = class extends x(g) {
410
+ let e = class extends g(x) {
374
411
  constructor() {
375
412
  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;
376
413
  }
@@ -393,8 +430,8 @@ let e = class extends x(g) {
393
430
  const r = (i = this.shadowRoot) == null ? void 0 : i.querySelector("slot:not([name])");
394
431
  !((r == null ? void 0 : r.assignedNodes({ flatten: !0 })) ?? []).some(
395
432
  (o) => {
396
- var h;
397
- return o.nodeType !== Node.TEXT_NODE || (((h = o.textContent) == null ? void 0 : h.trim().length) ?? 0) > 0;
433
+ var l;
434
+ return o.nodeType !== Node.TEXT_NODE || (((l = o.textContent) == null ? void 0 : l.trim().length) ?? 0) > 0;
398
435
  }
399
436
  ) && !this._effectiveLabel && (this._emptySlotWarnEmitted = !0);
400
437
  }
@@ -410,11 +447,11 @@ let e = class extends x(g) {
410
447
  // ─── Slot Handlers ───
411
448
  /** @internal */
412
449
  _handleDefaultSlotChange(t) {
413
- const l = t.target.assignedNodes({ flatten: !0 }).some((i) => {
450
+ const h = t.target.assignedNodes({ flatten: !0 }).some((i) => {
414
451
  var o;
415
452
  return i.nodeType !== Node.TEXT_NODE || (((o = i.textContent) == null ? void 0 : o.trim().length) ?? 0) > 0;
416
453
  });
417
- !l && !this._effectiveLabel && this._emptySlotWarnEmitted, l && (this._emptySlotWarnEmitted = !1);
454
+ !h && !this._effectiveLabel && this._emptySlotWarnEmitted, h && (this._emptySlotWarnEmitted = !1);
418
455
  }
419
456
  // ─── Event Handling ───
420
457
  /**
@@ -496,9 +533,9 @@ let e = class extends x(g) {
496
533
  return this.href !== void 0 ? d`
497
534
  <a
498
535
  part="button"
499
- class=${u(t)}
500
- href=${this.disabled || this.loading ? s : c(this.href)}
501
- target=${c(this.target)}
536
+ class=${c(t)}
537
+ href=${this.disabled || this.loading ? s : u(this.href)}
538
+ target=${u(this.target)}
502
539
  rel=${this.target === "_blank" ? "noopener noreferrer" : s}
503
540
  aria-label=${this._effectiveLabel || s}
504
541
  aria-disabled=${this.disabled ? "true" : s}
@@ -511,7 +548,7 @@ let e = class extends x(g) {
511
548
  ` : d`
512
549
  <button
513
550
  part="button"
514
- class=${u(t)}
551
+ class=${c(t)}
515
552
  ?disabled=${this.disabled}
516
553
  type=${this.type}
517
554
  aria-label=${this._effectiveLabel || s}
@@ -570,9 +607,9 @@ n([
570
607
  a({ type: String, attribute: "accessible-label" })
571
608
  ], e.prototype, "accessibleLabel", 2);
572
609
  e = n([
573
- v("hx-button")
610
+ f("hx-button")
574
611
  ], e);
575
612
  export {
576
613
  e as H
577
614
  };
578
- //# sourceMappingURL=hx-button-D3Royxqp.js.map
615
+ //# sourceMappingURL=hx-button-ebUV8KhT.js.map