/* ============================================
   <Button /> — shared chrome and variants

   Pairs with components/button/index.jsx. Variants are BEM modifiers:
     .btn--primary / .btn--secondary / .btn--outline / .btn--ghost
     .btn--danger / .btn--ghost-accent / .btn--ghost-outline
     .btn--ghost.btn--danger        ghost-danger compound (two orthogonal
                                    modifiers; severity carried by icon
                                    + label, not color).

   Sizes are an orthogonal modifier:
     .btn--xs   22px height, 11px text   (toolbar chrome on dark surfaces)
     .btn--sm   26px height, 12px text
     .btn--md   32px height, 13px text   (default)
     .btn--lg   42px height, 14px text

   Dark-surface variants (paired with the same neutral chrome but using the
   canvas ink palette + canvas borders) — for buttons that sit on canvas,
   sidebar, composer, or bubble surfaces:
     .btn--outline-canvas        hairline border, transparent fill
     .btn--ghost-canvas          borderless, soft hover fill
     .btn--ghost-accent-canvas   accent-tinted ghost on dark

   Forced-state helpers (.is-hover / .is-focus / .is-active) preview
   pseudo-class visuals in design canvases without requiring real
   keyboard/mouse focus.
   ============================================ */

/* ---------- Shared chrome ---------- */
.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-1-5);
  font-family: var(--md-sys-typescale-label-large-font);
  line-height: 1;
  user-select: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
    color var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
    border-color var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
    box-shadow var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
}
.btn svg { flex-shrink: 0; }
.btn:focus { outline: none; }
.btn:focus-visible,
.btn.is-focus {
  outline: none;
  box-shadow: var(--xm-state-focus-ring);
}

/* ---------- Sizes ---------- */
.btn--xs { padding: 3px 7px;   font: 600 11px/1 var(--md-sys-typescale-label-large-font); border-radius: 5px; gap: var(--s-1); }
.btn--sm { padding: 5px var(--s-2-5);  font: 600 12px/1 var(--md-sys-typescale-label-large-font); border-radius: 6px; }
.btn--md { padding: 9px var(--s-3-5);  font: 600 13px/1 var(--md-sys-typescale-label-large-font); border-radius: var(--md-sys-shape-corner-button); }
.btn--lg { padding: var(--s-3) var(--s-4-5); font: 600 14px/1 var(--md-sys-typescale-label-large-font); border-radius: var(--md-sys-shape-corner-button); }

/* ---------- Variants ---------- */

/* primary — accent fill, the workhorse CTA. Uses --xm-color-primary-fill
   (a darker coral) rather than --md-sys-color-primary so white-on-fill
   clears WCAG AA; the lighter primary role stays for accent text/border. */
.btn--primary {
  border: 1px solid var(--xm-color-primary-pressed);
  background: var(--xm-color-primary-fill);
  color: var(--md-sys-color-on-primary);
  box-shadow: var(--md-sys-elevation-level0);
}
.btn--primary:hover,
.btn--primary.is-hover { background: var(--xm-color-primary-pressed); }
.btn--primary:active,
.btn--primary.is-active { box-shadow: var(--xm-elevation-pressed); transform: translateY(1px); }

/* secondary — solid neutral, used for non-destructive secondary CTAs */
.btn--secondary {
  border: 1px solid var(--md-sys-color-secondary);
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}
.btn--secondary:hover,
.btn--secondary.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-on-secondary) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-secondary));
}

/* outline — bordered card, used for cancel / pair-actions */
.btn--outline {
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
}
.btn--outline:hover,
.btn--outline.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-inverse-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-inverse-surface));
  border-color: var(--md-sys-color-outline);
}
.btn--outline:focus-visible,
.btn--outline.is-focus { border-color: var(--md-sys-color-primary); }

/* ghost — transparent, sits on the dark canvas (sidebar, top bar) */
.btn--ghost {
  border: 1px solid transparent;
  background: transparent;
  color: var(--md-sys-color-on-surface);
}
.btn--ghost:hover,
.btn--ghost.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  color: var(--md-sys-color-on-surface);
}
/* ghost selected — used by toggle/tab buttons. Persistent fill + hairline
   to stand out next to inactive siblings in a segmented group. */
.btn--ghost.is-active {
  background: var(--md-sys-color-surface-container-lowest);
  border-color: var(--md-sys-color-outline);
  color: var(--md-sys-color-on-surface);
}

/* ghost-danger — neutral ghost; severity carried by trash/x icon + label.
   Composes with .btn--ghost: <button class="btn btn--ghost btn--danger"> */
