/*
 * ATOM: Input / Textarea / Select — sistema 2026-05
 * Foco con anillo coral suave, hover preview, error con shake opcional
 */

.input,
.textarea,
.select {
  width: 100%;
  height: 36px;
  padding: 0 var(--h-space-3);
  font-family: var(--h-font-sans);
  font-size: var(--h-text-base);
  color: var(--h-ink);
  background: var(--h-surface);
  border: 1px solid var(--h-border-soft);
  border-radius: var(--h-radius-md);
  transition:
    border-color 140ms ease-out,
    box-shadow 140ms ease-out,
    background 140ms ease-out;
  appearance: none;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--h-faint);
}

.input:hover:not(:disabled):not(:focus),
.textarea:hover:not(:disabled):not(:focus),
.select:hover:not(:disabled):not(:focus) {
  border-color: var(--h-muted);
  background: var(--h-nest);
}

.input:focus,
.textarea:focus,
.select:focus {
  outline: none;
  border-color: var(--h-brand-primary);
  background: var(--h-surface);
  box-shadow: 0 0 0 3px var(--h-brand-primary-soft);
}

.input:disabled,
.textarea:disabled,
.select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--h-nest);
}

/* ── Lo que rellena el navegador tiene que verse como lo que escribe la
 * persona ────────────────────────────────────────────────────────────────
 *
 * Cuando el navegador completa un campo guardado —el correo y la contraseña de
 * la pantalla de acceso, todos los días, en todas las máquinas— lo pinta con un
 * fondo propio, casi blanco, que NO sale de esta hoja: es una capa del motor y
 * gana sobre `background`. En modo claro casi no se nota. En oscuro es un
 * rectángulo blanco con letra oscura en el medio de una pantalla oscura, en la
 * primera pantalla del sistema. Visto el 22/8 en el acceso.
 *
 * El fondo se tapa con una sombra interior gigante, que es lo único que ese
 * relleno respeta, y la letra se fuerza con `-webkit-text-fill-color`, porque
 * `color` tampoco le llega. La transición larguísima es el truco conocido para
 * que el motor no vuelva a pintar el fondo al pasar el mouse: la animación
 * nunca llega a su primer cuadro.
 *
 * Vale para todos los navegadores que usan Blink o WebKit — o sea Chrome, Edge
 * y Safari, que es con lo que se trabaja en el laboratorio. */
.input:-webkit-autofill,
.input:-webkit-autofill:hover,
.input:-webkit-autofill:focus,
.textarea:-webkit-autofill,
.select:-webkit-autofill {
  -webkit-text-fill-color: var(--h-ink);
  -webkit-box-shadow: 0 0 0 100px var(--h-surface) inset;
  box-shadow: 0 0 0 100px var(--h-surface) inset;
  caret-color: var(--h-ink);
  transition: background-color 600000s 0s;
}
/* Con el foco puesto, el anillo tiene que seguir viéndose: la sombra interior
   de arriba pisaría la de `:focus`, así que se declaran las dos juntas. */
.input:-webkit-autofill:focus,
.textarea:-webkit-autofill:focus,
.select:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 100px var(--h-surface) inset,
                      0 0 0 3px var(--h-brand-primary-soft);
  box-shadow: 0 0 0 100px var(--h-surface) inset,
              0 0 0 3px var(--h-brand-primary-soft);
}

.textarea {
  height: auto;
  min-height: 80px;
  padding: var(--h-space-2) var(--h-space-3);
  resize: vertical;
  line-height: 1.5;
}

/* Select con chevron custom */
.select,
.input-combobox,
.input[list] {
  background-image: var(--h-icono-desplegable);  /* el color, en tokens.css (2836) */
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 32px;
}
.select { cursor: pointer; }

/* Inputs con datalist — ocultar el chevron nativo de WebKit/Safari
 * (que se ve negro y choca con el chevron custom del background).
 * IMPORTANTE: scope solo a [list], no a type="date" (que también usa
 * el mismo pseudo y necesita su icono de calendario). */
