/*
 * Interfaz de campo. Tres decisiones que mandan sobre todo lo demás:
 *
 *  - Alto contraste y tipografía grande: esto se usa a pleno sol, de pie y con
 *    prisa. Un gris elegante sobre blanco no se lee en la calle a mediodía.
 *  - Objetivos táctiles de 56 px o más: se opera con una mano, a veces con
 *    guantes o con el teléfono mojado.
 *  - Ningún color escrito directo en un componente. Todo por token, como pide
 *    el manual de identidad (§6.1).
 *
 * FUENTE DE VERDAD DE LOS TOKENS (Dirección, punto 3 del cierre de pendientes
 * del Estándar UX, 04-sep-2026): la paleta oficial de A la Palabra vive aquí
 * — ver `docs/DESIGN_TOKENS.md` para el mapeo completo con `portada.html` y
 * `catalogo-armazones.html` (que hereda esta misma hoja) y la matemática de
 * contraste de cada variante derivada. Reemplaza el manual anterior
 * (`--marca: #F57604`) por la paleta que Dirección aprobó el 04-sep-2026.
 *
 * LA REGLA QUE PARECE UN ERROR Y NO LO ES (manual §2.2): los botones naranjas
 * llevan texto oscuro, no blanco. El naranja de marca da 2.70:1 contra blanco
 * y reprueba AA; contra el carbón de marca da 4.69:1 y pasa (justo, por eso
 * el margen se documenta en `docs/DESIGN_TOKENS.md`). De ahí se siguen las
 * otras dos:
 *
 *   · el naranja de marca NUNCA es color de texto — para eso está
 *     --marca-texto, un naranja oscurecido a ~5.0:1 sobre blanco;
 *   · lo mismo aplica al ámbar de estado: --ambar da 4.24:1 sobre blanco (no
 *     alcanza AA de texto normal), así que colorea bordes e indicadores, y el
 *     texto ámbar usa --ambar-texto (~5.0:1).
 *
 * `test/identidad.test.ts` mide estos contrastes en cada corrida. Si alguien
 * pinta texto con un token de relleno, la prueba lo dice antes que un usuario.
 *
 * TIPOGRAFÍA (bloque 12, continuación 09-sep-2026): Montserrat para títulos
 * (SemiBold 600/Bold 700/ExtraBold 800 según peso visual) e Inter para texto
 * de cuerpo — mismo par y mismos pesos que ya cargan portada-preview.html,
 * dashboard-preview.html, auditoria-movimientos.html y alarmas-operativas.html
 * vía `<link>` en cada `<head>` (index.html y catalogo-armazones.html, que
 * enlaza esta misma hoja, cargan el suyo). Antes esta hoja usaba solo
 * system-ui; con red lenta o sin ella, la pila de reserva es la misma de
 * siempre, así que nunca se pierde legibilidad.
 */

