/*
 * ATOM: Button — sistema 2026-05
 * Variantes: primary | secondary | ghost | danger | soft-coral | soft-sage
 * Tamaños: sm | md | lg | icon
 * Press feedback con scale 0.97, transición 120ms ease-out
 *
 * ── Un solo criterio (2/10/2026, Matías sobre Caja: «en donde busco encuentro
 * botones con estilos totalmente diferentes») ────────────────────────────────
 *
 * Lo que se veía distinto en Caja eran DOS botones secundarios del mismo átomo:
 * «Imprimir planilla» (`.btn`, 36px con radio de 12px) parecía una pastilla y
 * «Cerrar caja» (`.btn-sm`, 28px con radio de 6px) un rectángulo. El radio
 * cambiaba con el tamaño, y encima 18 hojas pisaban alto, letra o radio a su
 * gusto. Desde hoy:
 *
 *   - UN radio para todo botón, de cualquier tamaño: `--h-radius-sm`. La forma
 *     de pastilla (`--h-radius-pill`) queda para estados y etiquetas (badge,
 *     chip), no para botones.
 *   - Tres altos y nada más: sm 28 · md 36 · lg 44. Las hojas de pantalla no
 *     cambian alto, letra, relleno, radio ni colores de `.btn*`: sólo dónde
 *     va (margen, alineación, ancho). Criterio y tabla de variantes en
 *     docs/manual/botones.md.
 */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--h-space-2);
  height: 36px;
  padding: 0 var(--h-space-4);
  font-family: var(--h-font-sans);
  font-size: var(--h-text-sm);
  font-weight: var(--h-weight-medium);
  border-radius: var(--h-radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  user-select: none;
  text-decoration: none;
  letter-spacing: 0.01em;
  transition:
    background var(--h-dur-1) var(--h-ease-out),
    border-color var(--h-dur-1) var(--h-ease-out),
    color var(--h-dur-1) var(--h-ease-out),
    box-shadow var(--h-dur-1) var(--h-ease-out),
    transform var(--h-dur-1) var(--h-ease-out);
}

/* El relieve: al pasar, el botón se despega apenas (1px + sombra); al apretar,
   vuelve al plano. Es la señal táctil de "esto responde" sin ningún adorno.
   Sólo los botones con cuerpo (primary/secondary/danger): un ghost que se
   levanta parece un error de render. */
.btn-primary:hover:not(:disabled),
.btn-secondary:hover:not(:disabled),
.btn-danger:hover:not(:disabled) {
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover:not(:disabled), .btn:active:not(:disabled) { transform: none; transition: none; }
}

.btn:active:not(:disabled) {
  transform: scale(0.97);
  transition-duration: calc(var(--h-dur-1) / 2);
}

/* Un botón apagado tiene que poder decir por qué.
 *
 * Estaba con `pointer-events: none`, y eso apaga TODO lo que pasa con el mouse
 * encima: el `cursor: not-allowed` de la línea de arriba no se veía nunca —era
 * letra muerta— y, peor, el `title` que varias pantallas le ponen para explicar
 * qué falta («elegí una sede», «cargá el diagnóstico») no aparecía. El botón se
 * veía apagado y no había forma de averiguar por qué, que es de las cosas que
 * más se preguntan por teléfono.
 *
 * Sacarlo no habilita nada: un `<button disabled>` no dispara `click` de todos
 * modos, eso lo garantiza el navegador. Lo único que vuelve es la explicación. */
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ── Dónde estoy parado, si vengo con el teclado ───────────────────────────
 *
 * Esto decía `outline: none` y dejaba SÓLO el halo del color suave de marca.
 * Medido el 22/8: ese halo da 1,17:1 contra la superficie donde se apoya el
 * botón — o sea, invisible. Y como el `outline:none` pisaba el contorno sólido
 * que tokens.css le pone a todo lo enfocable, el resultado era que en los
 * botones —justo en los botones— navegar con el teclado no mostraba nada.
 *
 * El mínimo para un indicador de foco es 3:1. El contorno sólido de
 * `--h-brand-primary` lo cumple en las ocho paletas y en los dos modos, porque
 * ese token está auditado para eso. El halo se queda: no alcanza solo, pero
 * ayuda a encontrarlo de reojo. */
.btn:focus-visible {
  outline: 2px solid var(--h-brand-primary);
  outline-offset: 2px;
  box-shadow: 0 0 0 3px var(--h-brand-primary-soft);
}

/* Primary — acción principal. El fondo puede divergir del color de marca
   textual: --h-brand-button-bg permite a un tema (ej. Ocaso) usar un acento
   más vivo en el botón del que sería legible como texto. Fallback: primary. */
.btn-primary {
  background: var(--h-brand-button-bg, var(--h-brand-primary));
  color: var(--h-brand-button-text, var(--h-brand-primary-text));
  border-color: var(--h-brand-button-bg, var(--h-brand-primary));
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--h-brillo) 18%, transparent) inset,
    0 1px 2px color-mix(in srgb, var(--h-brand-primary) 18%, transparent);
}
.btn-primary:hover:not(:disabled) {
  background: var(--h-brand-button-bg-hover, var(--h-brand-primary-hover));
  border-color: var(--h-brand-button-bg-hover, var(--h-brand-primary-hover));
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--h-brillo) 18%, transparent) inset,
    0 3px 8px color-mix(in srgb, var(--h-brand-primary) 28%, transparent);
}