.input-combobox,
.input[list] {
  appearance: none;
  -webkit-appearance: none;
}
.input[list]::-webkit-calendar-picker-indicator,
.input-combobox::-webkit-calendar-picker-indicator {
  opacity: 0;
  pointer-events: none;
}

/* Sin flechitas de number */
.input[type="number"]::-webkit-outer-spin-button,
.input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.input[type="number"] { -moz-appearance: textfield; }

/* Tamaños */
.input-sm,
.select-sm {
  height: 28px;
  padding: 0 var(--h-space-2);
  font-size: var(--h-text-sm);
  border-radius: var(--h-radius-sm);
}
.select-sm { padding-right: 28px; background-position: right 8px center; }

.input-lg,
.select-lg {
  height: 44px;
  padding: 0 var(--h-space-4);
  font-size: var(--h-text-md);
  border-radius: var(--h-radius-lg);
}

/* Búsqueda con icono integrado */
.input-search {
  max-width: 380px;
  padding-left: 36px;
  background-image: var(--h-icono-lupa);
  background-repeat: no-repeat;
  background-position: left 12px center;
}

/* Anchos canónicos */
.input-w-sm  { max-width: 160px; }
.input-w-md  { max-width: 220px; }
.input-w-lg  { max-width: 320px; }

/* Input con prefijo/sufijo */
.input-affix {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 100%;
}
.input-affix input {
  width: 100%;
  padding-right: 26px;
  text-align: right;
  font-family: var(--h-font-mono);
  font-variant-numeric: tabular-nums;
}
.input-affix .affix-suffix {
  position: absolute;
  right: 10px;
  font-size: var(--h-text-sm);
  color: var(--h-muted);
  pointer-events: none;
}
/* El signo de peso va adelante del numero, como se escribe en el pais.
   Puesto a la derecha se montaba encima de las flechas del campo numerico
   y del propio numero cuando el precio tenia cinco cifras (Matias, 8/9). */
.input-affix .affix-prefix {
  position: absolute;
  left: 10px;
  font-size: var(--h-text-sm);
  color: var(--h-muted);
  pointer-events: none;
}
.input-affix:has(.affix-prefix) input {
  padding-left: 24px;
  padding-right: 10px;
}
/* Las flechas de incremento del campo numerico se comen el ancho util y
   quedan debajo del texto alineado a la derecha. El precio se escribe. */
.input-affix input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
.input-affix input[type="number"]::-webkit-outer-spin-button,
.input-affix input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Error state */
.input-error,
.textarea-error {
  border-color: var(--h-danger);
  background: var(--h-danger-soft);
}
.input-error:focus,
.textarea-error:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--h-danger) 15%, transparent);
  background: var(--h-surface);
}
.input-error.shake { animation: input-shake var(--h-dur-3) var(--h-ease-out); }
@keyframes input-shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-3px); }
  75%      { transform: translateX(3px); }
}

/* Success state — confirmación visual */
.input-success {
  border-color: var(--h-ok);
  background: var(--h-ok-soft);
}

/* Field con label + helper */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--h-space-1);
}
.field-label {
  font-size: var(--h-text-xs);
  font-weight: var(--h-weight-semibold);
  color: var(--h-ink-soft);
  letter-spacing: 0.3px;
}
.field-label-required::after {
  content: ' *';
  color: var(--h-brand-primary);
  font-weight: 700;
}
.field-help {
  font-size: var(--h-text-xs);
  color: var(--h-muted);
  line-height: 1.4;
}
.field-error {
  font-size: var(--h-text-xs);
  color: var(--h-danger);
  display: flex;
  /* Al primer renglón, no al medio: un error de dos renglones ("Falta el
     documento del paciente, que es lo que la obra social pide para
     autorizar") dejaba el triángulo flotando en la mitad, lejos de donde
     empieza a leerse. El `margin-top` del ::before compensa la diferencia
     entre el alto del icono (12px) y el del renglón. */
  align-items: flex-start;
  gap: 4px;
}
/* 3/9: encontrado armando el compositor de la campanita — un `.field-error`
 * escondido con el atributo `hidden` (no con `x-show`, que pone `display`
 * inline y sí gana) se seguía viendo: el ícono `::before` de abajo se pinta
 * igual porque esta regla y `[hidden]` tienen la misma especificidad, y la
 * de acá carga después. Sin este freno, cualquier `.field-error` que se
 * abra/cierre por JS con `.hidden = true/false` en vez de `x-show` queda
 * con un triángulo fantasma permanente. */