:root {
  /* Marca — paleta oficial aprobada por Dirección, 04-sep-2026 */
  --marca: #F57C00;         /* relleno: fondos, barras, botones primarios */
  --marca-clara: #FFB15C;   /* "naranja suave" — acentos, no fondos de página */
  --marca-texto: #AE5800;   /* única variante permitida para texto naranja (~5.0:1 sobre blanco) */
  --marca-oscuro: #874400;  /* hover, presionado, bordes de piezas naranjas */
  --marca-suave: #FEF0E3;   /* tinte para placeholders de imagen y SLA urgente — no viene de la paleta oficial (solo 6 tokens), se conserva sin cambio */

  /* Neutros — paleta oficial */
  --marfil: #FAF8F5;        /* fondo general de página ("marfil") */
  --gris-calido: #E9E5E1;   /* bordes y divisores ("gris cálido") */
  --tinta: #3A312C;         /* "carbón" — texto principal */
  --gris-texto: #4A4A4A;    /* texto secundario — no viene de la paleta oficial, se conserva sin cambio */
  --gris-borde: var(--gris-calido);
  --blanco: #FFFFFF;

  /* Estado — paleta oficial. No son decorativos: comunican información. */
  --verde: #2E7D32;    /* éxito — al corriente · pagado · verificado */
  --ambar: #B26A00;    /* advertencia — por vencer */
  --rojo: #C62828;     /* error — mora · crítico · vencido */
  --whatsapp: #25D366; /* WhatsApp de marca — SOLO relleno/ícono, nunca texto (1.98:1 sobre blanco) */

  /* Derivados. No vienen de la paleta: son los fondos tenues y las variantes
     de texto que la regla de contraste obliga (ver docs/DESIGN_TOKENS.md). */
  --ambar-texto: #A16000;
  --whatsapp-texto: #16803E; /* enlaces/etiquetas de WhatsApp que sí necesitan ser texto */
  --verde-fondo: #E8F5EE;
  --ambar-fondo: #FFF9E8;
  --rojo-fondo: #FDEAEA;

  --fondo: var(--marfil);
  --radio: 8px;   /* manual §6.2 */
  --toque: 56px;  /* el manual pide 48; en campo se queda en 56 */

  /* Escala tipográfica (revisión de diseño, 15-sep-2026) — el archivo tenía
     25 valores de font-size distintos (0.72rem a 1.6rem, más un 17px y un
     0.9em sueltos) sin ninguna progresión clara, varios a menos de 0.02rem
     de diferencia entre sí sin razón visible. Estos 6 pasos no inventan
     números nuevos: son los valores que ya predominaban en el archivo,
     redondeados a una sola escala. Mismo criterio de "mismos valores, no
     una sola hoja física" que ya usa DESIGN_TOKENS.md entre esta hoja y
     dashboard-preview.html/caja.html (equivalentes en px ahí, mismo cálculo
     sobre los 17px de raíz de este archivo: 0.75rem≈13px, 0.85rem≈14.5px,
     0.95rem≈16px, 1.15rem≈20px, 1.35rem≈23px, 1.6rem≈27px). */
  --t-micro: 0.75rem;    /* badges, meta pequeño, dato de fila */
  --t-chico: 0.85rem;    /* labels, subtítulo de fila, notas */
  --t-base: 0.95rem;     /* cuerpo — la mayoría del texto no declara font-size, hereda esto vía html/body */
  --t-mediano: 1.15rem;  /* h3, subtítulo de sección, título de tarjeta */
  --t-grande: 1.35rem;   /* h2, título de sección */
  --t-titulo: 1.6rem;    /* h1, título de pantalla */
}

* { box-sizing: border-box; }

/* Hallazgo real (revisión de diseño, 15-sep-2026): CUALQUIER regla de
   autor con la misma especificidad que `[hidden]{display:none}` del user
   agent (una sola clase — `.campo`, `.modal-fondo`, `.boton`...) le gana
   por venir de la hoja de estilos, no del navegador. Un elemento con el
   atributo `hidden` presente podía seguir renderizándose e interceptando
   clics. Todas las demás páginas del panel (dashboard-preview.html,
   caja.html, alarmas-operativas.html...) ya traían este mismo candado
   desde antes — esta hoja era la única que no lo tenía. `!important` es
   exactamente lo correcto aquí: solo puede ganar cuando el atributo SÍ
   está presente, nunca esconde algo que debía verse. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 17px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, .tarjeta-titulo, .siguiente-nombre, .fila-nombre {
  font-family: 'Montserrat', 'Inter', sans-serif;
}

/* Jerarquía explícita (revisión de diseño, 15-sep-2026) — antes h1 no tenía
   regla propia (heredaba el 2em por defecto del navegador, sin relación con
   la escala del resto del sistema) y h2/h3 usaban valores sueltos (1.3rem,
   0.95rem) en vez de los pasos de --t-*. */
h1 { margin: 0; font-weight: 600; font-size: var(--t-titulo); }

/* Barra superior ---------------------------------------------------------- */

/* Fondo claro (RESOLUCIÓN DE DIRECCIÓN, continuación desde celular
   09-sep-2026): el naranja institucional que tenía antes no deja contraste
   legible para el logo oficial (monocromático naranja sobre transparente).
   Mismo tratamiento que ya usa pwa/portada.html (header claro + borde). */
.barra {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: max(12px, env(safe-area-inset-top)) 14px 12px;
  background: var(--blanco);
  color: var(--tinta);
  border-bottom: 1px solid var(--gris-borde);
}

