@helixui/library 3.5.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/custom-elements.json +529 -81
  2. package/dist/components/hx-alert/hx-alert.d.ts +18 -0
  3. package/dist/components/hx-alert/hx-alert.d.ts.map +1 -1
  4. package/dist/components/hx-badge/index.js +1 -1
  5. package/dist/components/hx-button/hx-button.d.ts +18 -0
  6. package/dist/components/hx-button/hx-button.d.ts.map +1 -1
  7. package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
  8. package/dist/components/hx-button/index.js +1 -1
  9. package/dist/components/hx-checkbox/hx-checkbox.d.ts +18 -0
  10. package/dist/components/hx-checkbox/hx-checkbox.d.ts.map +1 -1
  11. package/dist/components/hx-checkbox/hx-checkbox.styles.d.ts.map +1 -1
  12. package/dist/components/hx-checkbox/index.js +1 -1
  13. package/dist/components/hx-date-picker/hx-date-picker.styles.d.ts.map +1 -1
  14. package/dist/components/hx-date-picker/index.js +1 -1
  15. package/dist/components/hx-dialog/hx-dialog.d.ts +18 -0
  16. package/dist/components/hx-dialog/hx-dialog.d.ts.map +1 -1
  17. package/dist/components/hx-icon-button/hx-icon-button.styles.d.ts.map +1 -1
  18. package/dist/components/hx-icon-button/index.js +1 -1
  19. package/dist/components/hx-pagination/hx-pagination.styles.d.ts.map +1 -1
  20. package/dist/components/hx-pagination/index.js +1 -1
  21. package/dist/components/hx-radio-group/index.js +1 -1
  22. package/dist/components/hx-steps/index.js +1 -1
  23. package/dist/components/hx-text-input/hx-text-input.d.ts +18 -0
  24. package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
  25. package/dist/components/hx-toggle-button/hx-toggle-button.styles.d.ts.map +1 -1
  26. package/dist/components/hx-toggle-button/index.js +1 -1
  27. package/dist/css/helix-all.css +59 -34
  28. package/dist/css/helix-core.css +20 -14
  29. package/dist/css/helix-forms.css +33 -17
  30. package/dist/css/helix-navigation.css +6 -3
  31. package/dist/css/helix-tokens.css +5 -4
  32. package/dist/css/hx-badge.css +5 -5
  33. package/dist/css/hx-button.css +11 -4
  34. package/dist/css/hx-checkbox.css +10 -4
  35. package/dist/css/hx-date-picker.css +5 -2
  36. package/dist/css/hx-icon-button.css +4 -5
  37. package/dist/css/hx-pagination.css +6 -3
  38. package/dist/css/hx-toggle-button.css +18 -11
  39. package/dist/css/index.css +1 -1
  40. package/dist/css/manifest.json +18 -9
  41. package/dist/index.js +9 -9
  42. package/dist/shared/hx-alert-Bto8-TIi.js.map +1 -1
  43. package/dist/shared/{hx-badge-JlFtAdxS.js → hx-badge-DFL35nzi.js} +16 -16
  44. package/dist/shared/hx-badge-DFL35nzi.js.map +1 -0
  45. package/dist/shared/{hx-button-BOwAEcF1.js → hx-button-rRNmD4fd.js} +12 -5
  46. package/dist/shared/hx-button-rRNmD4fd.js.map +1 -0
  47. package/dist/shared/{hx-checkbox-CYd0YV_u.js → hx-checkbox-hPlIw6Lb.js} +25 -19
  48. package/dist/shared/hx-checkbox-hPlIw6Lb.js.map +1 -0
  49. package/dist/shared/{hx-date-picker-B49yo4Vm.js → hx-date-picker-DSKDkCy1.js} +6 -3
  50. package/dist/shared/hx-date-picker-DSKDkCy1.js.map +1 -0
  51. package/dist/shared/hx-dialog-B4weoj_1.js.map +1 -1
  52. package/dist/shared/{hx-icon-button-a6OpeQz5.js → hx-icon-button-B2BdVdyK.js} +10 -11
  53. package/dist/shared/hx-icon-button-B2BdVdyK.js.map +1 -0
  54. package/dist/shared/{hx-pagination-C7y8GVyU.js → hx-pagination-D726PyTM.js} +7 -4
  55. package/dist/shared/hx-pagination-D726PyTM.js.map +1 -0
  56. package/dist/shared/{hx-radio-C7eTj5YI.js → hx-radio-CY4kQfZw.js} +44 -44
  57. package/dist/shared/{hx-radio-C7eTj5YI.js.map → hx-radio-CY4kQfZw.js.map} +1 -1
  58. package/dist/shared/{hx-step-R2rjp1fT.js → hx-step-CUzliIK_.js} +3 -3
  59. package/dist/shared/hx-step-CUzliIK_.js.map +1 -0
  60. package/dist/shared/hx-text-input-D6FlOZM-.js.map +1 -1
  61. package/dist/shared/{hx-toggle-button-DwBers3A.js → hx-toggle-button-DSJeFlb0.js} +52 -45
  62. package/dist/shared/{hx-toggle-button-DwBers3A.js.map → hx-toggle-button-DSJeFlb0.js.map} +1 -1
  63. package/figma-inventory.json +1399 -103
  64. package/package.json +2 -2
  65. package/dist/shared/hx-badge-JlFtAdxS.js.map +0 -1
  66. package/dist/shared/hx-button-BOwAEcF1.js.map +0 -1
  67. package/dist/shared/hx-checkbox-CYd0YV_u.js.map +0 -1
  68. package/dist/shared/hx-date-picker-B49yo4Vm.js.map +0 -1
  69. package/dist/shared/hx-icon-button-a6OpeQz5.js.map +0 -1
  70. package/dist/shared/hx-pagination-C7y8GVyU.js.map +0 -1
  71. package/dist/shared/hx-step-R2rjp1fT.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helixui/library",
3
- "version": "3.5.0",
3
+ "version": "3.7.0",
4
4
  "description": "Enterprise Web Component Library built with Lit 3.x",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -59,7 +59,7 @@
59
59
  "customElements": "custom-elements.json",