.btn--ghost.btn--danger {
  color: var(--md-sys-color-on-surface);
  border-color: var(--md-sys-color-outline);
}
.btn--ghost.btn--danger:hover,
.btn--ghost.btn--danger.is-hover {
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
}

/* ghost-outline — transparent fill + hairline border on card surfaces.
   Sits between .btn--outline (filled card) and .btn--ghost (no chrome):
   the rest border outlines the affordance without lifting it onto a new
   surface. Used when a ghost needs a quiet anchor in busy layouts
   (toolbars on cards, secondary actions next to a primary CTA). */
.btn--ghost-outline {
  border: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  color: var(--md-sys-color-inverse-on-surface);
}
.btn--ghost-outline:hover,
.btn--ghost-outline.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-inverse-on-surface) var(--md-sys-state-hover-state-layer-opacity), var(--md-sys-color-inverse-surface));
  border-color: var(--md-sys-color-outline);
}
.btn--ghost-outline:focus-visible,
.btn--ghost-outline.is-focus { border-color: var(--md-sys-color-primary); }

/* ghost-accent — accent-tinted secondary, used by file pills etc. One tone,
   not a stack — written as a single hyphenated modifier per BEM. The resting
   fill is the accent wash over the card; since the card tier is theme-following
   (ADR 0006) that wash is dark in dark theme, so the resting ink is the card's
   inverse-on-surface (light there). On hover the fill becomes the full coral
   primary-container, so the ink steps to on-primary-container (dark). */
.btn--ghost-accent {
  border-color: color-mix(in oklab, var(--md-sys-color-primary-container) 80%, transparent);
  color: var(--md-sys-color-inverse-on-surface);
  background: color-mix(in oklch, var(--md-sys-color-primary-container) 30%, var(--md-sys-color-inverse-surface));
}
.btn--ghost-accent:hover,
.btn--ghost-accent.is-hover {
  background: var(--md-sys-color-primary-container);
  border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary-container);
}

/* outline-canvas — hairline + transparent fill, canvas ink palette.
   Used by artifact "Download" pills inside bubbles, and any outline action
   that sits on canvas / composer / sidebar surfaces. */
.btn--outline-canvas {
  border: 1px solid color-mix(in oklab, var(--md-sys-color-on-surface) 32%, transparent);
  background: transparent;
  color: var(--md-sys-color-on-surface);
}
.btn--outline-canvas:hover,
.btn--outline-canvas.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-on-surface) 10%, transparent);
  border-color: var(--xm-color-on-surface-soft);
}
.btn--outline-canvas:focus-visible,
.btn--outline-canvas.is-focus { border-color: var(--md-sys-color-primary); }

/* ghost-canvas — borderless toolbar chrome on dark surfaces. Mirrors
   .btn--ghost but uses the canvas ink palette and the composer/canvas
   hover fill so it works consistently across composer, bubble actions,
   and chat hover toolbars. */
.btn--ghost-canvas {
  border: 1px solid transparent;
  background: transparent;
  color: var(--md-sys-color-on-surface);
}
.btn--ghost-canvas:hover,
.btn--ghost-canvas.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity), transparent);
  color: var(--md-sys-color-on-surface);
}
.btn--ghost-canvas.is-active {
  background: var(--md-sys-color-surface-container-lowest);
  border-color: var(--md-sys-color-outline);
  color: var(--md-sys-color-on-surface);
}

/* ghost-accent-canvas — accent-tinted ghost on dark surfaces. */
.btn--ghost-accent-canvas {
  border: 1px solid transparent;
  background: transparent;
  color: var(--md-sys-color-primary);
}
.btn--ghost-accent-canvas:hover,
.btn--ghost-accent-canvas.is-hover {
  background: color-mix(in oklab, var(--md-sys-color-primary) 14%, transparent);
  color: var(--xm-color-primary-pressed);
}

/* danger — neutral solid; destructive intent expressed by trash icon + label.
   Rides the surface family (surface-container-high), so the ink is on-surface
   (rule 7a). Hover darkens within the surface ramp rather than jumping to the
   card tier, keeping the ink anchored to one surface family. */
.btn--danger {
  border: 1px solid var(--md-sys-color-outline);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
}
.btn--danger:hover,
.btn--danger.is-hover {
  background: var(--md-sys-color-surface-container-highest);
  border-color: var(--md-sys-color-on-surface);
}
.btn--danger:focus-visible,
.btn--danger.is-focus {
  box-shadow: var(--xm-state-focus-ring);
}