.barra h1 {
  flex: 1;
  margin: 0;
  font-size: var(--t-mediano);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.volver {
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.12);
  color: var(--tinta);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.estado { display: flex; gap: 6px; align-items: center; }

.chip {
  border: 0;
  border-radius: 999px;
  padding: 5px 11px;
  font-size: var(--t-micro);
  font-weight: 600;
  white-space: nowrap;
}

.chip-linea { background: rgba(0, 0, 0, 0.12); color: var(--tinta); }
/* Borde agregado junto con el fondo claro de .barra (arriba): sin él, un
   chip blanco sobre una barra ahora blanca queda invisible — antes
   contrastaba solo porque la barra era naranja. */
.chip-linea.sin-linea { background: var(--blanco); color: var(--ambar-texto); border: 1px solid var(--gris-borde); }
/* REGLA DEFINITIVA de Dirección (2026-09-04, 5+5): minuto 5-10 (gracia) en
   ámbar, más de 10 (bloqueada) en rojo — mismo criterio de color que el
   resto de la app (§ manual de identidad, "no son decorativos"). */
.chip-linea.chip-gracia { background: var(--ambar-fondo); color: var(--ambar-texto); }
.chip-linea.chip-bloqueada { background: var(--rojo-fondo); color: var(--rojo); }
.chip-cola { background: var(--blanco); color: var(--tinta); cursor: pointer; border: 1px solid var(--gris-borde); }

/* Vistas ------------------------------------------------------------------ */

main { padding: 16px 14px calc(28px + env(safe-area-inset-bottom)); max-width: 640px; margin: 0 auto; }

.vista[hidden] { display: none; }

h2 { margin: 0 0 4px; font-size: var(--t-grande); }
/* h3 = etiqueta de sección dentro de un .bloque ("BUSCAR CLIENTE"), nunca un
   título real — por eso es más chico que el cuerpo, no más grande. Un
   título que sí necesita peso (p. ej. .modal h3) declara su propio tamaño
   explícito, nunca hereda este. */
h3 { margin: 0 0 8px; font-size: var(--t-chico); text-transform: uppercase; letter-spacing: 0.06em; color: var(--gris-texto); }

.intro, .nota { margin: 0 0 16px; color: var(--gris-texto); }
.ayuda { margin: 8px 0 0; font-size: 0.85rem; color: var(--gris-texto); }
.vacio { padding: 24px; text-align: center; color: var(--gris-texto); background: var(--blanco); border-radius: var(--radio); }

.bloque {
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  padding: 16px;
  margin-bottom: 14px;
}

.bloque-tenue { background: transparent; border-style: dashed; }

/* Grupos del inicio (bloque 12, home por rol) -----------------------------
   Agrupación puramente visual: no cambia qué tarjetas se muestran (eso lo
   sigue decidiendo `aplicarFiltroTarjetas` en app.js por `data-rol-permite`,
   que sigue funcionando igual sin importar el anidamiento). Un grupo sin
   ninguna tarjeta visible para el rol actual se oculta completo por JS. */

.grupo-inicio { margin-bottom: 20px; }
.grupo-inicio-titulo {
  margin: 0 0 10px;
  font-size: var(--t-chico);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--gris-texto);
}

/* Tarjetas del inicio ----------------------------------------------------- */

