/*
 * components/buttons.css — Button component (Session 4: Design System).
 *
 * Token-driven only (D5) — no hardcoded visual literals. Paired with the
 * `button()` macro in templates/components/buttons.html. Namespaced `.btn`
 * (distinct from the legacy `.portal-btn*` in app.css) so migrated and
 * unmigrated pages coexist without collision.
 */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: var(--border-1);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-fg);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  line-height: var(--lh-base);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.btn:hover {
  background: var(--color-surface-2);
}

/* Press feedback — micro-interaction (no gratuitous motion) */
.btn:active:not(:disabled):not([aria-disabled="true"]) {
  transform: scale(0.97);
}

.btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Loading state — inline spinner while awaiting server response.
   Uses an explicit color (not currentColor) because the parent sets
   color: transparent to hide the button text; currentColor would
   inherit that transparency and make the spinner invisible. */
.btn.is-loading {
  pointer-events: none;
  position: relative;
  color: transparent;
}

.btn.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1rem;
  height: 1rem;
  margin: -0.5rem 0 0 -0.5rem;
  border: 2px solid var(--color-accent);
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin var(--dur-base) linear infinite;
}

@keyframes btn-spin {
  to { transform: rotate(360deg); }
}

.btn--primary {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-fg);
}

.btn--primary:hover {
  background: var(--color-accent-hover);
}

.btn--danger {
  border-color: var(--color-danger-fg);
  color: var(--color-danger-fg);
}

.btn--danger:hover {
  background: var(--color-danger-bg);
}

.btn--danger.btn--primary {
  background: var(--color-danger-fg);
  border-color: var(--color-danger-fg);
  color: var(--color-accent-fg);
}

.btn--danger.btn--primary:hover {
  background: var(--color-danger-hover);
}

.btn--small {
  padding: var(--space-1) var(--space-3);
  font-size: var(--fs-sm);
}

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

@media (prefers-reduced-motion: reduce) {
  .btn {
    transition: none;
  }
  .btn:active:not(:disabled):not([aria-disabled="true"]) {
    transform: none;
  }
  .btn.is-loading::after {
    animation: none;
  }
}