60
60
  "dependencies": {
61
61
  "lit": "^3.3.2",
62
- "@helixui/tokens": "3.5.0"
62
+ "@helixui/tokens": "3.7.0"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@floating-ui/dom": "^1.7.6"
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-badge-JlFtAdxS.js","sources":["../../src/components/hx-badge/hx-badge.styles.ts","../../src/components/hx-badge/hx-badge.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixBadgeStyles = css`\n :host {\n display: inline-block;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-1, 0.25rem);\n border-radius: var(--hx-badge-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-badge-bg, var(--hx-color-primary-500, #429797));\n color: var(--hx-badge-color, var(--hx-color-text-on-primary, #0d1825));\n font-family: var(--hx-badge-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-badge-font-weight, var(--hx-font-weight-semibold, 600));\n line-height: var(--hx-line-height-tight, 1.25);\n white-space: nowrap;\n vertical-align: middle;\n position: relative;\n }\n\n /* ─── Size Variants ─── */\n\n .badge--sm {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-2xs, 0.625rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-0-5, 0.125rem))\n var(--hx-badge-padding-x, var(--hx-space-1-5, 0.375rem));\n }\n\n .badge--md {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-xs, 0.75rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-badge-padding-x, var(--hx-space-2, 0.5rem));\n }\n\n .badge--lg {\n font-size: var(--hx-badge-font-size, var(--hx-font-size-sm, 0.875rem));\n padding: var(--hx-badge-padding-y, var(--hx-space-1, 0.25rem))\n var(--hx-badge-padding-x, var(--hx-space-3, 0.75rem));\n }\n\n /* ─── Style Variants ─── */\n\n .badge--primary {\n --hx-badge-bg: var(--hx-badge-primary-bg, var(--hx-color-primary-500, #429797));\n --hx-badge-color: var(--hx-badge-primary-color, var(--hx-color-text-on-primary, #0d1825));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-primary-bg, var(--hx-color-primary-500, #429797))\n );\n }\n\n .badge--secondary {\n --hx-badge-bg: var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #ebeee9));\n --hx-badge-color: var(--hx-badge-secondary-color, var(--hx-color-neutral-700, #313e4b));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-secondary-bg, var(--hx-color-neutral-100, #ebeee9))\n );\n }\n\n .badge--success {\n --hx-badge-bg: var(--hx-badge-success-bg, var(--hx-color-success-700, #146831));\n --hx-badge-color: var(--hx-badge-success-color, var(--hx-color-neutral-0, #ffffff));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-success-bg, var(--hx-color-success-700, #146831))\n );\n }\n\n .badge--warning {\n --hx-badge-bg: var(--hx-badge-warning-bg, var(--hx-color-warning-500, #c2711c));\n --hx-badge-color: var(--hx-badge-warning-color, var(--hx-color-neutral-900, #0d1825));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-warning-bg, var(--hx-color-warning-500, #c2711c))\n );\n }\n\n .badge--error {\n --hx-badge-bg: var(--hx-badge-error-bg, var(--hx-color-error-500, #e5493e));\n --hx-badge-color: var(--hx-badge-error-color, var(--hx-color-text-on-error, #0d1825));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-error-bg, var(--hx-color-error-500, #e5493e))\n );\n }\n\n .badge--neutral {\n --hx-badge-bg: var(--hx-badge-neutral-bg, var(--hx-color-neutral-200, #d6dbd5));\n --hx-badge-color: var(--hx-badge-neutral-color, var(--hx-color-neutral-700, #313e4b));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-neutral-bg, var(--hx-color-neutral-200, #d6dbd5))\n );\n }\n\n .badge--info {\n --hx-badge-bg: var(--hx-badge-info-bg, var(--hx-color-info-700, #0e5997));\n --hx-badge-color: var(--hx-badge-info-color, var(--hx-color-neutral-0, #ffffff));\n --hx-badge-pulse-color-internal: var(\n --hx-badge-pulse-color,\n var(--hx-badge-info-bg, var(--hx-color-info-700, #0e5997))\n );\n }\n\n /* ─── Semantic Variant Label (WCAG 1.4.1) ─── */\n /* Visually hidden text prefix for semantic variants (success/warning/error/info). */\n /* Ensures the variant is not conveyed by color alone. */\n\n .badge__variant-label {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Pill Mode ─── */\n\n .badge--pill {\n border-radius: var(--hx-badge-border-radius, var(--hx-border-radius-full, 9999px));\n }\n\n /* ─── Dot Indicator (empty + pulse) ─── */\n\n .badge--dot {\n width: var(--hx-badge-dot-size, var(--hx-space-2, 0.5rem));\n height: var(--hx-badge-dot-size, var(--hx-space-2, 0.5rem));\n padding: 0;\n border-radius: var(--hx-border-radius-full, 9999px);\n }\n\n /* Guard: hide all inner content in dot mode — the dot is purely visual */\n .badge--dot ::slotted(*),\n .badge--dot slot,\n .badge--dot slot[name='prefix'] {\n display: none !important;\n }\n\n /* ─── Pulse Animation ─── */\n\n @keyframes hx-badge-pulse {\n 0%,\n 100% {\n opacity: 1;\n box-shadow: 0 0 0 2px var(--hx-badge-pulse-color-internal, currentColor);\n }\n 50% {\n opacity: var(--hx-opacity-75, 0.75);\n box-shadow: 0 0 0 6px transparent;\n }\n }\n\n .badge--pulse {\n animation: hx-badge-pulse var(--hx-badge-pulse-duration, var(--hx-duration-slow, 2s))\n var(--hx-badge-pulse-easing, var(--hx-easing-in-out, ease-in-out)) infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .badge--pulse {\n animation: none;\n }\n }\n\n /* ─── Remove Button ─── */\n\n .badge__remove-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n margin-inline-start: var(--hx-space-1, 0.25rem);\n cursor: pointer;\n color: inherit;\n opacity: var(--hx-opacity-75, 0.75);\n border-radius: var(--hx-border-radius-sm, 0.25rem);\n line-height: 0;\n /* WCAG 2.5.5: minimum 44×44px touch target */\n min-width: var(--hx-touch-target-min, 2.75rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n }\n\n .badge__remove-button:hover {\n opacity: var(--hx-opacity-100, 1);\n }\n\n .badge__remove-button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid var(--hx-focus-ring-color, currentColor);\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n /* ─── Forced Colors (Windows High Contrast) ─── */\n\n @media (forced-colors: active) {\n .badge {\n border: 1px solid CanvasText;\n forced-color-adjust: none;\n background-color: Canvas;\n color: CanvasText;\n }\n\n .badge--pulse {\n animation: none;\n }\n\n .badge__remove-button {\n color: ButtonText;\n }\n\n /* Per-semantic-variant forced-colors fallbacks. The visually-hidden\n semantic variant label (.badge__variant-label) keeps AT users\n informed; these blocks restore visual semantic distinction for\n sighted users in HCM where bg/color collapse to system defaults.\n Pattern: distinct border-style per variant. */\n .badge--success {\n border-style: solid;\n border-width: 2px;\n }\n\n .badge--warning {\n border-style: dashed;\n border-width: 2px;\n }\n\n .badge--error {\n border-style: double;\n border-width: 3px;\n }\n\n .badge--info {\n border-style: dotted;\n border-width: 2px;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { HelixElement } from '../../base/index.js';\nimport { helixBadgeStyles } from './hx-badge.styles.js';\nimport { forcedColorsSurface } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/**\n * A small status indicator for notifications, counts, and labels.\n *\n * @summary Presentational badge for status indicators, notification counts, and labels.\n *\n * @tag hx-badge\n *\n * @slot - Default slot for badge content (text, number). When empty with pulse enabled, renders as a dot indicator.\n * @slot prefix - Icon or content rendered before the badge text.\n *\n * @fires {CustomEvent<void>} hx-remove - Dispatched when the user clicks the remove button.\n *\n * @csspart badge - The badge element.\n * @csspart remove-button - The remove/dismiss button.\n *\n * @cssprop [--hx-badge-bg=var(--hx-color-primary-500)] - Badge background color. The primary override point.\n * @cssprop [--hx-badge-color=var(--hx-color-neutral-0)] - Badge text color. The primary override point.\n * @cssprop [--hx-badge-font-size] - Badge font size (set per size variant).\n * @cssprop [--hx-badge-font-weight=var(--hx-font-weight-semibold)] - Badge font weight.\n * @cssprop [--hx-badge-font-family=var(--hx-font-family-sans)] - Badge font family.\n * @cssprop [--hx-badge-border-radius=var(--hx-border-radius-md)] - Badge border radius.\n * @cssprop [--hx-badge-padding-x] - Badge horizontal padding (set per size variant).\n * @cssprop [--hx-badge-padding-y] - Badge vertical padding (set per size variant).\n * @cssprop [--hx-badge-pulse-color] - Pulse color matching variant background with reduced opacity.\n * @cssprop [--hx-badge-dot-size=var(--hx-size-2)] - Dot indicator size when rendered without content.\n * @cssprop [--hx-badge-secondary-bg=var(--hx-color-neutral-100)] - Background for the secondary variant.\n * @cssprop [--hx-badge-secondary-color=var(--hx-color-neutral-700)] - Text color for the secondary variant.\n * @cssprop [--hx-badge-info-bg=var(--hx-color-info-700)] - Background for the info variant.\n * @cssprop [--hx-badge-info-color=var(--hx-color-neutral-0)] - Text color for the info variant.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-border-radius-md] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-font-weight-semibold] - Font weight.\n * @cssprop [--hx-line-height-tight] - Line height.\n * @cssprop [--hx-font-size-2xs] - Font size.\n * @cssprop [--hx-space-0-5] - Spacing token.\n * @cssprop [--hx-space-1-5] - Spacing token.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-space-3] - Spacing token.\n * @cssprop [--hx-badge-pulse-color-internal] - Color.\n * @cssprop [--hx-color-neutral-100] - Color.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-color-success-700] - Color.\n * @cssprop [--hx-color-warning-500] - Color.\n * @cssprop [--hx-color-neutral-900] - Color.\n * @cssprop [--hx-color-error-500] - Color.\n * @cssprop [--hx-color-neutral-200] - Color.\n * @cssprop [--hx-color-info-700] - Color.\n * @cssprop [--hx-border-radius-full] - CSS custom property.\n * @cssprop [--hx-opacity-75] - Opacity.\n * @cssprop [--hx-badge-pulse-duration=var(--hx-duration-slow)] - CSS custom property.\n * @cssprop [--hx-duration-slow] - Animation duration.\n * @cssprop [--hx-badge-pulse-easing=var(--hx-easing-in-out)] - CSS custom property.\n * @cssprop [--hx-easing-in-out] - CSS custom property.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-opacity-100] - Opacity.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n */\n@customElement('hx-badge')\nexport class HelixBadge extends HelixElement {\n static override styles = [helixBadgeStyles, forcedColorsSurface];\n\n /**\n * Visual style variant of the badge.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'neutral' | 'info' =\n 'primary';\n\n /**\n * Size of the badge.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Whether the badge uses fully rounded (pill) styling.\n * @attr pill\n */\n @property({ type: Boolean, reflect: true })\n pill = false;\n\n /**\n * Whether the badge displays an animated pulse for attention.\n * @attr pulse\n */\n @property({ type: Boolean, reflect: true })\n pulse = false;\n\n /**\n * Whether the badge renders a dismiss button.\n * @attr removable\n */\n @property({ type: Boolean, reflect: true })\n removable = false;\n\n /**\n * Numeric count to display. When set, renders the count as badge content.\n * When count exceeds `max`, displays `${max}+` (e.g. `99+`).\n * @attr count\n */\n @property({ type: Number, reflect: true })\n count: number | undefined = undefined;\n\n /**\n * Maximum count value before truncation to `${max}+`. Defaults to 99.\n * @attr max\n */\n @property({ type: Number, reflect: true })\n max = 99;\n\n /**\n * Accessible label for the dot indicator mode (pulse + empty slot).\n * Required for WCAG 4.1.2 compliance when using the dot indicator pattern.\n * Example: `dot-label=\"3 new messages\"`.\n * @attr dot-label\n */\n @property({ type: String, attribute: 'dot-label' })\n dotLabel = '';\n\n /**\n * Accessible label for the remove button. Should describe what is being removed.\n * Defaults to \"Remove\". For better accessibility, include context: e.g. \"Remove Critical badge\".\n * @attr remove-label\n */\n @property({ type: String, attribute: 'remove-label' })\n removeLabel = 'Remove';\n\n /**\n * Tracks whether the default slot has assigned content.\n * @internal\n */\n @state()\n private _hasSlotContent = false;\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Backward compat: accept legacy `size` attribute. When present and `hx-size`\n // is not set, map the value and emit a deprecation warning.\n const legacySize = this.getAttribute('size');\n if (legacySize !== null && !this.hasAttribute('hx-size')) {\n devWarn('hx-badge', 'The \"size\" attribute is deprecated. Use \"hx-size\" instead.');\n this.size = legacySize as 'sm' | 'md' | 'lg';\n }\n }\n\n // ─── Slot Change Handling ───\n\n /** @internal */\n private _handleSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const nodes = slot.assignedNodes({ flatten: true });\n // Check if any assigned node has non-whitespace content\n this._hasSlotContent = nodes.some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) return true;\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').trim().length > 0;\n }\n return false;\n });\n }\n\n // ─── Event Handling ───\n\n /** @internal */\n private _handleRemove(): void {\n this.dispatchEvent(\n new CustomEvent<void>('hx-remove', {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Count Display ───\n\n /** @internal */\n private get _countDisplay(): string {\n if (this.count === undefined) return '';\n return this.count > this.max ? `${this.max}+` : String(this.count);\n }\n\n // ─── WCAG 1.4.1: Semantic variant label map ───\n // Variants that carry semantic meaning beyond decoration need a non-color cue.\n // Visually-hidden text is prepended so screen reader users and color-blind\n // users get the variant context even when no icon is slotted.\n\n /** @internal */\n private static readonly _SEMANTIC_VARIANT_LABELS: Partial<Record<HelixBadge['variant'], string>> =\n {\n success: 'Success',\n warning: 'Warning',\n error: 'Error',\n info: 'Info',\n };\n\n /** @internal */\n private get _semanticVariantLabel(): string {\n return HelixBadge._SEMANTIC_VARIANT_LABELS[this.variant] ?? '';\n }\n\n // ─── Render ───\n\n override render() {\n const hasCount = this.count !== undefined;\n const isDot = !this._hasSlotContent && !hasCount && this.pulse;\n\n if (isDot && !this.dotLabel) {\n devWarn(\n 'hx-badge',\n 'Dot badge is missing an accessible label. Set `dotLabel` so screen readers can announce the badge purpose (WCAG 4.1.2).',\n );\n }\n\n const classes = {\n badge: true,\n [`badge--${this.variant}`]: true,\n [`badge--${this.size}`]: true,\n 'badge--pill': this.pill,\n 'badge--pulse': this.pulse,\n 'badge--dot': isDot,\n };\n\n const variantLabel = this._semanticVariantLabel;\n\n return html`\n <span\n part=\"badge\"\n class=${classMap(classes)}\n role=${isDot && this.dotLabel ? 'img' : nothing}\n aria-label=${isDot && this.dotLabel ? this.dotLabel : nothing}\n aria-live=${hasCount ? 'polite' : nothing}\n >\n ${variantLabel\n ? html`<span class=\"badge__variant-label\">${variantLabel}: </span>`\n : nothing}\n ${isDot ? nothing : html`<slot name=\"prefix\"></slot>`}\n ${hasCount ? this._countDisplay : html`<slot @slotchange=${this._handleSlotChange}></slot>`}\n ${this.removable\n ? html`<button\n part=\"remove-button\"\n class=\"badge__remove-button\"\n aria-label=${this.removeLabel}\n @click=${this._handleRemove}\n >\n <svg viewBox=\"0 0 12 12\" aria-hidden=\"true\" width=\"10\" height=\"10\">\n <path\n d=\"M2.22 2.22a.75.75 0 011.06 0L6 4.94l2.72-2.72a.75.75 0 011.06 1.06L7.06 6l2.72 2.72a.75.75 0 01-1.06 1.06L6 7.06 3.28 9.78a.75.75 0 01-1.06-1.06L4.94 6 2.22 3.28a.75.75 0 010-1.06z\"\n fill=\"currentColor\"\n />\n </svg>\n </button>`\n : nothing}\n </span>\n `;\n }\n}\n\n/** Canonical type alias for the hx-badge component. */\nexport type HxBadge = HelixBadge;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-badge': HelixBadge;\n }\n}\n"],"names":["helixBadgeStyles","css","HelixBadge","HelixElement","legacySize","e","nodes","node","hasCount","isDot","classes","variantLabel","html","classMap","nothing","forcedColorsSurface","__decorateClass","property","state","customElement"],"mappings":";;;;;AAEO,MAAMA,IAAmBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-button-BOwAEcF1.js","sources":["../../src/components/hx-button/hx-button.styles.ts","../../src/components/hx-button/hx-button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixButtonStyles = css`\n :host {\n display: inline-block;\n }\n\n :host([disabled]) {\n pointer-events: none;\n opacity: var(--hx-opacity-disabled, 0.5);\n }\n\n :host([full]) {\n display: block;\n width: 100%;\n }\n\n :host([full]) .button {\n width: 100%;\n justify-content: center;\n }\n\n /* ─── Base Button ─── */\n\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--hx-space-2, 0.5rem);\n border: var(--hx-border-width-thin, 1px) solid var(--hx-button-border-color, transparent);\n border-radius: var(--hx-button-border-radius, var(--hx-border-radius-md, 0.375rem));\n background-color: var(--hx-button-bg, var(--hx-color-primary-500, #429797));\n color: var(--hx-button-color, var(--hx-color-neutral-0, #ffffff));\n font-family: var(--hx-button-font-family, var(--hx-font-family-sans, sans-serif));\n font-weight: var(--hx-button-font-weight, var(--hx-font-weight-semibold, 600));\n line-height: var(--hx-line-height-tight, 1.25);\n cursor: pointer;\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n text-decoration: none;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .button:focus-visible {\n outline: var(--hx-focus-ring-width, 2px) solid\n var(--hx-button-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-focus-ring-offset, 2px);\n }\n\n .button:hover {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .button:active {\n filter: brightness(var(--hx-filter-brightness-active, 0.8));\n }\n\n /* ─── Size Variants ─── */\n\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target for sm variant.\n min-height uses --hx-touch-target-min to guarantee the interactive area\n meets the threshold even though the visual size token is smaller. */\n .button--sm {\n padding: var(--hx-space-1, 0.25rem) var(--hx-space-3, 0.75rem);\n font-size: var(--hx-font-size-sm, 0.875rem);\n min-height: var(--hx-touch-target-min, 2.75rem);\n }\n\n .button--md {\n padding: var(--hx-space-2, 0.5rem) var(--hx-space-4, 1rem);\n font-size: var(--hx-font-size-md, 1rem);\n min-height: var(--hx-size-10, 2.5rem);\n }\n\n .button--lg {\n padding: var(--hx-space-3, 0.75rem) var(--hx-space-6, 1.5rem);\n font-size: var(--hx-font-size-lg, 1.125rem);\n min-height: var(--hx-size-12, 3rem);\n }\n\n /* ─── Style Variants ─── */\n\n .button--primary {\n --hx-button-bg: var(--hx-color-action-primary-bg, #429797);\n /* Inline #0d1825 matches text.on-primary's resolved primitive (neutral-900);\n cold-start without the semantic still paints AA-tuned dark-on-primary\n rather than white-on-primary (3.43:1 fail). */\n --hx-button-color: var(--hx-color-text-on-primary, #0d1825);\n --hx-button-border-color: transparent;\n }\n\n .button--secondary {\n --hx-button-bg: transparent;\n /* primary-500 (#429797) text on white surface = 3.44:1 — fails AA.\n primary-600 (#0F7078) on white = 5.82:1 — AA pass. */\n --hx-button-color: var(--hx-color-action-secondary-fg, #0f7078);\n --hx-button-border-color: var(--hx-color-action-secondary-border, #0f7078);\n }\n\n .button--secondary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-secondary-bg-hover, #ebf8f8));\n }\n\n .button--tertiary {\n --hx-button-bg: var(--hx-color-surface-sunken, #ebeee9);\n --hx-button-color: var(--hx-color-text-primary, #0d1825);\n --hx-button-border-color: transparent;\n }\n\n .button--tertiary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n .button--danger {\n --hx-button-bg: var(--hx-color-action-danger-bg, #e5493e);\n /* Inline #0d1825 matches text.on-error's resolved primitive (neutral-900);\n cold-start without the semantic still paints AA-tuned dark-on-error\n rather than white-on-error (3.92:1 fail). */\n --hx-button-color: var(--hx-color-text-on-error, #0d1825);\n --hx-button-border-color: transparent;\n }\n\n /* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).\n error-600 (#C92A2A) drops that to 3.28:1 — AA fail. text.on-error-strong\n resolves to neutral-0 across modes (no dark flip) so the darker hover fill\n stays legible. Mirrors hx-toast precedent (commit 300e21ab0); routed\n through the semantic tier in 3.2.1 token-cascade remediation. */\n .button--danger:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-hover, #c92a2a));\n --hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);\n }\n\n /* Pressed state binds explicitly to action.danger.bg-active (error-700,\n #A21312) + text.on-error-strong (neutral-0) = 7.96:1 AA. Base\n .button:active filter:brightness(0.8) would compound on top of bg-hover\n (#C92A2A) and produce ~3.3:1 sub-AA on the bound colors. Override the\n filter to none. HC override on action.danger.bg-active flips to HC\n error-500 so the on-error-strong (HC = #000) pair is AA in HC too. */\n .button--danger:active {\n --hx-button-bg: var(--hx-button-active-bg, var(--hx-color-action-danger-bg-active, #a21312));\n --hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);\n filter: none;\n }\n\n .button--ghost {\n --hx-button-bg: transparent;\n /* primary-500 (#429797) text on white surface = 3.44:1 — fails AA.\n primary-600 (#0F7078) on white = 5.82:1 — AA pass. */\n --hx-button-color: var(--hx-color-action-ghost-fg, #0f7078);\n --hx-button-border-color: transparent;\n }\n\n .button--ghost:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-ghost-bg-hover, #ebf8f8));\n }\n\n .button--outline {\n --hx-button-bg: transparent;\n --hx-button-color: var(--hx-color-text-primary, #0d1825);\n --hx-button-border-color: var(--hx-color-border-strong, #66787b);\n }\n\n .button--outline:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-surface-raised, #f5f8f3));\n }\n\n /* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.\n primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. text.on-primary-strong\n resolves to neutral-0 across modes (no dark flip) for the darker hover fill.\n Mirrors hx-toast precedent (commit 300e21ab0); routed through the semantic\n tier in 3.2.1 token-cascade remediation. */\n .button--primary:hover {\n --hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-hover, #0f7078));\n --hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);\n }\n\n /* Pressed state binds explicitly to action.primary.bg-active (primary-700,\n #0F6363) + text.on-primary-strong (neutral-0) = 7.03:1 AA. The base\n .button:active filter:brightness(0.8) would compound on top of bg-hover\n (#0F7078) and produce ~3.7:1 sub-AA on the bound colors. Override the\n filter to none so the action.*.bg-active token is what actually paints. */\n .button--primary:active {\n --hx-button-bg: var(--hx-button-active-bg, var(--hx-color-action-primary-bg-active, #0f6363));\n --hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);\n filter: none;\n }\n\n /* ─── Disabled ─── */\n\n /* Note: opacity is applied on :host([disabled]) above — do NOT add opacity here.\n Stacking opacity on both :host and .button[disabled] would multiply to 0.25. */\n .button[disabled] {\n cursor: not-allowed;\n }\n\n /* ─── Loading State ─── */\n\n .button--loading {\n position: relative;\n cursor: wait;\n }\n\n .button__spinner {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n animation: hx-spin var(--hx-duration-spinner, 750ms) linear infinite;\n }\n\n @keyframes hx-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .button {\n transition: none;\n }\n\n .button__spinner {\n animation: none;\n opacity: var(--hx-opacity-muted, 0.6);\n }\n }\n\n /* ─── Inverted Mode ─── */\n\n /* Inline-fallback contract for the on-dark-* tokens in this section:\n the literal rgba(255, 255, 255, 0.X) arms are a LIGHT-MODE-only last\n resort (cold-start, CSS-not-loaded). At runtime, hx-theme injects\n the dark.* override (overlay-black-* for the strong border and the\n surface.on-dark-overlay-* fills) so dark-mode inverted buttons stay\n visible on the now-light surface.inverse (#EBEEE9). The inline white\n overlays would render invisible (≈1.1:1) on a light surface, but\n they never paint when the theme is mounted. If a future change\n moves these into a context where hx-theme is not guaranteed,\n replace with mode-aware tokens. */\n\n /* Override text color and filter-based hover/active for all variants */\n :host([inverted]) .button {\n color: var(--hx-button-inverted-color, var(--hx-color-text-inverse, #ffffff));\n filter: none;\n }\n\n :host([inverted]) .button:hover {\n filter: none;\n }\n\n :host([inverted]) .button:active {\n filter: none;\n }\n\n :host([inverted]) .button:focus-visible {\n /* WCAG 1.4.11: focus indicator needs ≥3:1 against adjacent colors.\n border-on-dark-strong (overlay-white-70) ≈ 5:1 on neutral-900 — passes.\n The lower-alpha siblings used to live in border.* but were sub-3:1\n against any plausible surface and could not honour a border contract;\n they're now surface.on-dark-overlay-{default,subtle} (translucent\n fills, not borders) and used elsewhere in this file. See\n tokens.json color.surface.on-dark-overlay-* for canonical ratios. */\n outline-color: var(\n --hx-button-inverted-focus-ring-color,\n var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))\n );\n }\n\n /* Primary inverted — resting bg routes through action.primary.bg-inverted-rest\n so dark mode can flip the fill to primary-600. surface.inverse becomes light\n (#EBEEE9) in dark mode; primary-500 on #EBEEE9 = 2.94:1 (sub-3:1 UI floor\n fail for the inverted-button boundary). primary-600 on #EBEEE9 = 4.97:1\n (AA pass). Light mode tracks action.primary.bg-inverted-rest's base value\n (primary-500, 5.20:1 on dark surface.inverse).\n\n Override path note (codex round-11): this binds --hx-button-bg directly,\n matching the cascade convention every other .button--{variant} rule uses\n (light primary at line 89, danger at 120, secondary, tertiary, ghost). The\n consumer override path for inverted-primary rest is\n --hx-color-action-primary-bg-inverted-rest, NOT --hx-button-bg — the same\n pattern as light primary (consumers override --hx-color-action-primary-bg).\n Pinned by dark-mode-resolution.test.ts:185-197 across both modes. */\n :host([inverted]) .button--primary {\n --hx-button-bg: var(--hx-color-action-primary-bg-inverted-rest, #429797);\n }\n\n /* Primary inverted — hover/pressed lift to action.primary.bg-inverted-hover\n (primary-400, light teal). The base :host([inverted]) .button rule binds\n color to text.inverse, which flips by mode (neutral-0 in light, neutral-900\n in dark). On a permanent light-teal fill, white text drops to 2.4:1 in\n light mode (AA fail). Pin color to text.on-primary (neutral-900, no\n dark-mode flip) for both hover and active so the foreground is dark in\n both modes — neutral-900 on primary-400 = 7.27:1 (AA pass).\n Pressed === hover visually in inverted mode is acceptable UX (the\n transient absence of pointer over the button signals release).\n The fallback chain wraps --hx-button-active-bg (highest precedence) and\n --hx-button-hover-bg so consumer overrides on either prop apply under\n :host([inverted]) — the two share a paint here, so either knob is\n honored, with active-bg winning when both are set. */\n :host([inverted]) .button--primary:hover,\n :host([inverted]) .button--primary:active {\n --hx-button-bg: var(\n --hx-button-active-bg,\n var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1))\n );\n color: var(\n --hx-button-inverted-primary-interactive-color,\n var(--hx-color-text-on-primary, #0d1825)\n );\n }\n\n /* Danger inverted — sister to primary. Hover/pressed lift to\n action.danger.bg-inverted-hover (error-400, #FC7264). Same foreground\n contract: text.inverse fails in light mode (white on light red ≈ 2.6:1);\n pin to text.on-error (neutral-900, no dark-mode flip) for 6.58:1 in both\n modes. Same active-bg → hover-bg → semantic fallback chain as primary. */\n :host([inverted]) .button--danger:hover,\n :host([inverted]) .button--danger:active {\n --hx-button-bg: var(\n --hx-button-active-bg,\n var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-inverted-hover, #fc7264))\n );\n color: var(\n --hx-button-inverted-danger-interactive-color,\n var(--hx-color-text-on-error, #0d1825)\n );\n }\n\n /* Secondary inverted — white border and translucent hover fill */\n :host([inverted]) .button--secondary {\n --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));\n }\n\n /* Inverted overlay fills read both names so consumer overrides reach paint\n regardless of which token they target: the deprecated --hx-color-border-on-dark-*\n names (3.2.0/3.2.1 public API, scheduled for removal in 4.0.0) and the canonical\n --hx-color-surface-on-dark-overlay-* names (round-8 rename). Deprecated name\n wins when set; otherwise resolves through the canonical alias chain. */\n :host([inverted]) .button--secondary:hover {\n --hx-button-bg: var(\n --hx-color-border-on-dark-default,\n var(--hx-color-surface-on-dark-overlay-default, rgba(255, 255, 255, 0.3))\n );\n }\n\n /* Tertiary inverted — resting at the subtle overlay (10%) lifts to the default\n overlay (30%) on hover so the runtime hover delta is visually distinct, not\n collapsed onto a single token. */\n :host([inverted]) .button--tertiary {\n --hx-button-bg: var(\n --hx-color-border-on-dark-subtle,\n var(--hx-color-surface-on-dark-overlay-subtle, rgba(255, 255, 255, 0.1))\n );\n --hx-button-border-color: transparent;\n }\n\n :host([inverted]) .button--tertiary:hover {\n --hx-button-bg: var(\n --hx-color-border-on-dark-default,\n var(--hx-color-surface-on-dark-overlay-default, rgba(255, 255, 255, 0.3))\n );\n }\n\n /* Ghost inverted — transparent base, translucent hover bg */\n :host([inverted]) .button--ghost {\n --hx-button-bg: transparent;\n --hx-button-border-color: transparent;\n }\n\n :host([inverted]) .button--ghost:hover {\n --hx-button-bg: var(\n --hx-button-inverted-ghost-hover-bg,\n var(\n --hx-color-border-on-dark-default,\n var(--hx-color-surface-on-dark-overlay-default, rgba(255, 255, 255, 0.3))\n )\n );\n }\n\n /* Outline inverted — white border */\n :host([inverted]) .button--outline {\n --hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));\n }\n\n :host([inverted]) .button--outline:hover {\n --hx-button-bg: var(\n --hx-color-border-on-dark-default,\n var(--hx-color-surface-on-dark-overlay-default, rgba(255, 255, 255, 0.3))\n );\n }\n\n /* ─── Prefix / Suffix / Label ─── */\n\n .button__prefix,\n .button__suffix {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n }\n\n .button__label {\n flex: 1 1 auto;\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .button {\n /* Ensure button outline is visible in Windows High Contrast mode.\n ButtonText/ButtonFace are system colors recognized by the browser. */\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n border: 2px solid ButtonText;\n }\n\n .button:hover {\n /* Hover affordance must survive in HC. Highlight/HighlightText is the\n OS-level \"selected\" pair, mirroring the forcedColorsInteractive mixin's\n hover contract — kept inline since this component owns its bespoke HC\n block (XOR rule). */\n background-color: Highlight;\n color: HighlightText;\n border-color: Highlight;\n }\n\n .button:focus-visible {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .button[disabled] {\n background-color: ButtonFace;\n color: GrayText;\n border-color: GrayText;\n opacity: 1;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n .button--loading .button__spinner {\n /* Ensure spinner is visible in HCM */\n forced-color-adjust: auto;\n }\n }\n`;\n","import { html, nothing, type TemplateResult, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HelixElement } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { helixButtonStyles } from './hx-button.styles.js';\nimport { devWarn } from '../../utils/dev-warn.js';\n\n/** Detail for the hx-click event dispatched by hx-button. */\nexport interface HxButtonClickDetail {\n originalEvent: MouseEvent;\n}\n\n/**\n * A production-grade button component for user interaction. Supports multiple\n * visual variants, sizes, loading state, prefix/suffix slots, anchor rendering,\n * and full ElementInternals form association.\n *\n * @summary Primary interactive element for triggering actions and form submission.\n *\n * @tag hx-button\n *\n * @slot - Default slot for button label text or content.\n * @slot prefix - Icon or content rendered before the label.\n * @slot suffix - Icon or content rendered after the label.\n *\n * @fires {CustomEvent<{originalEvent: MouseEvent}>} hx-click - Dispatched when\n * the button is clicked and is neither disabled nor loading.\n *\n * @csspart button - The native button or anchor element.\n * @csspart label - The label text wrapper span.\n * @csspart prefix - The prefix slot container span.\n * @csspart suffix - The suffix slot container span.\n * @csspart spinner - The loading spinner SVG element.\n *\n * @cssprop [--hx-button-bg=var(--hx-color-action-primary-bg)] - Button background color. **Variant-shadowed**: every `.button--{variant}` rule rebinds this property at descendant scope, so a host-level override (`style=\"--hx-button-bg: …\"` or `:host`-targeting CSS) does not reach paint for primary/secondary/tertiary/danger/ghost/outline buttons. To recolor a variant fill, override the upstream semantic instead — e.g. `--hx-color-action-primary-bg` (light primary), `--hx-color-action-primary-bg-inverted-rest` (inverted primary), `--hx-color-action-danger-bg` (danger), or the inverted overlay tokens for tertiary/secondary/ghost/outline. The `--hx-button-bg` hook still works for the rare case of an unstyled base button without a `variant` class, and is internally rebound by the variant rules to participate in the active/hover override chain.\n * @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.\n * @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.\n * @cssprop [--hx-button-color=var(--hx-color-text-on-primary)] - Button text color (variants route through text.on-{role} / text.on-{role}-strong).\n * @cssprop [--hx-button-border-color=transparent] - Button border color (secondary/outline variants route through action.secondary.border).\n * @cssprop [--hx-button-border-radius=var(--hx-border-radius-md)] - Button border radius.\n * @cssprop [--hx-button-font-family=var(--hx-font-family-sans)] - Button font family.\n * @cssprop [--hx-button-font-weight=var(--hx-font-weight-semibold)] - Button font weight.\n * @cssprop [--hx-button-focus-ring-color=var(--hx-focus-ring-color)] - Focus ring color.\n *\n * @cssprop [--hx-button-inverted-color=var(--hx-color-text-inverse)] - Text color when inverted (resolves to neutral-0).\n * @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.\n * @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.\n * @cssprop [--hx-button-inverted-ghost-hover-bg=var(--hx-color-surface-on-dark-overlay-default)] - Ghost hover bg when inverted (overlay-white-30 — translucent fill, not a border; contrast not applicable).\n * @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 — clears WCAG 1.4.11 3:1 floor for non-text UI).\n *\n * @cssprop [--hx-color-action-primary-bg] - Primary variant resting fill (3.2.1 semantic action layer).\n * @cssprop [--hx-color-action-primary-bg-hover] - Primary variant hover fill.\n * @cssprop [--hx-color-action-primary-bg-active] - Primary variant active/pressed fill.\n * @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.\n * @cssprop [--hx-color-action-secondary-border] - Secondary/outline variant border (3.2.1 semantic; outline still routes through --hx-color-border-strong by default).\n * @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).\n * @cssprop [--hx-color-action-ghost-fg] - Ghost variant fg.\n * @cssprop [--hx-color-action-ghost-bg-hover] - Ghost variant hover fill.\n * @cssprop [--hx-color-action-danger-bg] - Danger variant resting fill.\n * @cssprop [--hx-color-action-danger-bg-hover] - Danger variant hover fill.\n * @cssprop [--hx-color-action-danger-bg-active] - Danger variant active fill.\n * @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).\n * @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).\n * @cssprop [--hx-color-text-on-primary] - Foreground for primary fill (resolves to neutral-900 — AA-tuned for primary-500).\n * @cssprop [--hx-color-text-on-primary-strong] - Foreground for primary-hover fill (resolves to neutral-0 across modes).\n * @cssprop [--hx-color-text-on-error] - Foreground for danger fill (resolves to neutral-900).\n * @cssprop [--hx-color-text-on-error-strong] - Foreground for danger-hover fill (resolves to neutral-0 across modes).\n * @cssprop [--hx-color-text-primary] - Foreground for tertiary variant on surface.sunken.\n * @cssprop [--hx-color-surface-sunken] - Tertiary variant resting fill.\n * @cssprop [--hx-color-surface-raised] - Tertiary variant hover fill.\n * @cssprop [--hx-color-surface-on-dark-overlay-subtle] - Inverted-tertiary resting fill (overlay-white-10 — translucent fill, not a border).\n * @cssprop [--hx-color-surface-on-dark-overlay-default] - Inverted-tertiary hover fill + inverted-secondary/ghost/outline hover fill (overlay-white-30 — translucent fill, not a border).\n * @cssprop [--hx-color-border-on-dark-strong] - Inverted-secondary/outline border + inverted focus-visible outline (overlay-white-70 ≈ 5:1 — clears WCAG 1.4.11 3:1 floor).\n * @cssprop [--hx-color-border-on-dark-subtle] - DEPRECATED 3.2.2; renamed to --hx-color-surface-on-dark-overlay-subtle (the value paints a translucent fill, not a border). Consume sites read both names via deprecated-first fallback so existing overrides keep working until removal in 4.0.0.\n * @cssprop [--hx-color-border-on-dark-default] - DEPRECATED 3.2.2; renamed to --hx-color-surface-on-dark-overlay-default (the value paints a translucent fill, not a border). Consume sites read both names via deprecated-first fallback so existing overrides keep working until removal in 4.0.0.\n */\n@customElement('hx-button')\nexport class HelixButton extends mixinDelegatesAria(HelixElement) {\n // 3.2.1: forced-colors deference is owned by the bespoke @media block in\n // hx-button.styles.ts (covers loading/disabled/focus, not just the base).\n // Do NOT also compose forcedColorsInteractive here — the mixin's docstring\n // forbids dual composition (XOR rule) and the dual approach was flagged in\n // the token-cascade campaign findings.\n static override styles = [helixButtonStyles];\n\n // ─── Form Association ───\n\n /** @internal */\n static override formAssociated = true;\n\n // ─── Public Properties ───\n\n /**\n * Visual style variant of the button.\n * @attr variant\n */\n @property({ type: String, reflect: true })\n variant: 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost' | 'outline' = 'primary';\n\n /**\n * Size of the button.\n * @attr hx-size\n */\n @property({ type: String, reflect: true, attribute: 'hx-size' })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Whether the button is disabled. Prevents all interaction and form actions.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the button is in a loading state. Shows spinner, prevents interaction,\n * and sets aria-busy. Does not set the disabled attribute.\n * @attr loading\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /**\n * The type attribute for the underlying button element. Ignored when href is set.\n * @attr type\n */\n @property({ type: String })\n type: 'button' | 'submit' | 'reset' = 'button';\n\n /**\n * When set, renders an anchor element instead of a button.\n * @attr href\n */\n @property({ type: String })\n href: string | undefined = undefined;\n\n /**\n * Anchor target attribute. Only used when href is set.\n * @attr target\n */\n @property({ type: String })\n target: string | undefined = undefined;\n\n /**\n * Form field name submitted via ElementInternals.setFormValue on submit.\n * @attr name\n */\n @property({ type: String })\n name: string | undefined = undefined;\n\n /**\n * Form field value submitted via ElementInternals.setFormValue on submit.\n * @attr value\n */\n @property({ type: String })\n value: string | undefined = undefined;\n\n /**\n * When true, the button stretches to fill its container width.\n * Sets the host to `display: block` and the inner element to `width: 100%`.\n * @attr full\n */\n @property({ type: Boolean, reflect: true })\n full = false;\n\n /**\n * When true, flips button colors for placement on dark or gradient backgrounds.\n * Forces 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*\n * within a light-mode-active page (hero banners, gradient sections, dark\n * cards). It is NOT validated for use within a dark-mode-active root\n * context: in dark mode, `surface.inverse` flips to a light surface\n * (neutral-100), and the lifted `-400` hover/active fills lose UI-floor\n * contrast against it (primary 2.10:1, danger 2.32:1 vs WCAG 1.4.11's 3:1\n * floor). Mode-aware fill stops + foreground for the dark-mode-inverted\n * combination are tracked as a 3.2.x follow-up.\n *\n * @attr inverted\n */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n /**\n * Accessible label for icon-only or text-less buttons.\n * Required when the button has no visible text content.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * `accessible-label` takes precedence when both are set.\n *\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Returns the effective label for the button, checking accessible-label first,\n * then the consumer-set aria-label attribute (read via data-aria-label which\n * mixinDelegatesAria writes when consumers set the host's `aria-label`),\n * then the still-pending `aria-label` attribute (in case the mixin has not\n * yet processed it), falling back to empty string.\n *\n * HX-015 migration: never read `this.ariaLabel` (the native HTMLElement IDL\n * property). The mixin overrides `ariaLabel` to read `data-aria-label` in\n * modern browsers, but the IDL fallback path breaks in fallback browsers and\n * confuses consumers who follow the v3 upgrade guide. Read the attribute\n * storage directly so the source-of-truth is unambiguous.\n *\n * @internal\n */\n private get _effectiveLabel(): string {\n return (\n this.accessibleLabel?.trim() ||\n this.getAttribute('data-aria-label')?.trim() ||\n this.getAttribute('aria-label')?.trim() ||\n ''\n );\n }\n\n // ─── Form API ───\n\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Lifecycle ───\n\n /** @internal */\n private static readonly _VALID_VARIANTS = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'danger',\n 'ghost',\n 'outline',\n ] as const;\n\n // Prevents double-warn on browsers that fire slotchange for empty initial slots.\n private _emptySlotWarnEmitted = false;\n\n override firstUpdated(changedProperties: PropertyValues<this>): void {\n super.firstUpdated(changedProperties);\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n const hasContent = (slot?.assignedNodes({ flatten: true }) ?? []).some(\n (n) => n.nodeType !== Node.TEXT_NODE || (n.textContent?.trim().length ?? 0) > 0,\n );\n if (!hasContent && !this._effectiveLabel) {\n this._emptySlotWarnEmitted = true;\n devWarn(\n 'hx-button',\n 'hx-button has no slot content and no accessible-label — button will have no accessible name.',\n );\n }\n }\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (changedProperties.has('variant')) {\n const validVariants: string[] = [...HelixButton._VALID_VARIANTS];\n if (!validVariants.includes(this.variant)) {\n devWarn(\n 'hx-button',\n `Invalid variant \"${this.variant}\". Expected one of: ${validVariants.join(', ')}. Clamping to \"primary\".`,\n );\n this.variant = 'primary';\n }\n }\n }\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleDefaultSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n const hasContent = slot\n .assignedNodes({ flatten: true })\n .some((n) => n.nodeType !== Node.TEXT_NODE || (n.textContent?.trim().length ?? 0) > 0);\n if (!hasContent && !this._effectiveLabel && !this._emptySlotWarnEmitted) {\n devWarn(\n 'hx-button',\n 'hx-button has no slot content and no accessible-label — button will have no accessible name.',\n );\n }\n // Only reset once content arrives so the guard stays armed for browsers\n // that fire a second slotchange for the same empty initial slot.\n if (hasContent) {\n this._emptySlotWarnEmitted = false;\n }\n }\n\n // ─── Event Handling ───\n\n /**\n * @private\n * @internal\n */\n private _handleClick(e: MouseEvent): void {\n if (this.disabled || this.loading) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n /**\n * Dispatched when the button is clicked.\n * @event hx-click\n */\n this.dispatchEvent(\n new CustomEvent<{ originalEvent: MouseEvent }>('hx-click', {\n bubbles: true,\n composed: true,\n detail: { originalEvent: e },\n }),\n );\n\n // Handle form submission/reset if form-associated and not in anchor mode\n if (this.href === undefined && this.type === 'submit' && this._internals.form) {\n if (this.name !== undefined && this.value !== undefined) {\n this._internals.setFormValue(this.value);\n }\n this._internals.form.requestSubmit();\n } else if (this.href === undefined && this.type === 'reset' && this._internals.form) {\n this._internals.form.reset();\n }\n }\n\n // ─── Render Helpers ───\n\n /**\n * @private\n * @internal\n */\n private _renderSpinner(): TemplateResult {\n return html`\n <svg\n class=\"button__spinner\"\n part=\"spinner\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n >\n <circle\n class=\"button__spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n opacity=\"0.3\"\n />\n <path\n class=\"button__spinner-arc\"\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n `;\n }\n\n /**\n * @private\n * @internal\n */\n private _renderInner(): TemplateResult {\n return html`\n ${this.loading ? this._renderSpinner() : nothing}\n <span part=\"prefix\" class=\"button__prefix\">\n <slot name=\"prefix\"></slot>\n </span>\n <span part=\"label\" class=\"button__label\">\n <slot @slotchange=${this._handleDefaultSlotChange}></slot>\n </span>\n <span part=\"suffix\" class=\"button__suffix\">\n <slot name=\"suffix\"></slot>\n </span>\n `;\n }\n\n // ─── Render ───\n\n override render() {\n const classes = {\n button: true,\n [`button--${this.variant}`]: true,\n [`button--${this.size}`]: true,\n 'button--loading': this.loading,\n };\n\n // mixinDelegatesAria forwarding: consumer-set aria-* (aria-pressed for\n // toggle buttons, aria-expanded/aria-haspopup/aria-controls for\n // menu/dropdown triggers, aria-describedby for inline help, aria-current\n // for active-link semantics in href mode) land in data-aria-* on the\n // host. Project them onto the inner role-bearing native element so AT\n // walks them on the <button>/<a>, not the generic host.\n const projectedPressed = this.getAttribute('data-aria-pressed');\n const projectedExpanded = this.getAttribute('data-aria-expanded');\n const projectedHasPopup = this.getAttribute('data-aria-haspopup');\n const projectedControls = this.getAttribute('data-aria-controls');\n const projectedDescribedBy = this.getAttribute('data-aria-describedby');\n const projectedCurrent = this.getAttribute('data-aria-current');\n const projectedLabelledBy = this.getAttribute('data-aria-labelledby');\n\n if (this.href !== undefined) {\n return html`\n <a\n part=\"button\"\n class=${classMap(classes)}\n href=${this.disabled || this.loading ? nothing : ifDefined(this.href)}\n target=${ifDefined(this.target)}\n rel=${this.target === '_blank' ? 'noopener noreferrer' : nothing}\n aria-label=${this._effectiveLabel || nothing}\n aria-labelledby=${ifDefined(projectedLabelledBy ?? undefined)}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-busy=${this.loading ? 'true' : nothing}\n aria-pressed=${ifDefined(projectedPressed ?? undefined)}\n aria-expanded=${ifDefined(projectedExpanded ?? undefined)}\n aria-haspopup=${ifDefined(projectedHasPopup ?? undefined)}\n aria-controls=${ifDefined(projectedControls ?? undefined)}\n aria-describedby=${ifDefined(projectedDescribedBy ?? undefined)}\n aria-current=${ifDefined(projectedCurrent ?? undefined)}\n tabindex=${this.disabled || this.loading ? '-1' : nothing}\n @click=${this._handleClick}\n >\n ${this._renderInner()}\n </a>\n `;\n }\n\n return html`\n <button\n part=\"button\"\n class=${classMap(classes)}\n ?disabled=${this.disabled}\n type=${this.type}\n aria-label=${this._effectiveLabel || nothing}\n aria-labelledby=${ifDefined(projectedLabelledBy ?? undefined)}\n aria-busy=${this.loading ? 'true' : nothing}\n aria-pressed=${ifDefined(projectedPressed ?? undefined)}\n aria-expanded=${ifDefined(projectedExpanded ?? undefined)}\n aria-haspopup=${ifDefined(projectedHasPopup ?? undefined)}\n aria-controls=${ifDefined(projectedControls ?? undefined)}\n aria-describedby=${ifDefined(projectedDescribedBy ?? undefined)}\n @click=${this._handleClick}\n >\n ${this._renderInner()}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-button': HelixButton;\n }\n interface HTMLElementEventMap {\n 'hx-click': CustomEvent<{ originalEvent: MouseEvent }>;\n }\n}\n"],"names":["helixButtonStyles","css","HelixButton","mixinDelegatesAria","HelixElement","_a","_b","_c","disabled","changedProperties","slot","n","validVariants","devWarn","e","hasContent","html","nothing","classes","projectedPressed","projectedExpanded","projectedHasPopup","projectedControls","projectedDescribedBy","projectedCurrent","projectedLabelledBy","classMap","ifDefined","__decorateClass","property","customElement"],"mappings":";;;;;;;AAEO,MAAMA,IAAoBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hx-checkbox-CYd0YV_u.js","sources":["../../src/components/hx-checkbox/hx-checkbox.styles.ts","../../src/components/hx-checkbox/hx-checkbox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const helixCheckboxStyles = css`\n :host {\n display: block;\n }\n\n :host([disabled]) {\n opacity: var(--hx-opacity-disabled, 0.5);\n pointer-events: none;\n }\n\n * {\n box-sizing: border-box;\n }\n\n .checkbox {\n display: flex;\n flex-direction: column;\n gap: var(--hx-space-1, 0.25rem);\n font-family: var(--hx-checkbox-font-family, var(--hx-font-family-sans, sans-serif));\n }\n\n /* ─── Control (checkbox + label row) ─── */\n\n .checkbox__control {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--hx-space-2, 0.5rem);\n /* WCAG 2.5.5 (healthcare mandate): minimum 44px touch target height */\n min-height: var(--hx-touch-target-min, 2.75rem);\n cursor: pointer;\n }\n\n :host([disabled]) .checkbox__control {\n cursor: not-allowed;\n }\n\n /* ─── Hidden Native Input ─── */\n\n .checkbox__input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n /* ─── Visual Checkbox ─── */\n\n .checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n height: var(--hx-checkbox-size, var(--hx-size-5, 1.25rem));\n border: var(--hx-border-width-medium, 2px) solid\n var(--hx-checkbox-border-color, var(--hx-color-border-strong, #66787b));\n border-radius: var(--hx-checkbox-border-radius, var(--hx-border-radius-sm, 0.25rem));\n background-color: var(--hx-checkbox-bg, var(--hx-color-surface-default, #ffffff));\n transition:\n background-color var(--hx-transition-fast, 150ms ease),\n border-color var(--hx-transition-fast, 150ms ease),\n box-shadow var(--hx-transition-fast, 150ms ease);\n margin-top: var(--hx-space-px, 1px);\n }\n\n /* ─── Focus Ring ─── */\n\n /*\n * Host-focus path: on the modern (IDL element-references) render branch the\n * host is the tabbable surface (tabindex=0) and the inner input is demoted\n * to tabindex=-1. Drive the focus ring from ':host(:focus-visible)' so\n * keyboard users still get a visible affordance. Codex round-11 P1.\n */\n :host(:focus-visible) .checkbox__box {\n outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));\n }\n\n /*\n * Fallback (no-IDL-ref) path: the host carries tabindex=-1 and the inner\n * input is the tab target. The native :focus-visible on the input drives\n * the same visual ring, scoped via the inner-state class.\n */\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: var(--hx-checkbox-focus-ring-width, var(--hx-focus-ring-width, 2px)) solid\n var(--hx-checkbox-focus-ring-color, var(--hx-focus-ring-color, #0f7078));\n outline-offset: var(--hx-checkbox-focus-ring-offset, var(--hx-focus-ring-offset, 2px));\n }\n\n /* ─── Checked State ─── */\n\n .checkbox--checked .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #429797));\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #429797));\n }\n\n /* ─── Indeterminate State ─── */\n\n .checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-checked-bg, var(--hx-color-primary-500, #429797));\n border-color: var(--hx-checkbox-checked-border-color, var(--hx-color-primary-500, #429797));\n }\n\n /* ─── Error State ─── */\n\n .checkbox--error .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Hover ─── */\n\n /* P1-03: use component token so consumer overrides of --hx-checkbox-border-color work on hover */\n .checkbox__control:hover .checkbox__box {\n border-color: var(\n --hx-checkbox-hover-border-color,\n var(--hx-checkbox-border-color, var(--hx-color-primary-500, #429797))\n );\n }\n\n .checkbox--checked .checkbox__control:hover .checkbox__box {\n filter: brightness(var(--hx-filter-brightness-hover, 0.9));\n }\n\n .checkbox--error .checkbox__control:hover .checkbox__box {\n border-color: var(--hx-checkbox-error-color, var(--hx-color-error-500, #e5493e));\n }\n\n /* ─── Checkmark Icon ─── */\n\n .checkbox__icon {\n display: none;\n width: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n height: calc(var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) * 0.65);\n fill: none;\n stroke: var(--hx-checkbox-checkmark-color, var(--hx-color-text-on-primary, #ffffff));\n stroke-width: 2.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n\n .checkbox--checked .checkbox__icon--check {\n display: block;\n }\n\n .checkbox--indeterminate .checkbox__icon--indeterminate {\n display: block;\n }\n\n /* ─── Label ─── */\n\n .checkbox__label {\n font-size: var(--hx-font-size-sm, 0.875rem);\n font-weight: var(--hx-font-weight-medium, 500);\n color: var(--hx-checkbox-label-color, var(--hx-color-text-strong, #202b39));\n line-height: var(--hx-line-height-normal, 1.5);\n user-select: none;\n -webkit-user-select: none;\n }\n\n .checkbox__required-marker {\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n font-weight: var(--hx-font-weight-bold, 700);\n }\n\n /* ─── Help Text & Error Messages ─── */\n\n .checkbox__help-text {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-help-text-color, var(--hx-color-text-muted, #4a5362));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n color: var(--hx-checkbox-error-color, var(--hx-color-error-text, #c92a2a));\n line-height: var(--hx-line-height-normal, 1.5);\n padding-inline-start: calc(\n var(--hx-checkbox-size, var(--hx-size-5, 1.25rem)) + var(--hx-space-2, 0.5rem)\n );\n }\n\n /* ─── Size Variants ─── */\n\n :host([hx-size='sm']) {\n --hx-checkbox-size: var(--hx-size-4, 1rem);\n }\n\n :host([hx-size='sm']) .checkbox__label {\n font-size: var(--hx-font-size-xs, 0.75rem);\n }\n\n :host([hx-size='sm']) .checkbox__help-text,\n :host([hx-size='sm']) .checkbox__error {\n font-size: var(--hx-font-size-xs, 0.75rem);\n padding-inline-start: calc(var(--hx-size-4, 1rem) + var(--hx-space-2, 0.5rem));\n }\n\n :host([hx-size='lg']) {\n --hx-checkbox-size: var(--hx-size-6, 1.5rem);\n }\n\n :host([hx-size='lg']) .checkbox__label {\n font-size: var(--hx-font-size-md, 1rem);\n }\n\n :host([hx-size='lg']) .checkbox__help-text,\n :host([hx-size='lg']) .checkbox__error {\n font-size: var(--hx-font-size-sm, 0.875rem);\n padding-inline-start: calc(var(--hx-size-6, 1.5rem) + var(--hx-space-2, 0.5rem));\n }\n\n /* ─── Reduced Motion ─── */\n\n @media (prefers-reduced-motion: reduce) {\n .checkbox__box {\n transition: none;\n }\n }\n\n /* ─── High Contrast Mode (forced-colors) ─── */\n\n @media (forced-colors: active) {\n .checkbox__box {\n forced-color-adjust: none;\n background-color: ButtonFace;\n border: 2px solid ButtonText;\n }\n\n :host(:focus-visible) .checkbox__box,\n .checkbox__input:focus-visible ~ .checkbox__box {\n outline: 3px solid Highlight;\n outline-offset: 2px;\n }\n\n .checkbox--checked .checkbox__box,\n .checkbox--indeterminate .checkbox__box {\n background-color: Highlight;\n border-color: Highlight;\n }\n\n .checkbox__icon {\n stroke: HighlightText;\n }\n\n .checkbox--error .checkbox__box {\n border-color: LinkText;\n }\n\n .checkbox--error.checkbox--checked .checkbox__box,\n .checkbox--error.checkbox--indeterminate .checkbox__box {\n background-color: LinkText;\n border-color: LinkText;\n }\n\n :host([disabled]) {\n opacity: 1;\n }\n\n :host([disabled]) .checkbox__box {\n border-color: GrayText;\n background-color: ButtonFace;\n }\n\n :host([disabled]) .checkbox--checked .checkbox__box,\n :host([disabled]) .checkbox--indeterminate .checkbox__box {\n background-color: GrayText;\n border-color: GrayText;\n }\n\n :host([disabled]) .checkbox__label {\n color: GrayText;\n }\n\n .checkbox__label {\n color: CanvasText;\n }\n\n .checkbox__help-text {\n color: GrayText;\n }\n\n .checkbox__error {\n color: LinkText;\n }\n }\n`;\n","import { html, nothing, type PropertyValues } from 'lit';\nimport '../../utilities/document-token-adoption.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { HelixElement, createIdCounter } from '../../base/index.js';\nimport { mixinDelegatesAria } from '../../mixins/index.js';\nimport { FormMixin } from '../../mixins/FormMixin.js';\nimport { helixCheckboxStyles } from './hx-checkbox.styles.js';\nimport { forcedColorsField } from '../../styles/forced-colors.js';\nimport { devWarn } from '../../utils/dev-warn.js';\nimport {\n installAriaIdrefMirror,\n resolveIdrefTokens,\n supportsIdrefElementReferences,\n type AriaIdrefMirrorHandle,\n} from '../../utils/aria-idref.js';\n\n// P2-05: monotonic counter — collision-free, deterministic, SSR-safe\nconst _nextCheckboxId = createIdCounter('hx-checkbox');\n\n/** Detail for the hx-change event dispatched by hx-checkbox. */\nexport interface HxCheckboxChangeDetail {\n checked: boolean;\n value: string;\n}\n\n/**\n * A checkbox component with label, validation, and form association.\n *\n * @summary Form-associated checkbox with built-in label, error, and help text.\n *\n * @tag hx-checkbox\n *\n * @slot - Custom label content (overrides the label property). Rich HTML allowed — Drupal can include links in consent labels.\n * @slot error - Custom error content (overrides the error property).\n * @slot help-text - Custom help text content (overrides the helpText property).\n *\n * @fires {CustomEvent<{checked: boolean, value: string}>} hx-change - Dispatched when the checkbox is toggled. Boolean-selection controls (`hx-switch`, `hx-checkbox`) include both `checked` (boolean state) and `value` (form value) in the detail; text-value controls (`hx-text-input`, `hx-combobox`, `hx-select`) emit only `{value}`.\n *\n * @csspart checkbox - The visual checkbox element.\n * @csspart checkmark - The SVG checkmark icon inside the checkbox.\n * @csspart label - The label element.\n * @csspart help-text - The help text container.\n * @csspart error - The error message container.\n * @csspart control - The wrapper around checkbox and label.\n *\n * @cssprop [--hx-checkbox-size=var(--hx-size-5, 1.25rem)] - Checkbox dimensions.\n * @cssprop [--hx-checkbox-bg=var(--hx-color-neutral-0, #ffffff)] - Unchecked background color.\n * @cssprop [--hx-checkbox-border-color=var(--hx-color-neutral-300, #B6BFB9)] - Checkbox border color.\n * @cssprop [--hx-checkbox-border-radius=var(--hx-border-radius-sm, 0.25rem)] - Checkbox border radius.\n * @cssprop [--hx-checkbox-checked-bg=var(--hx-color-primary-500, #429797)] - Checked background color.\n * @cssprop [--hx-checkbox-checked-border-color=var(--hx-color-primary-500, #429797)] - Checked border color.\n * @cssprop [--hx-checkbox-checkmark-color=var(--hx-color-neutral-0, #ffffff)] - Checkmark color.\n * @cssprop [--hx-checkbox-focus-ring-color=var(--hx-focus-ring-color, #6AB1B1)] - Focus ring color.\n * @cssprop [--hx-checkbox-label-color=var(--hx-color-neutral-700, #313E4B)] - Label text color.\n * @cssprop [--hx-checkbox-help-text-color=var(--hx-color-neutral-500, #66787B)] - Help text color.\n * @cssprop [--hx-checkbox-hover-border-color=var(--hx-checkbox-border-color)] - Border color on hover.\n * @cssprop [--hx-checkbox-error-color=var(--hx-color-error-500, #E5493E)] - Error state color.\n * @cssprop [--hx-opacity-disabled] - Opacity.\n * @cssprop [--hx-space-1] - Spacing token.\n * @cssprop [--hx-checkbox-font-family=var(--hx-font-family-sans)] - Font family for checkbox label and help text.\n * @cssprop [--hx-font-family-sans] - Font family.\n * @cssprop [--hx-space-2] - Spacing token.\n * @cssprop [--hx-touch-target-min] - Minimum touch target size.\n * @cssprop [--hx-size-5] - Size token.\n * @cssprop [--hx-border-width-medium] - Width.\n * @cssprop [--hx-color-neutral-300] - Color.\n * @cssprop [--hx-border-radius-sm] - CSS custom property.\n * @cssprop [--hx-color-neutral-0] - Color.\n * @cssprop [--hx-transition-fast] - Transition timing.\n * @cssprop [--hx-space-px] - Spacing token.\n * @cssprop [--hx-focus-ring-width] - Width.\n * @cssprop [--hx-focus-ring-color] - Color.\n * @cssprop [--hx-color-primary-400] - Color.\n * @cssprop [--hx-focus-ring-offset] - CSS custom property.\n * @cssprop [--hx-color-primary-500] - Color.\n * @cssprop [--hx-filter-brightness-hover] - CSS filter.\n * @cssprop [--hx-font-size-sm] - Font size.\n * @cssprop [--hx-font-weight-medium] - Font weight.\n * @cssprop [--hx-color-neutral-700] - Color.\n * @cssprop [--hx-line-height-normal] - Line height.\n * @cssprop [--hx-color-error-text] - Color.\n * @cssprop [--hx-font-weight-bold] - Font weight.\n * @cssprop [--hx-font-size-xs] - Font size.\n * @cssprop [--hx-color-neutral-500] - Color.\n * @cssprop [--hx-size-4] - Size token.\n * @cssprop [--hx-size-6] - Size token.\n * @cssprop [--hx-font-size-md] - Font size.\n * @cssprop [--hx-color-error-500] - Color.\n */\n@customElement('hx-checkbox')\nexport class HelixCheckbox extends mixinDelegatesAria(FormMixin(HelixElement)) {\n static override styles = [helixCheckboxStyles, forcedColorsField];\n\n // ─── Form Association ───\n\n /** @internal */\n static override formAssociated = true;\n\n // ─── Properties ───\n\n /**\n * Whether the checkbox is checked.\n * @attr checked\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * Whether the checkbox is in an indeterminate state (e.g., for \"select all\" patterns).\n * @attr indeterminate\n */\n @property({ type: Boolean, reflect: true })\n indeterminate = false;\n\n /**\n * Whether the checkbox is disabled.\n * @attr disabled\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Whether the checkbox is required for form submission.\n * @attr required\n */\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /**\n * The name of the checkbox, used for form submission.\n * @attr name\n */\n @property({ type: String, reflect: true })\n name = '';\n\n /**\n * The value submitted when the checkbox is checked.\n * @attr value\n */\n @property({ type: String, reflect: true })\n value = 'on';\n\n /**\n * The visible label text for the checkbox.\n * @attr label\n */\n @property({ type: String })\n label = '';\n\n /**\n * Error message to display. When set, the checkbox enters an error state.\n * @attr error\n */\n @property({ type: String })\n error = '';\n\n /**\n * Help text displayed below the checkbox for guidance.\n * @attr help-text\n */\n @property({ type: String, attribute: 'help-text' })\n helpText = '';\n\n /**\n * Validation message shown when the field is required but empty.\n * @attr required-message\n */\n @property({ attribute: 'required-message' })\n requiredMessage = 'This field is required.';\n\n /**\n * The size of the checkbox.\n * @attr hx-size\n */\n @property({ type: String, attribute: 'hx-size', reflect: true })\n size: 'sm' | 'md' | 'lg' = 'md';\n\n /**\n * Accessible label for the checkbox when no visible label text is provided.\n * Use when embedding a checkbox in a context where a label element is not practical.\n *\n * Accepts both `accessible-label` and the standard `aria-label` HTML attribute.\n * `accessible-label` takes precedence when both are set.\n * When set, replaces the visible label as the input's accessible name. Cannot be combined\n * with a visible label — set either `accessible-label` or the `label` slot, not both.\n *\n * @attr accessible-label\n */\n @property({ type: String, attribute: 'accessible-label' })\n accessibleLabel: string = '';\n\n /**\n * Returns the effective label for the checkbox, checking accessible-label first,\n * then the aria-label attribute, falling back to empty string.\n * @internal\n */\n private get _effectiveLabel(): string {\n return (\n this.accessibleLabel?.trim() ||\n this.getAttribute('data-aria-label')?.trim() ||\n this.getAttribute('aria-label')?.trim() ||\n ''\n );\n }\n\n /** @internal */\n @query('.checkbox__input')\n private _inputEl: HTMLInputElement | undefined;\n\n /** @internal */\n @state() private _hasErrorSlot = false;\n\n /** @internal */\n @state() private _hasHelpTextSlot = false;\n\n /** @internal */\n @state() private _hasLabelSlot = false;\n\n /**\n * Set by `hx-checkbox-group` to mark this child as group-managed. While\n * truthy, `_updateFormValue()` short-circuits to `setFormValue(null)`\n * regardless of `name`, so the child does NOT participate in form submission\n * — only the group does. This is durable against post-attach mutations to\n * `cb.name` by consumers/frameworks (which would otherwise re-arm\n * `_updateFormValue()` via the `name` setter and cause double-submission).\n * Codex round-3 finding #1.\n *\n * Public via accessor for the group's exclusive use; the underscore prefix\n * marks it as group-internal (not consumer API). The group sets it during\n * `slotchange` and clears it (via the same setter) when a child is removed.\n * @internal\n */\n set _groupedSuppress(value: boolean) {\n if (this.__groupedSuppress === value) return;\n this.__groupedSuppress = value;\n // Re-run form-value sync so the suppression takes effect immediately.\n this._updateFormValue();\n }\n get _groupedSuppress(): boolean {\n return this.__groupedSuppress;\n }\n /** @internal */\n private __groupedSuppress = false;\n\n /**\n * Deferred copy of this.error used inside the live region. Injected after\n * the region is visible (via requestAnimationFrame) so screen readers\n * re-announce the message even if it was set before the region became\n * visible — see WCAG 4.1.3.\n * @internal\n */\n @state() private _announcedError = '';\n\n /** @internal */\n private _hasWarnedLabelConflict = false;\n\n /**\n * Handle for the shared IDREF observer. Installed in `connectedCallback()`\n * so late-mutated `aria-labelledby`/`aria-describedby` and late-inserted\n * IDREF targets are picked up. See `installAriaIdrefMirror()`.\n * @internal\n */\n private _ariaMirror: AriaIdrefMirrorHandle | null = null;\n\n // ─── Slot Handlers ───\n\n /** @internal */\n private _handleErrorSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasErrorSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleHelpTextSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n this._hasHelpTextSlot = slot.assignedNodes({ flatten: true }).length > 0;\n }\n\n /** @internal */\n private _handleLabelSlotChange(e: Event): void {\n const slot = e.target as HTMLSlotElement;\n // Default slot may include the fallback `${this.label}` text node — count\n // assigned (not flattened) nodes so the slot fallback is not mistaken for\n // user-supplied content. The visible label is independently tracked via\n // the `label` property below.\n this._hasLabelSlot = slot.assignedNodes().length > 0;\n }\n\n // ─── Lifecycle ───\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Detect platform support for IDL element references. Cached as reactive\n // state so the render-time branch is consistent across update cycles and\n // tests can stub it deterministically. Codex round-2 finding #2.\n this._supportsIdrefRefs = supportsIdrefElementReferences(this._internals);\n // Seed root-independent semantics so the host carries the checkbox role\n // and reactive ARIA state from the moment of connection — before the\n // first paint. This closes the gap where AT scanning between connect\n // and `firstUpdated()` would see an unannounced surface.\n this._syncHostAriaSemantics();\n // Codex round-1 finding #1: host is the canonical announced surface on\n // modern browsers, so the inner `<input>` is demoted via\n // `aria-hidden + tabindex=-1` and the host owns tab order.\n //\n // Codex round-2 finding #2: on no-IDL-ref browsers the inner `<input>`\n // is the only surface AT can reach, so the host is demoted to\n // `tabindex=-1` and the inner input owns tab order. Without this,\n // `aria-labelledby`/`aria-describedby` on the inner input were inert\n // (the input was `aria-hidden`), leaving the control unnamed.\n // Codex round-14 P2: only claim ownership of `tabindex` when no consumer\n // value is present. Consumers using roving-tabindex toolbar patterns\n // must be able to set `tabindex=\"-1\"` on the host without it being\n // clobbered on every disabled flip. Note we still claim ownership when\n // disabled — the initial value is `-1` to keep the host out of tab order\n // and `updated()` re-asserts the appropriate value when disabled flips.\n if (!this.hasAttribute('tabindex')) {\n this._internalTabindexManaged = true;\n const enabledTabIndex = this._supportsIdrefRefs ? '0' : '-1';\n this.setAttribute('tabindex', this.disabled ? '-1' : enabledTabIndex);\n }\n this.addEventListener('keydown', this._handleHostKeyDown);\n this.addEventListener('click', this._handleHostClick);\n // Install the shared IDREF observer once the host is in a tree. The\n // observer covers consumer mutations to `aria-labelledby`/`-describedby`\n // (or their `data-aria-*` mirrors), late-inserted IDREF targets, and\n // `id` renames in the host's resolved root.\n this._ariaMirror = installAriaIdrefMirror(this, () => {\n this._syncHostAriaSemantics();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleHostKeyDown);\n this.removeEventListener('click', this._handleHostClick);\n this._ariaMirror?.disconnect();\n this._ariaMirror = null;\n }\n\n /**\n * Host-level keydown handler. Space toggles per ARIA APG checkbox pattern\n * — but only on the modern path where the host is the announced focus\n * surface. On the no-IDL-ref fallback (round-2 finding #2), the inner\n * `<input>` owns focus + native Space activation, so the host stays out\n * of the activation pipeline to avoid double-toggle.\n * @internal\n */\n private _handleHostKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n if (!this._supportsIdrefRefs) return;\n // Only handle when the host itself is the focus target — events from\n // slotted/nested controls bubble through here too.\n if (e.target !== this) return;\n if (e.key === ' ') {\n e.preventDefault();\n this._handleChange();\n }\n };\n\n /**\n * Host-level click handler. Routes clicks on the host (e.g. via assistive\n * tech activation) to the change handler — only on the modern path. On the\n * fallback path the inner input is the announced surface and natively\n * receives clicks/AT activation.\n * @internal\n */\n private _handleHostClick = (e: MouseEvent): void => {\n if (this.disabled) return;\n if (!this._supportsIdrefRefs) return;\n // Only respond to clicks that originated on the host itself. Bubbled\n // events from inner shadow elements (which toggle through the existing\n // label/input change handler) are skipped to avoid double-activation.\n const path = e.composedPath();\n if (path[0] !== this) return;\n this._handleChange();\n };\n\n override updated(changedProperties: PropertyValues<this>): void {\n super.updated(changedProperties);\n if (\n changedProperties.has('checked') ||\n changedProperties.has('value') ||\n changedProperties.has('name')\n ) {\n this._updateFormValue();\n }\n\n // Codex round-1 finding #1: keep host focusability in sync with disabled\n // state. Disabled custom elements should not be in tab order.\n // Codex round-2 finding #2: on no-IDL-ref browsers the host is demoted\n // to `tabindex=-1` so the inner input remains the announced surface.\n // Codex round-14 P2: only re-assert when the component owns tabindex.\n // Consumer-managed values (e.g. roving-tabindex toolbar with `-1`) must\n // not be overwritten on disabled flips or supports-flag transitions.\n if (\n changedProperties.has('disabled') ||\n (changedProperties as Map<PropertyKey, unknown>).has('_supportsIdrefRefs')\n ) {\n if (this._internalTabindexManaged) {\n if (this.disabled) {\n this.setAttribute('tabindex', '-1');\n } else {\n this.setAttribute('tabindex', this._supportsIdrefRefs ? '0' : '-1');\n }\n }\n }\n\n // Re-resolve element references against the (possibly mutated) shadow\n // tree. `_syncHostAriaSemantics()` is also invoked from `_updateValidity()`\n // and by the IDREF mirror observer, so this keeps property-driven changes\n // current without depending on observer scheduling.\n this._syncHostAriaSemantics();\n // Warn when accessible-label is set alongside a visible label — they are mutually exclusive.\n // Checked unconditionally (not gated on changedProperties) because aria-label is supplied\n // via data-aria-label by mixinDelegatesAria and never appears in changedProperties.\n {\n const hasAccessibleLabel = !!(\n this.accessibleLabel?.trim() ||\n this.getAttribute('data-aria-label')?.trim() ||\n this.getAttribute('aria-label')?.trim()\n );\n const hasVisibleLabel =\n !!this.label ||\n (this.shadowRoot\n ?.querySelector<HTMLSlotElement>('.checkbox__label slot')\n ?.assignedNodes({ flatten: true }).length ?? 0) > 0;\n if (hasAccessibleLabel && hasVisibleLabel && !this._hasWarnedLabelConflict) {\n this._hasWarnedLabelConflict = true;\n devWarn(\n 'hx-checkbox',\n 'accessible-label is set alongside a visible label. Use either accessible-label or the label slot, not both.',\n );\n } else if (!hasAccessibleLabel || !hasVisibleLabel) {\n this._hasWarnedLabelConflict = false;\n }\n }\n // WCAG 4.1.3: Keep _announcedError in sync with the error property.\n // When error changes from one non-empty value to another, clear the live region\n // first then re-inject after a rAF tick so screen readers re-announce the updated\n // message (clearing content before the region is re-populated triggers a new event).\n // When transitioning from empty to non-empty (initial display), set directly so\n // the text is immediately available for synchronous DOM assertions.\n if (changedProperties.has('error')) {\n const previousError = changedProperties.get('error') as string;\n if (previousError && this.error) {\n // Changing from one error message to another: defer to trigger re-announcement.\n this._announcedError = '';\n requestAnimationFrame(() => {\n this._announcedError = this.error;\n });\n } else {\n // Transitioning from empty→error or error→empty: set directly.\n this._announcedError = this.error;\n }\n }\n }\n\n // ─── Form Integration ───\n\n /** Returns the associated form element, if any. */\n override get form(): HTMLFormElement | null {\n return this._internals.form;\n }\n\n /** Returns the validation message. */\n override get validationMessage(): string {\n return this._internals.validationMessage;\n }\n\n /** Returns the ValidityState object. */\n override get validity(): ValidityState {\n return this._internals.validity;\n }\n\n /** @internal */\n _updateValidity(): void {\n if (this.required && !this.checked) {\n // Codex round-17 P2: anchor validity UI to the announced surface. On\n // the modern path the host is the canonical announced/focus surface\n // (the inner input is `aria-hidden + tabindex=-1`), so reportValidity()\n // would otherwise focus a hidden node. On the fallback path the inner\n // input is the announced surface.\n const anchor: HTMLElement | undefined = this._supportsIdrefRefs\n ? this\n : (this._inputEl ?? undefined);\n this._internals.setValidity(\n { valueMissing: true },\n this.error || this.requiredMessage,\n anchor,\n );\n } else {\n this._internals.setValidity({});\n }\n // Sync host ARIA semantics immediately after every setValidity() call so\n // `internals.ariaInvalid` reflects the current `ValidityState` rather than\n // the previous render cycle's snapshot. Codex round-1 finding #6.\n this._syncHostAriaSemantics();\n }\n\n // ─── Form Lifecycle Hooks ───\n\n protected override _onFormReset(): void {\n this.checked = false;\n this.indeterminate = false;\n this._internals.setFormValue(null);\n this._resetInteractionState();\n }\n\n protected override _onFormStateRestore(\n state: File | string | FormData | null,\n _mode: 'restore' | 'autocomplete',\n ): void {\n this.checked = typeof state === 'string' && state === this.value;\n }\n\n protected override _onFormDisabled(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n // ─── Event Handling ───\n\n /**\n * Writes the checkbox value to ElementInternals' form value. Suppressed when\n * the checkbox is grouped — `hx-checkbox-group` flips `_groupedSuppress` on\n * children so the group is the sole form participant.\n *\n * Codex round-3 finding #1: round-2 used `cb.name = ''` as the suppression\n * signal, but a consumer (or framework binding) that re-set `cb.name = 'foo'`\n * after attach regained form participation through the `name` setter. The\n * `_groupedSuppress` flag is a durable, name-independent kill switch.\n * Stand-alone checkboxes (no parent group) are unaffected.\n * @internal\n */\n private _updateFormValue(): void {\n if (this.__groupedSuppress || !this.name) {\n this._internals.setFormValue(null);\n return;\n }\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n /** @internal */\n private _handleChange(): void {\n if (this.disabled) return;\n\n this.indeterminate = false;\n this.checked = !this.checked;\n\n this._updateFormValue();\n this._handleInteractionInput();\n\n /**\n * Dispatched when the checkbox is toggled.\n * @event hx-change\n */\n this.dispatchEvent(\n new CustomEvent<{ checked: boolean; value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n\n // Codex round-12 P2 (parity with hx-switch / hx-toggle-button): on the\n // modern path the host owns role=\"checkbox\" and tabindex=0; the inner\n // `<input>` is aria-hidden and tabindex=-1. Clicking the surrounding\n // `<label>` still routes activation to the input via native label-forward,\n // which focuses the input. Move focus to the host so the announced\n // surface is also the focus target.\n if (this._supportsIdrefRefs) {\n this.focus();\n }\n }\n\n /**\n * Handles native `change` events from the inner `<input type=checkbox>` on\n * the no-IDL-ref fallback path. On that path the inner input is the\n * announced surface (no `aria-hidden`, `tabindex=0`) and AT activates it\n * directly — pointer/keyboard activation flips `input.checked` natively.\n * We mirror the input's state onto the host, dispatch `hx-change`, and\n * update form participation.\n *\n * Codex round-3 finding #2: round-2 left the inner input click suppressed\n * on both paths, so on no-IDL-ref browsers AT activation could not toggle\n * the control. The fix is to NOT suppress click on the fallback path and\n * to honor the resulting `change` event here.\n * @internal\n */\n private _handleInternalChange = (e: Event): void => {\n e.stopPropagation();\n if (this.disabled) return;\n const input = e.currentTarget as HTMLInputElement;\n // The native input flipped its own state; mirror onto the host. Avoid\n // re-toggling — `_handleChange()` toggles `this.checked = !this.checked`,\n // which would invert the user's actual choice.\n this.indeterminate = false;\n this.checked = input.checked;\n\n this._updateFormValue();\n this._handleInteractionInput();\n\n this.dispatchEvent(\n new CustomEvent<{ checked: boolean; value: string }>('hx-change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.value },\n }),\n );\n };\n\n /** @internal */\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n this._handleChange();\n }\n }\n\n /**\n * Stable inner-input click suppressor for the modern (announced-host) path.\n * Hoisted to a class field so Lit sees a stable listener identity across\n * renders; previously inline arrows were re-allocated each render and\n * caused listener detach/re-attach churn (codex round-4 F3 — performance).\n * @internal\n */\n private _suppressInnerClick = (e: Event): void => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n /**\n * Stable inner-input change suppressor for the modern (announced-host) path.\n * Mirrors the click suppressor above — stable identity across renders so\n * Lit's event-listener cache keeps a single registration (codex round-4 F3).\n * @internal\n */\n private _suppressInnerChange = (e: Event): void => {\n e.stopPropagation();\n };\n\n // ─── Public Methods ───\n\n /**\n * Moves focus to the announced checkbox surface. Codex round-1 finding #1\n * relocated the focus target from the inner `<input>` to the host on\n * modern engines so AT only sees one announced widget. Round-7 finding #3\n * extends that contract to the no-IDL-ref fallback: when the host is\n * demoted (`tabindex=-1`, role/state cleared on `internals`) the inner\n * `<input>` owns the announced semantics and tab order, so programmatic\n * `focus()` must redirect there — otherwise scripted focus and error\n * recovery land on the demoted host on unsupported engines.\n */\n override focus(options?: FocusOptions): void {\n if (this._supportsIdrefRefs) {\n super.focus(options);\n return;\n }\n this._inputEl?.focus(options);\n }\n\n // ─── Host ARIA Semantics (ElementInternals) ───\n\n /**\n * Mirrors checkbox semantics onto the host via ElementInternals so that\n * consumer-supplied `aria-label`, `aria-labelledby`, and `aria-describedby`\n * on `<hx-checkbox>` reach the announced control. Without this, those\n * attributes — intercepted by `mixinDelegatesAria` and stored on the host —\n * would not propagate through to the inner shadow `<input>`.\n *\n * Codex finding (aria-delegation, severity high): the announced semantic\n * node was the inner `<input>` and the host's labelled-by tokens could not\n * cross the shadow boundary.\n * @internal\n */\n private _syncHostAriaSemantics(): void {\n const internals = this._internals;\n const hostLabel = this._effectiveLabel;\n\n // Codex round-2 finding #2: branch on platform support for IDL element\n // references. On modern browsers the host is the canonical announced\n // surface and carries all checkbox semantics via ElementInternals. On\n // older browsers the inner `<input>` is the announced surface, so the\n // host's role/state are cleared and the consumer-supplied IDREFs are\n // mirrored to the inner input via render-time fallback state.\n if (this._supportsIdrefRefs) {\n // ─── Modern path: host is the announced surface ───\n internals.role = 'checkbox';\n internals.ariaChecked = this.indeterminate ? 'mixed' : this.checked ? 'true' : 'false';\n internals.ariaRequired = this.required ? 'true' : 'false';\n // Drive aria-invalid from validity state, not from visible error content.\n // A required-but-unchecked checkbox sets `valueMissing` via setValidity()\n // but may render no visible error yet — assistive tech still needs to hear\n // the invalid state.\n internals.ariaInvalid = !internals.validity.valid ? 'true' : 'false';\n internals.ariaDisabled = this.disabled ? 'true' : 'false';\n internals.ariaLabel = hostLabel || null;\n\n type InternalsWithRefs = ElementInternals & {\n ariaLabelledByElements: Element[] | null;\n ariaDescribedByElements: Element[] | null;\n };\n const refsInternals = internals as InternalsWithRefs;\n\n const externalLabelTokens = this.getAttribute('data-aria-labelledby');\n const externalDescTokens = this.getAttribute('data-aria-describedby');\n\n const labelEls = resolveIdrefTokens(this, externalLabelTokens);\n // Append the internal label element when the visible label has content\n // and no external labelling source already names the host.\n const internalLabel = this.shadowRoot?.getElementById(this._labelId);\n const hasVisibleLabel = !!this.label || this._hasLabelSlot;\n if (labelEls.length === 0 && !hostLabel && hasVisibleLabel && internalLabel) {\n labelEls.push(internalLabel);\n }\n refsInternals.ariaLabelledByElements = labelEls.length > 0 ? labelEls : null;\n\n const descEls = resolveIdrefTokens(this, externalDescTokens);\n // Codex round-13 P2: while an error is active, drop help text from the\n // described-by chain. The visible help node is suppressed in the render\n // tree, but referenced descriptions are announced even when their nodes\n // are hidden — leaving help in the chain would have AT read stale\n // guidance before the validation error. Otherwise help precedes error so\n // guidance reads before validation feedback when only one is shown.\n const helpEl = this.shadowRoot?.getElementById(this._helpTextId);\n const errorEl = this.shadowRoot?.getElementById(this._errorId);\n const hasError = !!(this.error || this._hasErrorSlot);\n if (helpEl && (this.helpText || this._hasHelpTextSlot) && !hasError) {\n descEls.push(helpEl);\n }\n if (errorEl && hasError) {\n descEls.push(errorEl);\n }\n refsInternals.ariaDescribedByElements = descEls.length > 0 ? descEls : null;\n // Clear fallbacks — IDL refs path is the canonical surface.\n this._fallbackAriaLabelledBy = null;\n this._fallbackAriaDescribedBy = null;\n } else {\n // ─── Fallback path: inner <input> is the announced surface ───\n // Codex round-2 finding #2: in round-1 we set host role/state via\n // ElementInternals AND mirrored aria-labelledby/describedby onto the\n // inner input. But the inner input was kept `aria-hidden`, making the\n // mirrored attributes inert — the control had no accessible name on\n // older browsers. The fix is to demote the host (clear its role/state\n // on internals so AT does not double-announce) and let the inner native\n // `<input type=checkbox>` be the announced surface, with consumer\n // IDREFs mirrored as real `aria-*` attributes that resolve through the\n // shadow root for shadow-internal IDs (cross-boundary IDREFs remain\n // unreachable on these engines — same baseline as the pre-fix code).\n internals.role = null;\n internals.ariaChecked = null;\n internals.ariaRequired = null;\n internals.ariaInvalid = null;\n internals.ariaDisabled = null;\n internals.ariaLabel = null;\n\n const externalLabelTokens = this.getAttribute('data-aria-labelledby');\n const externalDescTokens = this.getAttribute('data-aria-describedby');\n this._fallbackAriaLabelledBy = externalLabelTokens || null;\n this._fallbackAriaDescribedBy = externalDescTokens || null;\n }\n }\n\n /**\n * Fallback `aria-labelledby` token list applied to the inner input on\n * browsers that lack IDL element references. Tracked as a reactive state\n * so the value flows through the next `render()` call.\n * @internal\n */\n @state() private _fallbackAriaLabelledBy: string | null = null;\n\n /**\n * Fallback `aria-describedby` token list applied to the inner input on\n * browsers that lack IDL element references.\n * @internal\n */\n @state() private _fallbackAriaDescribedBy: string | null = null;\n\n /**\n * Whether the platform supports IDL element references on `ElementInternals`.\n * Drives the render-time branch between the modern path (host is the\n * announced surface, inner input is `aria-hidden + tabindex=-1`) and the\n * fallback path (inner input is the announced surface, host is demoted).\n *\n * Round-2 finding #2: the previous fallback mirrored `aria-labelledby` /\n * `aria-describedby` onto an `aria-hidden` inner input, leaving older\n * browsers with no accessible name. The fallback now keeps the inner input\n * in the a11y tree so AT can name and activate it natively.\n * @internal\n */\n @state() private _supportsIdrefRefs = true;\n\n /**\n * Tracks whether the host's `tabindex` is managed by the component itself\n * (vs. set explicitly by a consumer). Codex round-14 P2: a consumer-supplied\n * `tabindex` (e.g. roving-tabindex toolbar pattern with `tabindex=\"-1\"`)\n * must survive disabled flips and re-renders. Only re-assert tabindex in\n * `updated()` when the component originally claimed it.\n * @internal\n */\n private _internalTabindexManaged = false;\n\n // ─── Render ───\n\n // P2-05: monotonic counter — collision-free and deterministic\n /** @internal */\n private _id = _nextCheckboxId();\n /** @internal */\n private _helpTextId = `${this._id}-help`;\n /** @internal */\n private _errorId = `${this._id}-error`;\n /** @internal */\n private _labelId = `${this._id}-label`;\n\n override render() {\n const hasError = !!this.error || this._hasErrorSlot;\n const hasHelpText = !!this.helpText || this._hasHelpTextSlot;\n const hasVisibleLabel = !!this.label || this._hasLabelSlot;\n // Drive aria-invalid from the same validity source used by setValidity()\n // so a required-unchecked checkbox is announced as invalid even before any\n // visible error content has rendered.\n const isInvalid = hasError || (this.required && !this.checked);\n\n const containerClasses = {\n checkbox: true,\n 'checkbox--checked': this.checked,\n 'checkbox--indeterminate': this.indeterminate,\n 'checkbox--error': hasError,\n 'checkbox--disabled': this.disabled,\n 'checkbox--required': this.required,\n 'checkbox--sm': this.size === 'sm',\n 'checkbox--md': this.size === 'md',\n 'checkbox--lg': this.size === 'lg',\n };\n\n // describedBy chain: while an error is active, the visible help text is\n // suppressed in the rendered tree, so we must also drop it from the\n // described-by chain — referenced descriptions are announced even when\n // their nodes are hidden, and announcing stale guidance before the\n // validation error confuses screen-reader users (codex round-13 P2).\n // Otherwise help-text precedes error in the chain so guidance is read\n // before validation feedback when only one is shown.\n const describedBy =\n [hasError ? null : hasHelpText ? this._helpTextId : null, hasError ? this._errorId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n const hostAriaLabel = this._effectiveLabel || undefined;\n // Only point the inner input at `_labelId` when there is actual visible\n // label content; otherwise the input would reference an empty container.\n const useInternalLabelId = !hostAriaLabel && hasVisibleLabel;\n\n // Codex round-1 finding #7: on no-IDL-ref browsers, mirror consumer\n // tokens (stored as `data-aria-*`) onto the inner input so cross-shadow\n // labelling still resolves for shadow-internal IDs. The render fallbacks\n // are tracked as reactive state from `_syncHostAriaSemantics()`.\n const fallbackLabelledBy = this._fallbackAriaLabelledBy;\n const fallbackDescribedBy = this._fallbackAriaDescribedBy;\n\n // Merge internal describedBy chain with consumer fallback tokens.\n const innerDescribedBy =\n [describedBy ?? null, fallbackDescribedBy].filter(Boolean).join(' ') || undefined;\n // For labelledby, prefer consumer fallback tokens; otherwise keep the\n // internal label association.\n const innerLabelledBy = fallbackLabelledBy ?? (useInternalLabelId ? this._labelId : undefined);\n\n // Codex round-2 finding #2: branch the inner input on platform support.\n // Modern path — host is announced, inner input is `aria-hidden + tabindex=-1`.\n // Fallback path — inner input is announced (NO aria-hidden, tabindex=0)\n // so consumer-mirrored aria-labelledby/describedby actually resolve to a\n // visible accessibility-tree node. The inner input keeps its own click\n // suppressor because the visible activation surface is the surrounding\n // `<label>`; the input's native click activation is wired through that.\n const innerIsAnnounced = !this._supportsIdrefRefs;\n const innerTabIndex = innerIsAnnounced && !this.disabled ? '0' : '-1';\n\n // Codex round-3 finding #2: branch the inner input event model on\n // platform support.\n //\n // Modern path (`innerIsAnnounced === false`): the inner input is\n // `aria-hidden + tabindex=-1` — AT cannot reach it. Pointer clicks on the\n // inner input bubble through the surrounding `<label>` whose `@click`\n // handler runs `_handleChange()`. The inner click handler suppresses the\n // native click so the label's click is the sole activation pipeline,\n // avoiding double-toggle. Native `change` is also swallowed.\n //\n // Fallback path (`innerIsAnnounced === true`): the inner input IS the\n // announced surface (no `aria-hidden`, `tabindex=0`). AT activation lands\n // directly on the input and must produce a real toggle. We do NOT\n // suppress click; instead we wire `@change=${_handleInternalChange}` so\n // the host mirrors the input's state, fires `hx-change`, and updates\n // form participation. The label's `@click` is a no-op on this path —\n // pointer clicks on the label bubble to the input which toggles natively.\n // Codex round-4 F3 (performance): handlers are class-field arrows with\n // stable identity, so Lit's event-listener cache keeps a single\n // registration across re-renders instead of detach/re-attach churn.\n const innerClickHandler = innerIsAnnounced ? undefined : this._suppressInnerClick;\n const innerChangeHandler = innerIsAnnounced\n ? this._handleInternalChange\n : this._suppressInnerChange;\n const labelClickHandler = innerIsAnnounced ? undefined : this._handleChange;\n // On the fallback path the native input owns Space/Enter activation; its\n // native `change` event flows through `_handleInternalChange`. Wiring the\n // host-side `_handleKeyDown` here would double-toggle (native flips +\n // _handleChange flips again). On the modern path the input is `aria-hidden\n // + tabindex=-1` so this handler is defensive only.\n const innerKeyDownHandler = innerIsAnnounced ? undefined : this._handleKeyDown;\n\n return html`\n <div class=${classMap(containerClasses)}>\n <label part=\"control\" class=\"checkbox__control\" @click=${ifDefined(labelClickHandler)}>\n <input\n class=\"checkbox__input\"\n type=\"checkbox\"\n id=${this._id}\n tabindex=${innerTabIndex}\n .checked=${live(this.checked)}\n .indeterminate=${live(this.indeterminate)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n .value=${this.value}\n aria-checked=${this.indeterminate ? 'mixed' : nothing}\n aria-invalid=${isInvalid ? 'true' : nothing}\n aria-describedby=${ifDefined(innerDescribedBy)}\n aria-label=${ifDefined(hostAriaLabel)}\n aria-labelledby=${ifDefined(innerLabelledBy)}\n aria-hidden=${innerIsAnnounced ? nothing : 'true'}\n @keydown=${ifDefined(innerKeyDownHandler)}\n @click=${ifDefined(innerClickHandler)}\n @change=${innerChangeHandler}\n />\n\n <span part=\"checkbox\" class=\"checkbox__box\">\n <svg\n part=\"checkmark\"\n class=\"checkbox__icon checkbox__icon--check\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8 6.5 11 12.5 5\"></polyline>\n </svg>\n <svg\n class=\"checkbox__icon checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n aria-hidden=\"true\"\n >\n <line x1=\"4\" y1=\"8\" x2=\"12\" y2=\"8\"></line>\n </svg>\n </span>\n\n <span part=\"label\" class=\"checkbox__label\" id=${this._labelId}>\n <slot @slotchange=${this._handleLabelSlotChange}>${this.label}</slot>\n ${this.required\n ? html`<span class=\"checkbox__required-marker\" aria-hidden=\"true\">*</span>`\n : nothing}\n </span>\n </label>\n\n <!--\n P0-01: wrapper div always owns _errorId so aria-describedby works\n regardless of whether error content comes from the .error property\n or the named slot. role=\"status\" replaces aria-live=\"polite\" to\n avoid conflicting live-region semantics.\n -->\n <div\n part=\"error\"\n class=\"checkbox__error\"\n id=${this._errorId}\n role=\"status\"\n ?hidden=${!hasError}\n >\n <slot name=\"error\" @slotchange=${this._handleErrorSlotChange}>\n ${this._announcedError}\n </slot>\n </div>\n\n <!--\n Persistent help-text container. Rendered whenever the property OR\n the slot has content, hidden when an error is present so guidance\n does not compete with validation feedback. Always present in the\n shadow tree so the host's aria-describedby chain remains stable.\n -->\n <div\n part=\"help-text\"\n class=\"checkbox__help-text\"\n id=${this._helpTextId}\n ?hidden=${!hasHelpText || hasError}\n >\n <slot name=\"help-text\" @slotchange=${this._handleHelpTextSlotChange}\n >${this.helpText}</slot\n >\n </div>\n </div>\n `;\n }\n}\n\n/** Canonical type alias for the hx-checkbox component. */\nexport type HxCheckbox = HelixCheckbox;\n\n/**\n * Per-component event map for type-safe addEventListener on hx-checkbox.\n * The `hx-change` detail always includes both `checked` and `value` for this component.\n */\nexport interface HxCheckboxEventMap {\n 'hx-change': CustomEvent<{ checked: boolean; value: string }>;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hx-checkbox': HelixCheckbox;\n }\n /**\n * Global hx-change event type. The detail shape is a union because hx-change is dispatched\n * by multiple components: form-field components (value only) and toggle components\n * (checked + value). Use per-component EventMap types (e.g. HxCheckboxEventMap) for\n * narrowed addEventListener calls.\n */\n interface HTMLElementEventMap {\n 'hx-change': CustomEvent<{ value: string } | { checked: boolean; value: string }>;\n }\n}\n"],"names":["helixCheckboxStyles","css","_nextCheckboxId","createIdCounter","HelixCheckbox","mixinDelegatesAria","FormMixin","HelixElement","input","_a","_b","_c","value","slot","supportsIdrefElementReferences","enabledTabIndex","installAriaIdrefMirror","changedProperties","hasAccessibleLabel","hasVisibleLabel","_e","_d","anchor","state","_mode","disabled","options","internals","hostLabel","refsInternals","externalLabelTokens","externalDescTokens","labelEls","resolveIdrefTokens","internalLabel","descEls","helpEl","errorEl","hasError","hasHelpText","isInvalid","containerClasses","describedBy","hostAriaLabel","useInternalLabelId","fallbackLabelledBy","fallbackDescribedBy","innerDescribedBy","innerLabelledBy","innerIsAnnounced","innerTabIndex","innerClickHandler","innerChangeHandler","labelClickHandler","innerKeyDownHandler","html","classMap","ifDefined","live","nothing","forcedColorsField","__decorateClass","property","query","customElement"],"mappings":";;;;;;;;;;;AAEO,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}