/* ---------------------------------------------------------------------------
   buttons.css — MAIN-THREAD OWNED.
   Every interactive control is at least 44px tall on touch. Every one has a
   visible hover, active and focus state, and a disabled state that explains
   itself via [title] rather than just going grey.
--------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  min-height: 36px;
  border: 1px solid transparent; border-radius: var(--r-md);
  background: var(--c-surface); color: var(--c-fg);
  font-size: var(--t-md); font-weight: var(--fw-medium);
  line-height: 1.2; white-space: nowrap; text-decoration: none;
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              box-shadow var(--m-fast) var(--m-ease);
}
.btn:active:not(:disabled) { transform: translateY(1px); }

.btn--primary {
  background: var(--c-primary); color: var(--c-on-primary); border-color: var(--c-primary);
  box-shadow: var(--sh-1);
}
.btn--primary:hover:not(:disabled) { background: var(--c-primary-hover); border-color: var(--c-primary-hover); }

.btn--secondary { background: var(--c-surface); color: var(--c-fg); border-color: var(--c-border-strong); }
.btn--secondary:hover:not(:disabled) { background: var(--c-primary-soft); border-color: var(--c-primary); color: var(--c-primary); }

.btn--ghost { background: transparent; color: var(--c-fg-muted); }
.btn--ghost:hover:not(:disabled) { background: var(--c-idle-soft); color: var(--c-fg); }

.btn--danger { background: var(--c-danger); color: #fff; border-color: var(--c-danger); }
.btn--danger:hover:not(:disabled) { background: var(--c-danger-ink); border-color: var(--c-danger-ink); }

/* The single most consequential control in the app: arming a real POST to the
   live marketplace. It looks different from every other button on purpose. */
.btn--armed {
  background: var(--c-danger-soft); color: var(--c-danger-ink);
  border-color: var(--c-danger); border-style: dashed;
}
.btn--armed:hover:not(:disabled) { background: var(--c-danger); color: #fff; border-style: solid; }

.btn:disabled { opacity: .5; }

.btn--sm { min-height: 28px; padding: var(--s-1) var(--s-2); font-size: var(--t-sm); }
.btn--lg { min-height: 44px; padding: var(--s-3) var(--s-5); font-size: var(--t-lg); }
.btn--block { width: 100%; }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid transparent; border-radius: var(--r-md);
  background: transparent; color: var(--c-fg-muted);
  transition: background var(--m-fast) var(--m-ease), color var(--m-fast) var(--m-ease);
}
.icon-btn:hover:not(:disabled) { background: var(--c-idle-soft); color: var(--c-fg); }
.icon-btn svg { width: 16px; height: 16px; }

/* Touch: the 32px icon button keeps its visual size but gets a 44px hit area. */
@media (pointer: coarse) {
  .icon-btn { position: relative; }
  .icon-btn::after { content: ''; position: absolute; inset: -6px; }
  .btn { min-height: 44px; }
}

/* A button that kicks off a 20 minute run must acknowledge the click
   immediately, or the operator clicks it again. */
.btn[aria-busy="true"] { pointer-events: none; opacity: .8; }
.btn[aria-busy="true"]::before {
  content: ''; width: 12px; height: 12px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn-group { display: inline-flex; gap: var(--s-2); flex-wrap: wrap; }