.tarjeta {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-left: 5px solid var(--marca);
  border-radius: var(--radio);
  padding: 18px;
  margin-bottom: 12px;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.tarjeta-cliente { border-left-color: var(--marca-oscuro); }
.tarjeta-titulo { display: block; font-size: var(--t-mediano); font-weight: 650; }
.tarjeta-detalle { display: block; color: var(--gris-texto); margin-top: 3px; }
.tarjeta-dato { display: block; margin-top: 10px; font-weight: 650; color: var(--marca-texto); }

/* Listas ------------------------------------------------------------------ */

.lista { list-style: none; margin: 0 0 16px; padding: 0; }

.lista li {
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  margin-bottom: 8px;
  overflow: hidden;
}

.lista button.fila {
  display: block;
  width: 100%;
  min-height: var(--toque);
  text-align: left;
  background: none;
  border: 0;
  padding: 14px 16px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.fila-nombre { display: block; font-weight: 600; }
.fila-detalle { display: block; font-size: 0.88rem; color: var(--gris-texto); margin-top: 2px; }
.fila-dato { display: block; font-size: 0.88rem; margin-top: 4px; font-variant-numeric: tabular-nums; }

.lista-ruta { counter-reset: parada; }
.lista-ruta li { display: flex; align-items: stretch; }
.orden-numero {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  background: var(--fondo);
  font-weight: 700;
  color: var(--gris-texto);
  font-variant-numeric: tabular-nums;
}

/* Botones ----------------------------------------------------------------- */

.boton {
  display: block;
  width: 100%;
  min-height: var(--toque);
  border: 1px solid var(--marca-texto);
  border-radius: var(--radio);
  background: var(--blanco);
  color: var(--marca-texto);
  font: inherit;
  font-weight: 650;
  cursor: pointer;
  padding: 14px;
  margin-top: 10px;
}

.boton-principal { background: var(--marca); color: var(--tinta); border-color: var(--marca-oscuro); }
.boton-secundario { border-style: dashed; }
.boton-texto { border: 0; background: none; color: var(--gris-texto); font-weight: 500; }
.boton:disabled { opacity: 0.45; cursor: not-allowed; }

.opciones { display: grid; gap: 8px; }

.opcion {
  min-height: var(--toque);
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  background: var(--blanco);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 12px;
}

.opcion[aria-pressed="true"] { background: var(--marca); color: var(--tinta); border-color: var(--marca-oscuro); }

/* Resultados de visita (bloque 12, punto 14 aplicado a cobranza: "evitar
   errores de captura por botones similares" — 5 opciones parecidas antes
   solo se distinguían por el texto). Un borde izquierdo por significado;
   `aria-pressed="true"` sigue pintando el fondo naranja completo igual que
   antes — esto no lo reemplaza, solo ayuda ANTES de tocar. */
.opcion[data-resultado="PAGO"], .opcion[data-resultado="ABONO"] { border-left: 4px solid var(--verde); }
.opcion[data-resultado="PROMESA_DE_PAGO"] { border-left: 4px solid var(--ambar); }
.opcion[data-resultado="NO_ENCONTRADO"], .opcion[data-resultado="DOMICILIO_INCORRECTO"] { border-left: 4px solid var(--gris-texto); }
.opcion[aria-pressed="true"][data-resultado] { border-left-color: var(--marca-oscuro); }

/* Conceptos de caja (punto 14: "diferenciar visualmente ingreso, egreso,
   consulta, enganche, pago, seguro, deducible, transferencia, corte").
   `data-concepto` lo agregan las vistas que ya construyen renglones de
   dinero por concepto (lentes.js: corte de caja; desembolso-tesoreria.js). */
.fila[data-concepto="CONSULTA"] { border-left: 4px solid var(--gris-texto); }
.fila[data-concepto="ENGANCHE"] { border-left: 4px solid var(--marca); }
.fila[data-concepto="SEGURO"] { border-left: 4px solid var(--marca-oscuro); }
.fila[data-concepto="PRECIO_TOTAL"] { border-left: 4px solid var(--tinta); }
.fila[data-concepto="PAGO_CREDITO"] { border-left: 4px solid var(--verde); }
.fila[data-concepto="TRANSFERENCIA"] { border-left: 4px solid var(--marca-oscuro); }
.fila[data-concepto="DEDUCIBLE"] { border-left: 4px solid var(--rojo); }

/* Kanban de laboratorio de sucursal (bloque 12, §9). Columnas = el pipeline
   real de 9 estados (laboratorio_lente.ts) + CANCELADA aparte — no se
   inventa ninguna columna que la orden no pueda alcanzar de verdad. En
   móvil, scroll horizontal controlado por columna (mismo criterio que
   `.pestanas-scroll` — punto 12 del mandato); en desktop, todas las
   columnas caben sin scroll. */
.kanban-laboratorio {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
  margin-top: 12px;
}
.kanban-columna {
  flex: 0 0 200px;
  background: var(--fondo);
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  padding: 10px;
}
.kanban-columna-titulo {
  font-size: var(--t-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gris-texto);
  margin: 0 0 8px;
  display: flex;
  justify-content: space-between;
}
.kanban-tarjeta {
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-left: 4px solid var(--marca);
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 8px;
  font-size: 0.85rem;
}
.kanban-tarjeta.tipo-reposicion { border-left-color: var(--ambar); }
.kanban-tarjeta.tipo-siniestro { border-left-color: var(--rojo); }
.kanban-tarjeta-cliente { font-weight: 650; display: block; }
.kanban-tarjeta-detalle { color: var(--gris-texto); font-size: 0.8rem; display: block; margin-top: 2px; }
.kanban-columna-vacia { color: var(--gris-texto); font-size: 0.8rem; font-style: italic; }

/* Campos ------------------------------------------------------------------ */

.campo { display: block; margin-bottom: 8px; }
.campo span { display: block; font-size: 0.88rem; color: var(--gris-texto); margin-bottom: 6px; }

.campo input, .campo textarea, .campo-select {
  width: 100%;
  min-height: var(--toque);
  padding: 12px;
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  font: inherit;
  background: var(--blanco);
  color: var(--tinta);
}

.campo textarea { min-height: 80px; resize: vertical; }

.campo input:focus, .campo textarea:focus, .campo-select:focus {
  outline: none;
  border-color: var(--marca);
  box-shadow: 0 0 0 3px var(--marca-suave);
}

/* Modal --------------------------------------------------------------------
   Componente reutilizable (UX operativa, 15-sep-2026 — DESIGN_SYSTEM_AUDIT.md
   ya lo marcaba como pendiente: "botones/inputs/selects/badges/alertas
   reutilizables no existen como clases con nombre"). Mismos tokens que el
   resto del sistema — radio de 16px a propósito, más generoso que el --radio
   de 8px de la interfaz de campo utilitaria (mismo criterio documentado en
   DESIGN_TOKENS.md: la app operativa y el sitio de marketing usan radios
   distintos aposta). Primer uso real: Cliente 360, "Nuevo cliente" y "Nuevo
   crédito — Efectivo" (antes paneles en línea, ahora aquí). ------------- */

/* `[hidden]` por sí solo no alcanza: cualquier regla de autor con la misma
   especificidad que `[hidden]{display:none}` del user-agent le gana (mismo
   hallazgo ya documentado en index.html sobre `.campo`) — aquí `.modal-fondo`
   declara `display:flex` con especificidad igual (0,1,0), así que sin este
   selector más específico el modal quedaría "hidden" en el atributo pero
   visible e interceptando clics. */
.modal-fondo[hidden] { display: none; }

.modal-fondo {
  position: fixed;
  inset: 0;
  background: rgba(58, 49, 44, 0.45);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
  z-index: 100;
}

.modal {
  background: var(--blanco);
  border-radius: 16px;
  width: 100%;
  max-width: 520px;
  margin: auto 0;
  padding: 24px;
  box-shadow: 0 8px 32px rgba(58, 49, 44, 0.18);
}

/* Título real, no una etiqueta de sección: la regla global de h3 (arriba)
   lo pondría en mayúsculas y gris tenue, correcto para "BUSCAR CLIENTE"
   dentro de un .bloque, pero equivocado para el título de un modal — hay
   que apagar esas tres propiedades a propósito, no dejarlas heredadas por
   accidente (hallazgo de esta revisión: así estaba antes de este cambio). */
.modal h3 {
  font-family: 'Montserrat', 'Inter', sans-serif;
  font-weight: 600;
  font-size: var(--t-grande);
  text-transform: none;
  letter-spacing: normal;
  color: var(--tinta);
  margin: 0 0 16px;
}

.modal .campo:last-of-type { margin-bottom: 0; }

.modal-pie {
  display: flex;
  gap: 10px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--gris-calido);
}

.modal-pie .boton { margin-top: 0; width: auto; flex: 1; }

@media (min-width: 640px) {
  .modal-fondo { align-items: center; }
}

/* Tabla ----------------------------------------------------------------
   Clase reutilizable para tablas de datos dentro de la SPA (antes solo
   `#audit-tabla` con estilo en línea) — mismo criterio de tokens que
   `.ec-tabla` ya usa en escritorio-cobranza.html (páginas standalone de
   Dirección, fuera de esta hoja de estilos). No es una tabla "cards en
   móvil" genérica: cada tabla ancha ya resuelve su propio responsive
   (ver `#audit-tabla` más abajo), esta clase solo da el look de escritorio. */

.tabla { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
.tabla thead th {
  background: var(--gris-calido);
  color: var(--tinta);
  font-family: 'Montserrat', 'Inter', sans-serif;
  font-weight: 500;
  font-size: var(--t-micro);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  padding: 10px 12px;
}
.tabla thead th:first-child { border-top-left-radius: var(--radio); }
.tabla thead th:last-child { border-top-right-radius: var(--radio); }
.tabla tbody td { padding: 10px 12px; border-bottom: 1px solid var(--gris-calido); }
.tabla tbody tr:hover { background: var(--fondo); }
.tabla tbody tr:last-child td { border-bottom: none; }

/* GPS --------------------------------------------------------------------- */

.gps {
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  padding: 14px;
  background: var(--fondo);
  font-variant-numeric: tabular-nums;
}

.gps-estado { margin: 0; color: var(--gris-texto); }
.gps-coordenada { margin: 0 0 4px; font-weight: 650; font-size: 1.05rem; }
.gps-precision { margin: 0; font-size: 0.9rem; }
.gps.buena { background: var(--verde-fondo); border-color: var(--verde); }
.gps.regular { background: var(--ambar-fondo); border-color: var(--ambar); }
.gps.mala { background: var(--rojo-fondo); border-color: var(--rojo); }

/* Galería ----------------------------------------------------------------- */

.galeria { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.galeria figure { margin: 0; position: relative; }
.galeria img { width: 84px; height: 84px; object-fit: cover; border-radius: 8px; display: block; }

.galeria .quitar {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 0;
  background: var(--rojo);
  color: var(--blanco);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
}

/* Siguiente punto --------------------------------------------------------- */

.siguiente {
  background: var(--marca);
  color: var(--tinta);
  border-radius: var(--radio);
  padding: 20px;
  margin-bottom: 16px;
}

.siguiente-etiqueta { margin: 0; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.09em; }
.siguiente-nombre { margin: 4px 0 2px; font-size: 1.5rem; font-weight: 700; line-height: 1.2; }
.siguiente-direccion { margin: 0; font-size: 0.92rem; }
.siguiente-datos { display: flex; gap: 18px; margin-top: 14px; }
.dato-fuerte { font-size: 1.45rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.siguiente .boton { background: var(--blanco); color: var(--marca-texto); border-color: var(--blanco); }

/* Atraso del cobrador (bloque 12, §8): ciclo_credito.atraso, semanas — dato
   real (ver src/pg/cobranza.ts, PENDIENTES). Un solo nivel (no una escala de
   severidad inventada): con atraso se marca, sin atraso no se muestra nada —
   la escala de "qué tan grave" no es una decisión que corresponda inventar
   aquí (documentado en el reporte de cierre del bloque). */
.siguiente-atraso {
  display: inline-block;
  margin: 10px 0 0;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.14);
  color: var(--tinta);
  font-size: 0.85rem;
  font-weight: 700;
}

.ritmo {
  border-radius: var(--radio);
  padding: 12px 14px;
  margin-bottom: 16px;
  font-weight: 600;
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
}

.ritmo.lenta { background: var(--ambar-fondo); border-color: var(--ambar); color: var(--ambar-texto); }

/* Pinpad ------------------------------------------------------------------ */

.vista-pinpad { max-width: 420px; margin: 0 auto; }
.pinpad { text-align: center; }
.pinpad-titulo { font-size: var(--t-grande); font-weight: 700; margin: 8px 0 2px; }
.pinpad-detalle { margin: 0 0 20px; color: var(--gris-texto); }

.pinpad-puntos { display: flex; justify-content: center; gap: 16px; margin: 18px 0 26px; }

.punto {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--marca-oscuro);
  background: transparent;
}

.punto.lleno { background: var(--marca); }

.teclado { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }

.tecla {
  min-height: 68px;
  border: 1px solid var(--gris-borde);
  border-radius: var(--radio);
  background: var(--blanco);
  font: inherit;
  font-size: 1.6rem;
  font-weight: 600;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.tecla:active { background: var(--fondo); }
.tecla-tenue, .tecla-entrar { font-size: 0.95rem; }
.tecla-entrar { background: var(--marca); color: var(--tinta); border-color: var(--marca-oscuro); }

.pinpad-mensaje { min-height: 1.5em; margin: 16px 0 0; font-weight: 650; color: var(--rojo); }

.pinpad-resultado { text-align: center; padding-top: 20px; }
.resultado-icono { font-size: 3.4rem; margin: 0; }
.resultado-mensaje { font-size: 1.15rem; font-weight: 650; margin: 8px 0 20px; }

.resultado-orden {
  background: var(--verde-fondo);
  border: 1px solid var(--verde);
  border-radius: var(--radio);
  padding: 16px;
  margin-bottom: 20px;
}

.orden-etiqueta { margin: 0; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--gris-texto); }
.orden-acciones { margin: 4px 0 10px; font-weight: 700; font-size: 1.05rem; }
.orden-ticket { margin: 0; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 1.2rem; font-weight: 700; }

/* Varios ------------------------------------------------------------------ */

.error {
  margin: 12px 0 0;
  padding: 12px;
  border-radius: var(--radio);
  background: var(--rojo-fondo);
  border: 1px solid var(--rojo);
  color: var(--rojo);
  font-weight: 600;
}

/* Confirmación (verde) — mismo criterio que .error/.advertencia, para el
   resultado de una operación que sí se completó (UX operativa, 15-sep-2026). */
.exito {
  margin: 12px 0;
  padding: 12px;
  border-radius: var(--radio);
  background: var(--verde-fondo);
  border: 1px solid var(--verde);
  color: var(--verde);
  font-weight: 600;
}

/* Advertencia (ámbar) — cuenta bancaria §1: "Las transferencias solo podrán
   realizarse a una cuenta previamente validada y a nombre del cliente." */
.advertencia {
  margin: 12px 0;
  padding: 12px;
  border-radius: var(--radio);
  background: var(--ambar-fondo);
  border: 1px solid var(--ambar);
  color: var(--ambar-texto);
  font-weight: 600;
}

/* Máscara de CLABE — nunca mostrar el número completo por defecto (§4). */
.clabe-mascarada { font-family: ui-monospace, Menlo, Consolas, monospace; letter-spacing: 0.05em; }

.aviso {
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--tinta);
  color: var(--blanco);
  padding: 13px 20px;
  border-radius: 999px;
  font-weight: 600;
  z-index: 50;
  max-width: 92vw;
  text-align: center;
}

.etiqueta-cola {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--ambar-fondo);
  color: var(--ambar-texto);
  font-size: 0.78rem;
  font-weight: 700;
}

