/*
 * Shared `.l-button` appearance — the single source of truth for the button's
 * base look, primary, and destructive variants. Lives in the HTML tree so it is
 * both:
 *   - `@import`ed (and layered) by src/css/elements/button.css for the light-DOM
 *     `.l-button`, and
 *   - imported `?inline` into shadow-DOM elements (l-alert-dialog) that render
 *     their own `.l-button` actions and can't reach the global stylesheet.
 *
 * Intentionally UNLAYERED: the light-DOM import wraps it in `@layer components`
 * via `@import … layer(components)`, while shadow consumers want it unlayered to
 * sit alongside the (also unlayered) dialog styles. Size/icon-only/press-effect
 * variants stay in button.css — shadow actions don't need them.
 *
 * Shadow consumers must emit the class via `cls('button')`, never a static
 * `class="l-button"` literal: this file ships to dist as a real CSS file, so the
 * CONSUMER's postcss-plugin-prefix rewrites this selector to
 * `.<cssPrefix>-button`, while the vite-plugin's `transform` hook only rewrites
 * `_cssPrefix` in registry.js and never touches template literals in element JS.
 */
.l-button {
  /* Local size scaffolding (referenced by the size variants in button.css). */
  --_button-size-xs: var(--l-size-control-xs); /* 28px */
  --_button-size-sm: var(--l-size-control-sm); /* 32px */
  --_button-size-md: var(--l-size-control-md); /* 36px */
  --_button-size-lg: var(--l-size-control-lg); /* 40px */
  --_button-size-xl: var(--l-size-control-xl); /* 44px */

  /* Appearance (default: secondary) */
  --height: var(--_button-size-md);
  --padding-inline: 0.625rem;
  --background-color: var(--l-color-bg-fill-secondary);
  --background-color-active: color-mix(
    in oklab,
    var(--l-color-bg-fill-secondary) 90%,
    var(--l-color-text-primary)
  );
  --background-color-hover: var(--background-color-active);
  --font-size: var(--l-text-sm);
  --text-color: var(--l-color-text-primary);
  --text-color-hover: var(--text-color);
  --border-color: var(--l-color-border);
  --border-color-hover: color-mix(in oklab, var(--l-color-border) 75%, var(--l-color-text-primary));

  position: relative;
  display: inline-flex;
  place-items: center;
  justify-content: center;
  gap: var(--l-spacing-2);
  height: var(--height);
  padding-inline: var(--padding-inline);
  border: 1px solid var(--border-color);
  border-radius: calc(var(--height) / 8);
  background: var(--background-color);
  color: var(--text-color);
  outline: none;
  font-size: var(--font-size);
  font-weight: var(--l-font-weight-semibold);
  text-decoration: none;
  user-select: none;
  white-space: nowrap;
  appearance: none;
  -webkit-tap-highlight-color: transparent;

  transition-property: background-color, color, text-decoration, border-color;
  transition-duration: 150ms;

  /* `:disabled` (native) and `[aria-disabled]` (a busy/blocked control kept in
     the tab order) read the same. */
  &:not(:disabled):not([aria-disabled='true']) {
    cursor: pointer;
  }

  &:disabled,
  &[aria-disabled='true'] {
    cursor: not-allowed;
    opacity: 0.4;
  }

  &:not(:disabled):not([aria-disabled='true']):hover {
    background-color: var(--background-color-hover);
    border-color: var(--border-color-hover);
    color: var(--text-color-hover);
  }

  &:not(:disabled):not([aria-disabled='true']):active {
    background-color: var(--background-color-active);
  }

  &:focus-visible {
    outline: 2px solid var(--l-focus-ring);
    outline-offset: 2px;
  }
}

.l-button[data-variant='primary'] {
  --background-color: var(--l-color-bg-fill-brand);
  --background-color-active: var(--l-color-bg-fill-brand-active);
  --background-color-hover: var(--l-color-bg-fill-brand-hover);
  --text-color: var(--l-color-text-on-fill-brand);
  --text-color-hover: var(--l-color-text-on-fill-brand);
  --border-color: transparent;
  --border-color-hover: transparent;
}

/* Soft danger fill: a pale tint with a dark-red label, deepening the tint on
   hover/active. Reads clearly as destructive without the visual shout of a solid
   red — the consequence lives in the copy and the confirmation, not the chrome.
   Derivations mix the soft fill toward the danger text color, so the tint
   deepens in light mode and lightens in dark mode (where soft is near-black). */
.l-button[data-variant='destructive'] {
  --background-color: var(--l-color-bg-fill-danger-soft);
  --background-color-hover: color-mix(
    in oklab,
    var(--l-color-bg-fill-danger-soft) 80%,
    var(--l-color-text-danger)
  );
  --background-color-active: color-mix(
    in oklab,
    var(--l-color-bg-fill-danger-soft) 65%,
    var(--l-color-text-danger)
  );
  --text-color: var(--l-color-text-danger);
  --text-color-hover: var(--l-color-text-danger);
  --border-color: transparent;
  --border-color-hover: transparent;
}

/* Toggle button in the pressed state (APG toggle pattern): the button keeps its
   `:active` fill for as long as it is on. Rebinding the knobs rather than
   setting `background-color` is what makes this variant-agnostic — every
   variant inherits the pressed look from the active/hover colors it already
   defines. Hover mixes that fill toward the variant's own text color so a
   pressed button still answers the pointer: darker for the secondary button,
   lighter for `primary`, a deeper red for `destructive`.

   `:has(input:checked)` gives the same look to a `.l-button` wrapping a checked
   radio or checkbox — the shape `.l-radio-group` uses, where the visible segment
   is a `<label class="l-button">`. Same state, same look, defined once.

   MUST stay after the variant rules: `.l-button[aria-pressed='true']` and
   `.l-button[data-variant='…']` have the same specificity, so source order is
   what lets the pressed state win over a variant's base fill. (The `:has()`
   selector scores one higher and would win either way.) */
.l-button[aria-pressed='true'],
.l-button:has(input:checked) {
  --background-color: var(--background-color-active);
  --background-color-hover: color-mix(
    in oklab,
    var(--background-color-active) 88%,
    var(--text-color)
  );
  --border-color: var(--border-color-hover);
}
