/* src/components/basic/XWUIButton/XWUIButton.css */
/**
 * XWUIButton Component Styles
 * Button component with various variants and states
 * 
 * Style Dependencies:
 * - Base: reset.css, typography.css, utilities.css
 * - Brand: brand/xwui/brand.css
 * - Style: style/modern/spacing.css, style/modern/shadows.css
 * - Theme: theme/colors/{selected-theme}.css (MANDATORY - provides all color variables)
 * - Theme: theme/accents/{selected-accent}.css (MANDATORY - provides accent color variables)
 * - Roundness: theme/roundness/button/*.css (component-specific roundness)
 * - Lines: theme/lines/button/*.css (component-specific border widths)
 * - Typography: theme/typography/*.css
 */

.xwui-button-container {
    display: inline-block;
}

.xwui-button-container.xwui-button-full-width {
    display: block;
    width: 100%;
}

.xwui-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-xs, 0.5rem);
    font-family: var(--xwui-button-label-family, var(--font-button-family, var(--font-family-base, sans-serif)));
    font-weight: var(--xwui-button-label-weight, var(--button-font-weight, var(--font-weight-medium, 500)));
    border: none;
    border-radius: var(--radius-button, var(--radius-sm, 6px));
    cursor: pointer;
    transition: all var(--motion-duration-fast, 150ms) var(--motion-easing-standard, ease);
    text-decoration: none;
    outline: none;
    position: relative;
    box-sizing: border-box;
    /* WHY 1: inherited --line-height-normal (1.5) plus pad-y plus border
       pushed the painted box past --xwui-control-height-* (md 32 → 35). */
    line-height: var(--xwui-control-line-height, 1);
    /* Light resting shadow - a STYLE-LEVEL setting (`--button-shadow`, defined
       per style in styles/style/{style}/shadows.css; default --shadow-sm). On by
       default. Per-button opt-out via config `shadow: false` (see below). */
    box-shadow: var(--button-shadow, var(--shadow-sm));
}

/* Per-button opt-out (config `shadow: false`) - drop the resting shadow. */
.xwui-button.xwui-button-no-shadow { --button-shadow: none; box-shadow: none; }

.xwui-button:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    box-shadow: var(--glow-button-focus, none);
}

/* A busy <button> is aria-disabled rather than natively disabled, so it keeps
   keyboard focus; it is listed here so it still looks exactly as it did when
   loading also matched :disabled. */
.xwui-button:disabled,
.xwui-button.xwui-button-disabled,
button.xwui-button.xwui-button-loading {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: none;
    /* Ensure text remains visible even when disabled */
    color: inherit !important;
}

/* Physical press - the button visibly depresses (shrinks) while held down,
   the way a real key does. The depth is a STYLE-LEVEL setting, not hardcoded:
   `--button-press-scale` is defined per style in styles/style/{style}/spacing.css
   (1 = no press / off). On by default. The `0.95` fallback keeps the press
   working for brands/styles that don't define the token. Per-button opt-out:
   XWUIButton sets `--button-press-scale: 1` inline when `press: false`.
   Variants set only `background` on :active, so this transform composes; the
   effect/toggleable buttons that declare their OWN :active transform (raised
   translateY, gradient reset, …) win by specificity and keep their feel. */
.xwui-button:active:not(:disabled) {
    transform: scale(var(--button-press-scale, 0.95));
}
/* Per-button opt-out (config `press: false`) - pin the scale to 1 (no press). */
.xwui-button.xwui-button-no-press { --button-press-scale: 1; }
@media (prefers-reduced-motion: reduce) {
    .xwui-button:active:not(:disabled) { transform: none; }
}

/* Sizes - driven by XWUI size standard (--xwui-control-height-* / --xwui-size-*) */
:is(.xwui-button-3xs,.xwui-button-xxxs) {
    padding: var(--xwui-size-pad-y-xxxs, 1px) var(--xwui-size-pad-x-xxxs, 3px);
    font-size: var(--xwui-size-font-xxxs, 9px);
    height: var(--xwui-button-height-xxxs);
    min-height: var(--xwui-button-height-xxxs);
    gap: 2px;
}
:is(.xwui-button-4xs,.xwui-button-xxxxs) {
    padding: var(--xwui-size-pad-y-xxxxs, 1px) var(--xwui-size-pad-x-xxxxs, 1.5px);
    font-size: var(--xwui-size-font-xxxxs, 8px);
    height: var(--xwui-button-height-xxxxs);
    min-height: var(--xwui-button-height-xxxxs);
    gap: 1px;
}
:is(.xwui-button-2xs,.xwui-button-xxs) {
    padding: var(--xwui-size-pad-y-xxs, 2px) var(--xwui-size-pad-x-xxs, 4px);
    font-size: var(--xwui-size-font-xxs, 10px);
    height: var(--xwui-button-height-xxs);
    min-height: var(--xwui-button-height-xxs);
    gap: 2px;
}
.xwui-button-xs {
    padding: var(--xwui-size-pad-y-xs, 3px) var(--xwui-size-pad-x-xs, 6px);
    font-size: var(--xwui-size-font-xs, 11px);
    height: var(--xwui-button-height-xs);
    min-height: var(--xwui-button-height-xs);
    gap: 2px;
}
:is(.xwui-button-s,.xwui-button-sm) {
    padding: var(--xwui-size-pad-y-sm, 4px) var(--xwui-size-pad-x-sm, 10px);
    font-size: var(--xwui-size-font-sm, 12px);
    height: var(--xwui-button-height-sm);
    min-height: var(--xwui-button-height-sm);
}
:is(.xwui-button-m,.xwui-button-md) {
    padding: var(--xwui-size-pad-y-md, 6px) var(--xwui-size-pad-x-md, 14px);
    font-size: var(--xwui-size-font-md, 14px);
    height: var(--xwui-button-height-md);
    min-height: var(--xwui-button-height-md);
}
:is(.xwui-button-l,.xwui-button-lg) {
    padding: var(--xwui-size-pad-y-lg, 8px) var(--xwui-size-pad-x-lg, 18px);
    font-size: var(--xwui-size-font-lg, 16px);
    height: var(--xwui-button-height-lg);
    min-height: var(--xwui-button-height-lg);
}
.xwui-button-xl {
    padding: var(--xwui-size-pad-y-xl, 10px) var(--xwui-size-pad-x-xl, 22px);
    font-size: var(--xwui-size-font-xl, 20px);
    height: var(--xwui-button-height-xl);
    min-height: var(--xwui-button-height-xl);
}
:is(.xwui-button-2xl,.xwui-button-xxl) {
    padding: var(--xwui-size-pad-y-xxl, 12px) var(--xwui-size-pad-x-xxl, 28px);
    font-size: var(--xwui-size-font-xxl, 24px);
    height: var(--xwui-button-height-xxl);
    min-height: var(--xwui-button-height-xxl);
}
:is(.xwui-button-3xl,.xwui-button-xxxl) {
    padding: var(--xwui-size-pad-y-xxxl, 16px) var(--xwui-size-pad-x-xxxl, 36px);
    font-size: var(--xwui-size-font-xxxl, 32px);
    height: var(--xwui-button-height-xxxl);
    min-height: var(--xwui-button-height-xxxl);
}
:is(.xwui-button-4xl,.xwui-button-xxxxl) {
    padding: var(--xwui-size-pad-y-xxxxl, 24px) var(--xwui-size-pad-x-xxxxl, 56px);
    font-size: var(--xwui-size-font-xxxxl, 48px);
    height: var(--xwui-button-height-xxxxl);
    min-height: var(--xwui-button-height-xxxxl);
}