@media (prefers-reduced-motion: no-preference) {
  .aviso { animation: aparecer 0.18s ease-out; }
  @keyframes aparecer { from { opacity: 0; transform: translate(-50%, 8px); } }
}

/* Agenda -------------------------------------------------------------------
   Módulo AGENDA (mandato de Dirección, 01-sep-2026). Solo tokens ya
   declarados arriba — la regla de identidad (§2.2) no se repite dos veces. */

.agenda-filtros { display: flex; gap: 8px; margin-bottom: 12px; }
.agenda-filtros .campo-select { margin: 0; }

.agenda-fila {
  padding: 12px 14px;
}
.agenda-fila-encabezado { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-top: 8px; }
.agenda-fila-nombre { font-weight: 700; font-size: 1.02rem; }
.agenda-fila-meta { font-size: 0.88rem; color: var(--gris-texto); margin-top: 2px; }
.agenda-fila-meta-diabetico { font-weight: 600; color: var(--ambar-texto); }
.agenda-fila-codigo { font-size: 0.85rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: 0.02em; margin-top: 2px; }
.agenda-hora { font-weight: 700; font-variant-numeric: tabular-nums; }
.agenda-fila-detalle { font-size: 0.88rem; color: var(--gris-texto); margin-top: 4px; }
.agenda-fila-nota { font-size: 0.85rem; color: var(--gris-texto); margin-top: 2px; font-style: italic; }