/* Secondary — superficie limpia con borde */
.btn-secondary {
  background: var(--h-surface);
  color: var(--h-ink);
  border-color: var(--h-border-soft);
  box-shadow: 0 1px 1px color-mix(in srgb, var(--h-sombra) 2%, transparent);
}
.btn-secondary:hover:not(:disabled) {
  background: var(--h-nest);
  border-color: var(--h-muted);
  color: var(--h-ink);
}

/* Ghost — sin chrome hasta hover */
.btn-ghost {
  background: transparent;
  color: var(--h-ink-soft);
  border-color: transparent;
}
.btn-ghost:hover:not(:disabled) {
  background: var(--h-nest);
  color: var(--h-ink);
}

/* Danger */
.btn-danger {
  background: var(--h-danger-soft);
  color: var(--h-danger);
  border-color: transparent;
}
.btn-danger:hover:not(:disabled) {
  background: var(--h-danger);
  color: var(--h-brand-primary-text);
  box-shadow: 0 3px 8px color-mix(in srgb, var(--h-danger) 25%, transparent);
}

/* Soft coral — variante warm para acciones positivas sin gritar */
.btn-soft-coral {
  background: var(--h-brand-primary-soft);
  color: var(--h-brand-primary-hover);
  border-color: transparent;
}
.btn-soft-coral:hover:not(:disabled) {
  background: var(--h-brand-primary-soft-hover);
  color: var(--h-brand-primary-hover);
}

/* Soft sage — para confirmaciones tranquilas */
.btn-soft-sage {
  background: var(--h-ok-soft);
  color: var(--h-ok);
  border-color: transparent;
}
.btn-soft-sage:hover:not(:disabled) {
  background: var(--h-ok-soft-hover);
}

/* Soft warn — para acciones de atención (revisar, ver sugerencias) */
.btn-soft-warn {
  background: var(--h-warn-soft);
  color: var(--h-warn);
  border-color: transparent;
}
.btn-soft-warn:hover:not(:disabled) {
  background: var(--h-warn-soft-hover);
}

/* Icon button — cuadrado, para toolbars */
.btn-icon {
  width: 36px;
  height: 36px;
  padding: 0;
}
.btn-icon.btn-sm { width: 28px; height: 28px; }
.btn-icon.btn-lg { width: 44px; height: 44px; }

/* Tamaños */
.btn-sm {
  height: 28px;
  padding: 0 var(--h-space-3);
  font-size: var(--h-text-xs);
  gap: 6px;
}

.btn-lg {
  height: 44px;
  padding: 0 var(--h-space-6);
  font-size: var(--h-text-md);
}
/* Con el dedo (celular, tablet) el grande sube a 48px: es el mínimo táctil
 * que piden el recorrido de domicilios y el resto de las pantallas de celular
 * (prueba el-recorrido-se-hace-desde-el-celular). Con mouse queda en 44. */
@media (pointer: coarse) {
  .btn-lg { height: 48px; }
  .btn-icon.btn-lg { width: 48px; height: 48px; }
}

/* Loading spinner inline */
.btn .spinner {
  width: 14px;
  height: 14px;
  border: 2px solid color-mix(in srgb, var(--h-brillo) 30%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: btn-spin var(--h-dur-giro) linear infinite;
}
@keyframes btn-spin {
  to { transform: rotate(360deg); }
}

/* Grupo de botones contiguos — toolbar */
.btn-group {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  background: var(--h-border-soft);
  padding: 1px;
  /* El grupo envuelve a los botones con 1px de relleno: su radio es el del
   * botón más ese 1px, así las puntas siguen la misma curva (Mesada, 1/10). */
  border-radius: calc(var(--h-radius-sm) + 1px);
}
.btn-group .btn {
  border: none;
  background: var(--h-surface);
}
/* El elegido de un grupo: fondo de tinta, letra del color de la superficie.
 *
 * Decía `color: var(--h-brand-primary-text)`, que es blanco fijo. Anda en modo
 * claro —tinta oscura, letra blanca— y se rompe entero en oscuro, porque ahí
 * `--h-ink` es un crema claro: quedaba blanco sobre casi blanco, 1,21:1.
 * Medido el 22/8. Es la misma trampa que describe `--h-sobre-estado` en
 * tokens.css: los tokens INVIERTEN su claridad entre modos, y como el CSS se
 * escribe mirando el claro, el que queda roto es el oscuro.
 *
 * `--h-surface` es lo contrario de `--h-ink` en los dos modos por definición,
 * así que el par se sostiene solo: 15,8:1 en claro y 14,1:1 en oscuro. */
.btn-group .btn.active {
  background: var(--h-ink);
  color: var(--h-surface);
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn:active:not(:disabled) {
    transition: none;
    transform: none;
  }
}

/* ─── Density support ──────────────────────────────────────────── */
[data-density="compact"] .btn {
  height: 32px;
  padding: 0 var(--h-space-3);
  font-size: var(--h-text-sm);
}
[data-density="cozy"] .btn {
  height: 44px;
  padding: 0 var(--h-space-5);
  font-size: var(--h-text-md);
}

/* Angosto (≤700px, celular; encargo 4694): alto mínimo táctil. El general
 * (44px para .btn) está en templates/angosto.css; el chico se fija acá con
 * las dos clases para ganarle a ese general sin depender del orden. */
@media (max-width: 700px) and (pointer: coarse),
  (pointer: coarse) and (max-height: 500px) {
  .btn.btn-sm { min-height: 44px; min-width: 44px; }
}
