@awc-ui/core 1.0.0-beta.5 → 1.0.0-beta.7
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.
- package/dist/cjs/md-button_6.cjs.entry.js +17 -2
- package/dist/cjs/md-button_6.cjs.entry.js.map +1 -1
- package/dist/cjs/md-segmented-button-set.cjs.entry.js +20 -2
- package/dist/cjs/md-segmented-button-set.cjs.entry.js.map +1 -1
- package/dist/collection/components/md-button/md-button.js +17 -2
- package/dist/collection/components/md-button/md-button.js.map +1 -1
- package/dist/collection/components/md-segmented-button-set/md-segmented-button-set.js +20 -2
- package/dist/collection/components/md-segmented-button-set/md-segmented-button-set.js.map +1 -1
- package/dist/components/md-button.js +1 -1
- package/dist/components/md-date-picker.js +1 -1
- package/dist/components/md-dialog.js +1 -1
- package/dist/components/md-multi-select.js +1 -1
- package/dist/components/md-segmented-button-set.js +1 -1
- package/dist/components/md-segmented-button-set.js.map +1 -1
- package/dist/components/md-snackbar.js +1 -1
- package/dist/components/md-step.js +1 -1
- package/dist/components/md-stepper.js +1 -1
- package/dist/components/md-time-picker.js +1 -1
- package/dist/components/{p-C1RN8YA1.js → p-BTgac9TA.js} +2 -2
- package/dist/components/p-BTgac9TA.js.map +1 -0
- package/dist/components-csr/md-button.js +1 -1
- package/dist/components-csr/md-date-picker.js +1 -1
- package/dist/components-csr/md-dialog.js +1 -1
- package/dist/components-csr/md-multi-select.js +1 -1
- package/dist/components-csr/md-segmented-button-set.js +1 -1
- package/dist/components-csr/md-segmented-button-set.js.map +1 -1
- package/dist/components-csr/md-snackbar.js +1 -1
- package/dist/components-csr/md-step.js +1 -1
- package/dist/components-csr/md-stepper.js +1 -1
- package/dist/components-csr/md-time-picker.js +1 -1
- package/dist/components-csr/{p-GG1ZMEng.js → p-QF3B4ODr.js} +2 -2
- package/dist/components-csr/p-QF3B4ODr.js.map +1 -0
- package/dist/esm/md-button_6.entry.js +17 -2
- package/dist/esm/md-button_6.entry.js.map +1 -1
- package/dist/esm/md-segmented-button-set.entry.js +20 -2
- package/dist/esm/md-segmented-button-set.entry.js.map +1 -1
- package/dist/md3/md3.esm.js +1 -1
- package/dist/md3/p-91df971f.entry.js +2 -0
- package/dist/md3/p-91df971f.entry.js.map +1 -0
- package/dist/md3/p-e661754b.entry.js +2 -0
- package/dist/md3/p-e661754b.entry.js.map +1 -0
- package/dist/types/components/md-segmented-button-set/md-segmented-button-set.d.ts +16 -0
- package/hydrate/index.js +37 -4
- package/hydrate/index.mjs +37 -4
- package/package.json +2 -2
- package/dist/components/p-C1RN8YA1.js.map +0 -1
- package/dist/components-csr/p-GG1ZMEng.js.map +0 -1
- package/dist/md3/p-56ea09a4.entry.js +0 -2
- package/dist/md3/p-56ea09a4.entry.js.map +0 -1
- package/dist/md3/p-6b841f69.entry.js +0 -2
- package/dist/md3/p-6b841f69.entry.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"md-button_6.cjs.entry.js","mappings":"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","names":["sanitizeHref","SAFE_WINDOW_FEATURES","triggerRipple","h","Host","SAFE_LINK_REL","Fragment","LazyLoadingIndicator","setFormValue","setValidityState","getValidityOf","checkValidityOf","reportValidityOf"],"sources":["src/components/md-button/md-button.css?tag=md-button&encapsulation=shadow","src/components/md-button/md-button.tsx","src/components/md-card/md-card.css?tag=md-card&encapsulation=shadow","src/components/md-card/md-card.tsx","src/components/md-icon-button/md-icon-button.css?tag=md-icon-button&encapsulation=shadow","src/components/md-icon-button/md-icon-button.tsx","src/components/md-radio/md-radio.css?tag=md-radio&encapsulation=shadow","src/components/md-radio/md-radio.tsx","src/components/md-ripple/md-ripple.css?tag=md-ripple&encapsulation=shadow","src/components/md-ripple/md-ripple.tsx","src/components/md-snackbar/md-snackbar.css?tag=md-snackbar&encapsulation=shadow","src/components/md-snackbar/md-snackbar.tsx"],"sourcesContent":["/* ==========================================================\n md-button — Material Design 3 Common Button\n Spec: https://m3.material.io/components/buttons/specs\n API: https://developer.android.com/reference/kotlin/\n androidx/compose/material3/ButtonDefaults\n Supports M3 + M3 Expressive (size, shape)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-button-container-color Container background\n --md-button-label-color Label + icon text color\n --md-button-icon-color Icon-only color override\n --md-button-icon-size Icon dimensions\n --md-button-container-shape Border-radius override\n --md-button-outline-color Outlined border color\n --md-button-outline-width Outlined border width\n --md-button-width Fixed inline-size (default: auto)\n --md-button-min-width Minimum inline-size (default: per-size touch target)\n --md-button-max-width Maximum inline-size (default: none)\n --md-button-height Fixed block-size (default: auto)\n --md-button-min-height Minimum block-size (default: per-size touch target)\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Leading icon (fallback)\n trailing-icon Trailing icon (fallback)\n label Label text wrapper\n loading Loading spinner\n\n SLOTS:\n leading-icon Custom leading icon (replaces icon prop)\n trailing-icon Custom trailing icon (replaces trailingIcon prop)\n\n RTL:\n Layout uses CSS logical properties throughout, so leading/\n trailing icons swap visual sides automatically in `dir=\"rtl\"`.\n Set the `mirror-icon` attribute on buttons that use directional\n glyphs (arrows, chevrons) so the icon path itself flips.\n ========================================================== */\n\n:host {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-0, none);\n --_icon-size: var(--md-button-icon-size, 18px);\n\n /* Sizing — defaults come from each size class via --_size-* tokens.\n Public --md-button-{width,min-width,max-width,height,min-height}\n custom properties override per-instance for variable / full-width\n buttons without sacrificing the spec touch-target on resize. */\n --_width: var(--md-button-width, auto);\n /* Min-width tightens with density too (floored at 40px) so short-label\n buttons narrow, not just content-wide ones. Unchanged at density 0. */\n --_min-width: var(\n --md-button-min-width,\n max(40px, calc(var(--_size-min-width, 48px) + var(--md-sys-density-scale, 0) * 4px))\n );\n --_max-width: var(--md-button-max-width, none);\n --_height: var(--md-button-height, auto);\n /* Global density: on top of the size scale, each `data-density` rung (0…-4)\n trims 4px off the touch target, floored at 24px so small buttons stay\n usable. density-scale is 0 by default so the per-size height is unchanged. */\n --_min-height: var(\n --md-button-min-height,\n max(24px, calc(var(--_size-min-height, 32px) + var(--md-sys-density-scale, 0) * 4px))\n );\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n border: none;\n /* Transparent resting outline; focus-visible swaps outline-color in instantly.\n Deliberately NOT transitioned — on hydration the host's pre-upgrade UA outline\n (style:none, color:currentColor) animates to solid/transparent, which renders a\n dark ring that fades out on every button. Most visible when many mount at once\n (e.g. the 42 day cells in md-date-picker). Instant focus ring matches M3. */\n outline: 3px solid transparent;\n outline-offset: 2px;\n box-sizing: border-box;\n inline-size: var(--_width);\n block-size: var(--_height);\n min-inline-size: var(--_min-width);\n min-block-size: var(--_min-height);\n max-inline-size: var(--_max-width);\n background-color: var(--_container-color);\n color: var(--_label-color);\n box-shadow: var(--_container-elevation);\n --_shape-round: 20px;\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n -webkit-tap-highlight-color: transparent;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 1. SIZE\n XS (32px) · SM (40px, default) · MD (48px) · LG (56px) · XL (96px)\n ========================================================== */\n/* Icon<->label gap tapers with density like the rest of the button: the\n container height and icon already shrink per rung, so a frozen gap made\n compact buttons read as loosely spaced. Each tier halves across the range\n (rate = base/8 per rung), floored at half its base. */\n:host(.md-button--xs) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 16px;\n --_size-min-height: 32px;\n --_size-min-width: 48px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(6px, calc(12px + var(--md-sys-density-scale, 0) * 0.75px));\n gap: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n font-family: var(--md-sys-typescale-label-medium-font-family, Roboto, sans-serif);\n font-size: max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-medium-letter-spacing, 0.5px);\n line-height: max(14px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n}\n\n:host(.md-button--sm) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 20px;\n --_size-min-height: 40px;\n --_size-min-width: 58px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(8px, calc(16px + var(--md-sys-density-scale, 0) * 1px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--md) {\n --_icon-size: var(--md-button-icon-size, max(12px, calc(24px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 28px;\n --_size-min-height: 56px;\n --_size-min-width: 72px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(12px, calc(24px + var(--md-sys-density-scale, 0) * 1.5px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-title-small-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-small-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-small-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--lg) {\n --_icon-size: var(--md-button-icon-size, max(16px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 48px;\n --_size-min-height: 96px;\n --_size-min-width: 88px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(24px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n gap: max(6px, calc(12px + var(--md-sys-density-scale, 0) * 1.5px));\n font-family: var(--md-sys-typescale-title-medium-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing, 0.15px);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--xl) {\n --_icon-size: var(--md-button-icon-size, max(20px, calc(40px + var(--md-sys-density-scale, 0) * 5px)));\n --_shape-round: 68px;\n --_size-min-height: 136px;\n --_size-min-width: 120px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px));\n gap: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-headline-small-font-family, Roboto, sans-serif);\n font-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n font-weight: var(--md-sys-typescale-headline-small-font-weight, 400);\n letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing, 0px);\n line-height: max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px));\n}\n\n/* ==========================================================\n 1b. FULL WIDTH — block-level, fills inline axis\n `full-width` switches the host from inline-flex to flex and stretches\n inline-size to 100% of the containing block. The size's\n --_size-min-height (touch target) is still in force, so the button\n keeps its spec block-size unless --md-button-height overrides it.\n --md-button-width still wins if explicitly set.\n ========================================================== */\n:host(.md-button--full-width) {\n display: flex;\n --_width: var(--md-button-width, 100%);\n}\n\n/* ==========================================================\n 2. SHAPE\n Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n --md-button-container-shape overrides both.\n ========================================================== */\n/* The RESTING radius is named (--_shape-rest) so the morph states below can be\n expressed as a blend back toward it. --_morph-to carries the morphed target\n and defaults to the resting value, so a button with no active morph state\n resolves to exactly its resting radius:\n\n calc(REST + FLAG * (MORPH - REST)) FLAG 1 -> MORPH, FLAG 0 -> REST\n\n That is what makes `data-shape-morph=\"off\"` / `shape-morph=\"off\"` freeze the\n shape (§13 in tokens.css) without a re-render and without :host-context,\n which Firefox does not implement. */\n:host(.md-button--round) {\n --_shape-rest: var(--md-button-container-shape, var(--_shape-round));\n border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest)));\n}\n\n:host(.md-button--square.md-button--xs) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-small, 8px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--sm) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--md) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--lg) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-large, 16px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--xl) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n\n/* ==========================================================\n 2b. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides for reliable transitions.\n\n Order: selected rules FIRST, pressed rules LAST so pressed\n always wins while the pointer is down.\n\n Asymmetric timing (M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xs) { --_morph-to: var(--md-sys-shape-corner-small, 8px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--md) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--lg) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-button--shape-morph.md-button--square.md-button--selected) {\n --_morph-to: var(--md-button-container-shape, var(--_shape-round));\n}\n\n/* ── Pressed shape — both round & square morph to more square, overrides selected ── */\n:host(.md-button--pressed.md-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-extra-small, 4px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--md) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 2c. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 2, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-button--connected-left.md-button--xs),\n:host(.md-button--connected-right.md-button--xs) { --_c-inner: 4px; }\n:host(.md-button--connected-left.md-button--sm),\n:host(.md-button--connected-right.md-button--sm) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--md),\n:host(.md-button--connected-right.md-button--md) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--lg),\n:host(.md-button--connected-right.md-button--lg) { --_c-inner: 16px; }\n:host(.md-button--connected-left.md-button--xl),\n:host(.md-button--connected-right.md-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-button--connected-left.md-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-button--round.md-button--connected-right:not(.md-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-button--round.md-button--connected-left:not(.md-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-button--square.md-button--connected-right:not(.md-button--connected-left)),\n:host(.md-button--square.md-button--connected-left:not(.md-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 3. ICON PADDING\n An icon does NOT change the button's insets. The M3 Expressive size sheet\n specifies the SAME padding on both sides whether or not a leading icon is\n present (12/12, 16/16, 24/24, 48/48, 64/64) — the third number on those\n drawings is the icon-to-label gap, not a reduced leading inset. The size's\n base padding therefore applies symmetrically and there is nothing to override.\n ========================================================== */\n\n/* ==========================================================\n 4. COLOR VARIANTS\n --md-button-container-color and --md-button-label-color\n override the variant defaults when set.\n ========================================================== */\n\n/* Filled */\n:host(.md-button--filled) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-primary));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-primary));\n --_state-layer-color: var(--md-sys-color-on-primary);\n}\n:host(.md-button--filled:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--filled:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--filled:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* Outlined */\n:host(.md-button--outlined) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n border: var(--md-button-outline-width, 1px) solid var(--md-button-outline-color, var(--md-sys-color-outline));\n}\n/* Variant padding follows the SAME density rule as the base size rules above:\n slope = base/16 (25% shrink across the four rungs) and a floor of base/2.\n These overrides previously decayed at 52-133% per the old tuning — text sm\n lost 133% of its inset and pinned to its floor by rung -2 — so outlined and\n text shrank far faster than the button did. Past rung -2 that INVERTED the\n variants: an outlined button, wider than filled at density 0, became\n narrower than it, and a row of mixed-variant buttons went visibly ragged.\n Density-0 values are unchanged; only the decay was corrected. */\n:host(.md-button--outlined.md-button--xs) { padding: 0 max(5.5px, calc(11px + var(--md-sys-density-scale, 0) * 0.6875px)); }\n:host(.md-button--outlined.md-button--sm) { padding: 0 max(11.5px, calc(23px + var(--md-sys-density-scale, 0) * 1.4375px)); }\n:host(.md-button--outlined.md-button--md) { padding: 0 max(13.5px, calc(27px + var(--md-sys-density-scale, 0) * 1.6875px)); }\n:host(.md-button--outlined.md-button--lg) { padding: 0 max(15.5px, calc(31px + var(--md-sys-density-scale, 0) * 1.9375px)); }\n:host(.md-button--outlined.md-button--xl) { padding: 0 max(23.5px, calc(47px + var(--md-sys-density-scale, 0) * 2.9375px)); }\n:host(.md-button--outlined:hover:not(.md-button--disabled)) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n:host(.md-button--outlined:focus-visible) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n\n/* Text */\n:host(.md-button--text) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n/* Text buttons intentionally carry the SAME horizontal padding as every other\n variant (the base size rules above); there is deliberately no override here.\n They used to sit far tighter — a text button's inset was a third of a\n filled one's and pinned to its floor at tight densities (4px by rung -2).\n The container is invisible at rest, but the hover/press state layer is not:\n it paints the padding box, so a text button in a toggle strip beside a\n tonal or filled one showed a cramped pill hugging its label while its\n neighbour's was roomy, and the mismatch grew with density. Sharing the base\n padding keeps every state layer in a strip the same shape, and keeps a\n button's width stable if its variant changes to signal selection. */\n\n/* Elevated */\n:host(.md-button--elevated) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-low));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-1);\n}\n:host(.md-button--elevated:hover) { --_container-elevation: var(--md-sys-elevation-2); }\n:host(.md-button--elevated:focus-visible) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--elevated:active) { --_container-elevation: var(--md-sys-elevation-1); }\n\n/* Tonal */\n:host(.md-button--tonal) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n:host(.md-button--tonal:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--tonal:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--tonal:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* ==========================================================\n 4b. TOGGLE SELECTED / UNSELECTED — MD3 spec\n When toggle=true, the unselected state is muted; selected\n shows the full variant color. Mirrors md-icon-button pattern.\n ========================================================== */\n\n/* The toggle-state rules below all carry `:not(.md-button--disabled)` so\n they drop out when the host becomes disabled. Without it, their higher\n specificity (4 classes vs the disabled rules' 2–3) would override the\n muted disabled palette and the button would still look enabled. */\n\n/* ── Filled toggle ── */\n:host(.md-button--filled.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n\n/* ── Tonal toggle ── */\n:host(.md-button--tonal.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ── Outlined toggle ── */\n:host(.md-button--outlined.md-button--toggle.md-button--selected:not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-sys-color-on-secondary-container, #1E192B);\n border-color: transparent;\n}\n\n/* ── Elevated toggle ── */\n:host(.md-button--elevated.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n/* ── Text toggle ── */\n:host(.md-button--text.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ==========================================================\n 5. STATE LAYER\n ========================================================== */\n.md-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active:not(.md-button--disabled)) .md-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n transition-duration: var(--md-sys-motion-duration-short1, 50ms);\n transition-timing-function: var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n:host(:focus-visible) .md-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 6. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline is never clipped by a neighbor — important inside\n md-button-group, where connected groups have only 2px between\n buttons and standard groups animate neighbor padding on press.\n ========================================================== */\n/* Connected children inside md-button-group sit only 2px apart, so a\n 3px-outset focus ring naturally extends across the neighbor. The\n `z-index: 1` raise lets it draw *on top* of the neighbor cleanly so\n the ring keeps its full 2px breathing room — same visual treatment\n as a stand-alone button. */\n:host(:focus-visible) {\n outline-color: var(--md-sys-color-secondary);\n z-index: 1;\n}\n\n/* ==========================================================\n 7. DISABLED\n ========================================================== */\n:host(.md-button--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n transition: none;\n}\n\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-button__state-layer { display: none; }\n\n:host(.md-button--filled.md-button--disabled),\n:host(.md-button--tonal.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n:host(.md-button--elevated.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-button--disabled) {\n --_label-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-button--outlined.md-button--disabled) {\n --_container-color: transparent;\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-button--text.md-button--disabled) {\n --_container-color: transparent;\n}\n\n:host(.md-button--disabled:hover) .md-button__state-layer,\n:host(.md-button--disabled:active) .md-button__state-layer,\n:host(.md-button--disabled:focus-visible) .md-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 8. ICON (prop-based fallback inside slot)\n ========================================================== */\n.md-button__icon,\n.md-button__trailing-icon {\n color: var(--md-button-icon-color, inherit);\n font-size: var(--_icon-size, 18px);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 9. NAMED ICON SLOTS\n Slots use display:contents so they don't create a box;\n slotted content participates directly in flex layout.\n ========================================================== */\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n color: var(--md-button-icon-color, inherit);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n flex-shrink: 0;\n}\n\n/* ----------------------------------------------------------\n Trailing-icon rotation when this button is a popover anchor.\n\n md-menu (and any other popup component using the same ARIA\n contract) sets aria-expanded=\"true\" on its anchor element\n while the popup is open. Rotating the trailing dropdown\n indicator 180° on that signal flips arrow_drop_down to\n point up, matching MD3 select-trigger behavior, with no\n wiring needed on the consumer side.\n\n Honors prefers-reduced-motion via short2 motion duration.\n ---------------------------------------------------------- */\n.md-button__trailing-icon,\n::slotted([slot=\"trailing-icon\"]) {\n transition: transform var(--md-sys-motion-duration-short2, 150ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) .md-button__trailing-icon,\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) ::slotted([slot=\"trailing-icon\"]) {\n transform: rotate(180deg);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-button__state-layer {\n transition: none;\n }\n\n .md-button__trailing-icon,\n ::slotted([slot=\"trailing-icon\"]) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 10. LABEL\n ========================================================== */\n.md-button__label {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n/* ==========================================================\n 11. LOADING SPINNER (scales with icon size)\n ========================================================== */\n.md-button__loading {\n /* A FRACTION of the icon it stands in for. Two constraints pull against each\n other: at full --_icon-size the ring reads heavier than the glyph (a bare\n stroke has none of the internal padding a Material glyph carries), but at\n 1em it was pinned to the label and stopped scaling per tier -- sm and md\n share a 14px label, so a 40px and a 56px button drew the same 14px ring\n despite 20px vs 24px icons. 0.7 keeps it visibly lighter than a glyph while\n tracking the tier, and inherits the icon's density taper. */\n /* 10px floor: the icon token itself bottoms out at 10px on the small tiers,\n and 0.7 of that is a 7px ring — too small to read as a spinner at all. */\n --_loading-size: var(--md-button-loading-size, max(10px, calc(var(--_icon-size, 18px) * 0.7)));\n\n /* Hand the size straight to md-loading-indicator's PUBLIC hooks. These\n replace the child's whole default expression, so the button's own taper\n (and its 10px floor) survives instead of hitting the child's 32px floor.\n Not --_size / --_shape-size: those are the child's private vars and\n writing them from out here is the handoff trap. currentColor keeps the\n indicator matching each variant's label, which a token would not. */\n --md-loading-indicator-size: var(--_loading-size);\n --md-loading-indicator-shape-size: var(--_loading-size);\n --md-loading-indicator-color: currentColor;\n flex-shrink: 0;\n /* A wrapper now, so the hooks above reach a SLOTTED replacement too. It has\n to lay out like the indicator it replaced — an inline span would add a text\n baseline gap next to the label. */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Whatever the consumer slots in gets the same box the default occupies. */\n.md-button__loading ::slotted(*) {\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 12. MATERIAL SYMBOLS (default icon font)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 18px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 13. RTL — opt-in directional-icon mirroring\n\n Buttons that show directional Material Symbols (arrow_forward,\n chevron_right, send, reply…) should set `mirror-icon` so the\n glyph itself flips alongside the leading/trailing slot swap that\n the logical-property layout already performs. Non-directional\n icons (add, search, favorite…) leave `mirror-icon` unset so the\n glyph stays semantically correct.\n\n Two rules cover both placements of `dir=\"rtl\"`:\n (a) on the host itself — `:host([dir=\"rtl\"])`\n (b) on any ancestor element — `:host-context([dir=\"rtl\"])`\n ========================================================== */\n:host([mirror-icon][dir=\"rtl\"]) .md-button__icon,\n:host([mirror-icon][dir=\"rtl\"]) .md-button__trailing-icon,\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"leading-icon\"]),\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__trailing-icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"leading-icon\"]),\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n LINK MODE — the anchor rendered when `href` is set\n\n The anchor wraps the button's innards so the LABEL gives it its accessible\n name, and it carries the tab stop (the host drops role/tabindex in this\n mode). It reproduces the host's own flex row rather than sitting inside it,\n so a link button lays out identically to a plain one.\n\n `::after` stretches the hit area over the host's padding: the anchor itself\n only fills the CONTENT box, so without it a click on the padding — a good\n third of a large button — would miss the link and lose native activation.\n The host is already `position: relative`, so the inset resolves to it.\n ========================================================== */\n.md-button__anchor {\n display: flex;\n align-items: center;\n justify-content: center;\n /* Not inherited by default; picking up the host's computed value keeps the\n icon/label spacing identical to a non-link button at every density. */\n gap: inherit;\n inline-size: 100%;\n block-size: 100%;\n min-inline-size: 0;\n /* A button is not underlined blue text. */\n color: inherit;\n font: inherit;\n text-decoration: none;\n outline: none;\n}\n\n.md-button__anchor::after {\n content: '';\n position: absolute;\n inset: 0;\n /* Behind the state layer and ripple so neither is occluded. */\n z-index: 0;\n}\n\n/* The focus ring belongs to the whole button, not the inner content box. */\n:host(:has(.md-button__anchor:focus-visible)) {\n outline: var(--md-sys-state-focus-ring-width, 3px) solid\n var(--md-button-focus-ring-color, var(--md-sys-color-secondary, #625B71));\n outline-offset: var(--md-sys-state-focus-ring-offset, 2px);\n}\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Fragment, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { LazyLoadingIndicator } from '../../utils/lazy-loading-indicator';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_LINK_REL, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n /* A safe href renders a REAL <a> in the shadow root, and the browser\n owns activation from there — so do nothing here. That is what makes\n middle-click, cmd/ctrl-click and \"copy link address\" work, and it is\n why cancelling mdClick above (which calls preventDefault on this very\n event) still vetoes navigation.\n\n The fallback below covers only the case where NO anchor exists: an\n href that failed sanitising renders none, so there is nothing to\n navigate and nothing to fall back to — the navigation is refused, as\n before. window.open remains for a programmatic click() on a button\n whose href is safe but whose anchor has not rendered yet. */\n const href = sanitizeHref(this.href);\n if (href && !this.el.shadowRoot?.querySelector('.md-button__anchor')) {\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n }\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n /* A component that accepts `href` must produce a real link. Sanitising\n here (not just at click time) means an unsafe URL renders NO anchor at\n all rather than an inert one. Disabled link-buttons also drop the\n anchor: there is no disabled state for <a>, and a focusable link that\n refuses to navigate is worse than no link. */\n const linkHref =\n this.href && !isEffectivelyDisabled ? sanitizeHref(this.href) : '';\n /* rel only where it means something: a target that opens a NEW browsing\n context. Blanket noreferrer would also strip the Referer on ordinary\n same-tab navigation, quietly breaking referrer-based analytics. */\n const opensNewContext = !!this.target && this.target !== '_self';\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || (linkHref ? null : 'button')}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n /* When a real anchor is rendered IT is the focusable element, so the\n host must not be a tab stop as well — otherwise every link button\n costs two presses of Tab and screen readers meet a button wrapping\n a link. */\n linkHref\n ? null\n : this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {linkHref ? (\n <a\n class=\"md-button__anchor\"\n part=\"anchor\"\n role=\"link\"\n href={linkHref}\n target={this.target || undefined}\n rel={opensNewContext ? SAFE_LINK_REL : undefined}\n tabindex={this.groupTabindex !== null ? String(this.groupTabindex) : '0'}\n aria-disabled={isEffectivelyDisabled ? 'true' : null}\n >\n {this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)}\n </a>\n ) : (\n this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)\n )}\n </Host>\n );\n }\n\n /** Button innards, rendered either directly in the host or inside the\n * anchor when `href` makes this a link. */\n private renderContent(\n isEffectivelyDisabled: boolean,\n hasLeadingIcon: boolean,\n hasTrailingIcon: boolean,\n ) {\n return (\n <Fragment>\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24px M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <LazyLoadingIndicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Fragment>\n );\n }\n}\n","/* ==========================================================\n md-card — Material Design 3 Card\n Spec: https://m3.material.io/components/cards/specs\n\n Three variants:\n elevated — surface-container-low + elevation 1\n filled — surface-container-highest + no elevation\n outlined — surface + outline-variant border + no elevation\n\n Measurements (MD3 spec):\n Shape: 12px corner radius (shape-corner-medium)\n Left/right padding: 16px (applied to default slot via consumer)\n Padding between: 8px max (layout concern of consumer)\n Label text: start-aligned\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-card-container-color Container background\n --md-card-container-shape Border-radius override\n --md-card-container-elevation Box-shadow override\n --md-card-outline-color Outline color (outlined variant)\n --md-card-outline-width Outline width (outlined variant)\n --md-card-state-layer-color State layer color override\n --md-card-width Explicit inline-size (default: auto)\n --md-card-min-width Minimum inline-size\n --md-card-max-width Maximum inline-size\n --md-card-height Explicit block-size (default: auto)\n --md-card-min-height Minimum block-size\n --md-card-max-height Maximum block-size\n\n ATTRIBUTES:\n full-width Stretch the card to 100% of its container's inline-size\n full-height Stretch the card to 100% of its container's block-size\n\n CSS PARTS:\n state-layer Hover/press overlay (interactive only)\n outline Border element (outlined variant only)\n\n SLOTS:\n (default) Card content (images, text, actions, other components)\n ========================================================== */\n\n:host {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-low));\n --_container-shape: var(--md-card-container-shape, var(--md-sys-shape-corner-medium, max(8px, calc(12px + var(--md-sys-density-scale, 0) * 1px))));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-1));\n --_outline-color: var(--md-card-outline-color, var(--md-sys-color-outline-variant));\n --_outline-width: var(--md-card-outline-width, 1px);\n --_state-layer-color: var(--md-card-state-layer-color, var(--md-sys-color-on-surface));\n\n --_width: var(--md-card-width, auto);\n --_min-width: var(--md-card-min-width, auto);\n --_max-width: var(--md-card-max-width, none);\n --_height: var(--md-card-height, auto);\n --_min-height: var(--md-card-min-height, auto);\n --_max-height: var(--md-card-max-height, none);\n\n --_padding: var(--md-card-padding, max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px)));\n --_gap: var(--md-card-gap, max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px)));\n\n display: flex;\n flex-direction: column;\n position: relative;\n box-sizing: border-box;\n overflow: hidden;\n padding: var(--_padding);\n gap: var(--_gap);\n\n inline-size: var(--_width);\n min-inline-size: var(--_min-width);\n max-inline-size: var(--_max-width);\n block-size: var(--_height);\n min-block-size: var(--_min-height);\n max-block-size: var(--_max-height);\n\n background-color: var(--_container-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--_container-elevation);\n color: var(--md-sys-color-on-surface);\n\n /* MD3 body-medium typescale — set on :host so it inherits through to\n slotted content (which lives in light DOM and only inherits from the\n host element, not from shadow-DOM rules). Without this, slotted\n headings / paragraphs fall back to the user-agent font (typically\n Times) instead of the Roboto-based MD3 typescale.\n NOTE: never use `--md-sys-typescale-*-font` for `font-family` — that\n token is the `font` shorthand (e.g. `400 14px/20px Roboto, sans-serif`)\n and is invalid for `font-family`, which silently kills the rule. */\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-medium-font-weight, 400);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing, 0.25px);\n\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n FULL-WIDTH / FULL-HEIGHT attributes\n `100%` only resolves when the parent has a definite size on\n that axis, so consumers must place the card inside a flex /\n grid item or a sized block container. Combined with the\n `--md-card-max-{width,height}` tokens this gives a fluid\n \"fill but cap\" pattern useful in dashboards and grids.\n ========================================================== */\n\n:host(.md-card--full-width) {\n --_width: 100%;\n}\n\n:host(.md-card--full-height) {\n --_height: 100%;\n}\n\n/* ==========================================================\n 1. VARIANTS\n ========================================================== */\n\n/* Elevated (default) */\n:host(.md-card--elevated) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-low));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-1));\n}\n\n/* Filled */\n:host(.md-card--filled) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-highest));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-0, none));\n}\n\n/* Outlined */\n:host(.md-card--outlined) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-0, none));\n}\n\n/* ==========================================================\n 2. OUTLINE (outlined variant only)\n ========================================================== */\n\n.md-card__outline {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n border: var(--_outline-width) solid var(--_outline-color);\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. INTERACTIVE & DRAGGABLE STATES\n Interactive cards behave like buttons with state layers.\n Draggable cards support native HTML drag-and-drop with\n the dragged state layer and elevation changes.\n ========================================================== */\n\n:host(.md-card--interactive) {\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n:host(.md-card--draggable) {\n cursor: grab;\n touch-action: none;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n}\n\n:host(.md-card--interactive.md-card--draggable) {\n cursor: grab;\n}\n\n:host(.md-card--dragged) {\n cursor: grabbing;\n}\n\n/* --- State layer --- */\n\n.md-card__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short1, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n z-index: 1;\n}\n\n:host(.md-card--interactive:hover) .md-card__state-layer,\n:host(.md-card--draggable:hover) .md-card__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-card--interactive:focus-visible) .md-card__state-layer,\n:host(.md-card--draggable:focus-visible) .md-card__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n:host(.md-card--interactive:active) .md-card__state-layer,\n:host(.md-card--draggable:active) .md-card__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(.md-card--dragged) .md-card__state-layer {\n opacity: var(--md-sys-state-dragged-state-layer-opacity, 0.16);\n}\n\n/* --- Elevation changes for elevated cards (interactive / draggable) --- */\n\n:host(.md-card--elevated.md-card--interactive:hover),\n:host(.md-card--elevated.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-2);\n}\n\n:host(.md-card--elevated.md-card--interactive:focus-visible),\n:host(.md-card--elevated.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--elevated.md-card--interactive:active),\n:host(.md-card--elevated.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--elevated.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-4);\n}\n\n/* --- Elevation changes for filled cards (interactive / draggable) --- */\n\n:host(.md-card--filled.md-card--interactive:hover),\n:host(.md-card--filled.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--filled.md-card--interactive:focus-visible),\n:host(.md-card--filled.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--filled.md-card--interactive:active),\n:host(.md-card--filled.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--filled.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-3);\n}\n\n/* --- Elevation changes for outlined cards (interactive / draggable) --- */\n\n:host(.md-card--outlined.md-card--interactive:hover),\n:host(.md-card--outlined.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--outlined.md-card--interactive:focus-visible),\n:host(.md-card--outlined.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--outlined.md-card--interactive:active),\n:host(.md-card--outlined.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--outlined.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-3);\n}\n\n/* --- Outline state for outlined cards (interactive / draggable) --- */\n\n:host(.md-card--outlined.md-card--interactive:focus-visible) .md-card__outline,\n:host(.md-card--outlined.md-card--draggable:focus-visible) .md-card__outline {\n border-color: var(--md-sys-color-on-surface);\n}\n\n:host(.md-card--outlined.md-card--dragged) .md-card__outline {\n border-color: var(--md-sys-color-outline-variant);\n}\n\n/* ==========================================================\n 4. FOCUS RING (interactive only)\n ========================================================== */\n\n:host(.md-card--interactive:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: 2px;\n}\n\n/* ==========================================================\n 5. DISABLED (interactive only)\n ========================================================== */\n\n:host(.md-card--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-card--disabled.md-card--outlined) .md-card__outline {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-card--disabled:hover) .md-card__state-layer,\n:host(.md-card--disabled:active) .md-card__state-layer,\n:host(.md-card--disabled:focus-visible) .md-card__state-layer {\n opacity: 0;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled]) .md-card__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 6. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-card__state-layer {\n transition: none;\n }\n}\n\n/* ==========================================================\n 7. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n border: 1px solid ButtonText;\n background-color: ButtonFace;\n color: ButtonText;\n forced-color-adjust: none;\n }\n\n .md-card__outline {\n border-color: ButtonText;\n }\n\n :host(.md-card--interactive:focus-visible) {\n outline-color: Highlight;\n }\n\n :host(.md-card--disabled) {\n border-color: GrayText;\n color: GrayText;\n opacity: 1;\n }\n\n :host(.md-card--disabled) .md-card__outline {\n border-color: GrayText;\n }\n\n .md-card__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Watch } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\n\nexport interface MdCardDragDetail {\n /** Pointer X in viewport coordinates */\n clientX: number;\n /** Pointer Y in viewport coordinates */\n clientY: number;\n /** Horizontal distance from the drag start point */\n offsetX: number;\n /** Vertical distance from the drag start point */\n offsetY: number;\n /** X where the drag gesture began */\n startX: number;\n /** Y where the drag gesture began */\n startY: number;\n}\n\n@Component({ tag: 'md-card', styleUrl: 'md-card.css', shadow: true })\nexport class MdCard {\n @Element() el!: HTMLElement;\n\n /** Visual style variant */\n @Prop() variant: 'elevated' | 'filled' | 'outlined' = 'elevated';\n\n /**\n * Makes the card interactive (clickable, with ripple and state layers).\n *\n * When the card's own content has no focusable controls the host exposes\n * `role=\"button\"` + `tabindex` and is keyboard-activatable. If the content\n * *does* include its own focusable controls (buttons, links, form fields,\n * interactive `md-*` components) the host does not claim `role=\"button\"` —\n * that would be a `nested-interactive` a11y violation — and instead stays a\n * plain container that is still mouse-clickable (emits `mdClick`) while the\n * inner controls remain the keyboard tab stops.\n */\n @Prop({ reflect: true }) interactive: boolean = false;\n\n /** Enables pointer-event-based drag on the card */\n @Prop({ reflect: true, attribute: 'drag-enabled' }) dragEnabled: boolean = false;\n\n /** Disables the card — only meaningful when interactive */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable — only meaningful when interactive */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Whether the ripple effect is enabled when interactive */\n @Prop() ripple: boolean = true;\n\n /**\n * When `true` the card stretches to 100% of its container's inline-size.\n * Pair with the `--md-card-max-width` custom property to cap the fluid\n * width (useful inside dashboards and responsive grids).\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /**\n * When `true` the card stretches to 100% of its container's block-size.\n * The parent must have a definite block-size (e.g. a fixed height row in\n * a CSS grid, or a flex item with `align-items: stretch`) for `100%` to\n * resolve.\n */\n @Prop({ reflect: true, attribute: 'full-height' }) fullHeight: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Emits when an interactive card is clicked or activated via keyboard */\n @Event() mdClick: EventEmitter<MouseEvent>;\n\n /** Emits once when a draggable card starts being dragged (after crossing the movement threshold) */\n @Event() mdDragStart: EventEmitter<MdCardDragDetail>;\n\n /** Emits continuously as a dragged card moves — use for drop-zone detection or position tracking */\n @Event() mdDragMove: EventEmitter<MdCardDragDetail>;\n\n /** Emits when a draggable card is released after dragging */\n @Event() mdDragEnd: EventEmitter<MdCardDragDetail>;\n\n @State() private dragging = false;\n\n /**\n * True when the default slot contains its own focusable/interactive\n * descendants (buttons, links, form controls, or interactive `md-*`\n * components).\n *\n * An interactive card that wraps such controls must NOT expose itself as a\n * single `role=\"button\"`: a `button` has \"children presentational\" per\n * WAI-ARIA, so nesting focusable content inside it is a `nested-interactive`\n * violation and hides the inner controls from assistive tech. In that case\n * the host degrades to a plain (still mouse-clickable) container and the\n * inner controls remain the real tab stops — mirroring the `md-list-item`\n * rule of keeping a container role \"rather than masquerading as a button\".\n */\n @State() private hasInteractiveContent = false;\n\n private startX = 0;\n private startY = 0;\n private dragStarted = false;\n private suppressClick = false;\n private contentObserver: MutationObserver | null = null;\n\n private static readonly DRAG_THRESHOLD = 5;\n\n /**\n * Widget-role focusables whose presence makes the host stop masquerading as\n * a button. Covers the descendants axe's `nested-interactive` rule counts\n * (native controls + explicit interactive ARIA roles), plus the library's\n * own interactive components — those project their real focusable control\n * into a shadow root, so a light-DOM native-focusable scan cannot see them\n * and they must be matched by tag name.\n */\n private static readonly INTERACTIVE_CONTENT_SELECTOR = [\n 'a[href]', 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])', 'textarea:not([disabled])',\n 'audio[controls]', 'video[controls]', 'iframe',\n '[contenteditable=\"true\"]', '[contenteditable=\"\"]',\n '[role=\"button\"]', '[role=\"link\"]', '[role=\"checkbox\"]', '[role=\"radio\"]',\n '[role=\"switch\"]', '[role=\"tab\"]', '[role=\"menuitem\"]',\n '[role=\"menuitemcheckbox\"]', '[role=\"menuitemradio\"]', '[role=\"option\"]',\n '[role=\"slider\"]', '[role=\"spinbutton\"]', '[role=\"textbox\"]',\n '[role=\"combobox\"]', '[role=\"searchbox\"]',\n 'md-button', 'md-icon-button', 'md-fab', 'md-checkbox', 'md-switch',\n 'md-radio', 'md-chip', 'md-select', 'md-multi-select', 'md-text-field',\n 'md-slider', 'md-segmented-button', 'md-menu-button', 'md-link',\n 'md-autocomplete',\n ].join(',');\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n connectedCallback() {\n this.el.addEventListener('pointerdown', this.onPointerDown);\n }\n\n componentWillLoad() {\n // Initial (deep) scan BEFORE the first render — querySelectorAll traverses\n // the whole light-DOM subtree (present at connect time for declarative\n // markup), so `hasInteractiveContent` is already settled when render() first\n // computes `role`/`tabindex`. Doing this here (not in componentDidLoad)\n // guarantees an interactive card wrapping focusable content NEVER paints a\n // transient `role=\"button\"` around it — the nested-interactive window that a\n // pre-hydration snapshot (SSR / jsdom, where `slotchange` hasn't fired yet)\n // would otherwise catch — and avoids Stencil's \"state changed during\n // componentDidLoad → extra re-render\" warning.\n this.detectInteractiveContent();\n }\n\n componentDidLoad() {\n // A late deep scan catches any focusable content that only became present\n // between componentWillLoad and mount; the guard inside\n // detectInteractiveContent makes this a no-op (no re-render) when the state\n // is already correct.\n this.detectInteractiveContent();\n // slotchange only fires for top-level slottable add/remove; a MutationObserver\n // (subtree) additionally catches controls added/removed deep inside slotted\n // wrappers after mount. Matches the md-list-item light-DOM observer pattern.\n if (typeof MutationObserver !== 'undefined') {\n this.contentObserver = new MutationObserver(this.detectInteractiveContent);\n this.contentObserver.observe(this.el, { childList: true, subtree: true });\n }\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('pointerdown', this.onPointerDown);\n this.contentObserver?.disconnect();\n this.contentObserver = null;\n this.cancelDrag();\n }\n\n @Watch('dragEnabled')\n onDragEnabledChange() {\n if (!this.dragEnabled) this.cancelDrag();\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (!this.dragEnabled || this.isDisabled || e.button !== 0) return;\n\n this.startX = e.clientX;\n this.startY = e.clientY;\n this.dragStarted = false;\n\n this.el.setPointerCapture(e.pointerId);\n this.el.addEventListener('pointermove', this.onPointerMove);\n this.el.addEventListener('pointerup', this.onPointerUp);\n this.el.addEventListener('pointercancel', this.onPointerUp);\n };\n\n private buildDetail(e: PointerEvent): MdCardDragDetail {\n return {\n clientX: e.clientX,\n clientY: e.clientY,\n offsetX: e.clientX - this.startX,\n offsetY: e.clientY - this.startY,\n startX: this.startX,\n startY: this.startY,\n };\n }\n\n private onPointerMove = (e: PointerEvent) => {\n const dx = e.clientX - this.startX;\n const dy = e.clientY - this.startY;\n\n if (!this.dragStarted) {\n if (Math.abs(dx) + Math.abs(dy) < MdCard.DRAG_THRESHOLD) return;\n this.dragStarted = true;\n this.dragging = true;\n this.el.style.zIndex = '1000';\n this.mdDragStart.emit(this.buildDetail(e));\n }\n\n this.el.style.transform = `translate(${dx}px, ${dy}px)`;\n this.mdDragMove.emit(this.buildDetail(e));\n };\n\n private onPointerUp = (e: PointerEvent) => {\n if (this.dragStarted) {\n this.suppressClick = true;\n requestAnimationFrame(() => { this.suppressClick = false; });\n this.mdDragEnd.emit(this.buildDetail(e));\n }\n\n this.resetDragVisuals();\n this.cleanupListeners();\n };\n\n private cancelDrag() {\n this.resetDragVisuals();\n this.cleanupListeners();\n }\n\n private resetDragVisuals() {\n this.dragging = false;\n this.dragStarted = false;\n this.el.style.transform = '';\n this.el.style.zIndex = '';\n }\n\n private cleanupListeners() {\n this.el.removeEventListener('pointermove', this.onPointerMove);\n this.el.removeEventListener('pointerup', this.onPointerUp);\n this.el.removeEventListener('pointercancel', this.onPointerUp);\n }\n\n private handleClick = (e: MouseEvent) => {\n if (!this.interactive) return;\n if (this.suppressClick) return;\n if (this.isDisabled) { e.preventDefault(); return; }\n this.mdClick.emit(e);\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (!this.interactive || this.isDisabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n triggerRipple(this.el);\n this.el.click();\n }\n };\n\n /**\n * Re-evaluate whether the slotted content contains its own focusable\n * controls. `this.el.querySelectorAll` searches the light-DOM subtree (the\n * slotted content) only — never the shadow root — so the card's internal\n * state-layer / ripple / outline nodes are correctly ignored.\n */\n private detectInteractiveContent = () => {\n const found =\n this.el.querySelectorAll(MdCard.INTERACTIVE_CONTENT_SELECTOR).length > 0;\n if (found !== this.hasInteractiveContent) this.hasInteractiveContent = found;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n\n /* A card only exposes single `role=\"button\"` semantics when it is the sole\n action — i.e. it does NOT wrap its own focusable controls. A button may\n not contain focusable content (WAI-ARIA \"children presentational\"), so an\n interactive card that holds buttons/links/form controls keeps a plain\n container role instead of masquerading as one giant button. It stays\n mouse-clickable (host `onClick` → `mdClick`) and visually interactive, but\n the inner controls are the real keyboard tab stops. */\n const actsAsButton = this.interactive && !this.hasInteractiveContent;\n\n return (\n <Host\n class={{\n 'md-card': true,\n [`md-card--${this.variant}`]: true,\n 'md-card--interactive': this.interactive,\n 'md-card--draggable': this.dragEnabled,\n 'md-card--disabled': this.interactive && isEffectivelyDisabled,\n 'md-card--dragged': this.dragging,\n 'md-card--full-width': this.fullWidth,\n 'md-card--full-height': this.fullHeight,\n }}\n role={actsAsButton ? 'button' : undefined}\n aria-disabled={actsAsButton && isEffectivelyDisabled ? 'true' : undefined}\n aria-grabbed={this.dragEnabled ? (this.dragging ? 'true' : 'false') : undefined}\n tabindex={actsAsButton ? (this.disabled ? '-1' : '0') : undefined}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n {(this.interactive || this.dragEnabled) && this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n {(this.interactive || this.dragEnabled) && <span class=\"md-card__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>}\n {this.variant === 'outlined' && <span class=\"md-card__outline\" part=\"outline\" aria-hidden=\"true\"></span>}\n <slot onSlotchange={this.detectInteractiveContent} />\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-icon-button — Material Design 3 Icon Button\n Spec: https://m3.material.io/components/icon-buttons/specs\n Supports M3 + M3 Expressive (size, shape, width)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-icon-button-container-color Container background\n --md-icon-button-icon-color Icon color\n --md-icon-button-state-layer-color State-layer ink (hover / focus / press)\n --md-icon-button-icon-size Icon dimensions\n --md-icon-button-container-shape Border-radius override\n --md-icon-button-outline-color Outlined border color\n --md-icon-button-outline-width Outlined border width\n --md-icon-button-container-width Container width override\n --md-icon-button-container-height Container height override\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Default icon wrapper\n selected-icon Selected icon wrapper (toggle)\n\n SLOTS:\n (default) Custom icon content\n selected Custom selected icon (toggle)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — shared base\n ========================================================== */\n:host {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 20px;\n --_border-radius: var(--md-icon-button-container-shape, var(--_shape-round));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: var(--_container-width);\n height: var(--_container-height);\n /* Resting radius is --_border-radius; --_morph-to carries the morphed target\n and defaults to the resting value. calc(REST + FLAG * (MORPH - REST)) is\n MORPH at flag 1 and REST at flag 0, so `data-shape-morph=\"off\"` /\n `shape-morph=\"off\"` (§13 tokens.css) freezes the shape with no re-render. */\n border-radius: calc(var(--_border-radius) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_border-radius)) - var(--_border-radius)));\n cursor: pointer;\n user-select: none;\n border: none;\n outline: none;\n overflow: hidden;\n box-sizing: border-box;\n background-color: var(--_container-color);\n color: var(--_icon-color);\n -webkit-tap-highlight-color: transparent;\n transition:\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n flex-shrink: 0;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 2. SIZE — M3 Expressive\n XS (32px) · SM (40px, default) · MD (56px) · LG (96px) · XL (136px)\n ========================================================== */\n:host(.md-icon-button--xs) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 16px;\n}\n:host(.md-icon-button--sm) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 20px;\n}\n:host(.md-icon-button--md) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 28px;\n}\n:host(.md-icon-button--lg) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(96px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(96px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_shape-round: 48px;\n}\n:host(.md-icon-button--xl) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(136px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(136px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(28px, calc(40px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 68px;\n}\n\n/* ==========================================================\n 3. WIDTH — M3 Expressive\n Narrow (less horizontal padding) · Default (square) · Wide (more horizontal padding)\n Width = iconSize + leadingSpace + trailingSpace; height stays unchanged.\n ========================================================== */\n:host(.md-icon-button--width-narrow.md-icon-button--xs) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(28px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--sm) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--md) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--lg) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--xl) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(104px + var(--md-sys-density-scale, 0) * 4px))); }\n\n:host(.md-icon-button--width-wide.md-icon-button--xs) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--sm) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(52px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--md) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(72px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--lg) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(128px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--xl) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(184px + var(--md-sys-density-scale, 0) * 4px))); }\n\n/* ==========================================================\n 4. SHAPE — Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n ========================================================== */\n:host(.md-icon-button--round) {\n --_border-radius: var(--md-icon-button-container-shape, var(--_shape-round));\n}\n:host(.md-icon-button--square.md-icon-button--xs) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); }\n:host(.md-icon-button--square.md-icon-button--sm) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); }\n:host(.md-icon-button--square.md-icon-button--md) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-large, 16px)); }\n:host(.md-icon-button--square.md-icon-button--lg) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); }\n:host(.md-icon-button--square.md-icon-button--xl) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); }\n\n/* ==========================================================\n 5. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides (not CSS variable changes)\n for reliable browser-animated transitions.\n\n Order matters: selected rules FIRST, pressed rules LAST so\n pressed always wins while the pointer is down.\n\n Asymmetric timing (both via M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--xs) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--md) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--lg) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-icon-button--shape-morph.md-icon-button--square.md-icon-button--selected) { --_morph-to: var(--_shape-round); }\n\n/* ── Pressed shape — same for both round & square, overrides selected ── */\n:host(.md-icon-button--pressed.md-icon-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--md) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ── Narrow pressed — slightly longer duration for smaller surface area ── */\n:host(.md-icon-button--width-narrow.md-icon-button--pressed) {\n transition-duration: var(--md-sys-motion-duration-medium1, 250ms);\n}\n\n/* ==========================================================\n 5b. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 4, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-icon-button--connected-left.md-icon-button--xs),\n:host(.md-icon-button--connected-right.md-icon-button--xs) { --_c-inner: 4px; }\n:host(.md-icon-button--connected-left.md-icon-button--sm),\n:host(.md-icon-button--connected-right.md-icon-button--sm) { --_c-inner: 8px; }\n:host(.md-icon-button--connected-left.md-icon-button--md),\n:host(.md-icon-button--connected-right.md-icon-button--md) { --_c-inner: 8px; }\n:host(.md-icon-button--connected-left.md-icon-button--lg),\n:host(.md-icon-button--connected-right.md-icon-button--lg) { --_c-inner: 16px; }\n:host(.md-icon-button--connected-left.md-icon-button--xl),\n:host(.md-icon-button--connected-right.md-icon-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-icon-button--connected-left.md-icon-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-icon-button--round.md-icon-button--connected-right:not(.md-icon-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-icon-button--round.md-icon-button--connected-left:not(.md-icon-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-icon-button--square.md-icon-button--connected-right:not(.md-icon-button--connected-left)),\n:host(.md-icon-button--square.md-icon-button--connected-left:not(.md-icon-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 6. COLOR VARIANTS\n ========================================================== */\n\n/* ── Standard ── */\n:host(.md-icon-button--standard) {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n}\n:host(.md-icon-button--standard.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-primary, #6750A4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-primary, #6750A4));\n}\n\n/* The toggle / selected rules below all carry `:not(.md-icon-button--disabled)`\n so they drop out when the host becomes disabled. Without it, their higher\n specificity (3+ classes vs the disabled rules' 2) would override the muted\n disabled palette and the button would still look enabled. */\n\n/* ── Filled (non-toggle) ── */\n:host(.md-icon-button--filled) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-primary, #6750A4));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-primary, #FFFFFF));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-primary, #FFFFFF));\n}\n/* Filled toggle unselected */\n:host(.md-icon-button--filled.md-icon-button--toggle:not(.md-icon-button--selected):not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-primary, #6750A4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-primary, #6750A4));\n}\n/* Filled toggle selected */\n:host(.md-icon-button--filled.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-primary, #6750A4));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-primary, #FFFFFF));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-primary, #FFFFFF));\n}\n\n/* ── Tonal (non-toggle) ── */\n:host(.md-icon-button--tonal) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-secondary-container, #1E192B));\n}\n/* Tonal toggle unselected */\n:host(.md-icon-button--tonal.md-icon-button--toggle:not(.md-icon-button--selected):not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n}\n/* Tonal toggle selected */\n:host(.md-icon-button--tonal.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-secondary-container, #1E192B));\n}\n\n/* ── Outlined ── */\n:host(.md-icon-button--outlined) {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n border: var(--md-icon-button-outline-width, 1px) solid var(--md-icon-button-outline-color, var(--md-sys-color-outline, #79747E));\n}\n:host(.md-icon-button--outlined.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-inverse-surface, #313033));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n border-color: transparent;\n}\n\n/* ==========================================================\n 7. STATE LAYER\n ========================================================== */\n.md-icon-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n:host(:focus-visible) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 8. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline draws on top of any neighbor instead of being clipped —\n important inside md-button-group, where connected groups have\n only 2px between buttons and standard groups animate neighbor\n width on press. The 2px outline-offset is preserved so the ring\n gets the same breathing room it has on a stand-alone button.\n ========================================================== */\n:host(:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary, #625B71);\n outline-offset: 2px;\n z-index: 1;\n}\n\n/* ==========================================================\n 9. DISABLED\n ========================================================== */\n:host(.md-icon-button--disabled) {\n cursor: default;\n pointer-events: none;\n}\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-icon-button__state-layer { display: none; }\n\n/* Disabled colors — standard & outlined */\n:host(.md-icon-button--standard.md-icon-button--disabled),\n:host(.md-icon-button--outlined.md-icon-button--disabled) {\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n:host(.md-icon-button--outlined.md-icon-button--disabled) {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n/* Disabled colors — filled & tonal */\n:host(.md-icon-button--filled.md-icon-button--disabled),\n:host(.md-icon-button--tonal.md-icon-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n/* Kill state layers when disabled */\n:host(.md-icon-button--disabled:hover) .md-icon-button__state-layer,\n:host(.md-icon-button--disabled:active) .md-icon-button__state-layer,\n:host(.md-icon-button--disabled:focus-visible) .md-icon-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 10. ICON WRAPPER\n ========================================================== */\n.md-icon-button__icon {\n display: none;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n color: inherit;\n width: var(--_icon-size);\n height: var(--_icon-size);\n /* Collapse whitespace text nodes assigned to the default slot (Lit indentation). */\n font-size: 0;\n line-height: 0;\n}\n/* Restore a real glyph size on slotted content so a bare emoji/text node in the\n default slot renders at icon size (the wrapper's font-size:0 above would\n otherwise collapse it to invisible). Slotted md-icon elements set their own\n size, so this only takes effect for text-node content. */\n.md-icon-button__icon slot {\n font-size: var(--_icon-size);\n line-height: 1;\n}\n.md-icon-button__icon--on {\n display: inline-flex;\n}\n\n/* ==========================================================\n 11. ICON FONT (inside shadow)\n ========================================================== */\n.md-icon-button__icon-font {\n font-size: var(--_icon-size);\n width: var(--_icon-size);\n height: var(--_icon-size);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n/* A slotted badge anchors OUTSIDE the button's box — it is translated by\n (50%, -50%) so it straddles the corner. The host's `overflow: hidden` above\n exists to keep the ripple and state layer inside the rounded shape, but it\n also clipped the badge into a blob with a bite out of it.\n Both overlays clip themselves instead (inset: 0 + border-radius: inherit —\n md-ripple's own host inherits the radius too), so the host can let the badge\n escape without either leaking past the corners. */\n:host(.md-icon-button--has-badge) {\n overflow: visible;\n}\n\n:host(.md-icon-button--has-badge) .md-icon-button__state-layer {\n overflow: hidden;\n}\n\n/* ==========================================================\n 12. SLOTTED ICONS\n ========================================================== */\n/* NOT badges. A custom property inside ::slotted() resolves in the SLOTTED\n element's own scope, and md-badge defines its own `--_icon-size` (10px, for\n its glyph). So `height: var(--_icon-size) !important` here picked up the\n BADGE's 10px instead of this component's icon size and, being !important,\n beat the badge's own 16px — squashing every badge slotted onto an icon\n button / avatar / menu item into a 10px blob. A badge is not an icon; it\n sizes itself.\n\n NOT avatars either, for the same reason: an account button is an avatar\n inside a button, and the avatar's own `size` (or --md-avatar-size) is the\n whole point. Forcing it to --_icon-size shrank a 32px avatar to the ~19px\n glyph box. */\n::slotted(*:not(md-badge):not(md-avatar)) {\n width: var(--_icon-size) !important;\n height: var(--_icon-size) !important;\n font-size: var(--_icon-size) !important;\n color: inherit !important;\n fill: currentColor !important;\n /* Center the glyph inside the slot's sized box. Without these four\n declarations, an inline-text glyph (emoji, icon-font character) sits at\n the box's text baseline — producing a visible bottom-left offset that\n gets worse at larger sizes (md / lg / xl). The prop-based\n `.md-icon-button__icon-font` already centers via the same flex triple +\n line-height reset; keep them in lockstep so slotted and prop-based icons\n render identically. */\n display: inline-flex !important;\n align-items: center !important;\n justify-content: center !important;\n line-height: 1 !important;\n}\n\n/* ==========================================================\n 13. MATERIAL SYMBOLS (icon font inside shadow root)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 24px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 14. FORCED COLORS — Windows High Contrast\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n :host(.md-icon-button--outlined) {\n border-color: ButtonText;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n@Component({\n tag: 'md-icon-button',\n styleUrl: 'md-icon-button.css',\n shadow: true,\n})\nexport class MdIconButton {\n @Element() el!: HTMLElement;\n\n /** Visual style variant */\n @Prop() variant: 'standard' | 'filled' | 'outlined' | 'tonal' = 'standard';\n\n /** M3 Expressive size */\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n\n /** Container shape */\n @Prop() shape: 'round' | 'square' = 'round';\n\n /** M3 Expressive width (narrow, default, wide) */\n @Prop() buttonWidth: 'narrow' | 'default' | 'wide' = 'default';\n\n /** Prevents interaction and removes from tab order */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Visually disabled but remains focusable for discoverability */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /** Whether to show the ripple effect */\n @Prop() ripple: boolean = true;\n\n /** Material Symbols icon name */\n @Prop() icon: string = '';\n\n /** Icon shown when selected in toggle mode */\n @Prop() selectedIcon: string = '';\n\n /** Turns the button into a link */\n @Prop() href: string = '';\n\n /** Link target attribute */\n @Prop() target: string = '_self';\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group form association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires on pointer or keyboard activation. Detail includes toggle `selected` state. */\n @Event({ bubbles: true, composed: true })\n mdClick!: EventEmitter<{ selected: boolean }>;\n\n @State() private hasSlottedIcon = false;\n /** A badge is slotted in — the host must stop clipping so it can straddle\n * the corner. `:host(:has(md-badge))` does not match light-DOM children, so\n * the presence is tracked here and expressed as a host class. */\n @State() private hasSlottedBadge = false;\n @State() private hasSlottedSelected = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n componentWillLoad() {\n this.syncSlottedIcons();\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const iconSlot = shadow.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const selectedSlot = shadow.querySelector('slot[name=\"selected\"]') as HTMLSlotElement | null;\n\n this.syncSlottedIcons();\n iconSlot?.addEventListener('slotchange', () => this.syncSlottedIcons());\n selectedSlot?.addEventListener('slotchange', () => this.syncSlottedIcons());\n }\n\n /** Ignore whitespace-only text nodes (e.g. Lit template indentation) when detecting slots. */\n private hasMeaningfulSlotContent(slot: HTMLSlotElement | null): boolean {\n if (!slot) return false;\n return slot.assignedNodes().some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n // A badge is an ADORNMENT anchored to the button, not the button's\n // icon. Counting it here made `hasSlottedIcon` true, which suppresses\n // the `icon` prop's glyph — so the documented pattern (an icon button\n // with a count badge) rendered the badge and NO icon at all.\n if ((node as Element).tagName.toLowerCase() === 'md-badge') return false;\n return true;\n }\n if (node.nodeType === Node.TEXT_NODE) return (node.textContent?.trim().length ?? 0) > 0;\n return false;\n });\n }\n\n /** Sync default/selected slot presence (initial + slotchange). */\n private syncSlottedIcons() {\n const shadow = this.el.shadowRoot;\n const iconSlot = shadow?.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const selectedSlot = shadow?.querySelector('slot[name=\"selected\"]') as HTMLSlotElement | null;\n\n this.hasSlottedIcon = this.hasMeaningfulSlotContent(iconSlot);\n this.hasSlottedBadge = !!iconSlot\n ?.assignedElements()\n .some((el) => el.tagName.toLowerCase() === 'md-badge');\n this.hasSlottedSelected = this.hasMeaningfulSlotContent(selectedSlot);\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n const href = sanitizeHref(this.href);\n if (href) { window.open(href, this.target, SAFE_WINDOW_FEATURES); }\n if (this.toggle) this.selected = !this.selected;\n this.mdClick.emit({ selected: this.selected });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const showSelected = this.toggle && this.selected;\n const hasIcon = !!this.icon || this.hasSlottedIcon;\n // Do not gate visibility on `hasIcon` — slotted glyphs must paint before sync.\n const showDefaultIconLayer =\n !showSelected || (!this.selectedIcon && !this.hasSlottedSelected);\n\n return (\n <Host\n class={{\n 'md-icon-button': true,\n [`md-icon-button--${this.variant}`]: true,\n [`md-icon-button--${this.size}`]: true,\n [`md-icon-button--${this.shape}`]: true,\n [`md-icon-button--width-${this.buttonWidth}`]: this.buttonWidth !== 'default',\n 'md-icon-button--selected': this.selected,\n 'md-icon-button--toggle': this.toggle,\n 'md-icon-button--disabled': this.disabled || this.softDisabled,\n 'md-icon-button--shape-morph': this.shapeMorph,\n 'md-icon-button--has-badge': this.hasSlottedBadge,\n 'md-icon-button--pressed': this.shapeMorph && this.pressed,\n 'md-icon-button--connected-left': this.connectedLeft,\n 'md-icon-button--connected-right': this.connectedRight,\n }}\n role=\"button\"\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-icon-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {/* Default icon (shown when not toggle-selected, or no selected slot/icon) */}\n <span\n class={{\n 'md-icon-button__icon': true,\n 'md-icon-button__icon--on': showDefaultIconLayer,\n }}\n part=\"icon\"\n >\n <slot />\n {showDefaultIconLayer && hasIcon && !this.hasSlottedIcon && (\n <span class=\"md-icon-button__icon-font material-symbols-outlined\" aria-hidden=\"true\">\n {showSelected && this.selectedIcon ? this.selectedIcon : this.icon}\n </span>\n )}\n </span>\n\n {/* Selected icon (toggle mode only) */}\n {this.toggle && (this.selectedIcon || this.hasSlottedSelected) && (\n <span\n class={{\n 'md-icon-button__icon': true,\n 'md-icon-button__icon--on': showSelected,\n }}\n part=\"selected-icon\"\n >\n <slot name=\"selected\" />\n {!this.hasSlottedSelected && this.selectedIcon && (\n <span class=\"md-icon-button__icon-font material-symbols-outlined\" aria-hidden=\"true\">\n {this.selectedIcon}\n </span>\n )}\n </span>\n )}\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-radio — Material Design 3 Radio Button\n Spec: https://m3.material.io/components/radio-button/specs\n\n Measurements (MD3 spec):\n Icon size: 20px (outer circle)\n Inner dot: 10px (when checked)\n State-layer size: 40px\n Target (touch) size: 48px\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-radio-icon-color Unchecked outer circle color\n --md-radio-selected-icon-color Checked outer circle + inner dot color\n --md-radio-icon-size Outer circle size\n --md-radio-inner-circle-size Inner dot size\n --md-radio-state-layer-size State-layer diameter\n --md-radio-state-layer-color State-layer color (unchecked)\n --md-radio-selected-state-layer-color State-layer color (checked)\n\n CSS PARTS:\n state-layer Hover / focus / press overlay\n container Wrapper around outer + inner circles\n outer-circle The 20px circle border\n inner-circle The 10px filled dot\n\n SLOTS:\n (none — standalone control, label provided externally)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — TOUCH TARGET (48px)\n color controls md-ripple wave (md-ripple uses currentColor).\n ========================================================== */\n\n:host {\n --_icon-color: var(--md-radio-icon-color, var(--md-sys-color-on-surface-variant));\n --_selected-icon-color: var(--md-radio-selected-icon-color, var(--md-sys-color-primary));\n /* The visible circle + dot shrink with global density (20/10 at 0 → 16/8 at\n -4) so the control densifies, not just the tap target; ratio preserved. */\n --_icon-size: var(--md-radio-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n --_inner-circle-size: var(--md-radio-inner-circle-size, max(8px, calc(10px + var(--md-sys-density-scale, 0) * 0.5px)));\n /* Global density: the state layer shrinks in step with the host touch target\n (both trim 4px per `data-density` rung), so it stays 8px inside the host at\n every rung. Floored at 24px; unchanged at density 0. */\n --_state-layer-size: max(24px, calc(var(--md-radio-state-layer-size, 40px) + var(--md-sys-density-scale, 0) * 4px));\n --_state-layer-color: var(--md-radio-state-layer-color, var(--md-sys-color-on-surface));\n --_selected-state-layer-color: var(--md-radio-selected-state-layer-color, var(--md-sys-color-primary));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the touch\n target, floored at 32px to keep breathing room around the 20px circle.\n Unchanged at density 0. */\n inline-size: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n block-size: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n cursor: pointer;\n border-radius: var(--md-sys-shape-corner-full, 50%);\n overflow: hidden;\n -webkit-tap-highlight-color: transparent;\n box-sizing: border-box;\n flex-shrink: 0;\n vertical-align: middle;\n outline: none;\n color: var(--_state-layer-color);\n}\n\n:host(.md-radio--checked) {\n color: var(--_selected-state-layer-color);\n}\n\n/* ==========================================================\n 2. HIDDEN NATIVE INPUT\n The host is the interactive radio (role=\"radio\" + roving\n tabindex). This decorative input must be fully removed from\n the focus order and accessibility tree — a native <input> stays\n natively focusable despite tabindex=\"-1\"/aria-hidden, which would\n nest a second interactive control inside the role=\"radio\" host\n (axe: nested-interactive). display:none is the only reliable way\n to strip a native control's focusability; opacity/zero-size do not.\n ========================================================== */\n\n.md-radio__native {\n display: none;\n}\n\n/* ==========================================================\n 3. RIPPLE LAYER (40px — constrains md-ripple to state-layer size)\n md-ripple resolves this span as its host via parentElement,\n so its wave is sized and clipped to the 40px circle.\n ========================================================== */\n\n.md-radio__ripple-layer {\n position: absolute;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n overflow: hidden;\n}\n\n:host(.md-radio--disabled) .md-radio__ripple-layer,\n:host([soft-disabled]) .md-radio__ripple-layer {\n display: none;\n}\n\n/* ==========================================================\n 4. STATE LAYER (40px centered inside 48px touch target)\n ========================================================== */\n\n.md-radio__state-layer {\n position: absolute;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n\n/* Unchecked state-layer */\n:host(.md-radio--unchecked:hover) .md-radio__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-radio--unchecked:active) .md-radio__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* Checked state-layer */\n:host(.md-radio--checked) .md-radio__state-layer {\n background-color: var(--_selected-state-layer-color);\n}\n\n:host(.md-radio--checked:hover) .md-radio__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-radio--checked:active) .md-radio__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 5. FOCUS RING — separate pseudo so it is NOT affected by the\n state-layer's opacity (which would make the ring ~12% visible).\n Sized to the 40px state-layer, with a 2px gap from the 20px\n container.\n ========================================================== */\n\n:host(:focus-visible)::after,\n:host(.md-radio--focus-ring)::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n outline: 3px solid var(--md-sys-color-secondary);\n /* Sits ON the state layer, not pulled inside it. At -8px the ring drew at\n 24px around a 20px radio — a 2px gap — so it read as a bullseye welded to\n the control rather than as a focus indicator. On the state layer it clears\n the circle by a visible margin and still fits the touch target: the ring's\n outer edge is state-layer + 6px (46px inside a 48px host at density 0,\n 30px inside 32px at -4). */\n outline-offset: 0;\n pointer-events: none;\n}\n\n/* ==========================================================\n 6. CONTAINER (positions outer + inner circles)\n Transition uses same motion tokens as md-checkbox:\n Release: medium4 (400ms) + emphasized-decelerate (spring-back)\n Press: short4 (200ms) + standard (snap-in)\n ========================================================== */\n\n.md-radio__container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n pointer-events: none;\n transition:\n transform var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n/* Press animation — M3 Expressive squish */\n:host(.md-radio--pressed) .md-radio__container {\n transform: scale(0.82);\n transition:\n transform var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 7. OUTER CIRCLE (20px, 2px border)\n ========================================================== */\n\n.md-radio__outer {\n position: absolute;\n inset: 0;\n border-radius: var(--md-sys-shape-corner-full, 50%);\n border: 2px solid var(--_icon-color);\n box-sizing: border-box;\n transition:\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(.md-radio--checked) .md-radio__outer {\n border-color: var(--_selected-icon-color);\n}\n\n/* ==========================================================\n 8. INNER CIRCLE (10px filled dot)\n Grows from scale(0) to scale(1) when checked.\n ========================================================== */\n\n.md-radio__inner {\n inline-size: var(--_inner-circle-size);\n block-size: var(--_inner-circle-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n background-color: var(--_selected-icon-color);\n transform: scale(0);\n transition:\n transform var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n:host(.md-radio--checked) .md-radio__inner {\n transform: scale(1);\n}\n\n/* ==========================================================\n 9. DISABLED\n ========================================================== */\n\n:host(.md-radio--disabled) {\n cursor: default;\n pointer-events: none;\n}\n\n:host(.md-radio--disabled.md-radio--unchecked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled.md-radio--checked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled.md-radio--checked) .md-radio__inner {\n background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled) .md-radio__state-layer {\n display: none;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n\n:host([soft-disabled].md-radio--unchecked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled].md-radio--checked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled].md-radio--checked) .md-radio__inner {\n background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled]) .md-radio__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 10. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n .md-radio__container,\n .md-radio__state-layer,\n .md-radio__outer,\n .md-radio__inner {\n transition: none;\n }\n}\n\n/* ==========================================================\n 11. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n\n .md-radio__outer {\n border-color: ButtonText;\n }\n\n :host(.md-radio--checked) .md-radio__outer {\n border-color: Highlight;\n }\n\n :host(.md-radio--checked) .md-radio__inner {\n background-color: Highlight;\n }\n\n :host(:focus-visible)::after,\n :host(.md-radio--focus-ring)::after {\n outline-color: Highlight;\n }\n\n :host(.md-radio--disabled) .md-radio__outer {\n border-color: GrayText;\n }\n\n :host(.md-radio--disabled.md-radio--checked) .md-radio__inner {\n background-color: GrayText;\n }\n\n .md-radio__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { AttachInternals, Component, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';\nimport { RadioElement } from '../../utils/types';\nimport { triggerRipple } from '../../utils/ripple';\nimport {\n setFormValue,\n setValidityState,\n checkValidityOf,\n reportValidityOf,\n getValidityOf,\n} from '../../utils/form';\n\n@Component({\n tag: 'md-radio',\n styleUrl: 'md-radio.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdRadio {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Radios previously declared `name`/`value` but were\n * NOT form-associated, so a checked radio never reached FormData at all — the\n * group looked wired up and submitted nothing.\n */\n @AttachInternals() internals!: ElementInternals;\n\n\n /**\n * Localized constraint-validation message shown when `required` is unmet.\n *\n * A prop rather than a hardcoded string, matching md-time-picker's\n * `value-missing-label`: components stay i18n-engine-agnostic and the\n * consumer localizes through its own dictionary. Native inputs get their\n * message from the browser's locale for free; a form-associated custom\n * element supplies its own, so leaving this hardcoded would ship an\n * English-only form to every locale.\n */\n @Prop({ attribute: 'value-missing-label' }) valueMissingLabel: string =\n 'Please select one of these options.';\n\n /** Message set via setCustomValidity(); non-empty wins over valueMissing. */\n private customValidityMessage = '';\n\n /** Drives aria-invalid on the host. */\n @State() private invalid = false;\n\n /** `checked` at first render, restored on form reset (native radio behaviour). */\n private defaultChecked = false;\n\n // ─── Public Props ──────────────────────────────────────────\n\n /** Whether the radio button is selected */\n @Prop({ mutable: true, reflect: true }) checked: boolean = false;\n\n /** Disables the radio button */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable for discoverability */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Whether the radio is required in a form */\n @Prop({ reflect: true }) required: boolean = false;\n\n /** Form name — radios sharing a name form an exclusive group */\n @Prop({ reflect: true }) name: string = '';\n\n /** Form value submitted when checked */\n @Prop({ reflect: true }) value: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n // ─── Events ────────────────────────────────────────────────\n\n /** Emits when the checked state changes via user interaction */\n @Event() mdChange: EventEmitter<{ checked: boolean; value: string }>;\n\n /** Emits when the radio receives focus */\n @Event() mdFocus: EventEmitter<void>;\n\n /** Emits when the radio loses focus */\n @Event() mdBlur: EventEmitter<void>;\n\n // ─── Internal State ────────────────────────────────────────\n\n @State() private pressed = false;\n @State() private focused = false;\n @State() private programmaticFocus = false;\n @State() private managedTabIndex = '0';\n\n private parentLabel: HTMLLabelElement | null = null;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────\n\n connectedCallback() {\n this.parentLabel = this.el.closest('label');\n this.parentLabel?.addEventListener('click', this.handleLabelClick);\n }\n\n componentWillLoad() {\n this.defaultChecked = this.checked;\n this.syncFormValue();\n }\n\n componentDidLoad() {\n this.updateRovingTabIndex();\n // Group validity depends on SIBLINGS, which may not have upgraded when this\n // radio first rendered. Re-sync once the whole group exists, or a group\n // whose pre-checked member upgraded last would report itself empty.\n this.syncGroupValidity();\n }\n\n disconnectedCallback() {\n this.parentLabel?.removeEventListener('click', this.handleLabelClick);\n this.parentLabel = null;\n }\n\n // ─── Watchers ──────────────────────────────────────────────\n\n @Watch('checked')\n onCheckedChange(newVal: boolean) {\n if (newVal) {\n this.uncheckOthers(this.el);\n }\n this.updateRovingTabIndex();\n this.syncFormValue();\n // Runs for BOTH directions. Checking this radio satisfies `required` for\n // every member of the group; unchecking the last one must put the group\n // back into valueMissing. Either way every member re-publishes, not just\n // this one, because validity here is a property of the group.\n this.syncGroupValidity();\n }\n\n @Watch('required')\n @Watch('name')\n @Watch('valueMissingLabel')\n onValidityInputChange() {\n this.syncGroupValidity();\n }\n\n /** Only the checked member of a name group submits — native radio semantics. */\n private syncFormValue() {\n setFormValue(this.internals, this.checked ? this.value || 'on' : null);\n }\n\n /** True when any radio sharing this name is checked. */\n private get groupHasSelection(): boolean {\n if (!this.name) return this.checked;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)).some((r) => {\n const el = r as Element & { checked?: boolean };\n // The PROPERTY is authoritative once the element has upgraded. The\n // reflected `checked` attribute lags by a render, so reading it (or\n // OR-ing it in) reports a just-unchecked radio as still checked — the\n // group then looks satisfied, `required` never republishes valueMissing,\n // and the form submits empty. Fall back to the attribute only for an\n // element that has not upgraded yet, where the property does not exist.\n return typeof el.checked === 'boolean' ? el.checked : r.hasAttribute('checked');\n });\n }\n\n /**\n * True when ANY radio in the group is marked required.\n *\n * Per the HTML spec `required` on a single radio makes the whole GROUP\n * required, and every member then suffers valueMissing — not just the one\n * carrying the attribute. Reading it per-element meant a screen-reader user\n * landing on a sibling heard nothing wrong, and that sibling's own\n * checkValidity() disagreed with the form's.\n */\n private get groupIsRequired(): boolean {\n if (this.required) return true;\n if (!this.name) return false;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)).some((r) =>\n r.hasAttribute('required'),\n );\n }\n\n private syncValidity() {\n // See md-checkbox: WCAG 3.3.1 requires the invalid state to be exposed\n // programmatically. For a radio the condition is a GROUP property, so every\n // member reports invalid while the group has no selection — which is what a\n // screen reader user hears whichever member they land on.\n this.invalid = this.customValidityMessage\n ? true\n : this.groupIsRequired && !this.groupHasSelection;\n setValidityState(this.internals, {\n missing: this.groupIsRequired && !this.groupHasSelection,\n missingMessage: this.valueMissingLabel,\n customMessage: this.customValidityMessage,\n });\n this.emitValidityChange();\n }\n\n /** Re-publish validity for every radio in the group. */\n private syncGroupValidity() {\n this.syncValidity();\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n root.querySelectorAll(`md-radio[name=\"${this.name}\"]`).forEach((r) => {\n if (r !== this.el) (r as unknown as { syncValidityFromGroup?: () => void }).syncValidityFromGroup?.();\n });\n }\n\n /**\n * Group-coordination hook. Sibling radios call this so the whole group agrees\n * on validity; exposed as a @Method because a sibling can only reach this\n * component through its public element interface.\n */\n @Method()\n async syncValidityFromGroup() {\n this.syncValidity();\n }\n\n /** Restore the initial selection when the owning form is reset. */\n formResetCallback() {\n this.checked = this.defaultChecked;\n }\n\n /** Current validity: boolean, message and flags. Mirrors md-text-field. */\n @Method()\n async getValidity(): Promise<{\n valid: boolean;\n validationMessage: string;\n flags: Record<string, boolean>;\n }> {\n return getValidityOf(this.internals);\n }\n\n /**\n * Fires when this control's validity CHANGES — never on every keystroke, and\n * never for a re-publish that lands on the same state.\n *\n * `composed: false` is deliberate. Composites like md-select embed an\n * md-text-field, and a composed event escapes that inner shadow root, so a\n * listener on md-select would receive the inner field's event as well as the\n * host's — two events, different payloads, for one logical control. Keeping\n * it uncomposed means each component reports only for itself, while\n * `bubbles: true` still lets a <form> or app root hear every control.\n */\n @Event({ bubbles: true, composed: false }) mdValidityChange: EventEmitter<{\n valid: boolean;\n validationMessage: string;\n flags: Record<string, boolean>;\n }>;\n\n /** Last emitted validity, so a re-publish that changes nothing stays silent. */\n private lastValidityKey: string | null = null;\n\n /**\n * Emit mdValidityChange if validity actually moved.\n *\n * The FIRST call only primes the baseline. Initial state is not a change, and\n * emitting on mount would fire once per control on every page load — noise a\n * consumer would have to filter out, and misleading for anything logging\n * \"field became invalid\".\n */\n private emitValidityChange() {\n const v = getValidityOf(this.internals);\n const key = `${v.valid}|${v.validationMessage}`;\n if (this.lastValidityKey === key) return;\n const primed = this.lastValidityKey !== null;\n this.lastValidityKey = key;\n if (primed) this.mdValidityChange.emit(v);\n }\n\n /** Constraint-validation API, matching md-text-field and the native contract. */\n @Method()\n async checkValidity(): Promise<boolean> {\n return checkValidityOf(this.internals);\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return reportValidityOf(this.internals);\n }\n\n @Method()\n async setCustomValidity(message: string) {\n this.customValidityMessage = message;\n this.syncValidity();\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.updateRovingTabIndex();\n }\n\n // ─── Public Methods ────────────────────────────────────────\n\n /** Programmatically focus the radio */\n @Method()\n async setFocus() {\n // Script-initiated focus does not trigger :focus-visible, so flag it\n // explicitly to render the focus ring.\n this.programmaticFocus = true;\n this.el.focus();\n }\n\n /** Programmatically blur the radio */\n @Method()\n async setBlur() {\n this.el.blur();\n }\n\n /**\n * Programmatically select this radio and uncheck siblings.\n * Emits mdChange like a user interaction.\n */\n @Method()\n async select() {\n if (this.isDisabled || this.checked) return;\n this.checked = true;\n this.mdChange.emit({ checked: true, value: this.value });\n }\n\n // ─── Private — Roving tabindex (WAI-ARIA Radio Group) ─────\n\n /**\n * WAI-ARIA: only the active radio in a group receives Tab focus.\n * - checked radio → tabindex 0\n * - no radio checked → first enabled radio → tabindex 0\n * - all others → tabindex -1\n * - disabled → always tabindex -1\n * - no name (standalone) → tabindex 0\n */\n private updateRovingTabIndex() {\n if (this.disabled) {\n this.managedTabIndex = '-1';\n return;\n }\n if (this.checked) {\n this.managedTabIndex = '0';\n return;\n }\n if (!this.name) {\n this.managedTabIndex = '0';\n return;\n }\n\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`));\n\n const anyChecked = siblings.some(s => s !== this.el && (s as unknown as RadioElement).checked);\n if (anyChecked) {\n this.managedTabIndex = '-1';\n return;\n }\n\n const firstEnabled = siblings.find(s => !(s as unknown as RadioElement).disabled);\n this.managedTabIndex = firstEnabled === this.el ? '0' : '-1';\n }\n\n // ─── Private — Handlers ───────────────────────────────────\n\n private handleLabelClick = (e: MouseEvent) => {\n if (!e.composedPath().includes(this.el)) {\n this.handleClick();\n }\n };\n\n private handleClick = () => {\n if (this.isDisabled || this.checked) return;\n this.checked = true;\n this.mdChange.emit({ checked: true, value: this.value });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n\n if (e.key === ' ') {\n e.preventDefault();\n this.pressed = true;\n this.handleClick();\n triggerRipple(this.el);\n setTimeout(() => { this.pressed = false; }, 150);\n return;\n }\n\n if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {\n e.preventDefault();\n this.focusSibling(1);\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {\n e.preventDefault();\n this.focusSibling(-1);\n }\n };\n\n private handleFocus = () => {\n this.focused = true;\n this.mdFocus.emit();\n };\n\n private handleBlur = () => {\n this.focused = false;\n this.programmaticFocus = false;\n this.mdBlur.emit();\n };\n\n private handlePointerDown = () => {\n // Pointer interaction should not keep the programmatic focus ring.\n this.programmaticFocus = false;\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n // ─── Private — Group management ───────────────────────────\n\n /** Uncheck all radios in the group except the given element */\n private uncheckOthers(keepChecked: HTMLElement) {\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = root.querySelectorAll(`md-radio[name=\"${this.name}\"]`);\n siblings.forEach((sibling) => {\n if (sibling !== keepChecked && sibling.hasAttribute('checked')) {\n sibling.removeAttribute('checked');\n }\n });\n }\n\n /**\n * Focus next/previous sibling radio in the group.\n * Arrow keys move focus AND check the newly focused button (WAI-ARIA).\n * Skips disabled and soft-disabled radios.\n */\n private focusSibling(direction: 1 | -1) {\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)) as HTMLElement[];\n const enabled = siblings.filter(s => !s.hasAttribute('disabled') && !s.hasAttribute('soft-disabled'));\n if (enabled.length === 0) return;\n\n const idx = enabled.indexOf(this.el);\n const next = (idx + direction + enabled.length) % enabled.length;\n const target = enabled[next];\n target.focus();\n target.setAttribute('checked', '');\n triggerRipple(target);\n target.dispatchEvent(new CustomEvent('mdChange', {\n detail: { checked: true, value: target.getAttribute('value') || '' },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ─── Render ────────────────────────────────────────────────\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n\n return (\n <Host\n class={{\n 'md-radio': true,\n 'md-radio--checked': this.checked,\n 'md-radio--unchecked': !this.checked,\n 'md-radio--disabled': isEffectivelyDisabled,\n 'md-radio--pressed': this.pressed,\n 'md-radio--focused': this.focused,\n 'md-radio--focus-ring': this.programmaticFocus,\n }}\n role=\"radio\"\n aria-invalid={this.invalid ? 'true' : undefined}\n aria-checked={String(this.checked)}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n tabindex={this.managedTabIndex}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n <span class=\"md-radio__ripple-layer\" aria-hidden=\"true\">\n <md-ripple disabled={isEffectivelyDisabled}></md-ripple>\n </span>\n <span class=\"md-radio__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n <span class=\"md-radio__container\" part=\"container\" aria-hidden=\"true\">\n <span class=\"md-radio__outer\" part=\"outer-circle\"></span>\n <span class=\"md-radio__inner\" part=\"inner-circle\"></span>\n </span>\n\n <input\n type=\"radio\"\n class=\"md-radio__native\"\n checked={this.checked}\n disabled={this.disabled}\n required={this.required}\n name={this.name}\n value={this.value}\n aria-hidden=\"true\"\n tabindex=\"-1\"\n onChange={() => {}}\n />\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-ripple — Material Design 3 ripple effect\n Spec: https://m3.material.io/foundations/interaction/states\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-ripple-color Ripple tint color (default: currentColor)\n --md-ripple-opacity Ripple peak opacity (default: 0.12)\n --md-ripple-extend-inline Extra pixels to add on each inline edge\n of the host's rect when computing the\n wave's farthest-corner radius. Use on\n surfaces that GROW horizontally during\n the ripple's lifetime (e.g. md-search\n springing out on focus) so the wave is\n sized for the settled rect instead of\n the resting one. Wave position is\n unaffected — the wave still originates\n at the click point. Must be a CONCRETE\n PIXEL VALUE (e.g. `120px`). Computed\n expressions involving %, calc() or\n clamp() are NOT resolved by this hook —\n read the literal token via\n getComputedStyle and parseFloat returns\n NaN on those forms. Consumers needing\n such expressions should compute the\n value in JS and write it back as fixed\n pixels via inline style. (default: 0)\n --md-ripple-extend-block Same as --md-ripple-extend-inline but\n for the block axis. (default: 0)\n --md-ripple-grow-duration Override the wave's scale 0 → 1 grow\n duration. Use on surfaces that animate\n their own size during the ripple's\n lifetime (e.g. md-search) so the wave\n reaches full size at the same instant\n the surface settles — otherwise the\n wave is still ramping up while the\n surface is already at its final width.\n var() references and any value that\n resolves to a CSS time work (e.g.\n `250ms`). (default: 450ms)\n --md-ripple-grow-easing Companion to --md-ripple-grow-duration\n — usually set to the surface's own\n easing so the wave feels like part of\n the same motion.\n (default: cubic-bezier(0.2, 0, 0, 1))\n\n CSS PARTS:\n (none)\n\n SLOTS:\n (none)\n ========================================================== */\n\n:host {\n display: contents;\n\n /* `.md-ripple` clips the wave with `border-radius: inherit`, which inherits\n from THIS host — not from the component embedding us. Left at the initial\n 0, that clip is a square, and the wave only looked round because the\n embedding host happened to clip it with its own `overflow: hidden`. Any\n host that must let something escape (an icon button with a badge) then got\n a square ripple. Inheriting the radius here makes the clip follow the\n container's shape on its own. */\n border-radius: inherit;\n\n --_color: var(--md-ripple-color, currentColor);\n}\n\n.md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n overflow: hidden;\n pointer-events: none;\n}\n\n.md-ripple__wave {\n position: absolute;\n border-radius: 50%;\n pointer-events: none;\n background: var(--_color);\n opacity: 0;\n transform: scale(0);\n will-change: transform, opacity;\n}\n\n/* ==========================================================\n SUPPRESSION (global data-ripple=\"off\" / per-component ripple=\"off\")\n The real gate is in TS — onPointerDown and trigger() bail before a wave is\n ever created, so nothing is allocated or animated. This rule is the safety\n net for the one case TS cannot cover: a wave already mid-flight when the\n toggle flips. Without it that wave would finish its 450ms grow after ripples\n were switched off.\n\n The signal is 0/1, which is already a valid opacity, so it drops straight in\n — no keyword mapping, and the default of 1 makes this a no-op when the\n feature is on. opacity (not display) so nothing about layout or the\n containing block changes.\n ========================================================== */\n.md-ripple {\n opacity: var(--md-sys-ripple-enabled, 1);\n}\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Element, h, Host, Method, Prop } from '@stencil/core';\n\nconst PRESS_GROW_MS = 450;\nconst RELEASE_FADE_MS = 150;\nconst DEFAULT_PRESS_OPACITY = 0.12;\nconst EASING_STANDARD = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst GROW_DURATION_PROP = '--md-ripple-grow-duration';\nconst GROW_EASING_PROP = '--md-ripple-grow-easing';\n\n@Component({ tag: 'md-ripple', styleUrl: 'md-ripple.css', shadow: true })\nexport class MdRipple {\n @Element() el!: HTMLElement;\n\n @Prop() disabled: boolean = false;\n\n /**\n * True when ripples are switched off for this element, either globally\n * (`data-ripple=\"off\"` on any ancestor) or on the owning component\n * (`ripple=\"off\"`). Both spellings resolve to `--md-sys-ripple-enabled` in\n * tokens.css, so only the resolved value is read here.\n *\n * Read at interaction time rather than cached. The signal is a plain\n * inherited custom property, so it can change at any moment — a theme\n * switch, a settings toggle, a parent re-render — with no attribute mutation\n * on THIS element to observe. One getComputedStyle per press is cheap next to\n * the wave animation that follows, and it cannot go stale.\n *\n * The check is deliberately `=== '0'`: an unset property returns '' and must\n * mean ENABLED, so testing for falsiness would disable ripples everywhere the\n * token sheet has not loaded.\n */\n private rippleSuppressed(): boolean {\n if (typeof getComputedStyle !== 'function') return false;\n try {\n return (\n getComputedStyle(this.el).getPropertyValue('--md-sys-ripple-enabled').trim() === '0'\n );\n } catch {\n return false;\n }\n }\n\n private hostEl: HTMLElement | null = null;\n private activeWave: HTMLElement | null = null;\n private growAnimation: Animation | null = null;\n private activeOpacity: number = DEFAULT_PRESS_OPACITY;\n private bound = false;\n private settlePromise: Promise<void> | null = null;\n private settleResolve: (() => void) | null = null;\n\n private resolveOpacity(): number {\n if (!this.hostEl) return DEFAULT_PRESS_OPACITY;\n const raw = getComputedStyle(this.hostEl)\n .getPropertyValue('--md-ripple-opacity')\n .trim();\n if (!raw) return DEFAULT_PRESS_OPACITY;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : DEFAULT_PRESS_OPACITY;\n }\n\n /**\n * Resolve the inline / block extents that surfaces growing during the\n * ripple's lifetime (e.g. md-search springing out on focus) declare via\n * `--md-ripple-extend-inline` / `--md-ripple-extend-block`. The values\n * inflate the host's rect ONLY for the wave's farthest-corner radius\n * calculation, so the wave is sized for the SETTLED rect even though\n * the actual host is still at its resting size at pointerdown. Wave\n * POSITION still uses the unmodified rect so the wave originates\n * exactly where the user clicked.\n *\n * Consumers MUST pass concrete pixel values here (e.g.\n * `style.setProperty('--md-ripple-extend-inline', '120px')`).\n * `getComputedStyle().getPropertyValue()` on a custom property returns\n * the LITERAL TOKEN — for `calc()` / `clamp()` / `%` expressions the\n * string is unparsed (`\"calc(clamp(0px, 8%, 64px) * 2)\"`) and\n * `parseFloat()` returns `NaN`. Resolving such expressions reliably\n * requires knowing the consumer's intended containing-block reference,\n * which md-ripple cannot infer; consumers therefore compute the value\n * themselves (typically with a hidden probe element scoped to the\n * correct containing block) and write it back as fixed pixels.\n */\n private resolveExtent(prop: string): number {\n const raw = getComputedStyle(this.el).getPropertyValue(prop).trim();\n if (!raw) return 0;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n /**\n * Wave grow duration (ms). Surfaces that animate their size during the\n * ripple's lifetime (e.g. md-search springing from a narrower resting\n * width to its full width) should sync the wave's growth with their\n * own settle so the wave reaches scale = 1 at the same moment the\n * surface stops moving — otherwise the wave is still ramping up while\n * the surface is already at its final width and the user sees a\n * visible gap on the side that grew. Default is the spec-canonical\n * 450ms.\n */\n private resolveGrowDuration(): number {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_DURATION_PROP).trim();\n if (!raw) return PRESS_GROW_MS;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : PRESS_GROW_MS;\n }\n\n /**\n * Wave grow easing function. Companion to {@link resolveGrowDuration}\n * — when a surface drives the timing it should usually pass its own\n * easing (typically a back-out spring) so the wave's growth feels\n * like part of the same motion.\n */\n private resolveGrowEasing(): string {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_EASING_PROP).trim();\n return raw || EASING_STANDARD;\n }\n\n private beginSettle() {\n this.finishSettle();\n this.settlePromise = new Promise<void>((resolve) => {\n this.settleResolve = resolve;\n });\n }\n\n private finishSettle() {\n this.settleResolve?.();\n this.settleResolve = null;\n this.settlePromise = null;\n }\n\n /** Resolves when the active press ripple has fully faded out. */\n @Method()\n async whenSettled(): Promise<void> {\n if (!this.settlePromise) return;\n const maxWait = new Promise<void>((resolve) => {\n setTimeout(resolve, RELEASE_FADE_MS + 50);\n });\n await Promise.race([this.settlePromise, maxWait]);\n this.finishSettle();\n }\n\n private resolveHost(): HTMLElement | null {\n const root = this.el.getRootNode();\n return this.el.parentElement ??\n (root instanceof ShadowRoot ? (root.host as HTMLElement) : null);\n }\n\n private bind() {\n if (this.bound) return;\n this.hostEl = this.resolveHost();\n if (!this.hostEl) return;\n this.bound = true;\n this.hostEl.addEventListener('pointerdown', this.onPointerDown);\n }\n\n connectedCallback() {\n this.bind();\n if (!this.bound) {\n queueMicrotask(() => this.bind());\n }\n }\n\n disconnectedCallback() {\n this.hostEl?.removeEventListener('pointerdown', this.onPointerDown);\n this.hostEl = null;\n this.bound = false;\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (this.disabled || this.rippleSuppressed()) return;\n\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n // Treat the surface as if it spans an extended rect when the host has\n // declared `--md-ripple-extend-inline` / `--md-ripple-extend-block`.\n // Wave POSITION still uses the actual (current) rect so the wave\n // visually originates at the click point — only the RADIUS uses the\n // inflated bounds so the wave grows large enough to cover the surface\n // once it settles.\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const left = rect.left - extendInline;\n const right = rect.right + extendInline;\n const top = rect.top - extendBlock;\n const bottom = rect.bottom + extendBlock;\n const dx = Math.max(Math.abs(e.clientX - left), Math.abs(e.clientX - right));\n const dy = Math.max(Math.abs(e.clientY - top), Math.abs(e.clientY - bottom));\n const radius = Math.sqrt(dx * dx + dy * dy);\n const size = radius * 2;\n const x = e.clientX - rect.left - radius;\n const y = e.clientY - rect.top - radius;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${x}px`;\n wave.style.top = `${y}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n window.addEventListener('pointerup', this.onRelease, { once: true });\n window.addEventListener('pointercancel', this.onRelease, { once: true });\n };\n\n private onRelease = () => {\n this.endWave();\n };\n\n private async endWave() {\n const wave = this.activeWave;\n const grow = this.growAnimation;\n if (!wave || !grow) return;\n\n this.activeWave = null;\n this.growAnimation = null;\n\n if (grow.playState !== 'finished') {\n await grow.finished;\n }\n\n const fade = wave.animate(\n [{ opacity: this.activeOpacity }, { opacity: 0 }],\n { duration: RELEASE_FADE_MS, easing: EASING_STANDARD, fill: 'forwards' },\n );\n try {\n if (typeof fade.finished?.then === 'function') {\n await fade.finished;\n } else {\n await new Promise<void>((resolve) => setTimeout(resolve, RELEASE_FADE_MS));\n }\n } catch {\n /* animation cancelled */\n }\n wave.remove();\n this.finishSettle();\n }\n\n /** Programmatically trigger a centered ripple (for keyboard activations). */\n @Method()\n async trigger() {\n if (this.disabled || this.rippleSuppressed()) return;\n\n if (!this.hostEl) this.hostEl = this.resolveHost();\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n // Centered ripples use the rect's centre as both anchor and farthest\n // reference, so the inflated half-extents become the radius\n // contribution directly.\n const halfX = cx + extendInline;\n const halfY = cy + extendBlock;\n const radius = Math.sqrt(halfX * halfX + halfY * halfY);\n const size = radius * 2;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${cx - radius}px`;\n wave.style.top = `${cy - radius}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n this.growAnimation.addEventListener('finish', () => this.endWave(), { once: true });\n }\n\n render() {\n return (\n <Host aria-hidden=\"true\">\n <div class=\"md-ripple\"></div>\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-snackbar — Material Design 3 Snackbar\n Spec: https://m3.material.io/components/snackbar/specs\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-snackbar-container-color Surface background\n --md-snackbar-message-color Supporting text color\n --md-snackbar-action-color Action button text color\n --md-snackbar-close-color Close icon color\n --md-snackbar-container-shape Border radius\n --md-snackbar-min-width Minimum inline size\n --md-snackbar-max-width Maximum inline size\n\n CSS PARTS:\n surface Outer container\n message Supporting text wrapper\n actions Action button wrapper\n close Close button wrapper\n\n SLOTS:\n (default) Supporting text\n action Custom action element\n close Custom close element\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — positioning & visibility\n ========================================================== */\n\n:host {\n --_container-color: var(--md-snackbar-container-color, var(--md-sys-color-inverse-surface, #313033));\n --_message-color: var(--md-snackbar-message-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_action-color: var(--md-snackbar-action-color, var(--md-sys-color-inverse-primary, #D0BCFF));\n --_close-color: var(--md-snackbar-close-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_container-shape: var(--md-snackbar-container-shape, var(--md-sys-shape-corner-extra-small, 4px));\n --_min-width: var(--md-snackbar-min-width, 288px);\n --_max-width: var(--md-snackbar-max-width, 568px);\n --_slide-from: translateY(100%);\n\n display: flex;\n position: fixed;\n inset-block-start: 0;\n inset-block-end: 0;\n inset-inline-start: 0;\n inset-inline-end: 0;\n padding: var(--md-sys-spacing-inset-xl, 24px);\n align-items: flex-end;\n justify-content: center;\n /* Every snackbar shares one z-index, so with two of them up the DOM order —\n not the order they opened in — decides which paints on top, and a newly\n shown snackbar can appear BEHIND one already on screen. `--_stack-order`\n is stamped on open (see md-snackbar.tsx) and lifts the newest above its\n peers. It counts open snackbars, not opens, so it stays a small number and\n can't creep up past dialogs or other overlays above this token. */\n z-index: calc(var(--md-sys-z-index-snackbar, 2000) + var(--_stack-order, 0));\n pointer-events: none;\n visibility: hidden;\n opacity: 0;\n transform: var(--_slide-from);\n transition:\n opacity var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n transform var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n visibility 0ms linear var(--md-sys-motion-duration-short4, 200ms);\n}\n\n:host(.md-snackbar--open) {\n visibility: visible;\n opacity: 1;\n transform: translate(0, 0);\n transition:\n opacity var(--md-sys-motion-duration-medium1, 250ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n transform var(--md-sys-motion-duration-medium1, 250ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n visibility 0ms linear 0ms;\n}\n\n:host(.md-snackbar--open) .md-snackbar__surface {\n pointer-events: auto;\n}\n\n/* ─── Bottom positions (slide from bottom) ─────────────── */\n\n:host(.md-snackbar--bottom) {\n align-items: flex-end;\n justify-content: center;\n}\n\n:host(.md-snackbar--bottom-start) {\n align-items: flex-end;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--bottom-end) {\n align-items: flex-end;\n justify-content: flex-end;\n}\n\n/* ─── Top positions (slide from top) ───────────────────── */\n\n:host(.md-snackbar--top),\n:host(.md-snackbar--top-start),\n:host(.md-snackbar--top-end) {\n --_slide-from: translateY(-100%);\n}\n\n:host(.md-snackbar--top) {\n align-items: flex-start;\n justify-content: center;\n}\n\n:host(.md-snackbar--top-start) {\n align-items: flex-start;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--top-end) {\n align-items: flex-start;\n justify-content: flex-end;\n}\n\n/* ─── Side & center positions (fade only) ──────────────── */\n\n:host(.md-snackbar--start),\n:host(.md-snackbar--end),\n:host(.md-snackbar--center) {\n --_slide-from: translate(0, 0);\n}\n\n:host(.md-snackbar--start) {\n align-items: center;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--end) {\n align-items: center;\n justify-content: flex-end;\n}\n\n:host(.md-snackbar--center) {\n align-items: center;\n justify-content: center;\n}\n\n/* ==========================================================\n 2. SURFACE — container\n ========================================================== */\n\n.md-snackbar__surface {\n display: flex;\n align-items: center;\n min-inline-size: var(--_min-width);\n max-inline-size: var(--_max-width);\n min-block-size: max(36px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n padding-inline-start: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n padding-inline-end: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n background-color: var(--_container-color);\n color: var(--_message-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--md-sys-elevation-3);\n box-sizing: border-box;\n}\n\n:host(.md-snackbar--with-action:not(.md-snackbar--with-close)) .md-snackbar__surface {\n padding-inline-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-snackbar--with-close) .md-snackbar__surface {\n padding-inline-end: var(--md-sys-spacing-inset-md, 12px);\n}\n\n/* ─── Compact viewports (MD3) ───────────────────────────────\n Below 600px the snackbar spans the full available width (minus a smaller edge\n margin) instead of its fixed min/max width — so it never overflows or clips\n off-screen on a phone (the 288px min-width would otherwise exceed a narrow\n viewport). */\n@media (max-width: 599px) {\n :host {\n padding: var(--md-sys-spacing-inset-lg, 16px);\n }\n .md-snackbar__surface {\n inline-size: 100%;\n min-inline-size: 0;\n max-inline-size: 100%;\n }\n}\n\n/* ==========================================================\n 3. MESSAGE — supporting text\n ========================================================== */\n\n.md-snackbar__message {\n flex: 1;\n padding-block: max(6px, calc(14px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-medium-font-weight, 400);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing, 0.25px);\n color: inherit;\n}\n\n/* ==========================================================\n 4. ACTIONS — action button + close icon\n ========================================================== */\n\n.md-snackbar__actions {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* ─── Action button (md-button, text variant) ───────────── */\n\n/* The action is a real md-button (text variant). On the inverse (dark)\n snackbar surface it takes the inverse-primary action color for its label,\n icon, state layer and ripple — the button itself supplies the typescale,\n shape, focus ring and ripple. */\n.md-snackbar__action-btn {\n flex-shrink: 0;\n --md-button-label-color: var(--_action-color);\n --md-button-icon-color: var(--_action-color);\n --md-ripple-color: var(--_action-color);\n}\n\n/* ─── Close wrapper & icon button ──────────────────────── */\n\n.md-snackbar__close {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-snackbar__close md-icon-button {\n --md-icon-button-icon-color: var(--_close-color);\n --md-icon-button-container-width: max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-container-height: max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-icon-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n/* ==========================================================\n 5. STACKED LAYOUT — action below text, close at top-right\n ========================================================== */\n\n:host(.md-snackbar--stacked) .md-snackbar__surface {\n display: grid;\n grid-template-columns: 1fr auto;\n grid-template-rows: auto auto;\n align-items: start;\n /* Breathing room so the close isn't jammed against the message, and the action\n row isn't stacked tight under the close. */\n column-gap: var(--md-sys-spacing-gap-md, 12px);\n row-gap: 6px;\n min-block-size: 68px;\n padding-block-start: var(--md-sys-spacing-inset-sm, 8px);\n padding-block-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-snackbar--stacked) .md-snackbar__message {\n grid-column: 1;\n grid-row: 1;\n padding-block-end: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n/* Centre the 24px close glyph on the message's first-line\n centre. The message inherits `padding-block: 14px` from the\n base rule (the stacked override only resets the end padding),\n so its first line centre sits at row_top + 14 + 10 = row_top\n + 24. The icon-button is 40×40 with 8px internal padding —\n its glyph centre sits 20px below the button's top. We\n therefore push the button DOWN by 4px so the glyph centre\n lands at row_top + 24 = message line centre. Holds for\n multi-line messages too — the glyph stays on the FIRST line. */\n:host(.md-snackbar--stacked) .md-snackbar__close {\n grid-column: 2;\n grid-row: 1;\n align-self: start;\n margin-inline-start: 0;\n margin-block-start: var(--md-sys-spacing-inset-xs, 4px);\n padding-block-start: 0;\n}\n\n:host(.md-snackbar--stacked) .md-snackbar__actions {\n grid-column: 1 / -1;\n grid-row: 2;\n justify-self: end;\n}\n\n/* ==========================================================\n 6. SLOTTED CONTENT\n ========================================================== */\n\n::slotted([slot=\"action\"]) {\n color: var(--_action-color);\n}\n\n::slotted([slot=\"close\"]) {\n color: var(--_close-color);\n}\n\n/* ==========================================================\n 7. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n :host(.md-snackbar--open) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 8. FORCED COLORS (Windows High Contrast)\n ========================================================== */\n\n@media (forced-colors: active) {\n .md-snackbar__surface {\n border: 1px solid CanvasText;\n }\n\n .md-snackbar__action-btn {\n color: LinkText;\n }\n\n .md-snackbar__action-btn:focus-visible {\n outline-color: Highlight;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Method, Watch } from '@stencil/core';\n\n/**\n * @slot - Supporting text (overrides `message` prop)\n * @slot action - Custom action element (overrides `action` prop)\n * @slot close - Custom close element (overrides default X icon button)\n *\n * @part surface - Outer container surface\n * @part message - Supporting text wrapper\n * @part actions - Action button wrapper\n * @part close - Close button wrapper\n */\n@Component({\n tag: 'md-snackbar',\n styleUrl: 'md-snackbar.css',\n shadow: true,\n})\nexport class MdSnackbar {\n @Element() el!: HTMLElement;\n\n // ─── Public Props ──────────────────────────────────────────\n\n /** Whether the snackbar is visible */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n\n /** Primary supporting text */\n @Prop() message: string = '';\n\n /** Action button label (leave empty for no action) */\n @Prop() action: string = '';\n\n /** Show a close (X) icon button */\n @Prop({ reflect: true }) closeable: boolean = false;\n\n /** Auto-dismiss after `autoHideDuration` ms (dismissive behavior) */\n @Prop() autoHide: boolean = true;\n\n /** Time in ms before auto-dismiss */\n @Prop() autoHideDuration: number = 4000;\n\n /** Screen position */\n @Prop({ reflect: true }) position:\n | 'bottom' | 'bottom-start' | 'bottom-end'\n | 'top' | 'top-start' | 'top-end'\n | 'start' | 'end' | 'center' = 'bottom';\n\n /** Stack action below text (for longer action labels) */\n @Prop({ reflect: true }) stacked: boolean = false;\n\n /**\n * Live-region politeness. `'polite'` (default) → `role=\"status\"` /\n * `aria-live=\"polite\"` (announced when idle). `'assertive'` → `role=\"alert\"` /\n * `aria-live=\"assertive\"` — interrupts the screen reader; use sparingly for\n * important / error messages.\n */\n @Prop({ reflect: true }) politeness: 'polite' | 'assertive' = 'polite';\n\n /** Accessible label for the close button. Localize per the page locale. */\n @Prop({ attribute: 'dismiss-label' }) dismissLabel: string = 'Dismiss';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n // ─── Events ────────────────────────────────────────────────\n\n /** Emits when the snackbar becomes visible */\n @Event() mdOpen: EventEmitter<void>;\n\n /** Emits when the snackbar is dismissed, with reason */\n @Event() mdClose: EventEmitter<{ reason: 'auto' | 'action' | 'close' }>;\n\n /** Emits when the action button is clicked */\n @Event() mdAction: EventEmitter<void>;\n\n // ─── Internal State ────────────────────────────────────────\n\n @State() private hasSlottedAction = false;\n @State() private hasSlottedClose = false;\n @State() private hasSlottedDefault = false;\n\n private autoHideTimer?: ReturnType<typeof setTimeout>;\n private rippleDismissTimer?: ReturnType<typeof setTimeout>;\n private timerPaused = false;\n\n /** Coerce autoHide — HTML attribute `auto-hide=\"false\"` arrives as string \"false\" */\n private get isAutoHide(): boolean {\n return this.autoHide !== false && (this.autoHide as unknown) !== 'false';\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const defaultSlot = shadow.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const actionSlot = shadow.querySelector('slot[name=\"action\"]') as HTMLSlotElement | null;\n const closeSlot = shadow.querySelector('slot[name=\"close\"]') as HTMLSlotElement | null;\n\n defaultSlot?.addEventListener('slotchange', () => {\n this.hasSlottedDefault = defaultSlot.assignedNodes().some(n =>\n n.nodeType === Node.ELEMENT_NODE || (n.nodeType === Node.TEXT_NODE && n.textContent?.trim() !== ''),\n );\n });\n actionSlot?.addEventListener('slotchange', () => {\n this.hasSlottedAction = actionSlot.assignedElements().length > 0;\n });\n closeSlot?.addEventListener('slotchange', () => {\n this.hasSlottedClose = closeSlot.assignedElements().length > 0;\n });\n\n if (this.open) {\n this.onOpenChange(true, false);\n }\n }\n\n disconnectedCallback() {\n this.clearAutoHide();\n if (this.rippleDismissTimer != null) {\n clearTimeout(this.rippleDismissTimer);\n this.rippleDismissTimer = undefined;\n }\n window.removeEventListener('keydown', this.handleEscape);\n }\n\n // ─── Watchers ──────────────────────────────────────────────\n\n /**\n * Lift this snackbar above any that are already open.\n *\n * All snackbars share one z-index token, and equal z-index falls back to DOM\n * order — so showing a snackbar declared earlier in the markup put it BEHIND\n * one already on screen. Ranking against the currently-open peers (rather\n * than counting every open ever) keeps the offset bounded by how many are up\n * at once, so it never climbs into the range of dialogs above it.\n */\n private raiseAboveOpenPeers() {\n const peers = Array.from(document.querySelectorAll('md-snackbar')).filter(\n (s) => s !== this.el && (s as HTMLMdSnackbarElement).open,\n );\n const highest = peers.reduce(\n (max, s) => Math.max(max, Number((s as HTMLElement).style.getPropertyValue('--_stack-order')) || 0),\n 0,\n );\n this.el.style.setProperty('--_stack-order', String(highest + 1));\n }\n\n @Watch('open')\n onOpenChange(newVal: boolean, _oldVal?: boolean) {\n if (newVal) {\n this.raiseAboveOpenPeers();\n this.mdOpen.emit();\n if (this.isAutoHide) {\n this.startAutoHide();\n }\n window.addEventListener('keydown', this.handleEscape);\n } else {\n this.clearAutoHide();\n this.timerPaused = false;\n window.removeEventListener('keydown', this.handleEscape);\n }\n }\n\n // ─── Public Methods ────────────────────────────────────────\n\n /** Show the snackbar */\n @Method()\n async show() {\n this.open = true;\n }\n\n /** Hide the snackbar with an optional reason */\n @Method()\n async hide(reason: 'auto' | 'action' | 'close' = 'close') {\n if (!this.open) return;\n this.open = false;\n this.mdClose.emit({ reason });\n }\n\n // ─── Private ───────────────────────────────────────────────\n\n private startAutoHide() {\n this.clearAutoHide();\n this.autoHideTimer = setTimeout(() => {\n if (this.open) {\n this.open = false;\n this.mdClose.emit({ reason: 'auto' });\n }\n }, this.autoHideDuration);\n }\n\n private clearAutoHide() {\n if (this.autoHideTimer != null) {\n clearTimeout(this.autoHideTimer);\n this.autoHideTimer = undefined;\n }\n }\n\n private dismissAfterRipple(reason: 'action' | 'close') {\n this.rippleDismissTimer = setTimeout(() => {\n this.rippleDismissTimer = undefined;\n if (this.open) {\n this.open = false;\n this.mdClose.emit({ reason });\n }\n }, 150);\n }\n\n private handleActionClick = () => {\n this.mdAction.emit();\n this.startAutoHide();\n };\n\n private handleCloseClick = () => {\n this.dismissAfterRipple('close');\n };\n\n private handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.open && this.closeable) {\n e.preventDefault();\n this.handleCloseClick();\n }\n };\n\n /** WCAG 2.2.1 — pause auto-hide while the user is interacting */\n private pauseAutoHide = () => {\n if (this.autoHideTimer != null && this.open) {\n this.timerPaused = true;\n this.clearAutoHide();\n }\n };\n\n private resumeAutoHide = () => {\n if (this.timerPaused && this.open) {\n this.timerPaused = false;\n this.startAutoHide();\n }\n };\n\n private handleSurfaceFocusOut = (e: FocusEvent) => {\n const surface = e.currentTarget as HTMLElement;\n if (e.relatedTarget && surface.contains(e.relatedTarget as Node)) {\n return;\n }\n this.resumeAutoHide();\n };\n\n // ─── Render ────────────────────────────────────────────────\n\n render() {\n const hasAction = !!this.action || this.hasSlottedAction;\n const hasClose = this.closeable || this.hasSlottedClose;\n\n return (\n <Host\n class={{\n 'md-snackbar': true,\n 'md-snackbar--open': this.open,\n 'md-snackbar--stacked': this.stacked,\n [`md-snackbar--${this.position}`]: true,\n 'md-snackbar--with-action': hasAction,\n 'md-snackbar--with-close': hasClose,\n }}\n role={this.politeness === 'assertive' ? 'alert' : 'status'}\n aria-live={this.politeness}\n aria-atomic=\"true\"\n >\n <div\n class=\"md-snackbar__surface\"\n part=\"surface\"\n onMouseEnter={this.pauseAutoHide}\n onMouseLeave={this.resumeAutoHide}\n onFocusin={this.pauseAutoHide}\n onFocusout={this.handleSurfaceFocusOut}\n >\n <span class=\"md-snackbar__message\" part=\"message\">\n <slot>{this.message}</slot>\n </span>\n\n {hasAction && (\n <div class=\"md-snackbar__actions\" part=\"actions\">\n <slot name=\"action\">\n {this.action && (\n <md-button\n variant=\"text\"\n size=\"sm\"\n class=\"md-snackbar__action-btn\"\n onClick={this.handleActionClick}\n >\n {this.action}\n </md-button>\n )}\n </slot>\n </div>\n )}\n\n {hasClose && (\n <div class=\"md-snackbar__close\" part=\"close\">\n <slot name=\"close\">\n {this.closeable && (\n <md-icon-button\n variant=\"standard\"\n icon=\"close\"\n aria-label={this.dismissLabel}\n onClick={this.handleCloseClick}\n exportparts=\"icon:close-icon\"\n ></md-icon-button>\n )}\n </slot>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
|
|
1
|
+
{"file":"md-button_6.cjs.entry.js","mappings":"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","names":["sanitizeHref","SAFE_WINDOW_FEATURES","triggerRipple","h","Host","SAFE_LINK_REL","Fragment","LazyLoadingIndicator","setFormValue","setValidityState","getValidityOf","checkValidityOf","reportValidityOf"],"sources":["src/components/md-button/md-button.css?tag=md-button&encapsulation=shadow","src/components/md-button/md-button.tsx","src/components/md-card/md-card.css?tag=md-card&encapsulation=shadow","src/components/md-card/md-card.tsx","src/components/md-icon-button/md-icon-button.css?tag=md-icon-button&encapsulation=shadow","src/components/md-icon-button/md-icon-button.tsx","src/components/md-radio/md-radio.css?tag=md-radio&encapsulation=shadow","src/components/md-radio/md-radio.tsx","src/components/md-ripple/md-ripple.css?tag=md-ripple&encapsulation=shadow","src/components/md-ripple/md-ripple.tsx","src/components/md-snackbar/md-snackbar.css?tag=md-snackbar&encapsulation=shadow","src/components/md-snackbar/md-snackbar.tsx"],"sourcesContent":["/* ==========================================================\n md-button — Material Design 3 Common Button\n Spec: https://m3.material.io/components/buttons/specs\n API: https://developer.android.com/reference/kotlin/\n androidx/compose/material3/ButtonDefaults\n Supports M3 + M3 Expressive (size, shape)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-button-container-color Container background\n --md-button-label-color Label + icon text color\n --md-button-icon-color Icon-only color override\n --md-button-icon-size Icon dimensions\n --md-button-container-shape Border-radius override\n --md-button-outline-color Outlined border color\n --md-button-outline-width Outlined border width\n --md-button-width Fixed inline-size (default: auto)\n --md-button-min-width Minimum inline-size (default: per-size touch target)\n --md-button-max-width Maximum inline-size (default: none)\n --md-button-height Fixed block-size (default: auto)\n --md-button-min-height Minimum block-size (default: per-size touch target)\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Leading icon (fallback)\n trailing-icon Trailing icon (fallback)\n label Label text wrapper\n loading Loading spinner\n\n SLOTS:\n leading-icon Custom leading icon (replaces icon prop)\n trailing-icon Custom trailing icon (replaces trailingIcon prop)\n\n RTL:\n Layout uses CSS logical properties throughout, so leading/\n trailing icons swap visual sides automatically in `dir=\"rtl\"`.\n Set the `mirror-icon` attribute on buttons that use directional\n glyphs (arrows, chevrons) so the icon path itself flips.\n ========================================================== */\n\n:host {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-0, none);\n --_icon-size: var(--md-button-icon-size, 18px);\n\n /* Sizing — defaults come from each size class via --_size-* tokens.\n Public --md-button-{width,min-width,max-width,height,min-height}\n custom properties override per-instance for variable / full-width\n buttons without sacrificing the spec touch-target on resize. */\n --_width: var(--md-button-width, auto);\n /* Min-width tightens with density too (floored at 40px) so short-label\n buttons narrow, not just content-wide ones. Unchanged at density 0. */\n --_min-width: var(\n --md-button-min-width,\n max(40px, calc(var(--_size-min-width, 48px) + var(--md-sys-density-scale, 0) * 4px))\n );\n --_max-width: var(--md-button-max-width, none);\n --_height: var(--md-button-height, auto);\n /* Global density: on top of the size scale, each `data-density` rung (0…-4)\n trims 4px off the touch target, floored at 24px so small buttons stay\n usable. density-scale is 0 by default so the per-size height is unchanged. */\n --_min-height: var(\n --md-button-min-height,\n max(24px, calc(var(--_size-min-height, 32px) + var(--md-sys-density-scale, 0) * 4px))\n );\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n border: none;\n /* Transparent resting outline; focus-visible swaps outline-color in instantly.\n Deliberately NOT transitioned — on hydration the host's pre-upgrade UA outline\n (style:none, color:currentColor) animates to solid/transparent, which renders a\n dark ring that fades out on every button. Most visible when many mount at once\n (e.g. the 42 day cells in md-date-picker). Instant focus ring matches M3. */\n outline: 3px solid transparent;\n outline-offset: 2px;\n box-sizing: border-box;\n inline-size: var(--_width);\n block-size: var(--_height);\n min-inline-size: var(--_min-width);\n min-block-size: var(--_min-height);\n max-inline-size: var(--_max-width);\n background-color: var(--_container-color);\n color: var(--_label-color);\n box-shadow: var(--_container-elevation);\n --_shape-round: 20px;\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n -webkit-tap-highlight-color: transparent;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 1. SIZE\n XS (32px) · SM (40px, default) · MD (48px) · LG (56px) · XL (96px)\n ========================================================== */\n/* Icon<->label gap tapers with density like the rest of the button: the\n container height and icon already shrink per rung, so a frozen gap made\n compact buttons read as loosely spaced. Each tier halves across the range\n (rate = base/8 per rung), floored at half its base. */\n:host(.md-button--xs) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 16px;\n --_size-min-height: 32px;\n --_size-min-width: 48px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(6px, calc(12px + var(--md-sys-density-scale, 0) * 0.75px));\n gap: max(2px, calc(4px + var(--md-sys-density-scale, 0) * 0.5px));\n font-family: var(--md-sys-typescale-label-medium-font-family, Roboto, sans-serif);\n font-size: max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-medium-letter-spacing, 0.5px);\n line-height: max(14px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n}\n\n:host(.md-button--sm) {\n --_icon-size: var(--md-button-icon-size, max(10px, calc(20px + var(--md-sys-density-scale, 0) * 2.5px)));\n --_shape-round: 20px;\n --_size-min-height: 40px;\n --_size-min-width: 58px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(8px, calc(16px + var(--md-sys-density-scale, 0) * 1px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--md) {\n --_icon-size: var(--md-button-icon-size, max(12px, calc(24px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 28px;\n --_size-min-height: 56px;\n --_size-min-width: 72px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(12px, calc(24px + var(--md-sys-density-scale, 0) * 1.5px));\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n font-family: var(--md-sys-typescale-title-small-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-small-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-small-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--lg) {\n --_icon-size: var(--md-button-icon-size, max(16px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 48px;\n --_size-min-height: 96px;\n --_size-min-width: 88px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(24px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n gap: max(6px, calc(12px + var(--md-sys-density-scale, 0) * 1.5px));\n font-family: var(--md-sys-typescale-title-medium-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-title-medium-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing, 0.15px);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n:host(.md-button--xl) {\n --_icon-size: var(--md-button-icon-size, max(20px, calc(40px + var(--md-sys-density-scale, 0) * 5px)));\n --_shape-round: 68px;\n --_size-min-height: 136px;\n --_size-min-width: 120px;\n /* 25% across the density range, floored at half. At 50% the inset shrank\n faster than the button did — a -4 sm button was still 24px tall but had\n only 8px of side padding, which read crammed. */\n padding: 0 max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px));\n gap: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-headline-small-font-family, Roboto, sans-serif);\n font-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n font-weight: var(--md-sys-typescale-headline-small-font-weight, 400);\n letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing, 0px);\n line-height: max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px));\n}\n\n/* ==========================================================\n 1b. FULL WIDTH — block-level, fills inline axis\n `full-width` switches the host from inline-flex to flex and stretches\n inline-size to 100% of the containing block. The size's\n --_size-min-height (touch target) is still in force, so the button\n keeps its spec block-size unless --md-button-height overrides it.\n --md-button-width still wins if explicitly set.\n ========================================================== */\n:host(.md-button--full-width) {\n display: flex;\n --_width: var(--md-button-width, 100%);\n}\n\n/* ==========================================================\n 2. SHAPE\n Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n --md-button-container-shape overrides both.\n ========================================================== */\n/* The RESTING radius is named (--_shape-rest) so the morph states below can be\n expressed as a blend back toward it. --_morph-to carries the morphed target\n and defaults to the resting value, so a button with no active morph state\n resolves to exactly its resting radius:\n\n calc(REST + FLAG * (MORPH - REST)) FLAG 1 -> MORPH, FLAG 0 -> REST\n\n That is what makes `data-shape-morph=\"off\"` / `shape-morph=\"off\"` freeze the\n shape (§13 in tokens.css) without a re-render and without :host-context,\n which Firefox does not implement. */\n:host(.md-button--round) {\n --_shape-rest: var(--md-button-container-shape, var(--_shape-round));\n border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest)));\n}\n\n:host(.md-button--square.md-button--xs) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-small, 8px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--sm) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--md) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--lg) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-large, 16px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n:host(.md-button--square.md-button--xl) { --_shape-rest: var(--md-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); border-radius: calc(var(--_shape-rest) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_shape-rest)) - var(--_shape-rest))); }\n\n/* ==========================================================\n 2b. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides for reliable transitions.\n\n Order: selected rules FIRST, pressed rules LAST so pressed\n always wins while the pointer is down.\n\n Asymmetric timing (M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xs) { --_morph-to: var(--md-sys-shape-corner-small, 8px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--md) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--lg) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-button--shape-morph.md-button--round.md-button--selected.md-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-button--shape-morph.md-button--square.md-button--selected) {\n --_morph-to: var(--md-button-container-shape, var(--_shape-round));\n}\n\n/* ── Pressed shape — both round & square morph to more square, overrides selected ── */\n:host(.md-button--pressed.md-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-extra-small, 4px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--md) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-button--pressed.md-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 2c. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 2, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-button--connected-left.md-button--xs),\n:host(.md-button--connected-right.md-button--xs) { --_c-inner: 4px; }\n:host(.md-button--connected-left.md-button--sm),\n:host(.md-button--connected-right.md-button--sm) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--md),\n:host(.md-button--connected-right.md-button--md) { --_c-inner: 8px; }\n:host(.md-button--connected-left.md-button--lg),\n:host(.md-button--connected-right.md-button--lg) { --_c-inner: 16px; }\n:host(.md-button--connected-left.md-button--xl),\n:host(.md-button--connected-right.md-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-button--connected-left.md-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-button--round.md-button--connected-right:not(.md-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-button--round.md-button--connected-left:not(.md-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-button--square.md-button--connected-right:not(.md-button--connected-left)),\n:host(.md-button--square.md-button--connected-left:not(.md-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 3. ICON PADDING\n An icon does NOT change the button's insets. The M3 Expressive size sheet\n specifies the SAME padding on both sides whether or not a leading icon is\n present (12/12, 16/16, 24/24, 48/48, 64/64) — the third number on those\n drawings is the icon-to-label gap, not a reduced leading inset. The size's\n base padding therefore applies symmetrically and there is nothing to override.\n ========================================================== */\n\n/* ==========================================================\n 4. COLOR VARIANTS\n --md-button-container-color and --md-button-label-color\n override the variant defaults when set.\n ========================================================== */\n\n/* Filled */\n:host(.md-button--filled) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-primary));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-primary));\n --_state-layer-color: var(--md-sys-color-on-primary);\n}\n:host(.md-button--filled:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--filled:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--filled:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* Outlined */\n:host(.md-button--outlined) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n border: var(--md-button-outline-width, 1px) solid var(--md-button-outline-color, var(--md-sys-color-outline));\n}\n/* Variant padding follows the SAME density rule as the base size rules above:\n slope = base/16 (25% shrink across the four rungs) and a floor of base/2.\n These overrides previously decayed at 52-133% per the old tuning — text sm\n lost 133% of its inset and pinned to its floor by rung -2 — so outlined and\n text shrank far faster than the button did. Past rung -2 that INVERTED the\n variants: an outlined button, wider than filled at density 0, became\n narrower than it, and a row of mixed-variant buttons went visibly ragged.\n Density-0 values are unchanged; only the decay was corrected. */\n:host(.md-button--outlined.md-button--xs) { padding: 0 max(5.5px, calc(11px + var(--md-sys-density-scale, 0) * 0.6875px)); }\n:host(.md-button--outlined.md-button--sm) { padding: 0 max(11.5px, calc(23px + var(--md-sys-density-scale, 0) * 1.4375px)); }\n:host(.md-button--outlined.md-button--md) { padding: 0 max(13.5px, calc(27px + var(--md-sys-density-scale, 0) * 1.6875px)); }\n:host(.md-button--outlined.md-button--lg) { padding: 0 max(15.5px, calc(31px + var(--md-sys-density-scale, 0) * 1.9375px)); }\n:host(.md-button--outlined.md-button--xl) { padding: 0 max(23.5px, calc(47px + var(--md-sys-density-scale, 0) * 2.9375px)); }\n:host(.md-button--outlined:hover:not(.md-button--disabled)) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n:host(.md-button--outlined:focus-visible) {\n border-color: var(--md-button-outline-color, var(--md-sys-color-primary));\n}\n\n/* Text */\n:host(.md-button--text) {\n --_container-color: var(--md-button-container-color, transparent);\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n/* Text buttons intentionally carry the SAME horizontal padding as every other\n variant (the base size rules above); there is deliberately no override here.\n They used to sit far tighter — a text button's inset was a third of a\n filled one's and pinned to its floor at tight densities (4px by rung -2).\n The container is invisible at rest, but the hover/press state layer is not:\n it paints the padding box, so a text button in a toggle strip beside a\n tonal or filled one showed a cramped pill hugging its label while its\n neighbour's was roomy, and the mismatch grew with density. Sharing the base\n padding keeps every state layer in a strip the same shape, and keeps a\n button's width stable if its variant changes to signal selection. */\n\n/* Elevated */\n:host(.md-button--elevated) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-low));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n --_container-elevation: var(--md-sys-elevation-1);\n}\n:host(.md-button--elevated:hover) { --_container-elevation: var(--md-sys-elevation-2); }\n:host(.md-button--elevated:focus-visible) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--elevated:active) { --_container-elevation: var(--md-sys-elevation-1); }\n\n/* Tonal */\n:host(.md-button--tonal) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n:host(.md-button--tonal:hover) { --_container-elevation: var(--md-sys-elevation-1); }\n:host(.md-button--tonal:focus-visible) { --_container-elevation: var(--md-sys-elevation-0, none); }\n:host(.md-button--tonal:active) { --_container-elevation: var(--md-sys-elevation-0, none); }\n\n/* ==========================================================\n 4b. TOGGLE SELECTED / UNSELECTED — MD3 spec\n When toggle=true, the unselected state is muted; selected\n shows the full variant color. Mirrors md-icon-button pattern.\n ========================================================== */\n\n/* The toggle-state rules below all carry `:not(.md-button--disabled)` so\n they drop out when the host becomes disabled. Without it, their higher\n specificity (4 classes vs the disabled rules' 2–3) would override the\n muted disabled palette and the button would still look enabled. */\n\n/* ── Filled toggle ── */\n:host(.md-button--filled.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-primary));\n --_state-layer-color: var(--md-sys-color-primary);\n}\n\n/* ── Tonal toggle ── */\n:host(.md-button--tonal.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ── Outlined toggle ── */\n:host(.md-button--outlined.md-button--toggle.md-button--selected:not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-sys-color-on-secondary-container, #1E192B);\n border-color: transparent;\n}\n\n/* ── Elevated toggle ── */\n:host(.md-button--elevated.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_container-color: var(--md-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n/* ── Text toggle ── */\n:host(.md-button--text.md-button--toggle:not(.md-button--selected):not(.md-button--disabled)) {\n --_label-color: var(--md-button-label-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* ==========================================================\n 5. STATE LAYER\n ========================================================== */\n.md-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active:not(.md-button--disabled)) .md-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n transition-duration: var(--md-sys-motion-duration-short1, 50ms);\n transition-timing-function: var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n:host(:focus-visible) .md-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 6. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline is never clipped by a neighbor — important inside\n md-button-group, where connected groups have only 2px between\n buttons and standard groups animate neighbor padding on press.\n ========================================================== */\n/* Connected children inside md-button-group sit only 2px apart, so a\n 3px-outset focus ring naturally extends across the neighbor. The\n `z-index: 1` raise lets it draw *on top* of the neighbor cleanly so\n the ring keeps its full 2px breathing room — same visual treatment\n as a stand-alone button. */\n:host(:focus-visible) {\n outline-color: var(--md-sys-color-secondary);\n z-index: 1;\n}\n\n/* ==========================================================\n 7. DISABLED\n ========================================================== */\n:host(.md-button--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n transition: none;\n}\n\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-button__state-layer { display: none; }\n\n:host(.md-button--filled.md-button--disabled),\n:host(.md-button--tonal.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n:host(.md-button--elevated.md-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-button--disabled) {\n --_label-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-button--outlined.md-button--disabled) {\n --_container-color: transparent;\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-button--text.md-button--disabled) {\n --_container-color: transparent;\n}\n\n:host(.md-button--disabled:hover) .md-button__state-layer,\n:host(.md-button--disabled:active) .md-button__state-layer,\n:host(.md-button--disabled:focus-visible) .md-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 8. ICON (prop-based fallback inside slot)\n ========================================================== */\n.md-button__icon,\n.md-button__trailing-icon {\n color: var(--md-button-icon-color, inherit);\n font-size: var(--_icon-size, 18px);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 9. NAMED ICON SLOTS\n Slots use display:contents so they don't create a box;\n slotted content participates directly in flex layout.\n ========================================================== */\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n color: var(--md-button-icon-color, inherit);\n width: var(--_icon-size, 18px);\n height: var(--_icon-size, 18px);\n flex-shrink: 0;\n}\n\n/* ----------------------------------------------------------\n Trailing-icon rotation when this button is a popover anchor.\n\n md-menu (and any other popup component using the same ARIA\n contract) sets aria-expanded=\"true\" on its anchor element\n while the popup is open. Rotating the trailing dropdown\n indicator 180° on that signal flips arrow_drop_down to\n point up, matching MD3 select-trigger behavior, with no\n wiring needed on the consumer side.\n\n Honors prefers-reduced-motion via short2 motion duration.\n ---------------------------------------------------------- */\n.md-button__trailing-icon,\n::slotted([slot=\"trailing-icon\"]) {\n transition: transform var(--md-sys-motion-duration-short2, 150ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) .md-button__trailing-icon,\n:host([aria-expanded=\"true\"]:not([suppress-expand-icon-flip])) ::slotted([slot=\"trailing-icon\"]) {\n transform: rotate(180deg);\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-button__state-layer {\n transition: none;\n }\n\n .md-button__trailing-icon,\n ::slotted([slot=\"trailing-icon\"]) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 10. LABEL\n ========================================================== */\n.md-button__label {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n/* ==========================================================\n 11. LOADING SPINNER (scales with icon size)\n ========================================================== */\n.md-button__loading {\n /* A FRACTION of the icon it stands in for. Two constraints pull against each\n other: at full --_icon-size the ring reads heavier than the glyph (a bare\n stroke has none of the internal padding a Material glyph carries), but at\n 1em it was pinned to the label and stopped scaling per tier -- sm and md\n share a 14px label, so a 40px and a 56px button drew the same 14px ring\n despite 20px vs 24px icons. 0.7 keeps it visibly lighter than a glyph while\n tracking the tier, and inherits the icon's density taper. */\n /* 10px floor: the icon token itself bottoms out at 10px on the small tiers,\n and 0.7 of that is a 7px ring — too small to read as a spinner at all. */\n --_loading-size: var(--md-button-loading-size, max(10px, calc(var(--_icon-size, 18px) * 0.7)));\n\n /* Hand the size straight to md-loading-indicator's PUBLIC hooks. These\n replace the child's whole default expression, so the button's own taper\n (and its 10px floor) survives instead of hitting the child's 32px floor.\n Not --_size / --_shape-size: those are the child's private vars and\n writing them from out here is the handoff trap. currentColor keeps the\n indicator matching each variant's label, which a token would not. */\n --md-loading-indicator-size: var(--_loading-size);\n --md-loading-indicator-shape-size: var(--_loading-size);\n --md-loading-indicator-color: currentColor;\n flex-shrink: 0;\n /* A wrapper now, so the hooks above reach a SLOTTED replacement too. It has\n to lay out like the indicator it replaced — an inline span would add a text\n baseline gap next to the label. */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Whatever the consumer slots in gets the same box the default occupies. */\n.md-button__loading ::slotted(*) {\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 12. MATERIAL SYMBOLS (default icon font)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 18px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 13. RTL — opt-in directional-icon mirroring\n\n Buttons that show directional Material Symbols (arrow_forward,\n chevron_right, send, reply…) should set `mirror-icon` so the\n glyph itself flips alongside the leading/trailing slot swap that\n the logical-property layout already performs. Non-directional\n icons (add, search, favorite…) leave `mirror-icon` unset so the\n glyph stays semantically correct.\n\n Two rules cover both placements of `dir=\"rtl\"`:\n (a) on the host itself — `:host([dir=\"rtl\"])`\n (b) on any ancestor element — `:host-context([dir=\"rtl\"])`\n ========================================================== */\n:host([mirror-icon][dir=\"rtl\"]) .md-button__icon,\n:host([mirror-icon][dir=\"rtl\"]) .md-button__trailing-icon,\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"leading-icon\"]),\n:host([mirror-icon][dir=\"rtl\"]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) .md-button__trailing-icon,\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"leading-icon\"]),\n:host-context([dir=\"rtl\"]):host([mirror-icon]) ::slotted([slot=\"trailing-icon\"]) {\n transform: scaleX(-1);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n LINK MODE — the anchor rendered when `href` is set\n\n The anchor wraps the button's innards so the LABEL gives it its accessible\n name, and it carries the tab stop (the host drops role/tabindex in this\n mode). It reproduces the host's own flex row rather than sitting inside it,\n so a link button lays out identically to a plain one.\n\n `::after` stretches the hit area over the host's padding: the anchor itself\n only fills the CONTENT box, so without it a click on the padding — a good\n third of a large button — would miss the link and lose native activation.\n The host is already `position: relative`, so the inset resolves to it.\n ========================================================== */\n.md-button__anchor {\n display: flex;\n align-items: center;\n justify-content: center;\n /* Not inherited by default; picking up the host's computed value keeps the\n icon/label spacing identical to a non-link button at every density. */\n gap: inherit;\n inline-size: 100%;\n block-size: 100%;\n min-inline-size: 0;\n /* A button is not underlined blue text. */\n color: inherit;\n font: inherit;\n text-decoration: none;\n outline: none;\n}\n\n.md-button__anchor::after {\n content: '';\n position: absolute;\n inset: 0;\n /* Behind the state layer and ripple so neither is occluded. */\n z-index: 0;\n}\n\n/* The focus ring belongs to the whole button, not the inner content box. */\n:host(:has(.md-button__anchor:focus-visible)) {\n outline: var(--md-sys-state-focus-ring-width, 3px) solid\n var(--md-button-focus-ring-color, var(--md-sys-color-secondary, #625B71));\n outline-offset: var(--md-sys-state-focus-ring-offset, 2px);\n}\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Fragment, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { LazyLoadingIndicator } from '../../utils/lazy-loading-indicator';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_LINK_REL, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n /* A safe href renders a REAL <a> in the shadow root, and the browser\n owns activation from there — so do nothing here. That is what makes\n middle-click, cmd/ctrl-click and \"copy link address\" work, and it is\n why cancelling mdClick above (which calls preventDefault on this very\n event) still vetoes navigation.\n\n The fallback below covers only the case where NO anchor exists: an\n href that failed sanitising renders none, so there is nothing to\n navigate and nothing to fall back to — the navigation is refused, as\n before. window.open remains for a programmatic click() on a button\n whose href is safe but whose anchor has not rendered yet. */\n const href = sanitizeHref(this.href);\n if (!href) return;\n const anchor = this.el.shadowRoot?.querySelector('.md-button__anchor');\n /* Did this click actually pass THROUGH the anchor? composedPath sees\n across the shadow boundary, so a real pointer click — on the label, an\n icon, or the anchor's stretched ::after over the padding — is\n recognised and left alone: the browser is already navigating.\n\n A PROGRAMMATIC el.click() targets the host and never reaches the\n anchor, so nothing would happen at all. A native <a>.click() does\n navigate, and this component behaved that way before it grew a real\n anchor — including keyboard activation, which routes through\n el.click() in handleKeyDown. Falling back to window.open keeps both\n working, and the composedPath check is what stops a real click from\n navigating twice. */\n if (!anchor || !e.composedPath().includes(anchor)) {\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n }\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n /* A component that accepts `href` must produce a real link. Sanitising\n here (not just at click time) means an unsafe URL renders NO anchor at\n all rather than an inert one. Disabled link-buttons also drop the\n anchor: there is no disabled state for <a>, and a focusable link that\n refuses to navigate is worse than no link. */\n const linkHref =\n this.href && !isEffectivelyDisabled ? sanitizeHref(this.href) : '';\n /* rel only where it means something: a target that opens a NEW browsing\n context. Blanket noreferrer would also strip the Referer on ordinary\n same-tab navigation, quietly breaking referrer-based analytics. */\n const opensNewContext = !!this.target && this.target !== '_self';\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || (linkHref ? null : 'button')}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n /* When a real anchor is rendered IT is the focusable element, so the\n host must not be a tab stop as well — otherwise every link button\n costs two presses of Tab and screen readers meet a button wrapping\n a link. */\n linkHref\n ? null\n : this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {linkHref ? (\n <a\n class=\"md-button__anchor\"\n part=\"anchor\"\n role=\"link\"\n href={linkHref}\n target={this.target || undefined}\n rel={opensNewContext ? SAFE_LINK_REL : undefined}\n tabindex={this.groupTabindex !== null ? String(this.groupTabindex) : '0'}\n aria-disabled={isEffectivelyDisabled ? 'true' : null}\n >\n {this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)}\n </a>\n ) : (\n this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)\n )}\n </Host>\n );\n }\n\n /** Button innards, rendered either directly in the host or inside the\n * anchor when `href` makes this a link. */\n private renderContent(\n isEffectivelyDisabled: boolean,\n hasLeadingIcon: boolean,\n hasTrailingIcon: boolean,\n ) {\n return (\n <Fragment>\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24px M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <LazyLoadingIndicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Fragment>\n );\n }\n}\n","/* ==========================================================\n md-card — Material Design 3 Card\n Spec: https://m3.material.io/components/cards/specs\n\n Three variants:\n elevated — surface-container-low + elevation 1\n filled — surface-container-highest + no elevation\n outlined — surface + outline-variant border + no elevation\n\n Measurements (MD3 spec):\n Shape: 12px corner radius (shape-corner-medium)\n Left/right padding: 16px (applied to default slot via consumer)\n Padding between: 8px max (layout concern of consumer)\n Label text: start-aligned\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-card-container-color Container background\n --md-card-container-shape Border-radius override\n --md-card-container-elevation Box-shadow override\n --md-card-outline-color Outline color (outlined variant)\n --md-card-outline-width Outline width (outlined variant)\n --md-card-state-layer-color State layer color override\n --md-card-width Explicit inline-size (default: auto)\n --md-card-min-width Minimum inline-size\n --md-card-max-width Maximum inline-size\n --md-card-height Explicit block-size (default: auto)\n --md-card-min-height Minimum block-size\n --md-card-max-height Maximum block-size\n\n ATTRIBUTES:\n full-width Stretch the card to 100% of its container's inline-size\n full-height Stretch the card to 100% of its container's block-size\n\n CSS PARTS:\n state-layer Hover/press overlay (interactive only)\n outline Border element (outlined variant only)\n\n SLOTS:\n (default) Card content (images, text, actions, other components)\n ========================================================== */\n\n:host {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-low));\n --_container-shape: var(--md-card-container-shape, var(--md-sys-shape-corner-medium, max(8px, calc(12px + var(--md-sys-density-scale, 0) * 1px))));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-1));\n --_outline-color: var(--md-card-outline-color, var(--md-sys-color-outline-variant));\n --_outline-width: var(--md-card-outline-width, 1px);\n --_state-layer-color: var(--md-card-state-layer-color, var(--md-sys-color-on-surface));\n\n --_width: var(--md-card-width, auto);\n --_min-width: var(--md-card-min-width, auto);\n --_max-width: var(--md-card-max-width, none);\n --_height: var(--md-card-height, auto);\n --_min-height: var(--md-card-min-height, auto);\n --_max-height: var(--md-card-max-height, none);\n\n --_padding: var(--md-card-padding, max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px)));\n --_gap: var(--md-card-gap, max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px)));\n\n display: flex;\n flex-direction: column;\n position: relative;\n box-sizing: border-box;\n overflow: hidden;\n padding: var(--_padding);\n gap: var(--_gap);\n\n inline-size: var(--_width);\n min-inline-size: var(--_min-width);\n max-inline-size: var(--_max-width);\n block-size: var(--_height);\n min-block-size: var(--_min-height);\n max-block-size: var(--_max-height);\n\n background-color: var(--_container-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--_container-elevation);\n color: var(--md-sys-color-on-surface);\n\n /* MD3 body-medium typescale — set on :host so it inherits through to\n slotted content (which lives in light DOM and only inherits from the\n host element, not from shadow-DOM rules). Without this, slotted\n headings / paragraphs fall back to the user-agent font (typically\n Times) instead of the Roboto-based MD3 typescale.\n NOTE: never use `--md-sys-typescale-*-font` for `font-family` — that\n token is the `font` shorthand (e.g. `400 14px/20px Roboto, sans-serif`)\n and is invalid for `font-family`, which silently kills the rule. */\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-medium-font-weight, 400);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing, 0.25px);\n\n transition:\n box-shadow var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n FULL-WIDTH / FULL-HEIGHT attributes\n `100%` only resolves when the parent has a definite size on\n that axis, so consumers must place the card inside a flex /\n grid item or a sized block container. Combined with the\n `--md-card-max-{width,height}` tokens this gives a fluid\n \"fill but cap\" pattern useful in dashboards and grids.\n ========================================================== */\n\n:host(.md-card--full-width) {\n --_width: 100%;\n}\n\n:host(.md-card--full-height) {\n --_height: 100%;\n}\n\n/* ==========================================================\n 1. VARIANTS\n ========================================================== */\n\n/* Elevated (default) */\n:host(.md-card--elevated) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-low));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-1));\n}\n\n/* Filled */\n:host(.md-card--filled) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface-container-highest));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-0, none));\n}\n\n/* Outlined */\n:host(.md-card--outlined) {\n --_container-color: var(--md-card-container-color, var(--md-sys-color-surface));\n --_container-elevation: var(--md-card-container-elevation, var(--md-sys-elevation-0, none));\n}\n\n/* ==========================================================\n 2. OUTLINE (outlined variant only)\n ========================================================== */\n\n.md-card__outline {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n border: var(--_outline-width) solid var(--_outline-color);\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. INTERACTIVE & DRAGGABLE STATES\n Interactive cards behave like buttons with state layers.\n Draggable cards support native HTML drag-and-drop with\n the dragged state layer and elevation changes.\n ========================================================== */\n\n:host(.md-card--interactive) {\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n:host(.md-card--draggable) {\n cursor: grab;\n touch-action: none;\n -webkit-tap-highlight-color: transparent;\n user-select: none;\n}\n\n:host(.md-card--interactive.md-card--draggable) {\n cursor: grab;\n}\n\n:host(.md-card--dragged) {\n cursor: grabbing;\n}\n\n/* --- State layer --- */\n\n.md-card__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short1, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n z-index: 1;\n}\n\n:host(.md-card--interactive:hover) .md-card__state-layer,\n:host(.md-card--draggable:hover) .md-card__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-card--interactive:focus-visible) .md-card__state-layer,\n:host(.md-card--draggable:focus-visible) .md-card__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n:host(.md-card--interactive:active) .md-card__state-layer,\n:host(.md-card--draggable:active) .md-card__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(.md-card--dragged) .md-card__state-layer {\n opacity: var(--md-sys-state-dragged-state-layer-opacity, 0.16);\n}\n\n/* --- Elevation changes for elevated cards (interactive / draggable) --- */\n\n:host(.md-card--elevated.md-card--interactive:hover),\n:host(.md-card--elevated.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-2);\n}\n\n:host(.md-card--elevated.md-card--interactive:focus-visible),\n:host(.md-card--elevated.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--elevated.md-card--interactive:active),\n:host(.md-card--elevated.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--elevated.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-4);\n}\n\n/* --- Elevation changes for filled cards (interactive / draggable) --- */\n\n:host(.md-card--filled.md-card--interactive:hover),\n:host(.md-card--filled.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--filled.md-card--interactive:focus-visible),\n:host(.md-card--filled.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--filled.md-card--interactive:active),\n:host(.md-card--filled.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--filled.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-3);\n}\n\n/* --- Elevation changes for outlined cards (interactive / draggable) --- */\n\n:host(.md-card--outlined.md-card--interactive:hover),\n:host(.md-card--outlined.md-card--draggable:hover) {\n --_container-elevation: var(--md-sys-elevation-1);\n}\n\n:host(.md-card--outlined.md-card--interactive:focus-visible),\n:host(.md-card--outlined.md-card--draggable:focus-visible) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--outlined.md-card--interactive:active),\n:host(.md-card--outlined.md-card--draggable:active) {\n --_container-elevation: var(--md-sys-elevation-0, none);\n}\n\n:host(.md-card--outlined.md-card--dragged) {\n --_container-elevation: var(--md-sys-elevation-3);\n}\n\n/* --- Outline state for outlined cards (interactive / draggable) --- */\n\n:host(.md-card--outlined.md-card--interactive:focus-visible) .md-card__outline,\n:host(.md-card--outlined.md-card--draggable:focus-visible) .md-card__outline {\n border-color: var(--md-sys-color-on-surface);\n}\n\n:host(.md-card--outlined.md-card--dragged) .md-card__outline {\n border-color: var(--md-sys-color-outline-variant);\n}\n\n/* ==========================================================\n 4. FOCUS RING (interactive only)\n ========================================================== */\n\n:host(.md-card--interactive:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: 2px;\n}\n\n/* ==========================================================\n 5. DISABLED (interactive only)\n ========================================================== */\n\n:host(.md-card--disabled) {\n cursor: default;\n pointer-events: none;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-card--disabled.md-card--outlined) .md-card__outline {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-card--disabled:hover) .md-card__state-layer,\n:host(.md-card--disabled:active) .md-card__state-layer,\n:host(.md-card--disabled:focus-visible) .md-card__state-layer {\n opacity: 0;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n --_container-elevation: var(--md-sys-elevation-0, none) !important;\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled]) .md-card__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 6. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-card__state-layer {\n transition: none;\n }\n}\n\n/* ==========================================================\n 7. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n border: 1px solid ButtonText;\n background-color: ButtonFace;\n color: ButtonText;\n forced-color-adjust: none;\n }\n\n .md-card__outline {\n border-color: ButtonText;\n }\n\n :host(.md-card--interactive:focus-visible) {\n outline-color: Highlight;\n }\n\n :host(.md-card--disabled) {\n border-color: GrayText;\n color: GrayText;\n opacity: 1;\n }\n\n :host(.md-card--disabled) .md-card__outline {\n border-color: GrayText;\n }\n\n .md-card__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Watch } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\n\nexport interface MdCardDragDetail {\n /** Pointer X in viewport coordinates */\n clientX: number;\n /** Pointer Y in viewport coordinates */\n clientY: number;\n /** Horizontal distance from the drag start point */\n offsetX: number;\n /** Vertical distance from the drag start point */\n offsetY: number;\n /** X where the drag gesture began */\n startX: number;\n /** Y where the drag gesture began */\n startY: number;\n}\n\n@Component({ tag: 'md-card', styleUrl: 'md-card.css', shadow: true })\nexport class MdCard {\n @Element() el!: HTMLElement;\n\n /** Visual style variant */\n @Prop() variant: 'elevated' | 'filled' | 'outlined' = 'elevated';\n\n /**\n * Makes the card interactive (clickable, with ripple and state layers).\n *\n * When the card's own content has no focusable controls the host exposes\n * `role=\"button\"` + `tabindex` and is keyboard-activatable. If the content\n * *does* include its own focusable controls (buttons, links, form fields,\n * interactive `md-*` components) the host does not claim `role=\"button\"` —\n * that would be a `nested-interactive` a11y violation — and instead stays a\n * plain container that is still mouse-clickable (emits `mdClick`) while the\n * inner controls remain the keyboard tab stops.\n */\n @Prop({ reflect: true }) interactive: boolean = false;\n\n /** Enables pointer-event-based drag on the card */\n @Prop({ reflect: true, attribute: 'drag-enabled' }) dragEnabled: boolean = false;\n\n /** Disables the card — only meaningful when interactive */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable — only meaningful when interactive */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Whether the ripple effect is enabled when interactive */\n @Prop() ripple: boolean = true;\n\n /**\n * When `true` the card stretches to 100% of its container's inline-size.\n * Pair with the `--md-card-max-width` custom property to cap the fluid\n * width (useful inside dashboards and responsive grids).\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /**\n * When `true` the card stretches to 100% of its container's block-size.\n * The parent must have a definite block-size (e.g. a fixed height row in\n * a CSS grid, or a flex item with `align-items: stretch`) for `100%` to\n * resolve.\n */\n @Prop({ reflect: true, attribute: 'full-height' }) fullHeight: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Emits when an interactive card is clicked or activated via keyboard */\n @Event() mdClick: EventEmitter<MouseEvent>;\n\n /** Emits once when a draggable card starts being dragged (after crossing the movement threshold) */\n @Event() mdDragStart: EventEmitter<MdCardDragDetail>;\n\n /** Emits continuously as a dragged card moves — use for drop-zone detection or position tracking */\n @Event() mdDragMove: EventEmitter<MdCardDragDetail>;\n\n /** Emits when a draggable card is released after dragging */\n @Event() mdDragEnd: EventEmitter<MdCardDragDetail>;\n\n @State() private dragging = false;\n\n /**\n * True when the default slot contains its own focusable/interactive\n * descendants (buttons, links, form controls, or interactive `md-*`\n * components).\n *\n * An interactive card that wraps such controls must NOT expose itself as a\n * single `role=\"button\"`: a `button` has \"children presentational\" per\n * WAI-ARIA, so nesting focusable content inside it is a `nested-interactive`\n * violation and hides the inner controls from assistive tech. In that case\n * the host degrades to a plain (still mouse-clickable) container and the\n * inner controls remain the real tab stops — mirroring the `md-list-item`\n * rule of keeping a container role \"rather than masquerading as a button\".\n */\n @State() private hasInteractiveContent = false;\n\n private startX = 0;\n private startY = 0;\n private dragStarted = false;\n private suppressClick = false;\n private contentObserver: MutationObserver | null = null;\n\n private static readonly DRAG_THRESHOLD = 5;\n\n /**\n * Widget-role focusables whose presence makes the host stop masquerading as\n * a button. Covers the descendants axe's `nested-interactive` rule counts\n * (native controls + explicit interactive ARIA roles), plus the library's\n * own interactive components — those project their real focusable control\n * into a shadow root, so a light-DOM native-focusable scan cannot see them\n * and they must be matched by tag name.\n */\n private static readonly INTERACTIVE_CONTENT_SELECTOR = [\n 'a[href]', 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])', 'textarea:not([disabled])',\n 'audio[controls]', 'video[controls]', 'iframe',\n '[contenteditable=\"true\"]', '[contenteditable=\"\"]',\n '[role=\"button\"]', '[role=\"link\"]', '[role=\"checkbox\"]', '[role=\"radio\"]',\n '[role=\"switch\"]', '[role=\"tab\"]', '[role=\"menuitem\"]',\n '[role=\"menuitemcheckbox\"]', '[role=\"menuitemradio\"]', '[role=\"option\"]',\n '[role=\"slider\"]', '[role=\"spinbutton\"]', '[role=\"textbox\"]',\n '[role=\"combobox\"]', '[role=\"searchbox\"]',\n 'md-button', 'md-icon-button', 'md-fab', 'md-checkbox', 'md-switch',\n 'md-radio', 'md-chip', 'md-select', 'md-multi-select', 'md-text-field',\n 'md-slider', 'md-segmented-button', 'md-menu-button', 'md-link',\n 'md-autocomplete',\n ].join(',');\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n connectedCallback() {\n this.el.addEventListener('pointerdown', this.onPointerDown);\n }\n\n componentWillLoad() {\n // Initial (deep) scan BEFORE the first render — querySelectorAll traverses\n // the whole light-DOM subtree (present at connect time for declarative\n // markup), so `hasInteractiveContent` is already settled when render() first\n // computes `role`/`tabindex`. Doing this here (not in componentDidLoad)\n // guarantees an interactive card wrapping focusable content NEVER paints a\n // transient `role=\"button\"` around it — the nested-interactive window that a\n // pre-hydration snapshot (SSR / jsdom, where `slotchange` hasn't fired yet)\n // would otherwise catch — and avoids Stencil's \"state changed during\n // componentDidLoad → extra re-render\" warning.\n this.detectInteractiveContent();\n }\n\n componentDidLoad() {\n // A late deep scan catches any focusable content that only became present\n // between componentWillLoad and mount; the guard inside\n // detectInteractiveContent makes this a no-op (no re-render) when the state\n // is already correct.\n this.detectInteractiveContent();\n // slotchange only fires for top-level slottable add/remove; a MutationObserver\n // (subtree) additionally catches controls added/removed deep inside slotted\n // wrappers after mount. Matches the md-list-item light-DOM observer pattern.\n if (typeof MutationObserver !== 'undefined') {\n this.contentObserver = new MutationObserver(this.detectInteractiveContent);\n this.contentObserver.observe(this.el, { childList: true, subtree: true });\n }\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('pointerdown', this.onPointerDown);\n this.contentObserver?.disconnect();\n this.contentObserver = null;\n this.cancelDrag();\n }\n\n @Watch('dragEnabled')\n onDragEnabledChange() {\n if (!this.dragEnabled) this.cancelDrag();\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (!this.dragEnabled || this.isDisabled || e.button !== 0) return;\n\n this.startX = e.clientX;\n this.startY = e.clientY;\n this.dragStarted = false;\n\n this.el.setPointerCapture(e.pointerId);\n this.el.addEventListener('pointermove', this.onPointerMove);\n this.el.addEventListener('pointerup', this.onPointerUp);\n this.el.addEventListener('pointercancel', this.onPointerUp);\n };\n\n private buildDetail(e: PointerEvent): MdCardDragDetail {\n return {\n clientX: e.clientX,\n clientY: e.clientY,\n offsetX: e.clientX - this.startX,\n offsetY: e.clientY - this.startY,\n startX: this.startX,\n startY: this.startY,\n };\n }\n\n private onPointerMove = (e: PointerEvent) => {\n const dx = e.clientX - this.startX;\n const dy = e.clientY - this.startY;\n\n if (!this.dragStarted) {\n if (Math.abs(dx) + Math.abs(dy) < MdCard.DRAG_THRESHOLD) return;\n this.dragStarted = true;\n this.dragging = true;\n this.el.style.zIndex = '1000';\n this.mdDragStart.emit(this.buildDetail(e));\n }\n\n this.el.style.transform = `translate(${dx}px, ${dy}px)`;\n this.mdDragMove.emit(this.buildDetail(e));\n };\n\n private onPointerUp = (e: PointerEvent) => {\n if (this.dragStarted) {\n this.suppressClick = true;\n requestAnimationFrame(() => { this.suppressClick = false; });\n this.mdDragEnd.emit(this.buildDetail(e));\n }\n\n this.resetDragVisuals();\n this.cleanupListeners();\n };\n\n private cancelDrag() {\n this.resetDragVisuals();\n this.cleanupListeners();\n }\n\n private resetDragVisuals() {\n this.dragging = false;\n this.dragStarted = false;\n this.el.style.transform = '';\n this.el.style.zIndex = '';\n }\n\n private cleanupListeners() {\n this.el.removeEventListener('pointermove', this.onPointerMove);\n this.el.removeEventListener('pointerup', this.onPointerUp);\n this.el.removeEventListener('pointercancel', this.onPointerUp);\n }\n\n private handleClick = (e: MouseEvent) => {\n if (!this.interactive) return;\n if (this.suppressClick) return;\n if (this.isDisabled) { e.preventDefault(); return; }\n this.mdClick.emit(e);\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (!this.interactive || this.isDisabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n triggerRipple(this.el);\n this.el.click();\n }\n };\n\n /**\n * Re-evaluate whether the slotted content contains its own focusable\n * controls. `this.el.querySelectorAll` searches the light-DOM subtree (the\n * slotted content) only — never the shadow root — so the card's internal\n * state-layer / ripple / outline nodes are correctly ignored.\n */\n private detectInteractiveContent = () => {\n const found =\n this.el.querySelectorAll(MdCard.INTERACTIVE_CONTENT_SELECTOR).length > 0;\n if (found !== this.hasInteractiveContent) this.hasInteractiveContent = found;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n\n /* A card only exposes single `role=\"button\"` semantics when it is the sole\n action — i.e. it does NOT wrap its own focusable controls. A button may\n not contain focusable content (WAI-ARIA \"children presentational\"), so an\n interactive card that holds buttons/links/form controls keeps a plain\n container role instead of masquerading as one giant button. It stays\n mouse-clickable (host `onClick` → `mdClick`) and visually interactive, but\n the inner controls are the real keyboard tab stops. */\n const actsAsButton = this.interactive && !this.hasInteractiveContent;\n\n return (\n <Host\n class={{\n 'md-card': true,\n [`md-card--${this.variant}`]: true,\n 'md-card--interactive': this.interactive,\n 'md-card--draggable': this.dragEnabled,\n 'md-card--disabled': this.interactive && isEffectivelyDisabled,\n 'md-card--dragged': this.dragging,\n 'md-card--full-width': this.fullWidth,\n 'md-card--full-height': this.fullHeight,\n }}\n role={actsAsButton ? 'button' : undefined}\n aria-disabled={actsAsButton && isEffectivelyDisabled ? 'true' : undefined}\n aria-grabbed={this.dragEnabled ? (this.dragging ? 'true' : 'false') : undefined}\n tabindex={actsAsButton ? (this.disabled ? '-1' : '0') : undefined}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n {(this.interactive || this.dragEnabled) && this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n {(this.interactive || this.dragEnabled) && <span class=\"md-card__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>}\n {this.variant === 'outlined' && <span class=\"md-card__outline\" part=\"outline\" aria-hidden=\"true\"></span>}\n <slot onSlotchange={this.detectInteractiveContent} />\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-icon-button — Material Design 3 Icon Button\n Spec: https://m3.material.io/components/icon-buttons/specs\n Supports M3 + M3 Expressive (size, shape, width)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-icon-button-container-color Container background\n --md-icon-button-icon-color Icon color\n --md-icon-button-state-layer-color State-layer ink (hover / focus / press)\n --md-icon-button-icon-size Icon dimensions\n --md-icon-button-container-shape Border-radius override\n --md-icon-button-outline-color Outlined border color\n --md-icon-button-outline-width Outlined border width\n --md-icon-button-container-width Container width override\n --md-icon-button-container-height Container height override\n\n CSS PARTS:\n state-layer State-layer overlay\n icon Default icon wrapper\n selected-icon Selected icon wrapper (toggle)\n\n SLOTS:\n (default) Custom icon content\n selected Custom selected icon (toggle)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — shared base\n ========================================================== */\n:host {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_shape-round: 20px;\n --_border-radius: var(--md-icon-button-container-shape, var(--_shape-round));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: var(--_container-width);\n height: var(--_container-height);\n /* Resting radius is --_border-radius; --_morph-to carries the morphed target\n and defaults to the resting value. calc(REST + FLAG * (MORPH - REST)) is\n MORPH at flag 1 and REST at flag 0, so `data-shape-morph=\"off\"` /\n `shape-morph=\"off\"` (§13 tokens.css) freezes the shape with no re-render. */\n border-radius: calc(var(--_border-radius) + var(--md-sys-shape-morph-enabled, 1) * (var(--_morph-to, var(--_border-radius)) - var(--_border-radius)));\n cursor: pointer;\n user-select: none;\n border: none;\n outline: none;\n overflow: hidden;\n box-sizing: border-box;\n background-color: var(--_container-color);\n color: var(--_icon-color);\n -webkit-tap-highlight-color: transparent;\n transition:\n background-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n flex-shrink: 0;\n vertical-align: middle;\n}\n\n/* ==========================================================\n 2. SIZE — M3 Expressive\n XS (32px) · SM (40px, default) · MD (56px) · LG (96px) · XL (136px)\n ========================================================== */\n:host(.md-icon-button--xs) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 16px;\n}\n:host(.md-icon-button--sm) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 20px;\n}\n:host(.md-icon-button--md) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_shape-round: 28px;\n}\n:host(.md-icon-button--lg) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(96px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(96px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_shape-round: 48px;\n}\n:host(.md-icon-button--xl) {\n --_container-width: var(--md-icon-button-container-width, max(32px, calc(136px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-height: var(--md-icon-button-container-height, max(32px, calc(136px + var(--md-sys-density-scale, 0) * 4px)));\n --_icon-size: var(--md-icon-button-icon-size, max(28px, calc(40px + var(--md-sys-density-scale, 0) * 3px)));\n --_shape-round: 68px;\n}\n\n/* ==========================================================\n 3. WIDTH — M3 Expressive\n Narrow (less horizontal padding) · Default (square) · Wide (more horizontal padding)\n Width = iconSize + leadingSpace + trailingSpace; height stays unchanged.\n ========================================================== */\n:host(.md-icon-button--width-narrow.md-icon-button--xs) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(28px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--sm) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(32px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--md) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--lg) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(64px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-narrow.md-icon-button--xl) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(104px + var(--md-sys-density-scale, 0) * 4px))); }\n\n:host(.md-icon-button--width-wide.md-icon-button--xs) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--sm) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(52px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--md) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(72px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--lg) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(128px + var(--md-sys-density-scale, 0) * 4px))); }\n:host(.md-icon-button--width-wide.md-icon-button--xl) { --_container-width: var(--md-icon-button-container-width, max(32px, calc(184px + var(--md-sys-density-scale, 0) * 4px))); }\n\n/* ==========================================================\n 4. SHAPE — Round (default) · Square (scaled corner radius)\n Round uses --_shape-round (height/2 per size) instead of\n corner-full (9999px) so the browser can smoothly interpolate\n border-radius transitions between resting and morphed states.\n ========================================================== */\n:host(.md-icon-button--round) {\n --_border-radius: var(--md-icon-button-container-shape, var(--_shape-round));\n}\n:host(.md-icon-button--square.md-icon-button--xs) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); }\n:host(.md-icon-button--square.md-icon-button--sm) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-medium, 12px)); }\n:host(.md-icon-button--square.md-icon-button--md) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-large, 16px)); }\n:host(.md-icon-button--square.md-icon-button--lg) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); }\n:host(.md-icon-button--square.md-icon-button--xl) { --_border-radius: var(--md-icon-button-container-shape, var(--md-sys-shape-corner-extra-large, 28px)); }\n\n/* ==========================================================\n 5. SHAPE MORPHING — M3 Expressive\n Uses direct border-radius overrides (not CSS variable changes)\n for reliable browser-animated transitions.\n\n Order matters: selected rules FIRST, pressed rules LAST so\n pressed always wins while the pointer is down.\n\n Asymmetric timing (both via M3 motion tokens):\n Release / selected : medium4 (400ms) + emphasized-decelerate\n Press-in : short4 (200ms) + standard\n ========================================================== */\n\n/* ── Selected shape — round resting → square tokens when selected ── */\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--xs) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--sm) { --_morph-to: var(--md-sys-shape-corner-medium, 12px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--md) { --_morph-to: var(--md-sys-shape-corner-large, 16px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--lg) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n:host(.md-icon-button--shape-morph.md-icon-button--round.md-icon-button--selected.md-icon-button--xl) { --_morph-to: var(--md-sys-shape-corner-extra-large, 28px); }\n\n/* ── Selected shape — square resting → round when selected ── */\n:host(.md-icon-button--shape-morph.md-icon-button--square.md-icon-button--selected) { --_morph-to: var(--_shape-round); }\n\n/* ── Pressed shape — same for both round & square, overrides selected ── */\n:host(.md-icon-button--pressed.md-icon-button--xs) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--sm) {\n --_morph-to: var(--md-sys-shape-corner-small, 8px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--md) {\n --_morph-to: var(--md-sys-shape-corner-medium, 12px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--lg) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n:host(.md-icon-button--pressed.md-icon-button--xl) {\n --_morph-to: var(--md-sys-shape-corner-large, 16px);\n transition-duration: var(--md-sys-motion-duration-short4, 200ms);\n transition-timing-function: var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ── Narrow pressed — slightly longer duration for smaller surface area ── */\n:host(.md-icon-button--width-narrow.md-icon-button--pressed) {\n transition-duration: var(--md-sys-motion-duration-medium1, 250ms);\n}\n\n/* ==========================================================\n 5b. CONNECTED GROUP — per-corner border-radius\n Set by md-button-group when variant=\"connected\".\n shapeMorph is disabled for connected children so these rules\n only need to beat the base shape rules (section 4, specificity 0-1-0).\n ========================================================== */\n\n:host(.md-icon-button--connected-left.md-icon-button--xs),\n:host(.md-icon-button--connected-right.md-icon-button--xs) { --_c-inner: 4px; }\n:host(.md-icon-button--connected-left.md-icon-button--sm),\n:host(.md-icon-button--connected-right.md-icon-button--sm) { --_c-inner: 8px; }\n:host(.md-icon-button--connected-left.md-icon-button--md),\n:host(.md-icon-button--connected-right.md-icon-button--md) { --_c-inner: 8px; }\n:host(.md-icon-button--connected-left.md-icon-button--lg),\n:host(.md-icon-button--connected-right.md-icon-button--lg) { --_c-inner: 16px; }\n:host(.md-icon-button--connected-left.md-icon-button--xl),\n:host(.md-icon-button--connected-right.md-icon-button--xl) { --_c-inner: 20px; }\n\n/* Middle button — all corners inner */\n:host(.md-icon-button--connected-left.md-icon-button--connected-right) {\n border-radius: var(--_c-inner);\n}\n\n/* `connected-left` / `connected-right` reflect DOM-order siblings (set by\n md-button-group when a previous / next sibling exists), so the radii\n here must use logical corner properties to flip correctly under\n `dir=\"rtl\"`. The outer pill always lives on the free inline-start\n (first child) or inline-end (last child) edge. */\n\n/* First button (round) — pill on inline-start edge, inner on inline-end edge */\n:host(.md-icon-button--round.md-icon-button--connected-right:not(.md-icon-button--connected-left)) {\n border-start-start-radius: var(--_shape-round);\n border-end-start-radius: var(--_shape-round);\n border-start-end-radius: var(--_c-inner);\n border-end-end-radius: var(--_c-inner);\n}\n\n/* Last button (round) — inner on inline-start edge, pill on inline-end edge */\n:host(.md-icon-button--round.md-icon-button--connected-left:not(.md-icon-button--connected-right)) {\n border-start-start-radius: var(--_c-inner);\n border-end-start-radius: var(--_c-inner);\n border-start-end-radius: var(--_shape-round);\n border-end-end-radius: var(--_shape-round);\n}\n\n/* Square first / last — outer equals inner */\n:host(.md-icon-button--square.md-icon-button--connected-right:not(.md-icon-button--connected-left)),\n:host(.md-icon-button--square.md-icon-button--connected-left:not(.md-icon-button--connected-right)) {\n border-radius: var(--_c-inner);\n}\n\n/* ==========================================================\n 6. COLOR VARIANTS\n ========================================================== */\n\n/* ── Standard ── */\n:host(.md-icon-button--standard) {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n}\n:host(.md-icon-button--standard.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-primary, #6750A4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-primary, #6750A4));\n}\n\n/* The toggle / selected rules below all carry `:not(.md-icon-button--disabled)`\n so they drop out when the host becomes disabled. Without it, their higher\n specificity (3+ classes vs the disabled rules' 2) would override the muted\n disabled palette and the button would still look enabled. */\n\n/* ── Filled (non-toggle) ── */\n:host(.md-icon-button--filled) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-primary, #6750A4));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-primary, #FFFFFF));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-primary, #FFFFFF));\n}\n/* Filled toggle unselected */\n:host(.md-icon-button--filled.md-icon-button--toggle:not(.md-icon-button--selected):not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-primary, #6750A4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-primary, #6750A4));\n}\n/* Filled toggle selected */\n:host(.md-icon-button--filled.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-primary, #6750A4));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-primary, #FFFFFF));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-primary, #FFFFFF));\n}\n\n/* ── Tonal (non-toggle) ── */\n:host(.md-icon-button--tonal) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-secondary-container, #1E192B));\n}\n/* Tonal toggle unselected */\n:host(.md-icon-button--tonal.md-icon-button--toggle:not(.md-icon-button--selected):not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-surface-container-highest, #E6E0E9));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n}\n/* Tonal toggle selected */\n:host(.md-icon-button--tonal.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-secondary-container, #E8DEF8));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-secondary-container, #1E192B));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-secondary-container, #1E192B));\n}\n\n/* ── Outlined ── */\n:host(.md-icon-button--outlined) {\n --_container-color: var(--md-icon-button-container-color, transparent);\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-on-surface-variant, #49454F));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-on-surface-variant, #49454F));\n border: var(--md-icon-button-outline-width, 1px) solid var(--md-icon-button-outline-color, var(--md-sys-color-outline, #79747E));\n}\n:host(.md-icon-button--outlined.md-icon-button--selected:not(.md-icon-button--disabled)) {\n --_container-color: var(--md-icon-button-container-color, var(--md-sys-color-inverse-surface, #313033));\n --_icon-color: var(--md-icon-button-icon-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_state-layer-color: var(--md-icon-button-state-layer-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n border-color: transparent;\n}\n\n/* ==========================================================\n 7. STATE LAYER\n ========================================================== */\n.md-icon-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n:host(:hover) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n:host(:active) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n:host(:focus-visible) .md-icon-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 8. FOCUS RING\n `z-index: 1` raises the focused button above its siblings so the\n outline draws on top of any neighbor instead of being clipped —\n important inside md-button-group, where connected groups have\n only 2px between buttons and standard groups animate neighbor\n width on press. The 2px outline-offset is preserved so the ring\n gets the same breathing room it has on a stand-alone button.\n ========================================================== */\n:host(:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary, #625B71);\n outline-offset: 2px;\n z-index: 1;\n}\n\n/* ==========================================================\n 9. DISABLED\n ========================================================== */\n:host(.md-icon-button--disabled) {\n cursor: default;\n pointer-events: none;\n}\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n:host([soft-disabled]) .md-icon-button__state-layer { display: none; }\n\n/* Disabled colors — standard & outlined */\n:host(.md-icon-button--standard.md-icon-button--disabled),\n:host(.md-icon-button--outlined.md-icon-button--disabled) {\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n:host(.md-icon-button--outlined.md-icon-button--disabled) {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n/* Disabled colors — filled & tonal */\n:host(.md-icon-button--filled.md-icon-button--disabled),\n:host(.md-icon-button--tonal.md-icon-button--disabled) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface, #1C1B1F) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n/* Kill state layers when disabled */\n:host(.md-icon-button--disabled:hover) .md-icon-button__state-layer,\n:host(.md-icon-button--disabled:active) .md-icon-button__state-layer,\n:host(.md-icon-button--disabled:focus-visible) .md-icon-button__state-layer {\n opacity: 0;\n}\n\n/* ==========================================================\n 10. ICON WRAPPER\n ========================================================== */\n.md-icon-button__icon {\n display: none;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n color: inherit;\n width: var(--_icon-size);\n height: var(--_icon-size);\n /* Collapse whitespace text nodes assigned to the default slot (Lit indentation). */\n font-size: 0;\n line-height: 0;\n}\n/* Restore a real glyph size on slotted content so a bare emoji/text node in the\n default slot renders at icon size (the wrapper's font-size:0 above would\n otherwise collapse it to invisible). Slotted md-icon elements set their own\n size, so this only takes effect for text-node content. */\n.md-icon-button__icon slot {\n font-size: var(--_icon-size);\n line-height: 1;\n}\n.md-icon-button__icon--on {\n display: inline-flex;\n}\n\n/* ==========================================================\n 11. ICON FONT (inside shadow)\n ========================================================== */\n.md-icon-button__icon-font {\n font-size: var(--_icon-size);\n width: var(--_icon-size);\n height: var(--_icon-size);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n/* A slotted badge anchors OUTSIDE the button's box — it is translated by\n (50%, -50%) so it straddles the corner. The host's `overflow: hidden` above\n exists to keep the ripple and state layer inside the rounded shape, but it\n also clipped the badge into a blob with a bite out of it.\n Both overlays clip themselves instead (inset: 0 + border-radius: inherit —\n md-ripple's own host inherits the radius too), so the host can let the badge\n escape without either leaking past the corners. */\n:host(.md-icon-button--has-badge) {\n overflow: visible;\n}\n\n:host(.md-icon-button--has-badge) .md-icon-button__state-layer {\n overflow: hidden;\n}\n\n/* ==========================================================\n 12. SLOTTED ICONS\n ========================================================== */\n/* NOT badges. A custom property inside ::slotted() resolves in the SLOTTED\n element's own scope, and md-badge defines its own `--_icon-size` (10px, for\n its glyph). So `height: var(--_icon-size) !important` here picked up the\n BADGE's 10px instead of this component's icon size and, being !important,\n beat the badge's own 16px — squashing every badge slotted onto an icon\n button / avatar / menu item into a 10px blob. A badge is not an icon; it\n sizes itself.\n\n NOT avatars either, for the same reason: an account button is an avatar\n inside a button, and the avatar's own `size` (or --md-avatar-size) is the\n whole point. Forcing it to --_icon-size shrank a 32px avatar to the ~19px\n glyph box. */\n::slotted(*:not(md-badge):not(md-avatar)) {\n width: var(--_icon-size) !important;\n height: var(--_icon-size) !important;\n font-size: var(--_icon-size) !important;\n color: inherit !important;\n fill: currentColor !important;\n /* Center the glyph inside the slot's sized box. Without these four\n declarations, an inline-text glyph (emoji, icon-font character) sits at\n the box's text baseline — producing a visible bottom-left offset that\n gets worse at larger sizes (md / lg / xl). The prop-based\n `.md-icon-button__icon-font` already centers via the same flex triple +\n line-height reset; keep them in lockstep so slotted and prop-based icons\n render identically. */\n display: inline-flex !important;\n align-items: center !important;\n justify-content: center !important;\n line-height: 1 !important;\n}\n\n/* ==========================================================\n 13. MATERIAL SYMBOLS (icon font inside shadow root)\n ========================================================== */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_icon-size, 24px);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 14. FORCED COLORS — Windows High Contrast\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n :host(.md-icon-button--outlined) {\n border-color: ButtonText;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n@Component({\n tag: 'md-icon-button',\n styleUrl: 'md-icon-button.css',\n shadow: true,\n})\nexport class MdIconButton {\n @Element() el!: HTMLElement;\n\n /** Visual style variant */\n @Prop() variant: 'standard' | 'filled' | 'outlined' | 'tonal' = 'standard';\n\n /** M3 Expressive size */\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n\n /** Container shape */\n @Prop() shape: 'round' | 'square' = 'round';\n\n /** M3 Expressive width (narrow, default, wide) */\n @Prop() buttonWidth: 'narrow' | 'default' | 'wide' = 'default';\n\n /** Prevents interaction and removes from tab order */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Visually disabled but remains focusable for discoverability */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /** Whether to show the ripple effect */\n @Prop() ripple: boolean = true;\n\n /** Material Symbols icon name */\n @Prop() icon: string = '';\n\n /** Icon shown when selected in toggle mode */\n @Prop() selectedIcon: string = '';\n\n /** Turns the button into a link */\n @Prop() href: string = '';\n\n /** Link target attribute */\n @Prop() target: string = '_self';\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group form association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires on pointer or keyboard activation. Detail includes toggle `selected` state. */\n @Event({ bubbles: true, composed: true })\n mdClick!: EventEmitter<{ selected: boolean }>;\n\n @State() private hasSlottedIcon = false;\n /** A badge is slotted in — the host must stop clipping so it can straddle\n * the corner. `:host(:has(md-badge))` does not match light-DOM children, so\n * the presence is tracked here and expressed as a host class. */\n @State() private hasSlottedBadge = false;\n @State() private hasSlottedSelected = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n componentWillLoad() {\n this.syncSlottedIcons();\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const iconSlot = shadow.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const selectedSlot = shadow.querySelector('slot[name=\"selected\"]') as HTMLSlotElement | null;\n\n this.syncSlottedIcons();\n iconSlot?.addEventListener('slotchange', () => this.syncSlottedIcons());\n selectedSlot?.addEventListener('slotchange', () => this.syncSlottedIcons());\n }\n\n /** Ignore whitespace-only text nodes (e.g. Lit template indentation) when detecting slots. */\n private hasMeaningfulSlotContent(slot: HTMLSlotElement | null): boolean {\n if (!slot) return false;\n return slot.assignedNodes().some((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n // A badge is an ADORNMENT anchored to the button, not the button's\n // icon. Counting it here made `hasSlottedIcon` true, which suppresses\n // the `icon` prop's glyph — so the documented pattern (an icon button\n // with a count badge) rendered the badge and NO icon at all.\n if ((node as Element).tagName.toLowerCase() === 'md-badge') return false;\n return true;\n }\n if (node.nodeType === Node.TEXT_NODE) return (node.textContent?.trim().length ?? 0) > 0;\n return false;\n });\n }\n\n /** Sync default/selected slot presence (initial + slotchange). */\n private syncSlottedIcons() {\n const shadow = this.el.shadowRoot;\n const iconSlot = shadow?.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const selectedSlot = shadow?.querySelector('slot[name=\"selected\"]') as HTMLSlotElement | null;\n\n this.hasSlottedIcon = this.hasMeaningfulSlotContent(iconSlot);\n this.hasSlottedBadge = !!iconSlot\n ?.assignedElements()\n .some((el) => el.tagName.toLowerCase() === 'md-badge');\n this.hasSlottedSelected = this.hasMeaningfulSlotContent(selectedSlot);\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n const href = sanitizeHref(this.href);\n if (href) { window.open(href, this.target, SAFE_WINDOW_FEATURES); }\n if (this.toggle) this.selected = !this.selected;\n this.mdClick.emit({ selected: this.selected });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const showSelected = this.toggle && this.selected;\n const hasIcon = !!this.icon || this.hasSlottedIcon;\n // Do not gate visibility on `hasIcon` — slotted glyphs must paint before sync.\n const showDefaultIconLayer =\n !showSelected || (!this.selectedIcon && !this.hasSlottedSelected);\n\n return (\n <Host\n class={{\n 'md-icon-button': true,\n [`md-icon-button--${this.variant}`]: true,\n [`md-icon-button--${this.size}`]: true,\n [`md-icon-button--${this.shape}`]: true,\n [`md-icon-button--width-${this.buttonWidth}`]: this.buttonWidth !== 'default',\n 'md-icon-button--selected': this.selected,\n 'md-icon-button--toggle': this.toggle,\n 'md-icon-button--disabled': this.disabled || this.softDisabled,\n 'md-icon-button--shape-morph': this.shapeMorph,\n 'md-icon-button--has-badge': this.hasSlottedBadge,\n 'md-icon-button--pressed': this.shapeMorph && this.pressed,\n 'md-icon-button--connected-left': this.connectedLeft,\n 'md-icon-button--connected-right': this.connectedRight,\n }}\n role=\"button\"\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-icon-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {/* Default icon (shown when not toggle-selected, or no selected slot/icon) */}\n <span\n class={{\n 'md-icon-button__icon': true,\n 'md-icon-button__icon--on': showDefaultIconLayer,\n }}\n part=\"icon\"\n >\n <slot />\n {showDefaultIconLayer && hasIcon && !this.hasSlottedIcon && (\n <span class=\"md-icon-button__icon-font material-symbols-outlined\" aria-hidden=\"true\">\n {showSelected && this.selectedIcon ? this.selectedIcon : this.icon}\n </span>\n )}\n </span>\n\n {/* Selected icon (toggle mode only) */}\n {this.toggle && (this.selectedIcon || this.hasSlottedSelected) && (\n <span\n class={{\n 'md-icon-button__icon': true,\n 'md-icon-button__icon--on': showSelected,\n }}\n part=\"selected-icon\"\n >\n <slot name=\"selected\" />\n {!this.hasSlottedSelected && this.selectedIcon && (\n <span class=\"md-icon-button__icon-font material-symbols-outlined\" aria-hidden=\"true\">\n {this.selectedIcon}\n </span>\n )}\n </span>\n )}\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-radio — Material Design 3 Radio Button\n Spec: https://m3.material.io/components/radio-button/specs\n\n Measurements (MD3 spec):\n Icon size: 20px (outer circle)\n Inner dot: 10px (when checked)\n State-layer size: 40px\n Target (touch) size: 48px\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-radio-icon-color Unchecked outer circle color\n --md-radio-selected-icon-color Checked outer circle + inner dot color\n --md-radio-icon-size Outer circle size\n --md-radio-inner-circle-size Inner dot size\n --md-radio-state-layer-size State-layer diameter\n --md-radio-state-layer-color State-layer color (unchecked)\n --md-radio-selected-state-layer-color State-layer color (checked)\n\n CSS PARTS:\n state-layer Hover / focus / press overlay\n container Wrapper around outer + inner circles\n outer-circle The 20px circle border\n inner-circle The 10px filled dot\n\n SLOTS:\n (none — standalone control, label provided externally)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — TOUCH TARGET (48px)\n color controls md-ripple wave (md-ripple uses currentColor).\n ========================================================== */\n\n:host {\n --_icon-color: var(--md-radio-icon-color, var(--md-sys-color-on-surface-variant));\n --_selected-icon-color: var(--md-radio-selected-icon-color, var(--md-sys-color-primary));\n /* The visible circle + dot shrink with global density (20/10 at 0 → 16/8 at\n -4) so the control densifies, not just the tap target; ratio preserved. */\n --_icon-size: var(--md-radio-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n --_inner-circle-size: var(--md-radio-inner-circle-size, max(8px, calc(10px + var(--md-sys-density-scale, 0) * 0.5px)));\n /* Global density: the state layer shrinks in step with the host touch target\n (both trim 4px per `data-density` rung), so it stays 8px inside the host at\n every rung. Floored at 24px; unchanged at density 0. */\n --_state-layer-size: max(24px, calc(var(--md-radio-state-layer-size, 40px) + var(--md-sys-density-scale, 0) * 4px));\n --_state-layer-color: var(--md-radio-state-layer-color, var(--md-sys-color-on-surface));\n --_selected-state-layer-color: var(--md-radio-selected-state-layer-color, var(--md-sys-color-primary));\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the touch\n target, floored at 32px to keep breathing room around the 20px circle.\n Unchanged at density 0. */\n inline-size: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n block-size: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n cursor: pointer;\n border-radius: var(--md-sys-shape-corner-full, 50%);\n overflow: hidden;\n -webkit-tap-highlight-color: transparent;\n box-sizing: border-box;\n flex-shrink: 0;\n vertical-align: middle;\n outline: none;\n color: var(--_state-layer-color);\n}\n\n:host(.md-radio--checked) {\n color: var(--_selected-state-layer-color);\n}\n\n/* ==========================================================\n 2. HIDDEN NATIVE INPUT\n The host is the interactive radio (role=\"radio\" + roving\n tabindex). This decorative input must be fully removed from\n the focus order and accessibility tree — a native <input> stays\n natively focusable despite tabindex=\"-1\"/aria-hidden, which would\n nest a second interactive control inside the role=\"radio\" host\n (axe: nested-interactive). display:none is the only reliable way\n to strip a native control's focusability; opacity/zero-size do not.\n ========================================================== */\n\n.md-radio__native {\n display: none;\n}\n\n/* ==========================================================\n 3. RIPPLE LAYER (40px — constrains md-ripple to state-layer size)\n md-ripple resolves this span as its host via parentElement,\n so its wave is sized and clipped to the 40px circle.\n ========================================================== */\n\n.md-radio__ripple-layer {\n position: absolute;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n overflow: hidden;\n}\n\n:host(.md-radio--disabled) .md-radio__ripple-layer,\n:host([soft-disabled]) .md-radio__ripple-layer {\n display: none;\n}\n\n/* ==========================================================\n 4. STATE LAYER (40px centered inside 48px touch target)\n ========================================================== */\n\n.md-radio__state-layer {\n position: absolute;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n\n/* Unchecked state-layer */\n:host(.md-radio--unchecked:hover) .md-radio__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-radio--unchecked:active) .md-radio__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* Checked state-layer */\n:host(.md-radio--checked) .md-radio__state-layer {\n background-color: var(--_selected-state-layer-color);\n}\n\n:host(.md-radio--checked:hover) .md-radio__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-radio--checked:active) .md-radio__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 5. FOCUS RING — separate pseudo so it is NOT affected by the\n state-layer's opacity (which would make the ring ~12% visible).\n Sized to the 40px state-layer, with a 2px gap from the 20px\n container.\n ========================================================== */\n\n:host(:focus-visible)::after,\n:host(.md-radio--focus-ring)::after {\n content: '';\n position: absolute;\n inset: 0;\n margin: auto;\n inline-size: var(--_state-layer-size);\n block-size: var(--_state-layer-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n outline: 3px solid var(--md-sys-color-secondary);\n /* Sits ON the state layer, not pulled inside it. At -8px the ring drew at\n 24px around a 20px radio — a 2px gap — so it read as a bullseye welded to\n the control rather than as a focus indicator. On the state layer it clears\n the circle by a visible margin and still fits the touch target: the ring's\n outer edge is state-layer + 6px (46px inside a 48px host at density 0,\n 30px inside 32px at -4). */\n outline-offset: 0;\n pointer-events: none;\n}\n\n/* ==========================================================\n 6. CONTAINER (positions outer + inner circles)\n Transition uses same motion tokens as md-checkbox:\n Release: medium4 (400ms) + emphasized-decelerate (spring-back)\n Press: short4 (200ms) + standard (snap-in)\n ========================================================== */\n\n.md-radio__container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n pointer-events: none;\n transition:\n transform var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n/* Press animation — M3 Expressive squish */\n:host(.md-radio--pressed) .md-radio__container {\n transform: scale(0.82);\n transition:\n transform var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 7. OUTER CIRCLE (20px, 2px border)\n ========================================================== */\n\n.md-radio__outer {\n position: absolute;\n inset: 0;\n border-radius: var(--md-sys-shape-corner-full, 50%);\n border: 2px solid var(--_icon-color);\n box-sizing: border-box;\n transition:\n border-color var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(.md-radio--checked) .md-radio__outer {\n border-color: var(--_selected-icon-color);\n}\n\n/* ==========================================================\n 8. INNER CIRCLE (10px filled dot)\n Grows from scale(0) to scale(1) when checked.\n ========================================================== */\n\n.md-radio__inner {\n inline-size: var(--_inner-circle-size);\n block-size: var(--_inner-circle-size);\n border-radius: var(--md-sys-shape-corner-full, 50%);\n background-color: var(--_selected-icon-color);\n transform: scale(0);\n transition:\n transform var(--md-sys-motion-duration-medium4, 400ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n:host(.md-radio--checked) .md-radio__inner {\n transform: scale(1);\n}\n\n/* ==========================================================\n 9. DISABLED\n ========================================================== */\n\n:host(.md-radio--disabled) {\n cursor: default;\n pointer-events: none;\n}\n\n:host(.md-radio--disabled.md-radio--unchecked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled.md-radio--checked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled.md-radio--checked) .md-radio__inner {\n background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-radio--disabled) .md-radio__state-layer {\n display: none;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n\n:host([soft-disabled].md-radio--unchecked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled].md-radio--checked) .md-radio__outer {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled].md-radio--checked) .md-radio__inner {\n background-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host([soft-disabled]) .md-radio__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 10. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n .md-radio__container,\n .md-radio__state-layer,\n .md-radio__outer,\n .md-radio__inner {\n transition: none;\n }\n}\n\n/* ==========================================================\n 11. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n\n .md-radio__outer {\n border-color: ButtonText;\n }\n\n :host(.md-radio--checked) .md-radio__outer {\n border-color: Highlight;\n }\n\n :host(.md-radio--checked) .md-radio__inner {\n background-color: Highlight;\n }\n\n :host(:focus-visible)::after,\n :host(.md-radio--focus-ring)::after {\n outline-color: Highlight;\n }\n\n :host(.md-radio--disabled) .md-radio__outer {\n border-color: GrayText;\n }\n\n :host(.md-radio--disabled.md-radio--checked) .md-radio__inner {\n background-color: GrayText;\n }\n\n .md-radio__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { AttachInternals, Component, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';\nimport { RadioElement } from '../../utils/types';\nimport { triggerRipple } from '../../utils/ripple';\nimport {\n setFormValue,\n setValidityState,\n checkValidityOf,\n reportValidityOf,\n getValidityOf,\n} from '../../utils/form';\n\n@Component({\n tag: 'md-radio',\n styleUrl: 'md-radio.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdRadio {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Radios previously declared `name`/`value` but were\n * NOT form-associated, so a checked radio never reached FormData at all — the\n * group looked wired up and submitted nothing.\n */\n @AttachInternals() internals!: ElementInternals;\n\n\n /**\n * Localized constraint-validation message shown when `required` is unmet.\n *\n * A prop rather than a hardcoded string, matching md-time-picker's\n * `value-missing-label`: components stay i18n-engine-agnostic and the\n * consumer localizes through its own dictionary. Native inputs get their\n * message from the browser's locale for free; a form-associated custom\n * element supplies its own, so leaving this hardcoded would ship an\n * English-only form to every locale.\n */\n @Prop({ attribute: 'value-missing-label' }) valueMissingLabel: string =\n 'Please select one of these options.';\n\n /** Message set via setCustomValidity(); non-empty wins over valueMissing. */\n private customValidityMessage = '';\n\n /** Drives aria-invalid on the host. */\n @State() private invalid = false;\n\n /** `checked` at first render, restored on form reset (native radio behaviour). */\n private defaultChecked = false;\n\n // ─── Public Props ──────────────────────────────────────────\n\n /** Whether the radio button is selected */\n @Prop({ mutable: true, reflect: true }) checked: boolean = false;\n\n /** Disables the radio button */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable for discoverability */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Whether the radio is required in a form */\n @Prop({ reflect: true }) required: boolean = false;\n\n /** Form name — radios sharing a name form an exclusive group */\n @Prop({ reflect: true }) name: string = '';\n\n /** Form value submitted when checked */\n @Prop({ reflect: true }) value: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n // ─── Events ────────────────────────────────────────────────\n\n /** Emits when the checked state changes via user interaction */\n @Event() mdChange: EventEmitter<{ checked: boolean; value: string }>;\n\n /** Emits when the radio receives focus */\n @Event() mdFocus: EventEmitter<void>;\n\n /** Emits when the radio loses focus */\n @Event() mdBlur: EventEmitter<void>;\n\n // ─── Internal State ────────────────────────────────────────\n\n @State() private pressed = false;\n @State() private focused = false;\n @State() private programmaticFocus = false;\n @State() private managedTabIndex = '0';\n\n private parentLabel: HTMLLabelElement | null = null;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────\n\n connectedCallback() {\n this.parentLabel = this.el.closest('label');\n this.parentLabel?.addEventListener('click', this.handleLabelClick);\n }\n\n componentWillLoad() {\n this.defaultChecked = this.checked;\n this.syncFormValue();\n }\n\n componentDidLoad() {\n this.updateRovingTabIndex();\n // Group validity depends on SIBLINGS, which may not have upgraded when this\n // radio first rendered. Re-sync once the whole group exists, or a group\n // whose pre-checked member upgraded last would report itself empty.\n this.syncGroupValidity();\n }\n\n disconnectedCallback() {\n this.parentLabel?.removeEventListener('click', this.handleLabelClick);\n this.parentLabel = null;\n }\n\n // ─── Watchers ──────────────────────────────────────────────\n\n @Watch('checked')\n onCheckedChange(newVal: boolean) {\n if (newVal) {\n this.uncheckOthers(this.el);\n }\n this.updateRovingTabIndex();\n this.syncFormValue();\n // Runs for BOTH directions. Checking this radio satisfies `required` for\n // every member of the group; unchecking the last one must put the group\n // back into valueMissing. Either way every member re-publishes, not just\n // this one, because validity here is a property of the group.\n this.syncGroupValidity();\n }\n\n @Watch('required')\n @Watch('name')\n @Watch('valueMissingLabel')\n onValidityInputChange() {\n this.syncGroupValidity();\n }\n\n /** Only the checked member of a name group submits — native radio semantics. */\n private syncFormValue() {\n setFormValue(this.internals, this.checked ? this.value || 'on' : null);\n }\n\n /** True when any radio sharing this name is checked. */\n private get groupHasSelection(): boolean {\n if (!this.name) return this.checked;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)).some((r) => {\n const el = r as Element & { checked?: boolean };\n // The PROPERTY is authoritative once the element has upgraded. The\n // reflected `checked` attribute lags by a render, so reading it (or\n // OR-ing it in) reports a just-unchecked radio as still checked — the\n // group then looks satisfied, `required` never republishes valueMissing,\n // and the form submits empty. Fall back to the attribute only for an\n // element that has not upgraded yet, where the property does not exist.\n return typeof el.checked === 'boolean' ? el.checked : r.hasAttribute('checked');\n });\n }\n\n /**\n * True when ANY radio in the group is marked required.\n *\n * Per the HTML spec `required` on a single radio makes the whole GROUP\n * required, and every member then suffers valueMissing — not just the one\n * carrying the attribute. Reading it per-element meant a screen-reader user\n * landing on a sibling heard nothing wrong, and that sibling's own\n * checkValidity() disagreed with the form's.\n */\n private get groupIsRequired(): boolean {\n if (this.required) return true;\n if (!this.name) return false;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)).some((r) =>\n r.hasAttribute('required'),\n );\n }\n\n private syncValidity() {\n // See md-checkbox: WCAG 3.3.1 requires the invalid state to be exposed\n // programmatically. For a radio the condition is a GROUP property, so every\n // member reports invalid while the group has no selection — which is what a\n // screen reader user hears whichever member they land on.\n this.invalid = this.customValidityMessage\n ? true\n : this.groupIsRequired && !this.groupHasSelection;\n setValidityState(this.internals, {\n missing: this.groupIsRequired && !this.groupHasSelection,\n missingMessage: this.valueMissingLabel,\n customMessage: this.customValidityMessage,\n });\n this.emitValidityChange();\n }\n\n /** Re-publish validity for every radio in the group. */\n private syncGroupValidity() {\n this.syncValidity();\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n root.querySelectorAll(`md-radio[name=\"${this.name}\"]`).forEach((r) => {\n if (r !== this.el) (r as unknown as { syncValidityFromGroup?: () => void }).syncValidityFromGroup?.();\n });\n }\n\n /**\n * Group-coordination hook. Sibling radios call this so the whole group agrees\n * on validity; exposed as a @Method because a sibling can only reach this\n * component through its public element interface.\n */\n @Method()\n async syncValidityFromGroup() {\n this.syncValidity();\n }\n\n /** Restore the initial selection when the owning form is reset. */\n formResetCallback() {\n this.checked = this.defaultChecked;\n }\n\n /** Current validity: boolean, message and flags. Mirrors md-text-field. */\n @Method()\n async getValidity(): Promise<{\n valid: boolean;\n validationMessage: string;\n flags: Record<string, boolean>;\n }> {\n return getValidityOf(this.internals);\n }\n\n /**\n * Fires when this control's validity CHANGES — never on every keystroke, and\n * never for a re-publish that lands on the same state.\n *\n * `composed: false` is deliberate. Composites like md-select embed an\n * md-text-field, and a composed event escapes that inner shadow root, so a\n * listener on md-select would receive the inner field's event as well as the\n * host's — two events, different payloads, for one logical control. Keeping\n * it uncomposed means each component reports only for itself, while\n * `bubbles: true` still lets a <form> or app root hear every control.\n */\n @Event({ bubbles: true, composed: false }) mdValidityChange: EventEmitter<{\n valid: boolean;\n validationMessage: string;\n flags: Record<string, boolean>;\n }>;\n\n /** Last emitted validity, so a re-publish that changes nothing stays silent. */\n private lastValidityKey: string | null = null;\n\n /**\n * Emit mdValidityChange if validity actually moved.\n *\n * The FIRST call only primes the baseline. Initial state is not a change, and\n * emitting on mount would fire once per control on every page load — noise a\n * consumer would have to filter out, and misleading for anything logging\n * \"field became invalid\".\n */\n private emitValidityChange() {\n const v = getValidityOf(this.internals);\n const key = `${v.valid}|${v.validationMessage}`;\n if (this.lastValidityKey === key) return;\n const primed = this.lastValidityKey !== null;\n this.lastValidityKey = key;\n if (primed) this.mdValidityChange.emit(v);\n }\n\n /** Constraint-validation API, matching md-text-field and the native contract. */\n @Method()\n async checkValidity(): Promise<boolean> {\n return checkValidityOf(this.internals);\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return reportValidityOf(this.internals);\n }\n\n @Method()\n async setCustomValidity(message: string) {\n this.customValidityMessage = message;\n this.syncValidity();\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.updateRovingTabIndex();\n }\n\n // ─── Public Methods ────────────────────────────────────────\n\n /** Programmatically focus the radio */\n @Method()\n async setFocus() {\n // Script-initiated focus does not trigger :focus-visible, so flag it\n // explicitly to render the focus ring.\n this.programmaticFocus = true;\n this.el.focus();\n }\n\n /** Programmatically blur the radio */\n @Method()\n async setBlur() {\n this.el.blur();\n }\n\n /**\n * Programmatically select this radio and uncheck siblings.\n * Emits mdChange like a user interaction.\n */\n @Method()\n async select() {\n if (this.isDisabled || this.checked) return;\n this.checked = true;\n this.mdChange.emit({ checked: true, value: this.value });\n }\n\n // ─── Private — Roving tabindex (WAI-ARIA Radio Group) ─────\n\n /**\n * WAI-ARIA: only the active radio in a group receives Tab focus.\n * - checked radio → tabindex 0\n * - no radio checked → first enabled radio → tabindex 0\n * - all others → tabindex -1\n * - disabled → always tabindex -1\n * - no name (standalone) → tabindex 0\n */\n private updateRovingTabIndex() {\n if (this.disabled) {\n this.managedTabIndex = '-1';\n return;\n }\n if (this.checked) {\n this.managedTabIndex = '0';\n return;\n }\n if (!this.name) {\n this.managedTabIndex = '0';\n return;\n }\n\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`));\n\n const anyChecked = siblings.some(s => s !== this.el && (s as unknown as RadioElement).checked);\n if (anyChecked) {\n this.managedTabIndex = '-1';\n return;\n }\n\n const firstEnabled = siblings.find(s => !(s as unknown as RadioElement).disabled);\n this.managedTabIndex = firstEnabled === this.el ? '0' : '-1';\n }\n\n // ─── Private — Handlers ───────────────────────────────────\n\n private handleLabelClick = (e: MouseEvent) => {\n if (!e.composedPath().includes(this.el)) {\n this.handleClick();\n }\n };\n\n private handleClick = () => {\n if (this.isDisabled || this.checked) return;\n this.checked = true;\n this.mdChange.emit({ checked: true, value: this.value });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n\n if (e.key === ' ') {\n e.preventDefault();\n this.pressed = true;\n this.handleClick();\n triggerRipple(this.el);\n setTimeout(() => { this.pressed = false; }, 150);\n return;\n }\n\n if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {\n e.preventDefault();\n this.focusSibling(1);\n } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {\n e.preventDefault();\n this.focusSibling(-1);\n }\n };\n\n private handleFocus = () => {\n this.focused = true;\n this.mdFocus.emit();\n };\n\n private handleBlur = () => {\n this.focused = false;\n this.programmaticFocus = false;\n this.mdBlur.emit();\n };\n\n private handlePointerDown = () => {\n // Pointer interaction should not keep the programmatic focus ring.\n this.programmaticFocus = false;\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n // ─── Private — Group management ───────────────────────────\n\n /** Uncheck all radios in the group except the given element */\n private uncheckOthers(keepChecked: HTMLElement) {\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = root.querySelectorAll(`md-radio[name=\"${this.name}\"]`);\n siblings.forEach((sibling) => {\n if (sibling !== keepChecked && sibling.hasAttribute('checked')) {\n sibling.removeAttribute('checked');\n }\n });\n }\n\n /**\n * Focus next/previous sibling radio in the group.\n * Arrow keys move focus AND check the newly focused button (WAI-ARIA).\n * Skips disabled and soft-disabled radios.\n */\n private focusSibling(direction: 1 | -1) {\n if (!this.name) return;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n const siblings = Array.from(root.querySelectorAll(`md-radio[name=\"${this.name}\"]`)) as HTMLElement[];\n const enabled = siblings.filter(s => !s.hasAttribute('disabled') && !s.hasAttribute('soft-disabled'));\n if (enabled.length === 0) return;\n\n const idx = enabled.indexOf(this.el);\n const next = (idx + direction + enabled.length) % enabled.length;\n const target = enabled[next];\n target.focus();\n target.setAttribute('checked', '');\n triggerRipple(target);\n target.dispatchEvent(new CustomEvent('mdChange', {\n detail: { checked: true, value: target.getAttribute('value') || '' },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ─── Render ────────────────────────────────────────────────\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n\n return (\n <Host\n class={{\n 'md-radio': true,\n 'md-radio--checked': this.checked,\n 'md-radio--unchecked': !this.checked,\n 'md-radio--disabled': isEffectivelyDisabled,\n 'md-radio--pressed': this.pressed,\n 'md-radio--focused': this.focused,\n 'md-radio--focus-ring': this.programmaticFocus,\n }}\n role=\"radio\"\n aria-invalid={this.invalid ? 'true' : undefined}\n aria-checked={String(this.checked)}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n tabindex={this.managedTabIndex}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n <span class=\"md-radio__ripple-layer\" aria-hidden=\"true\">\n <md-ripple disabled={isEffectivelyDisabled}></md-ripple>\n </span>\n <span class=\"md-radio__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n <span class=\"md-radio__container\" part=\"container\" aria-hidden=\"true\">\n <span class=\"md-radio__outer\" part=\"outer-circle\"></span>\n <span class=\"md-radio__inner\" part=\"inner-circle\"></span>\n </span>\n\n <input\n type=\"radio\"\n class=\"md-radio__native\"\n checked={this.checked}\n disabled={this.disabled}\n required={this.required}\n name={this.name}\n value={this.value}\n aria-hidden=\"true\"\n tabindex=\"-1\"\n onChange={() => {}}\n />\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-ripple — Material Design 3 ripple effect\n Spec: https://m3.material.io/foundations/interaction/states\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-ripple-color Ripple tint color (default: currentColor)\n --md-ripple-opacity Ripple peak opacity (default: 0.12)\n --md-ripple-extend-inline Extra pixels to add on each inline edge\n of the host's rect when computing the\n wave's farthest-corner radius. Use on\n surfaces that GROW horizontally during\n the ripple's lifetime (e.g. md-search\n springing out on focus) so the wave is\n sized for the settled rect instead of\n the resting one. Wave position is\n unaffected — the wave still originates\n at the click point. Must be a CONCRETE\n PIXEL VALUE (e.g. `120px`). Computed\n expressions involving %, calc() or\n clamp() are NOT resolved by this hook —\n read the literal token via\n getComputedStyle and parseFloat returns\n NaN on those forms. Consumers needing\n such expressions should compute the\n value in JS and write it back as fixed\n pixels via inline style. (default: 0)\n --md-ripple-extend-block Same as --md-ripple-extend-inline but\n for the block axis. (default: 0)\n --md-ripple-grow-duration Override the wave's scale 0 → 1 grow\n duration. Use on surfaces that animate\n their own size during the ripple's\n lifetime (e.g. md-search) so the wave\n reaches full size at the same instant\n the surface settles — otherwise the\n wave is still ramping up while the\n surface is already at its final width.\n var() references and any value that\n resolves to a CSS time work (e.g.\n `250ms`). (default: 450ms)\n --md-ripple-grow-easing Companion to --md-ripple-grow-duration\n — usually set to the surface's own\n easing so the wave feels like part of\n the same motion.\n (default: cubic-bezier(0.2, 0, 0, 1))\n\n CSS PARTS:\n (none)\n\n SLOTS:\n (none)\n ========================================================== */\n\n:host {\n display: contents;\n\n /* `.md-ripple` clips the wave with `border-radius: inherit`, which inherits\n from THIS host — not from the component embedding us. Left at the initial\n 0, that clip is a square, and the wave only looked round because the\n embedding host happened to clip it with its own `overflow: hidden`. Any\n host that must let something escape (an icon button with a badge) then got\n a square ripple. Inheriting the radius here makes the clip follow the\n container's shape on its own. */\n border-radius: inherit;\n\n --_color: var(--md-ripple-color, currentColor);\n}\n\n.md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n overflow: hidden;\n pointer-events: none;\n}\n\n.md-ripple__wave {\n position: absolute;\n border-radius: 50%;\n pointer-events: none;\n background: var(--_color);\n opacity: 0;\n transform: scale(0);\n will-change: transform, opacity;\n}\n\n/* ==========================================================\n SUPPRESSION (global data-ripple=\"off\" / per-component ripple=\"off\")\n The real gate is in TS — onPointerDown and trigger() bail before a wave is\n ever created, so nothing is allocated or animated. This rule is the safety\n net for the one case TS cannot cover: a wave already mid-flight when the\n toggle flips. Without it that wave would finish its 450ms grow after ripples\n were switched off.\n\n The signal is 0/1, which is already a valid opacity, so it drops straight in\n — no keyword mapping, and the default of 1 makes this a no-op when the\n feature is on. opacity (not display) so nothing about layout or the\n containing block changes.\n ========================================================== */\n.md-ripple {\n opacity: var(--md-sys-ripple-enabled, 1);\n}\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Element, h, Host, Method, Prop } from '@stencil/core';\n\nconst PRESS_GROW_MS = 450;\nconst RELEASE_FADE_MS = 150;\nconst DEFAULT_PRESS_OPACITY = 0.12;\nconst EASING_STANDARD = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst GROW_DURATION_PROP = '--md-ripple-grow-duration';\nconst GROW_EASING_PROP = '--md-ripple-grow-easing';\n\n@Component({ tag: 'md-ripple', styleUrl: 'md-ripple.css', shadow: true })\nexport class MdRipple {\n @Element() el!: HTMLElement;\n\n @Prop() disabled: boolean = false;\n\n /**\n * True when ripples are switched off for this element, either globally\n * (`data-ripple=\"off\"` on any ancestor) or on the owning component\n * (`ripple=\"off\"`). Both spellings resolve to `--md-sys-ripple-enabled` in\n * tokens.css, so only the resolved value is read here.\n *\n * Read at interaction time rather than cached. The signal is a plain\n * inherited custom property, so it can change at any moment — a theme\n * switch, a settings toggle, a parent re-render — with no attribute mutation\n * on THIS element to observe. One getComputedStyle per press is cheap next to\n * the wave animation that follows, and it cannot go stale.\n *\n * The check is deliberately `=== '0'`: an unset property returns '' and must\n * mean ENABLED, so testing for falsiness would disable ripples everywhere the\n * token sheet has not loaded.\n */\n private rippleSuppressed(): boolean {\n if (typeof getComputedStyle !== 'function') return false;\n try {\n return (\n getComputedStyle(this.el).getPropertyValue('--md-sys-ripple-enabled').trim() === '0'\n );\n } catch {\n return false;\n }\n }\n\n private hostEl: HTMLElement | null = null;\n private activeWave: HTMLElement | null = null;\n private growAnimation: Animation | null = null;\n private activeOpacity: number = DEFAULT_PRESS_OPACITY;\n private bound = false;\n private settlePromise: Promise<void> | null = null;\n private settleResolve: (() => void) | null = null;\n\n private resolveOpacity(): number {\n if (!this.hostEl) return DEFAULT_PRESS_OPACITY;\n const raw = getComputedStyle(this.hostEl)\n .getPropertyValue('--md-ripple-opacity')\n .trim();\n if (!raw) return DEFAULT_PRESS_OPACITY;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : DEFAULT_PRESS_OPACITY;\n }\n\n /**\n * Resolve the inline / block extents that surfaces growing during the\n * ripple's lifetime (e.g. md-search springing out on focus) declare via\n * `--md-ripple-extend-inline` / `--md-ripple-extend-block`. The values\n * inflate the host's rect ONLY for the wave's farthest-corner radius\n * calculation, so the wave is sized for the SETTLED rect even though\n * the actual host is still at its resting size at pointerdown. Wave\n * POSITION still uses the unmodified rect so the wave originates\n * exactly where the user clicked.\n *\n * Consumers MUST pass concrete pixel values here (e.g.\n * `style.setProperty('--md-ripple-extend-inline', '120px')`).\n * `getComputedStyle().getPropertyValue()` on a custom property returns\n * the LITERAL TOKEN — for `calc()` / `clamp()` / `%` expressions the\n * string is unparsed (`\"calc(clamp(0px, 8%, 64px) * 2)\"`) and\n * `parseFloat()` returns `NaN`. Resolving such expressions reliably\n * requires knowing the consumer's intended containing-block reference,\n * which md-ripple cannot infer; consumers therefore compute the value\n * themselves (typically with a hidden probe element scoped to the\n * correct containing block) and write it back as fixed pixels.\n */\n private resolveExtent(prop: string): number {\n const raw = getComputedStyle(this.el).getPropertyValue(prop).trim();\n if (!raw) return 0;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n /**\n * Wave grow duration (ms). Surfaces that animate their size during the\n * ripple's lifetime (e.g. md-search springing from a narrower resting\n * width to its full width) should sync the wave's growth with their\n * own settle so the wave reaches scale = 1 at the same moment the\n * surface stops moving — otherwise the wave is still ramping up while\n * the surface is already at its final width and the user sees a\n * visible gap on the side that grew. Default is the spec-canonical\n * 450ms.\n */\n private resolveGrowDuration(): number {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_DURATION_PROP).trim();\n if (!raw) return PRESS_GROW_MS;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : PRESS_GROW_MS;\n }\n\n /**\n * Wave grow easing function. Companion to {@link resolveGrowDuration}\n * — when a surface drives the timing it should usually pass its own\n * easing (typically a back-out spring) so the wave's growth feels\n * like part of the same motion.\n */\n private resolveGrowEasing(): string {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_EASING_PROP).trim();\n return raw || EASING_STANDARD;\n }\n\n private beginSettle() {\n this.finishSettle();\n this.settlePromise = new Promise<void>((resolve) => {\n this.settleResolve = resolve;\n });\n }\n\n private finishSettle() {\n this.settleResolve?.();\n this.settleResolve = null;\n this.settlePromise = null;\n }\n\n /** Resolves when the active press ripple has fully faded out. */\n @Method()\n async whenSettled(): Promise<void> {\n if (!this.settlePromise) return;\n const maxWait = new Promise<void>((resolve) => {\n setTimeout(resolve, RELEASE_FADE_MS + 50);\n });\n await Promise.race([this.settlePromise, maxWait]);\n this.finishSettle();\n }\n\n private resolveHost(): HTMLElement | null {\n const root = this.el.getRootNode();\n return this.el.parentElement ??\n (root instanceof ShadowRoot ? (root.host as HTMLElement) : null);\n }\n\n private bind() {\n if (this.bound) return;\n this.hostEl = this.resolveHost();\n if (!this.hostEl) return;\n this.bound = true;\n this.hostEl.addEventListener('pointerdown', this.onPointerDown);\n }\n\n connectedCallback() {\n this.bind();\n if (!this.bound) {\n queueMicrotask(() => this.bind());\n }\n }\n\n disconnectedCallback() {\n this.hostEl?.removeEventListener('pointerdown', this.onPointerDown);\n this.hostEl = null;\n this.bound = false;\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (this.disabled || this.rippleSuppressed()) return;\n\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n // Treat the surface as if it spans an extended rect when the host has\n // declared `--md-ripple-extend-inline` / `--md-ripple-extend-block`.\n // Wave POSITION still uses the actual (current) rect so the wave\n // visually originates at the click point — only the RADIUS uses the\n // inflated bounds so the wave grows large enough to cover the surface\n // once it settles.\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const left = rect.left - extendInline;\n const right = rect.right + extendInline;\n const top = rect.top - extendBlock;\n const bottom = rect.bottom + extendBlock;\n const dx = Math.max(Math.abs(e.clientX - left), Math.abs(e.clientX - right));\n const dy = Math.max(Math.abs(e.clientY - top), Math.abs(e.clientY - bottom));\n const radius = Math.sqrt(dx * dx + dy * dy);\n const size = radius * 2;\n const x = e.clientX - rect.left - radius;\n const y = e.clientY - rect.top - radius;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${x}px`;\n wave.style.top = `${y}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n window.addEventListener('pointerup', this.onRelease, { once: true });\n window.addEventListener('pointercancel', this.onRelease, { once: true });\n };\n\n private onRelease = () => {\n this.endWave();\n };\n\n private async endWave() {\n const wave = this.activeWave;\n const grow = this.growAnimation;\n if (!wave || !grow) return;\n\n this.activeWave = null;\n this.growAnimation = null;\n\n if (grow.playState !== 'finished') {\n await grow.finished;\n }\n\n const fade = wave.animate(\n [{ opacity: this.activeOpacity }, { opacity: 0 }],\n { duration: RELEASE_FADE_MS, easing: EASING_STANDARD, fill: 'forwards' },\n );\n try {\n if (typeof fade.finished?.then === 'function') {\n await fade.finished;\n } else {\n await new Promise<void>((resolve) => setTimeout(resolve, RELEASE_FADE_MS));\n }\n } catch {\n /* animation cancelled */\n }\n wave.remove();\n this.finishSettle();\n }\n\n /** Programmatically trigger a centered ripple (for keyboard activations). */\n @Method()\n async trigger() {\n if (this.disabled || this.rippleSuppressed()) return;\n\n if (!this.hostEl) this.hostEl = this.resolveHost();\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n // Centered ripples use the rect's centre as both anchor and farthest\n // reference, so the inflated half-extents become the radius\n // contribution directly.\n const halfX = cx + extendInline;\n const halfY = cy + extendBlock;\n const radius = Math.sqrt(halfX * halfX + halfY * halfY);\n const size = radius * 2;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${cx - radius}px`;\n wave.style.top = `${cy - radius}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n this.growAnimation.addEventListener('finish', () => this.endWave(), { once: true });\n }\n\n render() {\n return (\n <Host aria-hidden=\"true\">\n <div class=\"md-ripple\"></div>\n </Host>\n );\n }\n}\n","/* ==========================================================\n md-snackbar — Material Design 3 Snackbar\n Spec: https://m3.material.io/components/snackbar/specs\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-snackbar-container-color Surface background\n --md-snackbar-message-color Supporting text color\n --md-snackbar-action-color Action button text color\n --md-snackbar-close-color Close icon color\n --md-snackbar-container-shape Border radius\n --md-snackbar-min-width Minimum inline size\n --md-snackbar-max-width Maximum inline size\n\n CSS PARTS:\n surface Outer container\n message Supporting text wrapper\n actions Action button wrapper\n close Close button wrapper\n\n SLOTS:\n (default) Supporting text\n action Custom action element\n close Custom close element\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — positioning & visibility\n ========================================================== */\n\n:host {\n --_container-color: var(--md-snackbar-container-color, var(--md-sys-color-inverse-surface, #313033));\n --_message-color: var(--md-snackbar-message-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_action-color: var(--md-snackbar-action-color, var(--md-sys-color-inverse-primary, #D0BCFF));\n --_close-color: var(--md-snackbar-close-color, var(--md-sys-color-inverse-on-surface, #F4EFF4));\n --_container-shape: var(--md-snackbar-container-shape, var(--md-sys-shape-corner-extra-small, 4px));\n --_min-width: var(--md-snackbar-min-width, 288px);\n --_max-width: var(--md-snackbar-max-width, 568px);\n --_slide-from: translateY(100%);\n\n display: flex;\n position: fixed;\n inset-block-start: 0;\n inset-block-end: 0;\n inset-inline-start: 0;\n inset-inline-end: 0;\n padding: var(--md-sys-spacing-inset-xl, 24px);\n align-items: flex-end;\n justify-content: center;\n /* Every snackbar shares one z-index, so with two of them up the DOM order —\n not the order they opened in — decides which paints on top, and a newly\n shown snackbar can appear BEHIND one already on screen. `--_stack-order`\n is stamped on open (see md-snackbar.tsx) and lifts the newest above its\n peers. It counts open snackbars, not opens, so it stays a small number and\n can't creep up past dialogs or other overlays above this token. */\n z-index: calc(var(--md-sys-z-index-snackbar, 2000) + var(--_stack-order, 0));\n pointer-events: none;\n visibility: hidden;\n opacity: 0;\n transform: var(--_slide-from);\n transition:\n opacity var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n transform var(--md-sys-motion-duration-short4, 200ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n visibility 0ms linear var(--md-sys-motion-duration-short4, 200ms);\n}\n\n:host(.md-snackbar--open) {\n visibility: visible;\n opacity: 1;\n transform: translate(0, 0);\n transition:\n opacity var(--md-sys-motion-duration-medium1, 250ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n transform var(--md-sys-motion-duration-medium1, 250ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n visibility 0ms linear 0ms;\n}\n\n:host(.md-snackbar--open) .md-snackbar__surface {\n pointer-events: auto;\n}\n\n/* ─── Bottom positions (slide from bottom) ─────────────── */\n\n:host(.md-snackbar--bottom) {\n align-items: flex-end;\n justify-content: center;\n}\n\n:host(.md-snackbar--bottom-start) {\n align-items: flex-end;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--bottom-end) {\n align-items: flex-end;\n justify-content: flex-end;\n}\n\n/* ─── Top positions (slide from top) ───────────────────── */\n\n:host(.md-snackbar--top),\n:host(.md-snackbar--top-start),\n:host(.md-snackbar--top-end) {\n --_slide-from: translateY(-100%);\n}\n\n:host(.md-snackbar--top) {\n align-items: flex-start;\n justify-content: center;\n}\n\n:host(.md-snackbar--top-start) {\n align-items: flex-start;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--top-end) {\n align-items: flex-start;\n justify-content: flex-end;\n}\n\n/* ─── Side & center positions (fade only) ──────────────── */\n\n:host(.md-snackbar--start),\n:host(.md-snackbar--end),\n:host(.md-snackbar--center) {\n --_slide-from: translate(0, 0);\n}\n\n:host(.md-snackbar--start) {\n align-items: center;\n justify-content: flex-start;\n}\n\n:host(.md-snackbar--end) {\n align-items: center;\n justify-content: flex-end;\n}\n\n:host(.md-snackbar--center) {\n align-items: center;\n justify-content: center;\n}\n\n/* ==========================================================\n 2. SURFACE — container\n ========================================================== */\n\n.md-snackbar__surface {\n display: flex;\n align-items: center;\n min-inline-size: var(--_min-width);\n max-inline-size: var(--_max-width);\n min-block-size: max(36px, calc(48px + var(--md-sys-density-scale, 0) * 3px));\n padding-inline-start: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n padding-inline-end: max(8px, calc(16px + var(--md-sys-density-scale, 0) * 2px));\n background-color: var(--_container-color);\n color: var(--_message-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--md-sys-elevation-3);\n box-sizing: border-box;\n}\n\n:host(.md-snackbar--with-action:not(.md-snackbar--with-close)) .md-snackbar__surface {\n padding-inline-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-snackbar--with-close) .md-snackbar__surface {\n padding-inline-end: var(--md-sys-spacing-inset-md, 12px);\n}\n\n/* ─── Compact viewports (MD3) ───────────────────────────────\n Below 600px the snackbar spans the full available width (minus a smaller edge\n margin) instead of its fixed min/max width — so it never overflows or clips\n off-screen on a phone (the 288px min-width would otherwise exceed a narrow\n viewport). */\n@media (max-width: 599px) {\n :host {\n padding: var(--md-sys-spacing-inset-lg, 16px);\n }\n .md-snackbar__surface {\n inline-size: 100%;\n min-inline-size: 0;\n max-inline-size: 100%;\n }\n}\n\n/* ==========================================================\n 3. MESSAGE — supporting text\n ========================================================== */\n\n.md-snackbar__message {\n flex: 1;\n padding-block: max(6px, calc(14px + var(--md-sys-density-scale, 0) * 2px));\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-medium-font-weight, 400);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing, 0.25px);\n color: inherit;\n}\n\n/* ==========================================================\n 4. ACTIONS — action button + close icon\n ========================================================== */\n\n.md-snackbar__actions {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* ─── Action button (md-button, text variant) ───────────── */\n\n/* The action is a real md-button (text variant). On the inverse (dark)\n snackbar surface it takes the inverse-primary action color for its label,\n icon, state layer and ripple — the button itself supplies the typescale,\n shape, focus ring and ripple. */\n.md-snackbar__action-btn {\n flex-shrink: 0;\n --md-button-label-color: var(--_action-color);\n --md-button-icon-color: var(--_action-color);\n --md-ripple-color: var(--_action-color);\n}\n\n/* ─── Close wrapper & icon button ──────────────────────── */\n\n.md-snackbar__close {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-snackbar__close md-icon-button {\n --md-icon-button-icon-color: var(--_close-color);\n --md-icon-button-container-width: max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-container-height: max(32px, calc(40px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-icon-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n}\n\n/* ==========================================================\n 5. STACKED LAYOUT — action below text, close at top-right\n ========================================================== */\n\n:host(.md-snackbar--stacked) .md-snackbar__surface {\n display: grid;\n grid-template-columns: 1fr auto;\n grid-template-rows: auto auto;\n align-items: start;\n /* Breathing room so the close isn't jammed against the message, and the action\n row isn't stacked tight under the close. */\n column-gap: var(--md-sys-spacing-gap-md, 12px);\n row-gap: 6px;\n min-block-size: 68px;\n padding-block-start: var(--md-sys-spacing-inset-sm, 8px);\n padding-block-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-snackbar--stacked) .md-snackbar__message {\n grid-column: 1;\n grid-row: 1;\n padding-block-end: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n/* Centre the 24px close glyph on the message's first-line\n centre. The message inherits `padding-block: 14px` from the\n base rule (the stacked override only resets the end padding),\n so its first line centre sits at row_top + 14 + 10 = row_top\n + 24. The icon-button is 40×40 with 8px internal padding —\n its glyph centre sits 20px below the button's top. We\n therefore push the button DOWN by 4px so the glyph centre\n lands at row_top + 24 = message line centre. Holds for\n multi-line messages too — the glyph stays on the FIRST line. */\n:host(.md-snackbar--stacked) .md-snackbar__close {\n grid-column: 2;\n grid-row: 1;\n align-self: start;\n margin-inline-start: 0;\n margin-block-start: var(--md-sys-spacing-inset-xs, 4px);\n padding-block-start: 0;\n}\n\n:host(.md-snackbar--stacked) .md-snackbar__actions {\n grid-column: 1 / -1;\n grid-row: 2;\n justify-self: end;\n}\n\n/* ==========================================================\n 6. SLOTTED CONTENT\n ========================================================== */\n\n::slotted([slot=\"action\"]) {\n color: var(--_action-color);\n}\n\n::slotted([slot=\"close\"]) {\n color: var(--_close-color);\n}\n\n/* ==========================================================\n 7. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n :host(.md-snackbar--open) {\n transition: none;\n }\n}\n\n/* ==========================================================\n 8. FORCED COLORS (Windows High Contrast)\n ========================================================== */\n\n@media (forced-colors: active) {\n .md-snackbar__surface {\n border: 1px solid CanvasText;\n }\n\n .md-snackbar__action-btn {\n color: LinkText;\n }\n\n .md-snackbar__action-btn:focus-visible {\n outline-color: Highlight;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Method, Watch } from '@stencil/core';\n\n/**\n * @slot - Supporting text (overrides `message` prop)\n * @slot action - Custom action element (overrides `action` prop)\n * @slot close - Custom close element (overrides default X icon button)\n *\n * @part surface - Outer container surface\n * @part message - Supporting text wrapper\n * @part actions - Action button wrapper\n * @part close - Close button wrapper\n */\n@Component({\n tag: 'md-snackbar',\n styleUrl: 'md-snackbar.css',\n shadow: true,\n})\nexport class MdSnackbar {\n @Element() el!: HTMLElement;\n\n // ─── Public Props ──────────────────────────────────────────\n\n /** Whether the snackbar is visible */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n\n /** Primary supporting text */\n @Prop() message: string = '';\n\n /** Action button label (leave empty for no action) */\n @Prop() action: string = '';\n\n /** Show a close (X) icon button */\n @Prop({ reflect: true }) closeable: boolean = false;\n\n /** Auto-dismiss after `autoHideDuration` ms (dismissive behavior) */\n @Prop() autoHide: boolean = true;\n\n /** Time in ms before auto-dismiss */\n @Prop() autoHideDuration: number = 4000;\n\n /** Screen position */\n @Prop({ reflect: true }) position:\n | 'bottom' | 'bottom-start' | 'bottom-end'\n | 'top' | 'top-start' | 'top-end'\n | 'start' | 'end' | 'center' = 'bottom';\n\n /** Stack action below text (for longer action labels) */\n @Prop({ reflect: true }) stacked: boolean = false;\n\n /**\n * Live-region politeness. `'polite'` (default) → `role=\"status\"` /\n * `aria-live=\"polite\"` (announced when idle). `'assertive'` → `role=\"alert\"` /\n * `aria-live=\"assertive\"` — interrupts the screen reader; use sparingly for\n * important / error messages.\n */\n @Prop({ reflect: true }) politeness: 'polite' | 'assertive' = 'polite';\n\n /** Accessible label for the close button. Localize per the page locale. */\n @Prop({ attribute: 'dismiss-label' }) dismissLabel: string = 'Dismiss';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n // ─── Events ────────────────────────────────────────────────\n\n /** Emits when the snackbar becomes visible */\n @Event() mdOpen: EventEmitter<void>;\n\n /** Emits when the snackbar is dismissed, with reason */\n @Event() mdClose: EventEmitter<{ reason: 'auto' | 'action' | 'close' }>;\n\n /** Emits when the action button is clicked */\n @Event() mdAction: EventEmitter<void>;\n\n // ─── Internal State ────────────────────────────────────────\n\n @State() private hasSlottedAction = false;\n @State() private hasSlottedClose = false;\n @State() private hasSlottedDefault = false;\n\n private autoHideTimer?: ReturnType<typeof setTimeout>;\n private rippleDismissTimer?: ReturnType<typeof setTimeout>;\n private timerPaused = false;\n\n /** Coerce autoHide — HTML attribute `auto-hide=\"false\"` arrives as string \"false\" */\n private get isAutoHide(): boolean {\n return this.autoHide !== false && (this.autoHide as unknown) !== 'false';\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const defaultSlot = shadow.querySelector('slot:not([name])') as HTMLSlotElement | null;\n const actionSlot = shadow.querySelector('slot[name=\"action\"]') as HTMLSlotElement | null;\n const closeSlot = shadow.querySelector('slot[name=\"close\"]') as HTMLSlotElement | null;\n\n defaultSlot?.addEventListener('slotchange', () => {\n this.hasSlottedDefault = defaultSlot.assignedNodes().some(n =>\n n.nodeType === Node.ELEMENT_NODE || (n.nodeType === Node.TEXT_NODE && n.textContent?.trim() !== ''),\n );\n });\n actionSlot?.addEventListener('slotchange', () => {\n this.hasSlottedAction = actionSlot.assignedElements().length > 0;\n });\n closeSlot?.addEventListener('slotchange', () => {\n this.hasSlottedClose = closeSlot.assignedElements().length > 0;\n });\n\n if (this.open) {\n this.onOpenChange(true, false);\n }\n }\n\n disconnectedCallback() {\n this.clearAutoHide();\n if (this.rippleDismissTimer != null) {\n clearTimeout(this.rippleDismissTimer);\n this.rippleDismissTimer = undefined;\n }\n window.removeEventListener('keydown', this.handleEscape);\n }\n\n // ─── Watchers ──────────────────────────────────────────────\n\n /**\n * Lift this snackbar above any that are already open.\n *\n * All snackbars share one z-index token, and equal z-index falls back to DOM\n * order — so showing a snackbar declared earlier in the markup put it BEHIND\n * one already on screen. Ranking against the currently-open peers (rather\n * than counting every open ever) keeps the offset bounded by how many are up\n * at once, so it never climbs into the range of dialogs above it.\n */\n private raiseAboveOpenPeers() {\n const peers = Array.from(document.querySelectorAll('md-snackbar')).filter(\n (s) => s !== this.el && (s as HTMLMdSnackbarElement).open,\n );\n const highest = peers.reduce(\n (max, s) => Math.max(max, Number((s as HTMLElement).style.getPropertyValue('--_stack-order')) || 0),\n 0,\n );\n this.el.style.setProperty('--_stack-order', String(highest + 1));\n }\n\n @Watch('open')\n onOpenChange(newVal: boolean, _oldVal?: boolean) {\n if (newVal) {\n this.raiseAboveOpenPeers();\n this.mdOpen.emit();\n if (this.isAutoHide) {\n this.startAutoHide();\n }\n window.addEventListener('keydown', this.handleEscape);\n } else {\n this.clearAutoHide();\n this.timerPaused = false;\n window.removeEventListener('keydown', this.handleEscape);\n }\n }\n\n // ─── Public Methods ────────────────────────────────────────\n\n /** Show the snackbar */\n @Method()\n async show() {\n this.open = true;\n }\n\n /** Hide the snackbar with an optional reason */\n @Method()\n async hide(reason: 'auto' | 'action' | 'close' = 'close') {\n if (!this.open) return;\n this.open = false;\n this.mdClose.emit({ reason });\n }\n\n // ─── Private ───────────────────────────────────────────────\n\n private startAutoHide() {\n this.clearAutoHide();\n this.autoHideTimer = setTimeout(() => {\n if (this.open) {\n this.open = false;\n this.mdClose.emit({ reason: 'auto' });\n }\n }, this.autoHideDuration);\n }\n\n private clearAutoHide() {\n if (this.autoHideTimer != null) {\n clearTimeout(this.autoHideTimer);\n this.autoHideTimer = undefined;\n }\n }\n\n private dismissAfterRipple(reason: 'action' | 'close') {\n this.rippleDismissTimer = setTimeout(() => {\n this.rippleDismissTimer = undefined;\n if (this.open) {\n this.open = false;\n this.mdClose.emit({ reason });\n }\n }, 150);\n }\n\n private handleActionClick = () => {\n this.mdAction.emit();\n this.startAutoHide();\n };\n\n private handleCloseClick = () => {\n this.dismissAfterRipple('close');\n };\n\n private handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.open && this.closeable) {\n e.preventDefault();\n this.handleCloseClick();\n }\n };\n\n /** WCAG 2.2.1 — pause auto-hide while the user is interacting */\n private pauseAutoHide = () => {\n if (this.autoHideTimer != null && this.open) {\n this.timerPaused = true;\n this.clearAutoHide();\n }\n };\n\n private resumeAutoHide = () => {\n if (this.timerPaused && this.open) {\n this.timerPaused = false;\n this.startAutoHide();\n }\n };\n\n private handleSurfaceFocusOut = (e: FocusEvent) => {\n const surface = e.currentTarget as HTMLElement;\n if (e.relatedTarget && surface.contains(e.relatedTarget as Node)) {\n return;\n }\n this.resumeAutoHide();\n };\n\n // ─── Render ────────────────────────────────────────────────\n\n render() {\n const hasAction = !!this.action || this.hasSlottedAction;\n const hasClose = this.closeable || this.hasSlottedClose;\n\n return (\n <Host\n class={{\n 'md-snackbar': true,\n 'md-snackbar--open': this.open,\n 'md-snackbar--stacked': this.stacked,\n [`md-snackbar--${this.position}`]: true,\n 'md-snackbar--with-action': hasAction,\n 'md-snackbar--with-close': hasClose,\n }}\n role={this.politeness === 'assertive' ? 'alert' : 'status'}\n aria-live={this.politeness}\n aria-atomic=\"true\"\n >\n <div\n class=\"md-snackbar__surface\"\n part=\"surface\"\n onMouseEnter={this.pauseAutoHide}\n onMouseLeave={this.resumeAutoHide}\n onFocusin={this.pauseAutoHide}\n onFocusout={this.handleSurfaceFocusOut}\n >\n <span class=\"md-snackbar__message\" part=\"message\">\n <slot>{this.message}</slot>\n </span>\n\n {hasAction && (\n <div class=\"md-snackbar__actions\" part=\"actions\">\n <slot name=\"action\">\n {this.action && (\n <md-button\n variant=\"text\"\n size=\"sm\"\n class=\"md-snackbar__action-btn\"\n onClick={this.handleActionClick}\n >\n {this.action}\n </md-button>\n )}\n </slot>\n </div>\n )}\n\n {hasClose && (\n <div class=\"md-snackbar__close\" part=\"close\">\n <slot name=\"close\">\n {this.closeable && (\n <md-icon-button\n variant=\"standard\"\n icon=\"close\"\n aria-label={this.dismissLabel}\n onClick={this.handleCloseClick}\n exportparts=\"icon:close-icon\"\n ></md-icon-button>\n )}\n </slot>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
|