.agenda-estado {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  background: var(--fondo);
  color: var(--gris-texto);
}
.agenda-estado-confirmed, .agenda-estado-reminder_sent { background: var(--verde-fondo); color: var(--verde); }
.agenda-estado-arrived, .agenda-estado-in_progress { background: var(--ambar-fondo); color: var(--ambar-texto); }
.agenda-estado-completed { background: var(--verde-fondo); color: var(--verde); }
.agenda-estado-no_show, .agenda-estado-cancelled { background: var(--rojo-fondo); color: var(--rojo); }

/* Parte C: SLA de la cola de Tesorería — 0-29 NORMAL, 30-44 ATENCIÓN, 45-59 URGENTE, 60+ VENCIDA. */
.agenda-estado-sla-normal { background: var(--verde-fondo); color: var(--verde); }
.agenda-estado-sla-atencion { background: var(--ambar-fondo); color: var(--ambar-texto); }
.agenda-estado-sla-urgente { background: var(--marca-suave); color: var(--marca-texto); }
.agenda-estado-sla-vencida { background: var(--rojo-fondo); color: var(--rojo); }

.agenda-acciones { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.boton-chico {
  width: auto;
  min-height: 40px;
  padding: 8px 12px;
  margin-top: 0;
  font-size: 0.85rem;
}

/* ACCESO ÚNICO — login central (mandato de Dirección, 2026-09-04) --------- */

.chip-salir {
  background: var(--blanco);
  color: var(--marca-texto);
  cursor: pointer;
  border: 1px solid var(--gris-borde);
}

.vista-login {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 8vh;
}

.tarjeta-login {
  width: 100%;
  max-width: 380px;
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-top: 5px solid var(--marca);
  border-radius: var(--radio);
  padding: 24px 20px;
}

/* Logo + slogan del login (bloque 12, punto 3: "slogan cuando corresponda")
   — el login es el único punto de la app operativa donde tiene sentido: es
   la puerta de entrada, igual que la portada pública. El resto de las
   pantallas de trabajo no lo lleva, para no quitarle espacio de pantalla al
   contenido operativo (§13, "prioridad móvil máxima"). */
.login-logo { display: block; max-width: 220px; width: 70%; margin: 0 auto 10px; }
.login-slogan {
  margin: 0 0 20px;
  font-size: 0.86rem;
  font-weight: 600;
  font-family: 'Montserrat', 'Inter', sans-serif;
  color: var(--marca-texto);
  text-align: center;
  letter-spacing: 0.01em;
}

/* ESTÁNDAR UX FASE 1 (Dirección, 04-sep-2026) — estados transversales que
   antes no existían en ningún componente: foco visible, carga y campo
   inválido. Aditivo: nada de lo anterior cambia de valor. */

:focus-visible {
  outline: 3px solid var(--marca-oscuro);
  outline-offset: 2px;
}

/* LOADING de botón, variante spinner — para cuando el texto no alcanza a
   decir "Guardando…" (icon buttons, botones cortos). La variante ya usada
   en el resto del código (cambiar el texto + disabled, ej. `verificador.js`
   "Buscando satélites…") sigue siendo válida y es la que usan las 5
   pantallas de esta fase; esta clase queda formalizada para cuando un
   botón no tenga un texto natural que cambiar. */
.boton.cargando {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}

.boton.cargando::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 3px solid rgba(0, 0, 0, 0.25);
  border-top-color: var(--tinta);
  border-radius: 50%;
}