/* Legacy aliases - keep old class names working */
.xwui-button-tiny   { padding: var(--xwui-size-pad-y-xxs, 2px) var(--xwui-size-pad-x-xxs, 4px); font-size: var(--xwui-size-font-xs, 11px); height: var(--xwui-button-height-xs); min-height: var(--xwui-button-height-xs); gap: 2px; }
.xwui-button-small  { padding: var(--xwui-size-pad-y-sm, 4px) var(--xwui-size-pad-x-sm, 10px); font-size: var(--xwui-size-font-sm, 12px); height: var(--xwui-button-height-sm); min-height: var(--xwui-button-height-sm); }
.xwui-button-medium { padding: var(--xwui-size-pad-y-md, 6px) var(--xwui-size-pad-x-md, 14px); font-size: var(--xwui-size-font-md, 14px); height: var(--xwui-button-height-md); min-height: var(--xwui-button-height-md); }
.xwui-button-large  { padding: var(--xwui-size-pad-y-lg, 8px) var(--xwui-size-pad-x-lg, 18px); font-size: var(--xwui-size-font-lg, 16px); height: var(--xwui-button-height-lg); min-height: var(--xwui-button-height-lg); }

/* Density (M3, Fluent, Carbon) - overrides size padding when set */
.xwui-button-container[data-density="compact"] .xwui-button {
    padding: var(--control-padding-y-compact) var(--control-padding-x-compact);
    height: var(--control-min-height-compact);
    min-height: var(--control-min-height-compact);
}
.xwui-button-container[data-density="comfortable"] .xwui-button {
    padding: var(--control-padding-y-comfortable) var(--control-padding-x-comfortable);
    height: var(--control-min-height-comfortable);
    min-height: var(--control-min-height-comfortable);
}
.xwui-button-container[data-density="spacious"] .xwui-button {
    padding: var(--control-padding-y-spacious) var(--control-padding-x-spacious);
    height: var(--control-min-height-spacious);
    min-height: var(--control-min-height-spacious);
}

/* ============================================
   Variants - driven by ROLE PAIRS (contrast-guaranteed bg+fg duos).
   Role pairs live in styles/theme/colors/*.css and are validated by
   tools/validate-theme-contrast.ts. Legacy tokens (--accent-*, --text-inverse)
   are kept as fallbacks so un-migrated themes keep working.
   ============================================ */

/* RESTING variant backgrounds no longer need !important: XWUIButton renders flat
   DOM and never carries XWUIItem status classes, so a resting solid button has no
   competing same-specificity background, and tonal/effect layers still win by
   specificity / source order. The :hover and :active backgrounds DO keep
   !important - there they must out-rank the tonal/effect `!important` resting
   fills (by specificity within the important tier) and let pressed fills (lower
   specificity) override :hover. Colors keep !important so the disabled
   `color:inherit` rule can't override the variant ink. */
.xwui-button.xwui-button-primary {
    background: var(--accent-primary, var(--role-primary-bg));
    color: var(--role-primary-fg, var(--text-inverse)) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-primary, var(--role-primary-bg));
    /* An accent may give its primary a resting glow; otherwise the style's
       resting shadow, as for every button. */
    box-shadow: var(--glow-button-primary, var(--button-shadow, var(--shadow-sm)));
}
.xwui-button.xwui-button-primary:hover:not(:disabled) {
    background: var(--accent-hover, var(--role-primary-bg-hover)) !important;
    border-color: var(--accent-hover, var(--role-primary-bg-hover));
    box-shadow: var(--glow-button-hover, var(--button-shadow, var(--shadow-md)));
}
.xwui-button.xwui-button-primary:active:not(:disabled) {
    background: var(--accent-primary, var(--role-primary-bg-active, var(--role-primary-bg))) !important;
    border-color: var(--accent-primary, var(--role-primary-bg-active, var(--role-primary-bg)));
    box-shadow: var(--glow-button-active, none);
}
.xwui-button.xwui-button-primary:focus-visible {
    box-shadow: var(--glow-button-focus, none);
}

/* CTA - brand marketing accent (Sell / Get key). Tokens let products map amber/gold
   without specificity wars against primary. */