.field-error[hidden] { display: none; }

/* El triángulo de aviso, de trazo, como el resto de la app (tarea 2451).
 *
 * Era el emoji ⚠ escrito en `content`, que Matías pidió sacar de todo el
 * sistema: cada sistema operativo lo dibuja distinto —en Windows sale amarillo
 * y relleno, en Mac naranja— y NO toma el color de la marca, así que el aviso
 * de error salía de dos colores a la vez. Éste es el mismo triángulo que usa
 * `.alert-icon` del banner (alert-banner.css), para que el aviso chico de un
 * campo y el aviso grande de la pantalla sean el mismo dibujo.
 *
 * Va por `mask` y no por `background-image` a propósito: así el color sale de
 * `currentColor` —que acá es el `var(--h-danger)` de `.field-error`— en vez de
 * quedar cocido en el data URI. Los dos data URI de más arriba (el chevron del
 * select y la lupa del buscador) sí lo tienen cocido en hex: son anteriores a
 * la regla 5 y no cambian en tema oscuro. Anotado al tablero, no se tocan acá.
 *
 * `flex: none` porque `.field-error` es flex: sin eso el triángulo se achica
 * cuando el texto del error es largo. */
.field-error::before {
  content: '';
  width: 12px;
  height: 12px;
  flex: none;
  margin-top: 1.5px;
  background-color: currentColor;
  -webkit-mask: var(--h-icono-alerta) center / contain no-repeat;
          mask: var(--h-icono-alerta) center / contain no-repeat;
}

@media (prefers-reduced-motion: reduce) {
  .input, .textarea, .select { transition: none; }
  .input-error.shake { animation: none; }
}

/* ─── Density support ──────────────────────────────────────────── */
[data-density="compact"] .input,
[data-density="compact"] .select,
[data-density="compact"] .textarea {
  height: 32px;
  padding: 0 var(--h-space-2);
  font-size: var(--h-text-sm);
}
[data-density="compact"] .textarea { height: auto; padding: var(--h-space-1) var(--h-space-2); }

[data-density="cozy"] .input,
[data-density="cozy"] .select,
[data-density="cozy"] .textarea {
  height: 44px;
  padding: 0 var(--h-space-4);
  font-size: var(--h-text-md);
}
[data-density="cozy"] .textarea { height: auto; padding: var(--h-space-3) var(--h-space-4); }

/* ─── Density aplicada a inputs */
.input { padding: var(--h-density-input-pad, var(--h-space-2) var(--h-space-3)); }

/*
 * El hueco de la lupa se vuelve a poner DESPUÉS de la densidad.
 *
 * `.input-search` reserva 36px a la izquierda para que el texto no se monte
 * sobre el ícono. Pero la regla de arriba escribe `padding` con la forma corta,
 * o sea que reescribe también el `padding-left` — y como está más abajo en el
 * archivo, ganaba. Resultado: en TODOS los buscadores del sistema el
 * "Buscar por nombre o código…" arrancaba encima de la lupa.
 *
 * Va con `.input.input-search` (más específico) y no simplemente más abajo,
 * para que no vuelva a romperse si mañana alguien reordena el archivo.
 */
.input.input-search { padding-left: 36px; }