@media (prefers-reduced-motion: no-preference) {
  .boton.cargando::after { animation: girar 0.7s linear infinite; }
  @keyframes girar { to { transform: rotate(360deg); } }
}

/* ERROR de campo individual — para cuando el problema es un campo preciso,
   no la operación completa (que ya usa `.error` debajo del formulario). */
.campo-invalido input, .campo-invalido textarea, .campo-invalido .campo-select {
  border-color: var(--rojo);
}

/* Badges de estado (bloque 12, puntos 10/15 del mandato: severidad de
   alertas y estado de documentos con "lenguaje visual consistente... no
   convertir todo en rojo"). Base neutral + 3 variantes de significado —
   deliberadamente solo 3: verde=resuelto/positivo, ámbar=atención,
   rojo=bloqueo/error, igual que el resto del sistema (§ manual de
   identidad). Ver `badge()` en ui.js — mapea cada valor REAL del backend
   (SeveridadAlertaRiesgo, DocumentoGenerado.estado) a una de estas 4; ningún
   valor se inventa aquí, ver la nota en cliente-360.js sobre el estado único
   de crédito que Dirección pidió y el backend no modela así (§7 del mandato,
   documentado aparte, no en este componente). */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 700;
  font-family: 'Montserrat', 'Inter', sans-serif;
  letter-spacing: 0.02em;
  white-space: nowrap;
  vertical-align: middle;
  margin-left: 6px;
}

