/* ============================================================================
   button — primary / secondary / ghost / destructive / on-dark, three sizes.

   Rules encoded here:
   • Every pressable element gets scale(.97) on :active over --dur-press.
   • Minimum tap target 44x44 at every size.
   • A primary button is NEVER rendered greyed-out without adjacent
     explanatory text (see .btn__note). The old site styled its submit pale
     pink until reCAPTCHA was ticked, and users read it as broken.
   • Hover transforms gated behind (hover: hover) and (pointer: fine).
   • Radius is 4px. There are no pills on this site.
   ========================================================================= */

.btn {
  --btn-bg: var(--ember);
  --btn-fg: #fff;
  --btn-border: var(--ember);
  --btn-bg-hover: var(--ember-deep);
  --btn-border-hover: var(--ember-deep);

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-block-size: var(--tap);
  min-inline-size: var(--tap);
  padding-inline: var(--sp-5);
  padding-block: var(--sp-3);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: var(--weight-semi);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 1px solid var(--btn-border);
  border-radius: var(--r-btn);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color var(--dur-hover) var(--ease-out),
    border-color var(--dur-hover) var(--ease-out),
    color var(--dur-hover) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--btn-bg-hover); border-color: var(--btn-border-hover); }
}
.btn:active { transform: scale(0.97); }
@media (prefers-reduced-motion: reduce) { .btn:active { transform: none; } }

.btn svg { inline-size: 1em; block-size: 1em; flex: none; }

/* --- Variants ----------------------------------------------------------- */
.btn--secondary {
  --btn-bg: transparent; --btn-fg: var(--fg);
  --btn-border: var(--border-strong);
  --btn-bg-hover: var(--mist); --btn-border-hover: var(--fg);
}
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--fg);
  --btn-border: transparent;
  --btn-bg-hover: var(--mist); --btn-border-hover: transparent;
}
.btn--destructive {
  --btn-bg: transparent; --btn-fg: var(--critical);
  --btn-border: var(--critical);
  --btn-bg-hover: var(--critical); --btn-border-hover: var(--critical);
}
@media (hover: hover) and (pointer: fine) {
  .btn--destructive:hover { color: #fff; }
}
.btn--on-dark {
  --btn-bg: transparent; --btn-fg: var(--fg-on-dark);
  --btn-border: rgba(245,241,236,.34);
  --btn-bg-hover: rgba(245,241,236,.10); --btn-border-hover: var(--fg-on-dark);
}

/* --- Sizes. sm keeps its 44px hit area via a transparent outset. --------- */
.btn--sm {
  padding-inline: var(--sp-4);
  padding-block: var(--sp-2);
  font-size: var(--fs-small);
  min-block-size: 36px;
}
.btn--sm::after {
  content: ""; position: absolute; inset-block: -4px; inset-inline: 0;
  min-block-size: var(--tap);
}
.btn--lg {
  padding-inline: var(--sp-6);
  padding-block: var(--sp-4);
  font-size: var(--fs-body);
  min-block-size: 56px;
}
.btn--block { display: flex; inline-size: 100%; }

/* --- States ------------------------------------------------------------- */
.btn[disabled], .btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: .5;
  filter: saturate(.3);
}
.btn[disabled]:active, .btn[aria-disabled="true"]:active { transform: none; }

/* A disabled primary must carry this note. Enforced by review, and by the
   component doc — see docs/components/README.md. */
.btn__note {
  display: block;
  margin-block-start: var(--sp-2);
  font-size: var(--fs-small);
  color: var(--fg-muted);
  max-inline-size: 44ch;
}

/* Loading: the label crossfades to a spinner using blur + opacity. A plain
   crossfade shows two overlapping objects and reads as a glitch; blur bridges
   them into one transformation. Blur stays well under 20px. */
.btn__label,
.btn__spinner,
.btn__success {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  transition: opacity var(--dur-dropdown) var(--ease-out),
              filter var(--dur-dropdown) var(--ease-out);
}
.btn__spinner, .btn__success {
  position: absolute; inset: 0;
  justify-content: center;
  opacity: 0; filter: blur(2px); pointer-events: none;
}
.btn[data-state="loading"] .btn__label   { opacity: 0; filter: blur(2px); }
.btn[data-state="loading"] .btn__spinner { opacity: 1; filter: blur(0); }
.btn[data-state="success"] .btn__label   { opacity: 0; filter: blur(2px); }
.btn[data-state="success"] .btn__success { opacity: 1; filter: blur(0); }
.btn[data-state="loading"] { pointer-events: none; }

/* Spin fast — a faster spinner makes the same wait feel shorter. */
.spinner {
  inline-size: 1em; block-size: 1em;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: 50%;
  animation: spin 620ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 1600ms; } }

/* --------------------------------------------------------------------------
   icon-button
   ----------------------------------------------------------------------- */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  inline-size: var(--tap); block-size: var(--tap);
  border-radius: var(--r-btn);
  color: var(--fg);
  border: 1px solid transparent;
  transition: background-color var(--dur-hover) var(--ease-out),
              border-color var(--dur-hover) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .icon-btn:hover { background: var(--mist); } }
.icon-btn:active { transform: scale(0.97); }
.icon-btn svg { inline-size: 20px; block-size: 20px; }
.icon-btn--bordered { border-color: var(--border); }

/* --------------------------------------------------------------------------
   link-arrow — the recurring "go" affordance. The arrow mirrors under RTL
   because it means "forward", not "east".
   ----------------------------------------------------------------------- */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-weight: var(--weight-semi);
  font-size: var(--fs-small);
  color: var(--fg);
  text-decoration: none;
  min-block-size: var(--tap);
}
.link-arrow__icon {
  inline-size: 16px; block-size: 16px; flex: none;
  transition: transform var(--dur-hover) var(--ease-out);
}
[dir="rtl"] .link-arrow__icon { transform: scaleX(-1); }
@media (hover: hover) and (pointer: fine) {
  .link-arrow:hover { color: var(--ember-deep); }
  .link-arrow:hover .link-arrow__icon { transform: translateX(4px); }
  [dir="rtl"] .link-arrow:hover .link-arrow__icon { transform: scaleX(-1) translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .link-arrow:hover .link-arrow__icon,
  [dir="rtl"] .link-arrow:hover .link-arrow__icon { transform: none; }
  [dir="rtl"] .link-arrow__icon { transform: scaleX(-1); }
}
