/**
 * iq-button — token-driven, WCAG 2.2 AA by default.
 * Target size: min 24×24 CSS px at every size (WCAG 2.5.8, an untokenized
 * hard floor); the three --iq-control-height-* tiers sit above it and md/lg
 * reach 44px (AAA 2.5.5).
 *
 * Every variant describes itself with three component-scoped internals —
 * --iq-button-bg / --iq-button-fg / --iq-button-border (like --iq-tabs-vt-fill-*)
 * — and nothing else. The shared hover/active rules mix --bg toward
 * --iq-color-state-mix, and the shared disabled rule fades all three toward
 * transparent, so one set of rules covers every variant and the whole thing
 * stays dial-able from the settings page.
 *
 * This replaces filter: brightness(), which was wrong in three ways: it did
 * nothing on a white or black fill, it lightened in both color schemes (light
 * UIs conventionally darken on hover), and as a filter it established a
 * containing block and stacking context on every hovered button.
 */

.iq-button {
	/* Every variant is described by these three internals and nothing else, so
	   the shared hover, active and disabled rules cover all of them. --bg was
	   already the contract; --fg and --border joined it for the disabled state,
	   which has to fade each one from its OWN resting value. `currentColor`
	   cannot do that job: inside the `color` property it resolves to the
	   INHERITED color, not the button's own. */
	--iq-button-bg: var(--iq-color-primary, #1442cc);
	--iq-button-fg: var(--iq-color-primary-contrast, #ffffff);
	--iq-button-border: transparent;

	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--iq-space-xs, 0.25rem);
	/* 24px is the WCAG 2.5.8 minimum target size — a constant of the success
	   criterion, not a design decision, so it is deliberately NOT tokenized.
	   The size tiers below re-state it inside max() rather than relying on this
	   rule: a `.iq-button--sm` declaration REPLACES this one (later source
	   order, equal specificity), so the floor only binds if each tier carries
	   it. max() also holds against a per-element builder override, which never
	   passes through the sanitizer. */
	min-inline-size: 24px;
	min-block-size: 24px;
	padding: var(--iq-space-sm, 0.5rem) var(--iq-space-md, 1rem);
	border: var(--iq-border-width-thick, 2px) solid var(--iq-button-border);
	border-radius: var(--iq-radius-md, 8px);
	background: var(--iq-button-bg);
	color: var(--iq-button-fg);
	box-shadow: var(--iq-shadow-sm);
	font: inherit;
	font-weight: var(--iq-font-weight-bold, 600);
	line-height: var(--iq-line-height-tight, 1.2);
	text-decoration: none;
	cursor: pointer;
	/* Fast: pure color feedback, where a visible ramp reads as lag. */
	transition: background-color var(--iq-duration-fast-effective, 120ms) var(--iq-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		color var(--iq-duration-fast-effective, 120ms) var(--iq-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		border-color var(--iq-duration-fast-effective, 120ms) var(--iq-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		box-shadow var(--iq-duration-fast-effective, 120ms) var(--iq-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* The companion to the `display: inline-flex` above. An unlayered author
   declaration on the button itself beats both the UA `[hidden] { display: none }`
   and Bricks' layered `[hidden], template { display: none }` reset, so without
   this a `<button class="iq-button" hidden>` — the `_attributes` route a Bricks
   author reaches for — stays painted and clickable while every script that
   filters `[hidden]` skips it. Same rule, same reason, as `.iq-alert[hidden]`
   and `.iq-badge__remove[hidden]`. */
.iq-button[hidden] {
	display: none !important;
}

/* oklab keeps the mix perceptually even across hues — sRGB mixing darkens
   saturated blues far faster than yellows at the same percentage.

   Every state rule carries :not(:disabled):not([aria-disabled='true']). It is
   not decoration: a disabled control must not react to the pointer, and the
   guards have to be on the VARIANT rules too, or the extra specificity they add
   here would let the base hover beat .iq-button--outline:hover. */
.iq-button:hover:not(:disabled):not([aria-disabled='true']) {
	background: color-mix(in oklab, var(--iq-button-bg), var(--iq-color-state-mix, #000000) var(--iq-state-hover-mix, 12%));
}

/* Pressing drops the button to the page: deeper mix, no elevation. */
.iq-button:active:not(:disabled):not([aria-disabled='true']) {
	background: color-mix(in oklab, var(--iq-button-bg), var(--iq-color-state-mix, #000000) var(--iq-state-active-mix, 20%));
	box-shadow: none;
}

/* Sizes */
.iq-button--sm {
	min-block-size: max(24px, var(--iq-control-height-sm, 32px));
	padding: var(--iq-space-xs, 0.25rem) var(--iq-space-sm, 0.5rem);
	font-size: var(--iq-text-sm, 0.875em);
}

.iq-button--md {
	min-block-size: max(24px, var(--iq-control-height-md, 44px));
}

.iq-button--lg {
	min-block-size: max(24px, var(--iq-control-height-lg, 52px));
	padding: var(--iq-space-md, 1rem) var(--iq-space-lg, 1.5rem);
	font-size: var(--iq-text-lg, 1.125em);
}

/* Variants.
   Setting --iq-button-bg is enough for a filled variant: the shared hover and
   active rules above pick it up. Unfilled variants (outline, ghost) opt out of
   the mix and elevation entirely — a state layer over `transparent` would be a
   translucent grey smear rather than a deliberate hover color. */
.iq-button--secondary {
	--iq-button-bg: var(--iq-color-secondary, #374151);
	--iq-button-fg: var(--iq-color-secondary-contrast, #ffffff);
}

.iq-button--outline {
	--iq-button-bg: transparent;
	--iq-button-fg: var(--iq-color-primary, #1442cc);
	--iq-button-border: var(--iq-color-primary, #1442cc);

	box-shadow: none;
}

.iq-button--outline:hover:not(:disabled):not([aria-disabled='true']),
.iq-button--outline:active:not(:disabled):not([aria-disabled='true']) {
	background: var(--iq-color-primary, #1442cc);
	color: var(--iq-color-primary-contrast, #ffffff);
}

.iq-button--ghost {
	--iq-button-bg: transparent;
	--iq-button-fg: var(--iq-color-primary, #1442cc);

	box-shadow: none;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.iq-button--ghost:hover:not(:disabled):not([aria-disabled='true']),
.iq-button--ghost:active:not(:disabled):not([aria-disabled='true']) {
	background: var(--iq-color-surface-alt, #f3f4f6);
}

/* Disabled.
   Placed after every variant so it wins on source order at equal specificity.

   Each of the three internals is faded from its OWN resting value toward
   `transparent` — CSS interpolates premultiplied, so mixing 50% transparent is
   the same as painting the color at alpha 0.5, with no shift toward black.

   `outline` is deliberately untouched. Applying `opacity` to the control would
   have been one line, but it fades the focus ring with everything else, and an
   [aria-disabled="true"] button REMAINS FOCUSABLE — its indicator still has to
   clear 3:1 (WCAG 1.4.11 / 2.4.7). WCAG 1.4.3 exempts the disabled label
   itself, but that is permission, not a target: keep the label readable. */
.iq-button:disabled,
.iq-button[aria-disabled='true'] {
	background: color-mix(in oklab, var(--iq-button-bg), transparent var(--iq-disabled-fade, 50%));
	border-color: color-mix(in oklab, var(--iq-button-border), transparent var(--iq-disabled-fade, 50%));
	color: color-mix(in oklab, var(--iq-button-fg), transparent var(--iq-disabled-fade, 50%));
	box-shadow: none;
	cursor: not-allowed;
}

/* Icon */
.iq-button__icon {
	flex: none;
	display: inline-flex;
}

/* This `display` is the one iq-copy-button.css names as the reason its glyphs
   deliberately declare none of their own — measured there, a `hidden` <svg>
   carrying this class painted at 13.13px with `checkVisibility() === true`. That
   file patches its own two glyphs; this patches the class, so the next icon to
   be toggled with `hidden` does not have to rediscover it. */
.iq-button__icon[hidden] {
	display: none !important;
}

.iq-button--icon-only {
	padding: var(--iq-space-sm, 0.5rem);
	aspect-ratio: 1;
}

/* Forced colors (Windows High Contrast) — F4 baseline, see
   docs/foundations/forced-colors.md. The palette is replaced with system
   colors and background fills stop identifying anything, so the BOUNDARY has
   to: the filled variants' border is `transparent` at rest (the fill carried
   the edge), which here becomes a real ButtonText border. The ghost variant
   is exempt on purpose — it presents as underlined text, like a link, and a
   boundary would change its identity.

   The disabled color-mix fades are color operations and do not survive the
   forcing; GrayText is the platform's own disabled convention, and it must
   be explicit because [aria-disabled] gets no native treatment. */
@media (forced-colors: active) {
	.iq-button:not(.iq-button--ghost) {
		border-color: ButtonText;
	}

	.iq-button:disabled,
	.iq-button[aria-disabled='true'] {
		color: GrayText;
		border-color: GrayText;
	}
}