.badge-neutral { background: var(--fondo); color: var(--gris-texto); }
.badge-exito { background: var(--verde-fondo); color: var(--verde); }
.badge-advertencia { background: var(--ambar-fondo); color: var(--ambar-texto); }
.badge-error { background: var(--rojo-fondo); color: var(--rojo); }

.fila-nombre .badge { margin-left: 8px; }

/* Pestañas con scroll horizontal controlado (bloque 12, punto 12: "no dejar
   tablas/paneles desktop imposibles en móvil"). Aplica a los grupos de
   pestañas con muchos elementos (Cliente 360: 11; Lentes: 6; Cuenta
   bancaria/Tesorería/Renovación: 2-3, donde igual no estorba). No cambia el
   comportamiento de clic — sigue siendo el mismo `.agenda-filtros`. */
.pestanas-scroll {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  flex-wrap: nowrap;
  margin-bottom: 12px;
  padding-bottom: 2px;
  scrollbar-width: thin;
}
.pestanas-scroll .boton-chico { flex: 0 0 auto; }

/* Tabla de auditoría como cards en móvil (bloque 12, punto 12: "no dejar
   tablas desktop imposibles de usar en celular... cuando corresponda:
   cards"). Arriba de 640px sigue siendo una tabla normal con scroll
   horizontal (ya lo tenía, `#audit-tabla-envoltura{overflow-x:auto}` en
   index.html) — 11 columnas en una tabla real siguen siendo más legibles en
   pantalla ancha. Los `data-label` los pone auditoria.js por celda, en el
   mismo orden que los <th> — solo presentación, ningún dato cambia. */
@media (max-width: 640px) {
  #audit-tabla thead { display: none; }
  #audit-tabla, #audit-tabla tbody, #audit-tabla tr, #audit-tabla td { display: block; width: 100%; }
  #audit-tabla tr {
    background: var(--blanco);
    border: 1px solid var(--gris-borde);
    border-radius: var(--radio);
    margin-bottom: 10px;
    padding: 4px 12px;
  }
  #audit-tabla td {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid var(--gris-calido);
    text-align: right;
  }
  #audit-tabla td:last-child { border-bottom: 0; }
  #audit-tabla td::before {
    content: attr(data-label);
    font-weight: 700;
    color: var(--gris-texto);
    text-align: left;
    flex-shrink: 0;
  }
}