/* ---------- Icon-only ---------- */
/* Square chip variant. Composes with any tone: pass an iconLeft and
   no children, or use .btn__icon directly. Sizes are square. */
.btn--icon-only {
  padding: 0;
  gap: 0;
}
.btn--icon-only.btn--xs { width: 22px; height: 22px; }
.btn--icon-only.btn--sm { width: 28px; height: 28px; }
.btn--icon-only.btn--md { width: 32px; height: 32px; }
.btn--icon-only.btn--lg { width: 38px; height: 38px; }

/* ---------- Full-width ---------- */
/* Stretches the button to fill its container. The label hugs the leading
   edge (next to icon-left) and `margin-inline-end: auto` pushes any
   icon-right slot (e.g. a kbd hint) to the trailing edge. */
.btn--full-width {
  width: 100%;
}
.btn--full-width .btn__label {
  margin-inline-end: auto;
  text-align: start;
}

/* ---------- Disabled / loading ----------
   No blanket opacity: dimming the whole control fades ink AND surface
   together and drops the label below WCAG AA (POLICIES 7a). Instead each
   variant swaps to a validated disabled ink (filled variants also flatten
   to the disabled container) so the label stays legible. */
.btn[disabled],
.btn[aria-busy="true"],
.btn.is-disabled {
  cursor: not-allowed;
  box-shadow: none;
}
/* filled variants — flatten fill to the disabled container + muted ink */
.btn--primary[disabled],   .btn--primary.is-disabled,
.btn--secondary[disabled], .btn--secondary.is-disabled,
.btn--danger[disabled],    .btn--danger.is-disabled {
  background: var(--xm-state-disabled-container);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--xm-color-on-surface-disabled);
}
/* surface-ink variants (ghost / outline-canvas / ghost-canvas on the canvas) */
.btn--ghost[disabled],         .btn--ghost.is-disabled,
.btn--ghost-canvas[disabled],  .btn--ghost-canvas.is-disabled,
.btn--ghost-accent-canvas[disabled], .btn--ghost-accent-canvas.is-disabled,
.btn--outline-canvas[disabled], .btn--outline-canvas.is-disabled {
  color: var(--xm-color-on-surface-disabled);
}
/* card-ink variants (outline / ghost-outline / ghost-accent on the card tier) */
.btn--outline[disabled],       .btn--outline.is-disabled,
.btn--ghost-outline[disabled], .btn--ghost-outline.is-disabled,
.btn--ghost-accent[disabled],  .btn--ghost-accent.is-disabled {
  color: var(--xm-color-inverse-on-surface-disabled);
}
.btn[disabled]:hover,
.btn[aria-busy="true"]:hover,
.btn.is-disabled:hover {
  filter: none;
  transform: none;
}
/* Disabled :hover is a no-op — hold the disabled fill/ink set above so
   hovering a disabled control doesn't restore the enabled (and contrast-
   failing) appearance. */
.btn--primary[disabled]:hover,   .btn--primary.is-disabled:hover,
.btn--secondary[disabled]:hover, .btn--secondary.is-disabled:hover,
.btn--danger[disabled]:hover,    .btn--danger.is-disabled:hover {
  background: var(--xm-state-disabled-container);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--xm-color-on-surface-disabled);
}
.btn--ghost[disabled]:hover,         .btn--ghost.is-disabled:hover,
.btn--ghost-canvas[disabled]:hover,  .btn--ghost-canvas.is-disabled:hover,
.btn--outline-canvas[disabled]:hover, .btn--outline-canvas.is-disabled:hover,
.btn--ghost-accent-canvas[disabled]:hover, .btn--ghost-accent-canvas.is-disabled:hover {
  background: transparent;
  color: var(--xm-color-on-surface-disabled);
}
.btn--outline[disabled]:hover,       .btn--outline.is-disabled:hover,
.btn--ghost-outline[disabled]:hover, .btn--ghost-outline.is-disabled:hover,
.btn--ghost-accent[disabled]:hover,  .btn--ghost-accent.is-disabled:hover {
  background: var(--md-sys-color-inverse-surface);
  border-color: var(--md-sys-color-outline-variant);
  color: var(--xm-color-inverse-on-surface-disabled);
}

/* ---------- Inner slots ---------- */
.btn__icon { display: inline-flex; align-items: center; }
.btn__label { display: inline-block; }

/* ---------- Loading spinner ---------- */
.btn__spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 1.6px solid currentColor;
  border-top-color: transparent;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.7s linear infinite;
  flex-shrink: 0;
  opacity: 0.85;
}
@keyframes btn-spin {
  to { transform: rotate(360deg); }
}