.xwui-button.xwui-button-cta {
    background: var(--accent-primary, var(--accent-warning, var(--accent-primary, var(--role-primary-bg))));
    color: var(--text-on-accent, #0d0c0b) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-primary, var(--accent-warning, var(--accent-primary, var(--role-primary-bg))));
    font-weight: 800;
}
.xwui-button.xwui-button-cta:hover:not(:disabled) {
    background: var(--accent-hover, var(--accent-primary, var(--accent-warning, var(--accent-hover)))) !important;
    border-color: var(--accent-hover, var(--accent-primary, var(--accent-warning, var(--accent-hover))));
    box-shadow: var(--glow-button-hover, var(--button-shadow, var(--shadow-md)));
}
.xwui-button.xwui-button-cta:active:not(:disabled) {
    background: var(--accent-primary, var(--accent-warning, var(--accent-primary))) !important;
    border-color: var(--accent-primary, var(--accent-warning, var(--accent-primary)));
    box-shadow: var(--glow-button-active, none);
}
.xwui-button.xwui-button-cta:focus-visible {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary, var(--accent-warning, #f59e0b)) 35%, transparent);
}

/* Secondary is a DARK neutral solid (dark surface, inverse text) - the
   high-contrast counterpart to primary, matching the slate-800 "Secondary"
   in common button catalogues. Theme-aware: --text-primary/--text-inverse
   flip with the active colour theme, so it stays a contrast button in dark
   mode too. (Tonal-neutral, `.xwui-button-tonal.xwui-button-secondary`, keeps
   the light tinted look and wins by specificity.) */
.xwui-button.xwui-button-secondary {
    background: var(--text-primary);
    color: var(--text-inverse) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--text-primary);
}
.xwui-button.xwui-button-secondary:hover:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 88%, #000) !important;
    border-color: color-mix(in srgb, var(--text-primary) 88%, #000);
}
.xwui-button.xwui-button-secondary:active:not(:disabled) {
    background: color-mix(in srgb, var(--text-primary) 78%, #000) !important;
}

.xwui-button.xwui-button-success {
    background: var(--accent-success, var(--role-success-bg));
    color: var(--role-success-fg, var(--text-inverse)) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-success, var(--role-success-bg));
}
.xwui-button.xwui-button-success:hover:not(:disabled) {
    background: var(--accent-success-hover, var(--role-success-bg-hover)) !important;
    border-color: var(--accent-success-hover, var(--role-success-bg-hover));
    box-shadow: var(--glow-button-hover, var(--button-shadow, var(--shadow-md)));
}
.xwui-button.xwui-button-success:active:not(:disabled) {
    background: var(--accent-success, var(--role-success-bg-active, var(--role-success-bg))) !important;
    border-color: var(--accent-success, var(--role-success-bg-active, var(--role-success-bg)));
}

.xwui-button.xwui-button-danger {
    background: var(--accent-error, var(--role-danger-bg));
    color: var(--role-danger-fg, var(--text-inverse)) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-error, var(--role-danger-bg));
}
.xwui-button.xwui-button-danger:hover:not(:disabled) {
    background: var(--accent-error, var(--role-danger-bg-hover)) !important;
    border-color: var(--accent-error, var(--role-danger-bg-hover));
    box-shadow: var(--glow-button-hover, var(--button-shadow, var(--shadow-md)));
}
.xwui-button.xwui-button-danger:active:not(:disabled) {
    background: var(--accent-error, var(--role-danger-bg-active, var(--role-danger-bg))) !important;
    border-color: var(--accent-error, var(--role-danger-bg-active, var(--role-danger-bg)));
}

.xwui-button.xwui-button-warning {
    background: var(--accent-warning, var(--role-warning-bg));
    /* fg guaranteed readable against the yellow bg via the theme pair */
    color: var(--role-warning-fg, var(--text-primary)) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-warning, var(--role-warning-bg));
}
.xwui-button.xwui-button-warning:hover:not(:disabled) {
    background: var(--accent-warning, var(--role-warning-bg-hover)) !important;
    border-color: var(--accent-warning, var(--role-warning-bg-hover));
    color: var(--role-warning-fg, var(--text-primary)) !important;
}
.xwui-button.xwui-button-warning:active:not(:disabled) {
    background: var(--accent-warning, var(--role-warning-bg-active, var(--role-warning-bg))) !important;
    border-color: var(--accent-warning, var(--role-warning-bg-active, var(--role-warning-bg)));
    color: var(--role-warning-fg, var(--text-primary)) !important;
}

.xwui-button.xwui-button-info {
    background: var(--accent-primary, var(--role-info-bg));
    color: var(--role-info-fg, var(--text-inverse)) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-primary, var(--role-info-bg));
}
.xwui-button.xwui-button-info:hover:not(:disabled) {
    background: var(--accent-hover, var(--role-info-bg-hover)) !important;
    border-color: var(--accent-hover, var(--role-info-bg-hover));
}
.xwui-button.xwui-button-info:active:not(:disabled) {
    background: var(--accent-primary, var(--role-info-bg-active, var(--role-info-bg))) !important;
    border-color: var(--accent-primary, var(--role-info-bg-active, var(--role-info-bg)));
}

/* Outline/ghost stay colored-text-only (no solid bg), so they use the role's bg
   as the *ink* color - which guarantees legibility against the page surface. */
.xwui-button.xwui-button-outline {
    background: transparent;
    /* Text is the accent as INK (4.5:1 text floor); the border keeps the raw
       accent (3:1 non-text floor). See --role-primary-ink in theme/colors. */
    color: var(--role-primary-ink, var(--accent-primary, var(--role-primary-bg))) !important;
    border: var(--border-button-width, var(--border-width-regular, 1.5px)) var(--border-button-style, solid) var(--accent-primary, var(--role-primary-bg));
}
.xwui-button.xwui-button-outline:hover:not(:disabled) {
    background: var(--bg-hover);
    border-color: var(--accent-hover, var(--role-primary-bg-hover));
}
.xwui-button.xwui-button-outline:active:not(:disabled) {
    background: var(--bg-active);
}

/* Ghost ink follows the painted surface: inherit the ancestor's `color`
   (set by .xwui-surface / .xwui-surface-inverse, or any host). Do NOT fall
   back to page-level --role-surface-fg / --text-primary - those stay dark
   under data-theme="light" and make ghost invisible on a dark inset panel.
   --xwui-button-ghost-fg remains the explicit override slot (game shells). */
.xwui-button.xwui-button-ghost {
    /* !important on bg: bare <button> UA styles are often solid white - that
       plus light inherited ink reads as white-on-white on dark panels. */
    background: transparent !important;
    color: var(--xwui-button-ghost-fg, inherit) !important;
    border: none;
}
.xwui-button.xwui-button-ghost:hover:not(:disabled) {
    background: var(--bg-hover) !important;
    color: var(--xwui-button-ghost-fg-hover, var(--xwui-button-ghost-fg, inherit)) !important;
}
.xwui-button.xwui-button-ghost:active:not(:disabled) {
    background: var(--bg-active) !important;
    color: var(--xwui-button-ghost-fg-hover, var(--xwui-button-ghost-fg, inherit)) !important;
}

/* Flat variants (ghost / outline / link) must NOT look raised. The base button
   applies a resting drop shadow via --button-shadow (a style-level default); a
   transparent, no-fill button with a drop shadow reads wrong. Override the
   VARIABLE to none so it's gone in EVERY style and theme - both the resting
   (.xwui-button) and the :hover box-shadow read --button-shadow, so killing the
   variable removes both. The deliberate inset "pressed" shadow is unaffected. */
.xwui-button.xwui-button-ghost,
.xwui-button.xwui-button-outline,
.xwui-button.xwui-button-link {
    --button-shadow: none;
    box-shadow: none;
}

/* ============================================
   Toggleable push-button (pressed/unpressed state)
   ============================================ */

/* Pressed state - "pushed in" look: inset shadow + slightly darker bg.
   The bg/color pair comes from role-primary so contrast is guaranteed. */
.xwui-button.xwui-button-pressed {
    background: var(--accent-primary, var(--role-primary-bg-active, var(--role-primary-bg))) !important;
    color: var(--role-primary-fg, var(--text-inverse)) !important;
    border-color: var(--accent-primary, var(--role-primary-bg-active, var(--role-primary-bg))) !important;
    /* Inset shadow gives the tactile "pressed" feel */
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.08) !important;
    transform: translateY(1px);
}

/* Outline variant when pressed: fill with role-primary (flip from ghost to filled) */
.xwui-button.xwui-button-outline.xwui-button-pressed {
    background: var(--accent-primary, var(--role-primary-bg)) !important;
    color: var(--role-primary-fg, var(--text-inverse)) !important;
    border-color: var(--accent-primary, var(--role-primary-bg)) !important;
}

/* Ghost variant when pressed: subtle fill, still no border */
.xwui-button.xwui-button-ghost.xwui-button-pressed {
    background: color-mix(in srgb, var(--accent-primary, var(--role-primary-bg)) 15%, transparent) !important;
    color: var(--accent-primary, var(--role-primary-bg)) !important;
    box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.08) !important;
}

/* Keep the hover state visible even when pressed */
.xwui-button.xwui-button-pressed:hover:not(:disabled) {
    filter: brightness(1.06);
}

/* Toggleable buttons always have keyboard focus treatment */
.xwui-button-toggleable:focus-visible {
    outline: 2px solid var(--accent-primary, var(--role-primary-bg));
    outline-offset: 2px;
}

/* Full width */
.xwui-button-full-width {
    width: 100%;
}

/* Loading state - the label stays visible next to a real XWUISpinner child
   (mounted by XWUIButton.applyLoadingSpinner). The spinner sits before the
   text and inherits the button's text colour. Pointer events are disabled. */
.xwui-button-loading {
    pointer-events: none;
}
/* Still focusable while busy, so Space could press it: no press depth (the
   same per-button opt-out `press: false` uses). */
.xwui-button.xwui-button-loading { --button-press-scale: 1; }
/* The busy words: announced, not shown. Owned here so the loading state does
   not depend on a global utility stylesheet; absolutely positioned, so it takes
   no flex slot or gap next to the spinner. */
.xwui-button-loading-text {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.xwui-button-loading-spinner {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* The embedded spinner: collapse its column gap and inherit the button colour
   so it reads as one of the button's own glyphs regardless of variant. */
.xwui-button .xwui-button-loading-spinner .xwui-spinner { gap: 0; }
.xwui-button .xwui-button-loading-spinner .xwui-spinner-icon { color: inherit; }

/* Icon */
.xwui-button-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--button-icon-color, currentColor);
}

/* flipRtl: true on an SVG-markup icon. A named icon is an XWUIIcon, which
   mirrors itself (.xwui-icon-directional in XWUIIcon.css); a markup glyph is
   not, so the button mirrors its box. Keyed off the inherited dir, so it
   follows a language switch with no re-render. */
[dir="rtl"] .xwui-button-icon-flip {
    transform: scaleX(-1);
}

/* Direct-child svg only (a raw custom-SVG icon) is sized to 1em. An XWUIIcon
   name-icon nests its svg deeper (.xwui-button-icon > .xwui-icon > … > svg) and
   sizes itself (18px), so this rule intentionally does NOT reach it. */
.xwui-button-icon > svg {
    width: 1em;
    height: 1em;
}

/* Icon-only buttons - square/circle via aspect-ratio:1.
   WHY a single :not(:has(A, B)) instead of OR-ing two :not(:has(...)) clauses:
   the legacy form matched EVERY modern icon+label button (labels use
   .xwui-button-text, so `:not(:has(.xwui-item-text))` always fired) and forced
   aspect-ratio:1 - pill Sign-in with long i18n labels became a dark circular blob. */
.xwui-button:not(:has(.xwui-button-text, .xwui-item-text)):has(.xwui-button-icon) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-xs, 0.375rem);
    aspect-ratio: 1;
}

/* Fallback for browsers that don't support :has() */
.xwui-button-icon-only {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-xs, 0.375rem);
    aspect-ratio: 1;
    min-width: var(--spacing-md, 1.25rem);
    min-height: var(--spacing-md, 1.25rem);
}

.xwui-button-icon-only .xwui-button-icon {
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.xwui-button-icon-only .xwui-button-icon svg {
    width: 1.25em;
    height: 1.25em;
    display: block;
    margin: auto;
}

/* Icon-only button sizes - same control heights as text buttons */
.xwui-button-icon-only:is(.xwui-button-3xs,.xwui-button-xxxs) { padding: 2px; width: var(--xwui-button-height-xxxs); height: var(--xwui-button-height-xxxs); min-width: var(--xwui-button-height-xxxs); min-height: var(--xwui-button-height-xxxs); }
.xwui-button-icon-only:is(.xwui-button-4xs,.xwui-button-xxxxs) { padding: 1px; width: var(--xwui-button-height-xxxxs); height: var(--xwui-button-height-xxxxs); min-width: var(--xwui-button-height-xxxxs); min-height: var(--xwui-button-height-xxxxs); }
.xwui-button-icon-only:is(.xwui-button-2xs,.xwui-button-xxs)  { padding: 2px; width: var(--xwui-button-height-xxs); height: var(--xwui-button-height-xxs); min-width: var(--xwui-button-height-xxs); min-height: var(--xwui-button-height-xxs); }
.xwui-button-icon-only.xwui-button-xs   { padding: 3px; width: var(--xwui-button-height-xs); height: var(--xwui-button-height-xs); min-width: var(--xwui-button-height-xs); min-height: var(--xwui-button-height-xs); }
.xwui-button-icon-only:is(.xwui-button-s,.xwui-button-sm)   { padding: var(--xwui-size-pad-y-sm, 4px); width: var(--xwui-button-height-sm); height: var(--xwui-button-height-sm); min-width: var(--xwui-button-height-sm); min-height: var(--xwui-button-height-sm); }
.xwui-button-icon-only:is(.xwui-button-m,.xwui-button-md)   { padding: var(--xwui-size-pad-y-md, 6px); width: var(--xwui-button-height-md); height: var(--xwui-button-height-md); min-width: var(--xwui-button-height-md); min-height: var(--xwui-button-height-md); }
.xwui-button-icon-only:is(.xwui-button-l,.xwui-button-lg)   { padding: var(--xwui-size-pad-y-lg, 8px); width: var(--xwui-button-height-lg); height: var(--xwui-button-height-lg); min-width: var(--xwui-button-height-lg); min-height: var(--xwui-button-height-lg); }
.xwui-button-icon-only.xwui-button-xl   { padding: var(--xwui-size-pad-y-xl, 10px); width: var(--xwui-button-height-xl); height: var(--xwui-button-height-xl); min-width: var(--xwui-button-height-xl); min-height: var(--xwui-button-height-xl); }
.xwui-button-icon-only:is(.xwui-button-2xl,.xwui-button-xxl)  { padding: var(--xwui-size-pad-y-xxl, 12px);  width: var(--xwui-button-height-xxl); height: var(--xwui-button-height-xxl); min-width: var(--xwui-button-height-xxl); min-height: var(--xwui-button-height-xxl); }
.xwui-button-icon-only:is(.xwui-button-3xl,.xwui-button-xxxl) { padding: var(--xwui-size-pad-y-xxxl, 16px);   width: var(--xwui-button-height-xxxl); height: var(--xwui-button-height-xxxl); min-width: var(--xwui-button-height-xxxl); min-height: var(--xwui-button-height-xxxl); }
.xwui-button-icon-only:is(.xwui-button-4xl,.xwui-button-xxxxl) { padding: var(--xwui-size-pad-y-xxxxl, 24px);   width: var(--xwui-button-height-xxxxl); height: var(--xwui-button-height-xxxxl); min-width: var(--xwui-button-height-xxxxl); min-height: var(--xwui-button-height-xxxxl); }

/* Icon-only legacy aliases */
.xwui-button-icon-only.xwui-button-small  { padding: var(--xwui-size-pad-y-sm, 4px); width: var(--xwui-button-height-sm); height: var(--xwui-button-height-sm); min-width: var(--xwui-button-height-sm); min-height: var(--xwui-button-height-sm); }
.xwui-button-icon-only.xwui-button-medium { padding: var(--xwui-size-pad-y-md, 6px); width: var(--xwui-button-height-md); height: var(--xwui-button-height-md); min-width: var(--xwui-button-height-md); min-height: var(--xwui-button-height-md); }
.xwui-button-icon-only.xwui-button-large  { padding: var(--xwui-size-pad-y-lg, 8px); width: var(--xwui-button-height-lg); height: var(--xwui-button-height-lg); min-width: var(--xwui-button-height-lg); min-height: var(--xwui-button-height-lg); }

/* Text - the label. Semibold to match the previous XWUIItem `-bold` label
   weight. NOT flex:1, so an icon + label stay a tight, centred group (the
   button's own justify-content:center centres them) instead of the label
   stretching and pushing the icon to the edge. */
.xwui-button-text {
    font-weight: var(--font-weight-semibold, 600);
    text-align: center;
}

/* Ensure text inside buttons inherits button color for visibility */
.xwui-button .xwui-button-text,
.xwui-button span,
.xwui-button div {
    color: inherit;
}

/* Ensure icons inside buttons inherit button color for visibility */
.xwui-button .xwui-button-icon,
.xwui-button .xwui-icon {
    color: inherit;
}

/* Do NOT force fill/stroke on button icons. Icons resolved by XWUIIcon carry
   their own correct paint (feather/tabler: stroke="currentColor" fill="none";
   bootstrap: fill="currentColor"). Forcing `fill: currentColor` here filled
   the stroke-based glyphs solid - the "icon transformation" that made e.g. the
   gear render as a chunky blob. Inheriting `color` (above) is enough: the
   glyph's own currentColor references resolve to the button's text colour. */

/* Remove margin from xwui-icon when inside button - button uses gap for spacing */
.xwui-button .xwui-icon {
    margin: 0;
}

/* ============================================
   Link variant - looks like inline text, underlines on hover. No bg/border.
   ============================================ */
.xwui-button.xwui-button-link {
    background: transparent;
    /* Accent as INK, not the raw fill: indigo on the dark ground is 3.85:1 as
       text. --role-primary-ink clears 4.5:1 in the four default grounds.
       The ink is a documented custom property, --xwui-button-link-ink, read in
       the var() FALLBACK slot (like --xwui-button-ghost-fg): a host sets it on
       any ancestor, or on the button, and the colour follows. It used to be a
       bare `color: ... !important`, which no host token layer could out-rank,
       so a page that draws its row links dark had to override internals.
       Hover reads --xwui-button-link-ink-hover and, unset, mixes the (possibly
       overridden) ink toward --text-primary, so a dark override stays dark. */
    color: var(--xwui-button-link-ink, var(--role-primary-ink, var(--accent-primary, var(--role-primary-bg))));
    border: none;
    padding-inline: var(--spacing-xs, 0.375rem);
    min-height: 0;
}
/* The base disabled rule is `color: inherit !important`; the link has always
   kept its ink while disabled (dimmed by the 0.6 opacity), so it is restated at
   higher specificity here and nowhere else. */
.xwui-button.xwui-button-link:disabled,
.xwui-button.xwui-button-link.xwui-button-disabled {
    color: var(--xwui-button-link-ink, var(--role-primary-ink, var(--accent-primary, var(--role-primary-bg)))) !important;
}
.xwui-button.xwui-button-link:hover:not(:disabled) {
    background: transparent;
    /* Hover moves toward --text-primary (the highest-contrast ink of either
       ground) instead of to --accent-hover, which is DARKER than the accent
       and so fell to ~2.5:1 on a dark surface. */
    color: var(--xwui-button-link-ink-hover, color-mix(in srgb, var(--xwui-button-link-ink, var(--role-primary-ink, var(--accent-primary))) 80%, var(--text-primary)));
    text-decoration: underline;
}
.xwui-button.xwui-button-link:active:not(:disabled) {
    background: transparent;
}

/* ============================================
   Tonal / soft variants - tinted fill + coloured ink (M3 "tonal").
   Higher specificity than the solid `.xwui-button-<variant>` rules so the
   tint wins; ink stays the saturated role colour for legibility on the tint.
   ============================================ */
.xwui-button.xwui-button-tonal {
    border-color: transparent !important;
    box-shadow: none;
}
.xwui-button.xwui-button-tonal.xwui-button-primary,
.xwui-button.xwui-button-tonal.xwui-button-info {
    background: color-mix(in srgb, var(--accent-primary) 14%, transparent) !important;
    color: var(--role-primary-ink, var(--accent-primary)) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-primary:hover:not(:disabled),
.xwui-button.xwui-button-tonal.xwui-button-info:hover:not(:disabled) {
    background: color-mix(in srgb, var(--accent-primary) 24%, transparent) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-danger {
    background: color-mix(in srgb, var(--accent-error) 14%, transparent) !important;
    color: var(--role-danger-ink, var(--accent-error)) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-danger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--accent-error) 24%, transparent) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-success {
    background: color-mix(in srgb, var(--accent-success) 16%, transparent) !important;
    color: var(--role-success-tonal-ink, color-mix(in srgb, var(--accent-success) 80%, black)) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-success:hover:not(:disabled) {
    background: color-mix(in srgb, var(--accent-success) 26%, transparent) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-warning {
    background: color-mix(in srgb, var(--accent-warning) 18%, transparent) !important;
    color: var(--role-warning-tonal-ink, color-mix(in srgb, var(--accent-warning) 70%, black)) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-warning:hover:not(:disabled) {
    background: color-mix(in srgb, var(--accent-warning) 28%, transparent) !important;
}
/* Neutral tonal (secondary) - surface tint, primary ink. */
.xwui-button.xwui-button-tonal.xwui-button-secondary {
    background: var(--bg-secondary, color-mix(in srgb, var(--text-primary) 8%, transparent)) !important;
    color: var(--text-primary) !important;
}
.xwui-button.xwui-button-tonal.xwui-button-secondary:hover:not(:disabled) {
    background: var(--bg-hover, color-mix(in srgb, var(--text-primary) 14%, transparent)) !important;
}

/* ============================================
   Shape overrides - per-button corner radius (overrides theme --radius-button).
   ============================================ */
.xwui-button.xwui-button-shape-sharp   { border-radius: 0 !important; }
.xwui-button.xwui-button-shape-rounded { border-radius: var(--radius-lg, 1rem) !important; }
.xwui-button.xwui-button-shape-pill    { border-radius: 9999px !important; }

/* Host element follows the button shape. The custom-element host (<xwui-button>)
   wraps the real <button>; without this it's a square box, so a border /
   background / backdrop-filter set on the HOST (the natural way to skin a button - e.g. a glassmorphism frosted ring) draws a stray RECTANGLE around the pill.
   Mirroring the shape attribute onto the host makes the host fully customizable:
   anything painted on it now hugs the button outline. inline-flex so the host
   shrink-wraps the button instead of stretching to a block. */
xwui-button { display: inline-flex; border-radius: var(--radius-button, var(--radius-sm, 6px)); }
xwui-button[shape="sharp"]   { border-radius: 0; }
xwui-button[shape="rounded"] { border-radius: var(--radius-lg, 1rem); }
xwui-button[shape="pill"]    { border-radius: 9999px; }
xwui-button[full-width="true"] { display: flex; width: 100%; }
/* fullWidth passed as config (a property, not the attribute): the host
   follows its full-width button. */
xwui-button:has(> .xwui-button-full-width) { display: flex; width: 100%; }

/* ============================================
   Decorative effects - opt-in marketing / premium CTA treatments.
   ============================================ */
/* Gradient fill - warm pink → red → yellow sweep, lifts on hover. */
.xwui-button.xwui-button-effect-gradient {
    background: linear-gradient(to right, #ec4899, #ef4444, #eab308) !important;
    color: #ffffff !important;
    border: none !important;
    box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.12));
}
.xwui-button.xwui-button-effect-gradient:hover:not(:disabled) {
    background: linear-gradient(to right, #db2777, #dc2626, #ca8a04) !important;
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.18));
}
.xwui-button.xwui-button-effect-gradient:active:not(:disabled) {
    transform: translateY(0);
}

/* Gradient border - a dark fill inside a 1px gradient ring. The ring follows
   --button-gradient-border, and the fill --button-gradient-border-fill. */
.xwui-button.xwui-button-effect-gradient-border {
    border: 1px solid transparent !important;
    background:
        linear-gradient(var(--button-gradient-border-fill, var(--bg-primary)), var(--button-gradient-border-fill, var(--bg-primary))) padding-box,
        var(--button-gradient-border, linear-gradient(100deg, #2ee6ff 0%, #9b6bff 34%, #ff4fa3 66%, #ff8a3d 100%)) border-box !important;
    color: var(--text-primary) !important;
}
.xwui-button.xwui-button-effect-gradient-border:hover:not(:disabled) {
    transform: translateY(-1px);
    filter: brightness(1.12);
}

/* Custom gradient fill - the gradient itself is set inline (with !important to
   beat the variant's own background); this rule supplies the on-accent text and
   removes the border so any CSS gradient reads cleanly. */
.xwui-button.xwui-button-gradient {
    color: var(--text-on-accent, #ffffff) !important;
    border: none !important;
}
.xwui-button.xwui-button-gradient:hover:not(:disabled) {
    filter: brightness(1.06);
}

/* 3D push - solid bottom edge that collapses when pressed. */
.xwui-button.xwui-button-effect-raised {
    border-bottom: 4px solid color-mix(in srgb, var(--accent-primary) 65%, black) !important;
    transition: transform var(--motion-duration-instant, 100ms) var(--motion-easing-standard, ease), border-bottom-width var(--motion-duration-instant, 100ms) var(--motion-easing-standard, ease);
}
.xwui-button.xwui-button-effect-raised:active:not(:disabled) {
    border-bottom-width: 0 !important;
    transform: translateY(4px);
}

/* Animated glow halo - fuchsia pulse (the marketing "glow" accent). */
.xwui-button.xwui-button-effect-glow {
    animation: xwui-button-glow 2s ease-in-out infinite;
}
@keyframes xwui-button-glow {
    0%, 100% { box-shadow: 0 0 10px 2px color-mix(in srgb, #e879f9 55%, transparent); }
    50%      { box-shadow: 0 0 22px 6px color-mix(in srgb, #e879f9 80%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
    .xwui-button.xwui-button-effect-glow { animation: none; }
}

/* Note: Dark theme support is handled automatically via theme/colors/{theme}.css files */


/* align: 'start' - icon and label line up at the start edge (menu / palette rows). */
.xwui-button.xwui-button-align-start { justify-content: flex-start; text-align: start; }

/* ============================================
   Looks - named finishes (gradient, glow, glass, tint, outline, ring, brand)
   and the start tile. Opt-in through config `look`; a button without one is
   untouched by everything below. Contract: docs/REF_BUTTON_PRESETS.md.

   PUBLIC tokens (set on :root, a theme, any ancestor, or per instance through
   the colour inputs, which write them inline): --xwui-button-color, -accent,
   -from, -to, -ink, -tile, -tile-ink, -fill, -hue-shift, -angle, -glow, -blur,
   -focus, -tile-size, -tile-radius.
   They are read ONLY in var() fallback slots, never declared on .xwui-button,
   so a theme value reaches the button and an inline value still wins.

   PRIVATE (--_*) values are resolved per element below. Every colour chains to
   a theme token (accent, role ink, text, bg); no literal colour is written.

   WHY the contrast holds (WCAG 1.4.3, 4.5:1): the label ink is the tone's own
   on-colour ink (the accent's --accent-primary-ink, or the role ink of a
   success / danger / warning variant), and every tone colour is already AA
   against it. The gradient starts at that tone and ends at the same colour
   turned 32 degrees round the hue wheel at the same lightness (oklch), then
   pushed 15% AWAY from the ink (toward black under a white ink, toward a light
   grey under a dark ink). The turn keeps lightness; the push absorbs the small
   luminance drift of the turn. The deep (hover) accent is deliberately NOT the
   base: against a dark ink it is the darker colour and falls below AA. The
   prototype's lilac stop (#c27bff) is 2.77:1 against white; this formula gives
   4.7:1 or better at the end stop and along the sweep for every shipped accent
   (XWUIButton.look.test.ts re-derives it, across all accent x theme pairs for
   the success, danger and warning variants too, and fails under 4.5:1). An
   engine without relative colour syntax draws the tone as a solid fill, which
   is the guaranteed starting colour.
   ============================================ */

/* ---- tone: which theme colours a look reads, by variant -------------------- */
.xwui-button[class*="xwui-button-look-"] {
    --_tone: var(--accent-primary, var(--role-primary-bg));
    --_onink: var(--accent-primary-ink, var(--role-primary-fg, var(--text-inverse)));
    --_tint-ink: var(--role-primary-ink, var(--accent-primary, var(--role-primary-bg)));
}
.xwui-button[class*="xwui-button-look-"].xwui-button-success {
    --_tone: var(--accent-success, var(--role-success-bg));
    --_onink: var(--role-success-fg, var(--text-primary));
    --_tint-ink: var(--role-success-tonal-ink, color-mix(in srgb, var(--accent-success) 80%, black));
}
.xwui-button[class*="xwui-button-look-"].xwui-button-danger {
    --_tone: var(--accent-error, var(--role-danger-bg));
    --_onink: var(--role-danger-fg, var(--text-inverse));
    --_tint-ink: var(--role-danger-ink, var(--accent-error));
}
.xwui-button[class*="xwui-button-look-"].xwui-button-warning {
    --_tone: var(--accent-warning, var(--role-warning-bg));
    --_onink: var(--role-warning-fg, var(--text-primary));
    --_tint-ink: var(--role-warning-tonal-ink, color-mix(in srgb, var(--accent-warning) 70%, black));
}
.xwui-button[class*="xwui-button-look-"].xwui-button-secondary {
    --_tone: var(--text-primary);
    --_onink: var(--text-inverse);
    --_tint-ink: var(--text-primary);
}

/* ---- resolution: public tokens win over the tone ---------------------------- */
.xwui-button[class*="xwui-button-look-"] {
    --_color: var(--xwui-button-color, var(--_tone));
    --_ink: var(--xwui-button-ink, var(--_onink));
    --_from: var(--xwui-button-from, var(--_color));
    --_to: var(--xwui-button-to, var(--_from));
    --_accent: var(--xwui-button-accent, var(--_from));
    --_ring-end: var(--xwui-button-accent, var(--_to));
    --_angle: var(--xwui-button-angle, 135deg);
    --_bw: var(--border-button-width, var(--border-width-regular, 1.5px));
    --_surface: var(--xwui-button-fill, var(--bg-elevated, var(--bg-primary)));
    --_text: var(--xwui-button-ink, var(--text-primary));
    --_focus: var(--xwui-button-focus, var(--accent-primary));
    --_tint-fg: var(--xwui-button-ink, var(--_tint-ink));
}
/* The author brought their own base colour: a tint's or outline's ink is built
   from it. 30 percent colour, 70 percent theme text: measured over every shipped
   accent on the light and dark themes it keeps that ink at or above 5.8:1 (a
   50/50 mix drops a pale colour such as chalk to 3.2:1). */
.xwui-button[class*="xwui-button-look-"].xwui-button-tone-custom {
    --_tint-ink: color-mix(in srgb, var(--_color) 30%, var(--text-primary));
}
/* A gradient reads start to end; in a right-to-left page it must run the other
   way round, so the angle mirrors. */
[dir="rtl"] .xwui-button[class*="xwui-button-look-"] {
    --_angle: calc(360deg - var(--xwui-button-angle, 135deg));
}
/* The end stop: the start colour turned round the hue wheel and nudged away from
   the ink (see the header). --xwui-button-hue-shift is a unitless angle. */
@supports (color: oklch(from red l c h)) {
    .xwui-button[class*="xwui-button-look-"] {
        --_away: oklch(from var(--_ink) calc(1 - l) 0 0);
        --_to: var(--xwui-button-to, color-mix(in oklab, oklch(from var(--_from) l c calc(h + var(--xwui-button-hue-shift, 32))) 85%, var(--_away)));
        --_ring-end: var(--xwui-button-accent, oklch(from var(--_to) l c calc(h + var(--xwui-button-hue-shift, 32))));
    }
}

/* ---- the looks: each sets private paint values; the shared rule applies them */
.xwui-button.xwui-button-look-gradient {
    --_bg: linear-gradient(var(--_angle), var(--_from), var(--_to));
    --_fg: var(--_ink);
    --_edge: transparent;
    --_shadow: var(--xwui-button-glow, 0 8px 24px -8px color-mix(in srgb, var(--_accent) 70%, transparent), inset 0 1px 0 color-mix(in srgb, var(--_ink) 25%, transparent));
    --_shadow-hover: 0 10px 30px -8px color-mix(in srgb, var(--_accent) 85%, transparent), inset 0 1px 0 color-mix(in srgb, var(--_ink) 30%, transparent);
    --_hover-filter: saturate(1.12);
}
.xwui-button.xwui-button-look-glow {
    --_bg: var(--_from);
    --_fg: var(--_ink);
    --_edge: var(--_from);
    --_shadow: var(--xwui-button-glow, 0 0 0 1px color-mix(in srgb, var(--_accent) 35%, transparent), 0 0 16px 1px color-mix(in srgb, var(--_accent) 50%, transparent), 0 10px 28px -10px color-mix(in srgb, var(--_accent) 70%, transparent));
    --_shadow-hover: 0 0 0 1px color-mix(in srgb, var(--_accent) 55%, transparent), 0 0 26px 4px color-mix(in srgb, var(--_accent) 65%, transparent), 0 12px 32px -10px color-mix(in srgb, var(--_accent) 80%, transparent);
}
.xwui-button.xwui-button-look-glass {
    /* Neutral panel; the tone only tints it when `color` is supplied. */
    --_glass: var(--xwui-button-color, var(--text-primary));
    --_bg: color-mix(in srgb, var(--_glass) 6%, transparent);
    --_bg-hover: color-mix(in srgb, var(--_glass) 11%, transparent);
    --_fg: var(--_text);
    --_edge: color-mix(in srgb, var(--_glass) 16%, transparent);
    --_edge-hover: color-mix(in srgb, var(--_glass) 28%, transparent);
    --_shadow: var(--xwui-button-glow, inset 0 1px 0 color-mix(in srgb, var(--_glass) 8%, transparent));
    backdrop-filter: blur(var(--xwui-button-blur, 8px));
    -webkit-backdrop-filter: blur(var(--xwui-button-blur, 8px));
}
.xwui-button.xwui-button-look-tint {
    --_bg: color-mix(in srgb, var(--_color) 14%, transparent);
    --_bg-hover: color-mix(in srgb, var(--_color) 24%, transparent);
    --_fg: var(--_tint-fg);
    --_edge: color-mix(in srgb, var(--_color) 38%, transparent);
    --_shadow: none;
}
.xwui-button.xwui-button-look-outline {
    --_bg: transparent;
    --_bg-hover: color-mix(in srgb, var(--_color) 12%, transparent);
    --_fg: var(--_tint-fg);
    --_edge: var(--_color);
    --_shadow: none;
}
.xwui-button.xwui-button-look-ring {
    /* Solid fill inside a gradient ring: the fill is the padding-box layer, the
       ring is the border-box layer showing through the transparent border. */
    --_bg: linear-gradient(var(--_surface), var(--_surface)) padding-box, linear-gradient(var(--_angle), var(--_from), var(--_to), var(--_ring-end)) border-box;
    --_clip: padding-box, border-box;
    --_fg: var(--_text);
    --_edge: transparent;
    --_shadow: var(--xwui-button-glow, 0 6px 22px -10px color-mix(in srgb, var(--_accent) 70%, transparent));
    --_shadow-hover: 0 8px 26px -10px color-mix(in srgb, var(--_accent) 90%, transparent);
}
.xwui-button.xwui-button-look-brand {
    --_bg: var(--_surface);
    --_bg-hover: color-mix(in srgb, var(--text-primary) 6%, var(--_surface));
    --_fg: var(--_text);
    --_edge: color-mix(in srgb, var(--text-primary) 24%, transparent);
    --_edge-hover: color-mix(in srgb, var(--text-primary) 40%, transparent);
    --_shadow: var(--xwui-button-glow, var(--button-shadow, var(--shadow-sm)));
}

/* ---- shared application (beats the variant rules by specificity and order) -- */
.xwui-button[class*="xwui-button-look-"] {
    background: var(--_bg);
    background-origin: border-box;
    background-clip: var(--_clip, border-box);
    color: var(--_fg) !important;
    border: var(--_bw) var(--border-button-style, solid) var(--_edge);
    box-shadow: var(--_shadow, none);
}
.xwui-button[class*="xwui-button-look-"].xwui-button-no-shadow {
    --_shadow: none;
    --_shadow-hover: none;
}
/* Hover: 5 specificity points, above the variant hover rules (4) that carry
   !important backgrounds. Hover never moves a fill toward the paper: gradient
   and glow gain saturation and light around the button, not luminance under the
   label, so the contrast the resting stops were proven for still holds. */
.xwui-button[class*="xwui-button-look-"]:hover:not(:disabled):not(.xwui-button-disabled) {
    background: var(--_bg-hover, var(--_bg)) !important;
    background-origin: border-box;
    background-clip: var(--_clip, border-box);
    color: var(--_fg) !important;
    border-color: var(--_edge-hover, var(--_edge));
    box-shadow: var(--_shadow-hover, var(--_shadow, none));
    filter: var(--_hover-filter, none);
    transform: translateY(-1px);
}
.xwui-button[class*="xwui-button-look-"]:active:not(:disabled):not(.xwui-button-disabled) {
    background: var(--_bg-hover, var(--_bg)) !important;
    color: var(--_fg) !important;
    transform: scale(var(--button-press-scale, 0.95));
}
/* Focus keeps the look's own shadow (the base rule would swap it for the
   style's focus glow) and draws the ring in the accent, outside the fill. */
.xwui-button[class*="xwui-button-look-"]:focus-visible {
    outline: 2px solid var(--_focus);
    outline-offset: 2px;
    box-shadow: var(--_shadow, none);
}
.xwui-button[class*="xwui-button-look-"]:disabled,
.xwui-button[class*="xwui-button-look-"].xwui-button-disabled,
.xwui-button[class*="xwui-button-look-"].xwui-button-loading {
    box-shadow: none;
    filter: saturate(0.55);
}
@media (prefers-reduced-motion: reduce) {
    .xwui-button[class*="xwui-button-look-"]:hover:not(:disabled):not(.xwui-button-disabled),
    .xwui-button[class*="xwui-button-look-"]:active:not(:disabled):not(.xwui-button-disabled) {
        transform: none;
    }
}
/* Windows high contrast and other forced-colours modes drop gradients, shadows
   and author colours. Say it in system colours so the button stays a visible,
   labelled control with a clear hover and focus. */
@media (forced-colors: active) {
    .xwui-button[class*="xwui-button-look-"],
    .xwui-button[class*="xwui-button-look-"]:hover:not(:disabled):not(.xwui-button-disabled) {
        background: ButtonFace !important;
        color: ButtonText !important;
        border: 1px solid ButtonText;
        box-shadow: none;
        filter: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    .xwui-button[class*="xwui-button-look-"]:hover:not(:disabled):not(.xwui-button-disabled) {
        border-color: Highlight;
    }
    .xwui-button[class*="xwui-button-look-"]:focus-visible {
        outline: 2px solid Highlight;
    }
    .xwui-button .xwui-button-tile {
        background: ButtonText;
        color: ButtonFace;
        forced-color-adjust: none;
    }
}

/* ---- start tile: a brand logo or partner letter at the inline-start edge ---- */
/* First flex child, so it leads in both directions with no direction rule. It
   works with or without a look; colours default to the accent and its ink pair. */
.xwui-button .xwui-button-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    inline-size: var(--xwui-button-tile-size, 1.5em);
    block-size: var(--xwui-button-tile-size, 1.5em);
    border-radius: var(--xwui-button-tile-radius, 0.3em);
    background: var(--xwui-button-tile, var(--xwui-button-color, var(--accent-primary, var(--role-primary-bg))));
    color: var(--xwui-button-tile-ink, var(--accent-primary-ink, var(--role-primary-fg, var(--text-inverse))));
    font-size: 0.78em;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0;
}
.xwui-button .xwui-button-tile > svg {
    inline-size: 70%;
    block-size: 70%;
}

/* contentFit scale: keep the icon and the whole label. The size variable is
   set by fitActionLabels; until then the control uses its size token. */
.xwui-button.xwui-button-content-scale {
    min-width: 0;
    font-size: var(--xwui-action-label-size, inherit);
}
.xwui-button.xwui-button-content-scale .xwui-button-text {
    overflow: visible;
    text-overflow: clip;
    white-space: nowrap;
    min-width: 0;
}
.xwui-button.xwui-button-content-scale .xwui-button-icon {
    display: inline-flex;
    flex-shrink: 0;
}
