/* Mini App de gestiones — estilo austero sobre el tema de Telegram. */

:root {
  --bg: var(--tg-theme-bg-color, #ffffff);
  --bg2: var(--tg-theme-secondary-bg-color, #f2f3f5);
  --texto: var(--tg-theme-text-color, #111111);
  --hint: var(--tg-theme-hint-color, #7a7a7a);
  --acento: var(--tg-theme-button-color, #2481cc);
  --acento-texto: var(--tg-theme-button-text-color, #ffffff);
  --link: var(--tg-theme-link-color, #2481cc);
  --peligro: #c62828;
  --ok: #2e7d32;
  --alerta: #f9a825;
  --indigo: #5c6bc0;
  --borde: color-mix(in srgb, var(--hint) 30%, transparent);

  /* Barra de gestos del iPhone. Sin esto la última fila de pestañas queda
     debajo del indicador y se toca la de al lado. */
  --piso: env(safe-area-inset-bottom, 0px);
  /* Alto de la barra inferior. Lo mide el JS al construirla, y la medida ya
     incluye la barra de gestos: por eso el padding del body NO vuelve a sumar
     --piso. El default es generoso a propósito, para el instante que va entre
     el primer pintado y la medición. */
  --alto-tabs: 74px;
  /* Target táctil mínimo: con guantes, al sol y arriba de una moto. */
  --tap: 44px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 0 calc(var(--alto-tabs) + 12px) 0;
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  background: var(--bg);
  color: var(--texto);
  /* Red de contención contra el scroll horizontal. Casi todo lo que se pinta
     es texto que viene de la base (razones sociales, direcciones, nombres de
     ministerios) y cualquiera de esos puede traer una palabra más ancha que el
     teléfono. `anywhere` —y no `break-word`— porque además achica el
     min-content, que es lo que deja encoger a los hijos de un flex. */
  overflow-wrap: anywhere;
}

.view { padding: 12px; }
.oculto { display: none !important; }
.centrado { text-align: center; }
.hint { color: var(--hint); font-size: 13px; }
.error { color: var(--peligro); font-size: 14px; }

h2 { font-size: 16px; margin: 4px 0 10px; }

#cabecera {
  padding: 10px 12px;
  background: var(--bg2);
  border-bottom: 1px solid var(--borde);
}
#gestor-nombre { font-weight: 600; }

/* --- chips ---------------------------------------------------------------
   UN solo componente para todo lo que antes eran cuatro sistemas distintos
   (.badge, .badge-seg, .hoy-item, .rat): mismas proporciones, mismo radio,
   misma altura de línea. El color dice qué tan bien o mal está la cosa.

   El fondo es un tinte y el texto va en --texto: un texto de color sobre un
   tinte del mismo color se cae en el tema oscuro de Telegram, donde --bg2 ya
   es oscuro. El tono se lee igual, por el borde y el punto de color. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--borde);
  background: var(--bg2);
  color: var(--texto);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.35;
  /* NO va `white-space: nowrap`. Un chip es un flex item y no se encoge por
     debajo de su min-content: con nowrap el min-content es el texto entero, así
     que un chip largo empuja la página y aparece scroll horizontal en TODA la
     app. Pasó con el chip del MEF: "🏛️ Funcionario: MINISTERIO DE EDUCACION Y
     CIENCIAS · Gs 3.200.000" medía 426px en una pantalla de 345 y se llevaba
     puesta la barra de abajo. Un chip que no entra ocupa dos renglones; los
     cortos no se parten nunca, porque entran. */
  max-width: 100%;
}
.chip-ok {
  background: color-mix(in srgb, var(--ok) 16%, transparent);
  border-color: color-mix(in srgb, var(--ok) 55%, transparent);
}
.chip-alerta {
  background: color-mix(in srgb, var(--alerta) 18%, transparent);
  border-color: color-mix(in srgb, var(--alerta) 60%, transparent);
}
.chip-peligro {
  background: color-mix(in srgb, var(--peligro) 16%, transparent);
  border-color: color-mix(in srgb, var(--peligro) 55%, transparent);
}
.chip-info {
  background: color-mix(in srgb, var(--acento) 14%, transparent);
  border-color: color-mix(in srgb, var(--acento) 50%, transparent);
}
.chip-indigo {
  background: color-mix(in srgb, var(--indigo) 16%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 55%, transparent);
}
.chip-neutro { color: var(--hint); }
/* Chip que filtra (bancos de la pestaña Con cuenta): es un botón, pero se ve
   igual que los chips de dato que tiene al lado. */
button.chip { font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
/* El chip que lleva el guion de abordaje es una frase larga, no un dato. */
.chip-guion { font-weight: 500; align-items: flex-start; }

/* Badge sólido: la calidad del candidato y el rating de Visión. Acá el relleno
   entero SÍ va, porque es una nota (A+, AAA) y se busca que grite. */
.badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 600;
  background: var(--acento);
  color: var(--acento-texto);
}

/* --- buscador --------------------------------------------------------------
   El campo tenía el MISMO relleno, borde y radio que las filas de Hoy, así que
   se leía como una tarjeta más y se perdía en la pila. Se separa por tres vías
   a la vez, que es lo que hace que un buscador se lea como buscador:

   1. Otro plano: va pegado arriba (sticky) sobre el fondo de la página, no en
      el gris de las tarjetas. Deja de ser contenido y pasa a ser herramienta.
   2. Otra forma: píldora completa contra el radio de 12px de las tarjetas.
   3. Un ícono fijo adentro, que no se va al escribir (antes la lupa vivía en
      el placeholder y desaparecía con la primera letra). */
.buscador {
  position: sticky;
  top: 0;
  z-index: 5;
  /* Los márgenes negativos compensan el padding de .view: si no, al scrollear
     el contenido asoma por los costados de la barra pegada. */
  margin: 0 -12px 4px;
  padding: 6px 12px 10px;
  background: var(--bg);
}
.buscador .caja { position: relative; }
.buscador .lupa {
  position: absolute;
  top: 50%;
  left: 13px;
  transform: translateY(-50%);
  color: var(--hint);
  font-size: 15px;
  pointer-events: none;
}
.buscador input {
  width: 100%;
  min-height: var(--tap);
  padding: 10px 14px 10px 38px;
  border: 1.5px solid var(--borde);
  border-radius: 999px;
  background: var(--bg);
  color: var(--texto);
  font-size: 15px;
}
.buscador input:focus {
  outline: none;
  border-color: var(--acento);
}

/* Rótulo de sección: separa la herramienta (buscar) del trabajo del día. */
.rotulo {
  margin: 12px 2px 2px;
  color: var(--hint);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* --- listas --- */

.item {
  width: 100%;
  display: block;
  text-align: left;
  min-height: var(--tap);
  padding: 11px 12px;
  margin-top: 8px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--bg2);
  color: var(--texto);
  font-size: 15px;
}
.item .sub { color: var(--hint); font-size: 13px; }

.tarjeta {
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--bg2);
  padding: 12px;
  margin-bottom: 10px;
}
.tarjeta h3 { margin: 0 0 6px; font-size: 14px; }
.tarjeta p { margin: 3px 0; }

.fila { display: flex; justify-content: space-between; gap: 8px; }
.fila .der { text-align: right; white-space: nowrap; }

.vencida { color: var(--peligro); font-weight: 600; }
.icono { font-size: 40px; margin: 6px 0; }

/* --- pantalla Hoy --------------------------------------------------------
   Es la entrada. Antes la app abría en un campo de búsqueda vacío: cero
   información en el momento de máxima atención. Ahora abre contestando "qué
   tengo que hacer", y el buscador vive arriba de esas filas. */
#saludo { font-size: 18px; font-weight: 600; margin: 2px 0 10px; }

.fila-hoy {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  min-height: var(--tap);
  padding: 13px 12px;
  margin-top: 8px;
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--bg2);
  color: var(--texto);
  font-size: 15px;
}
.fila-hoy:active { opacity: .7; }
.fila-hoy .ico { font-size: 21px; line-height: 1; }
.fila-hoy .cuerpo { flex: 1; min-width: 0; }
.fila-hoy .titulo { display: block; font-weight: 600; }
.fila-hoy .dato {
  display: block;
  margin-top: 1px;
  color: var(--hint);
  font-size: 13px;
}
/* El número que importa, a la derecha y grande: es lo que se lee primero. */
.fila-hoy .cuenta { font-size: 19px; font-weight: 700; }
.fila-hoy .cuenta.urgente { color: var(--peligro); }
.fila-hoy .flecha { color: var(--hint); font-size: 18px; }
.fila-hoy.vacia .cuenta { color: var(--hint); font-weight: 600; font-size: 15px; }

/* --- tabla de cuotas ---
   La única cosa de la app que SÍ scrollea en horizontal, a propósito y dentro
   de su caja. Por eso se exceptúa del `overflow-wrap: anywhere` del body: con
   la regla puesta, la tabla entraba a la fuerza partiendo los títulos por la
   mitad ("Prod ." / "Cuot a" / "Atras o"). Acá se quiere lo contrario: que no
   parta nada y que sobre ancho, que para eso está .scroll-x. */
.scroll-x { overflow-x: auto; overflow-wrap: normal; }
.cuotas { width: 100%; border-collapse: collapse; font-size: 13px; }
.cuotas th, .cuotas td {
  padding: 5px 4px;
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--borde);
}
.cuotas th:first-child, .cuotas td:first-child { text-align: left; }
.cuotas th { color: var(--hint); font-weight: 500; }

/* --- formulario --- */
.campo { display: block; margin: 12px 0; }
.campo > span { display: block; margin-bottom: 5px; font-size: 13px; color: var(--hint); }
.campo.check { display: flex; align-items: center; gap: 8px; min-height: var(--tap); }
.campo.check span { margin: 0; color: var(--texto); font-size: 14px; }
.campo.check input[type="checkbox"] { width: 20px; height: 20px; }

select, input[type="date"], input[type="number"], input[type="text"], textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 10px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--bg2);
  color: var(--texto);
  font-size: 15px;
}
textarea { min-height: 70px; }

.btn {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 12px;
  margin-top: 12px;
  border: none;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
}
.btn-primario { background: var(--acento); color: var(--acento-texto); }
.btn-secundario {
  background: var(--bg2);
  color: var(--texto);
  border: 1px solid var(--borde);
}
.btn:disabled { opacity: 0.6; }

.btn-volver {
  border: none;
  background: none;
  color: var(--link);
  font-size: 15px;
  min-height: var(--tap);
  padding: 0 0 8px 0;
}
/* Cuando Telegram nos presta su propio botón de atrás, el nuestro sobra: dos
   flechas de retroceso en la misma pantalla es una de más. */
body.con-backbutton .btn-volver { display: none; }

/* Ídem con el MainButton: el CTA queda pegado abajo, con el color del tema y
   barra de progreso nativa, en vez de al final de un formulario largo. */
body.con-mainbutton #btn-enviar,
body.con-mainbutton #btn-registrar,
body.con-mainbutton #btn-visita-enviar,
body.con-mainbutton #btn-oport-enviar { display: none; }

/* Sub-pantallas (las que tienen "atrás"): sin barra de pestañas.
   El MainButton lo dibuja Telegram FUERA del webview, así que queda por debajo
   de todo lo nuestro: con la barra puesta quedaban dos controles apilados abajo
   y el "Registrar" aparecía debajo del menú. Además, en una sub-pantalla no se
   navega, se hace una cosa y se vuelve: la barra ahí solo estorba. */
body.sin-tabs #tabs { display: none; }
body.sin-tabs { padding-bottom: 12px; }

/* --- botoneras -----------------------------------------------------------
   wrap: la tarjeta de una oportunidad llega a tener cuatro acciones
   (WhatsApp, Llamar, Ubicación, Registrar) y en pantalla angosta no entran
   en una sola fila.

   Va DESPUÉS de .btn a propósito: casi todas las acciones se pintan con
   `class="btn btn-secundario"` y necesitan que estas reglas le ganen al
   `width:100%` y al `display:block` de .btn. */
.botonera { display: flex; gap: 8px; flex-wrap: wrap; }
/* OJO: el selector apunta a `> *` y no a `button`. La mitad de las acciones
   son <a> (tel:, wa.me) y con el selector viejo no recibían el `flex`, así que
   el `width:100%` de .btn le daba una fila entera a cada una y la tarjeta
   crecía ~50px por acción. */
.botonera > * {
  flex: 1 1 0;
  /* 96px es lo que deja entrar TRES en una fila de 360px (la botonera de Canal
     y la de resultados del prospecto, que se leen como un control segmentado y
     partidas en dos filas dejan de leerse así). Con cuatro acciones no alcanza
     y caen 2+2, que es lo que se quiere. */
  min-width: 96px;
  width: auto;
  margin-top: 0;
  min-height: var(--tap);
  padding: 10px 8px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--bg2);
  color: var(--texto);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  /* Centra el texto de los <a>, que no se alinean solos como los <button>. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.botonera > .btn-primario {
  background: var(--acento);
  color: var(--acento-texto);
  border-color: var(--acento);
}
.botonera > button.activo {
  background: var(--acento);
  color: var(--acento-texto);
  border-color: var(--acento);
}

/* Campo obligatorio que falta y no es un control con `required` (la botonera
   de Canal). Sin esto el unico campo que el formulario podia señalar era el
   Resultado, que sin canal esta vacio por diseño. */
.campo.falta > span { color: var(--peligro); font-weight: 600; }
.campo.falta .botonera > * { border-color: var(--peligro); }

/* --- carga y error -------------------------------------------------------
   Antes toda lista decía "Cargando…" centrado y después saltaba al contenido.
   El fantasma ocupa el alto que va a ocupar la tarjeta: no hay salto, y la
   espera se percibe más corta aunque tarde lo mismo. */
.skel-tarjeta {
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--bg2);
  padding: 12px;
  margin-bottom: 10px;
}
.skel {
  /* `block` a propósito: el fantasma del renglón de una fila de Hoy es un
     <span>, y un inline ignora width y height. */
  display: block;
  position: relative;
  overflow: hidden;
  height: 12px;
  margin: 8px 0;
  border-radius: 6px;
  background: color-mix(in srgb, var(--hint) 20%, transparent);
}
.skel.alto { height: 17px; }
.skel::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--texto) 9%, transparent),
    transparent
  );
  animation: brillo 1.15s infinite;
}
@keyframes brillo { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .skel::after { animation: none; }
}

/* Un error de red dejaba un párrafo rojo en el medio de la lista y ninguna
   forma de reintentar sin cambiar de pestaña y volver. */
.bloque-error { text-align: center; padding: 22px 12px; }
.bloque-error .ico { font-size: 30px; }
.bloque-error p { color: var(--peligro); font-size: 14px; margin: 8px 0 0; }
.bloque-error button { max-width: 220px; margin: 14px auto 0; }

/* --- llamadas (aviso de salida de un asesor) --- */
.guion {
  border: 1px solid var(--acento);
  border-radius: 12px;
  background: color-mix(in srgb, var(--acento) 12%, transparent);
  padding: 12px;
  margin-bottom: 12px;
}
.guion strong { display: block; margin-bottom: 4px; }
.guion p { margin: 0; font-size: 14px; }

.tarjeta.llamada textarea { margin: 8px 0; }
/* Franja de color a la izquierda segun estado de la llamada. */
.tarjeta.llamada { border-left-width: 4px; }
.est-contactado { border-left-color: var(--ok); }
.est-no_contesta { border-left-color: var(--alerta); }
.est-telefono_erroneo { border-left-color: var(--peligro); }

/* --- Ruta de cobranza (operativo de campo) --- */
.tarjeta.parada { border-left-width: 4px; }
.parada-titulo { font-size: 15px; }
.parada-monto { font-size: 17px; font-weight: 700; }
.parada-monto .hint { font-weight: 400; font-size: 13px; }

/* Un color por segmento: se lee la dificultad de un vistazo. */
.seg-blando { border-left-color: var(--ok); }
.seg-tibio { border-left-color: var(--alerta); }
.seg-duro { border-left-color: var(--peligro); }
.seg-sin_historial { border-left-color: #78909c; }

/* Detalle secundario de una parada (dirección, cartera, canal sugerido).
   Plegado: lo que decide si vale la pena ir es el nombre, el monto y la
   distancia; el resto se mira una vez que ya decidiste. */
.detalle-sec { margin-top: 8px; }
.detalle-sec > summary {
  list-style: none;
  cursor: pointer;
  min-height: 34px;
  display: flex;
  align-items: center;
  color: var(--link);
  font-size: 13px;
  user-select: none;
}
.detalle-sec > summary::-webkit-details-marker { display: none; }
.detalle-sec > summary::after { content: " ▾"; color: var(--hint); }
.detalle-sec[open] > summary::after { content: " ▴"; }
.detalle-sec p { margin: 4px 0; }

/* --- Oportunidades (revolving) --- */
.tarjeta.oport { border-left-width: 4px; border-left-color: var(--ok); }
/* Los de cheques no tienen score ni monto: se distinguen por el borde. */
.tarjeta.oport-dch { border-left-color: var(--acento); }
.oport-titulo { font-size: 15px; }
.oport-monto { font-size: 17px; font-weight: 700; }
.oport-monto .hint { font-weight: 400; font-size: 13px; }

/* Un PP B/C no se ofrece directo: necesita que la dirección cargue una
   excepción. Ámbar, el mismo color de la calidad B, y NO rojo: no es un error
   ni un cliente malo, es otro camino.

   OJO: este comentario abría con `\*` en vez de `/*`. El parser se comía el
   prelude hasta la primera llave y descartaba la regla entera, así que el
   aviso se venía pintando como texto común, sin ámbar ni negrita. */
.aviso {
  color: var(--texto);
  background: color-mix(in srgb, var(--alerta) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--alerta) 60%, transparent);
  border-radius: 8px;
  padding: 6px 9px;
  font-size: 13.5px;
  font-weight: 600;
}
h3.aviso { display: inline-block; }
.tarjeta.oport-aprob { border-left-color: var(--alerta); }

/* Casos esperando la excepción de la dirección: es lo único del tablero que
   le pide una acción, así que lleva el borde ámbar entero.
   (Mismo typo `\*` que arriba: la regla no llegaba a aplicarse.) */
.tarjeta-elevados { border-left: 4px solid var(--alerta); }
.fila-elevado {
  border-top: 1px solid var(--borde);
  padding-top: 8px;
  margin-top: 8px;
}

/* --- Prospectos (campaña de Itá) ---
   Borde índigo, distinto del verde de Oportunidades a propósito: acá la
   persona todavía NO es cliente y el guion de la asesora es otro. */
.tarjeta.prospecto {
  border-left-width: 4px;
  border-left-color: var(--indigo);
}
.tarjeta.prospecto textarea { margin: 8px 0 0; }
.tarjeta.prospecto .botonera { margin-top: 8px; }
.tarjeta.prospecto .monto-ofrecido { margin-top: 10px; }

/* Conmutador "Por ofrecer" / "Gestionados". */
.segmentado {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 10px;
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--bg2);
}
.segmentado button {
  flex: 1;
  min-height: var(--tap);
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--hint);
  font-size: 14px;
  font-weight: 600;
}
.segmentado button.activo {
  background: var(--acento);
  color: var(--acento-texto);
}

/* La última gestión: qué se dijo, cuánto se ofreció y con qué palabras. El
   comentario ya se guardaba desde el día uno, pero nunca volvía a la pantalla;
   el monto directamente no se pedía. */
.ult-gestion {
  margin-top: 10px;
  padding: 8px 10px;
  border-left: 3px solid var(--alerta);
  border-radius: 0 8px 8px 0;
  background: var(--bg2);
}
.ult-gestion.ult-cerrada { border-left-color: var(--peligro); }
.ult-cab { font-size: 13px; font-weight: 600; }
.ult-monto { font-size: 13.5px; margin-top: 3px; }
.ult-com {
  font-size: 13px;
  margin-top: 3px;
  color: var(--hint);
  font-style: italic;
}
.ult-nota { font-size: 12px; margin-top: 5px; color: var(--hint); }

/* Historial completo. `oferta` es append-only: una gestión equivocada se
   corrige registrando otra encima, así que la última fila sola miente. */
.historial { margin-top: 8px; }
.btn-link {
  border: none;
  background: none;
  padding: 6px 0;
  min-height: var(--tap);
  color: var(--acento);
  font-size: 13.5px;
  font-weight: 600;
}
.historial-lista { margin-top: 4px; }
.hist-fila {
  border-top: 1px solid var(--borde);
  padding: 6px 0;
}
.hist-cab { font-size: 12.5px; font-weight: 600; }
.hist-monto { font-size: 12.5px; margin-top: 2px; }
.hist-com {
  font-size: 12.5px;
  margin-top: 2px;
  color: var(--hint);
  font-style: italic;
}
.hist-lab { font-size: 12.5px; margin-top: 2px; }

/* "¿De qué vive?" — plegado, porque no aplica a la mayoría de las llamadas.
   Mismo patrón que Contactabilidad. */
.laboral { margin-top: 10px; }
.laboral > summary {
  list-style: none;
  cursor: pointer;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  padding: 8px 10px;
  border: 1px dashed var(--borde);
  border-radius: 10px;
  font-size: 13.5px;
  color: var(--hint);
}
.laboral > summary::-webkit-details-marker { display: none; }
.laboral > summary::after { content: " ▾"; margin-left: auto; }
.laboral[open] > summary::after { content: " ▴"; }
.laboral[open] > summary { margin-bottom: 8px; }
.laboral select, .laboral input { margin-bottom: 8px; }

/* El disclaimer de que los datos son de 2024 iba repetido en CADA tarjeta, en
   el mismo gris que los datos. Va una sola vez arriba de la lista. */
.nota-lista {
  border: 1px solid var(--borde);
  border-radius: 10px;
  padding: 8px 10px;
  margin-bottom: 10px;
  color: var(--hint);
  font-size: 12.5px;
}

/* Contactabilidad plegable. Con cuatro números desplegados la tarjeta medía
   una pantalla y el nombre y el barrio —lo que decide si vale la pena ir—
   quedaban lejos del siguiente prospecto. */
.contactabilidad { margin-top: 8px; }
.contactabilidad > summary {
  list-style: none;
  cursor: pointer;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  padding: 8px 10px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--bg2);
  font-size: 14px;
  user-select: none;
}
.contactabilidad > summary::-webkit-details-marker { display: none; }
/* La flecha la ponemos nosotros: el marcador nativo cambia de forma entre
   WebViews de Android y iOS. */
.contactabilidad > summary::after {
  content: "▾";
  margin-left: auto;
  color: var(--hint);
}
.contactabilidad[open] > summary::after { content: "▴"; }
.contactabilidad[open] > summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.contactabilidad .tels {
  border: 1px solid var(--borde);
  border-top: none;
  border-radius: 0 0 10px 10px;
}
.tel-fila {
  display: flex;
  align-items: stretch;
  min-height: var(--tap);
  border-top: 1px solid var(--borde);
}
.tel-fila:first-child { border-top: none; }
.tel-num {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px;
  font-size: 14px;
  color: var(--texto);
  text-decoration: none;
}
.tel-num .hint { font-size: 12px; }
.tel-fila a:active { background: var(--bg2); }
/* El único número que sabemos normalizado a formato internacional. */
.tel-wa {
  display: flex;
  align-items: center;
  padding: 0 14px;
  border-left: 1px solid var(--borde);
  color: #25d366;
}
.ico-wa { width: 20px; height: 20px; display: block; }

/* Rating de Visión (AAA…C). Es el dato que más predice, así que se lee de un
   vistazo: verde el grado de inversión, ámbar el intermedio, rojo el malo. */
.rat {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  vertical-align: middle;
}
.rat-alto  { background: var(--ok);      color: #fff; }
.rat-medio { background: var(--alerta);  color: #000; }
.rat-bajo  { background: var(--peligro); color: #fff; }

/* Tarjeta que abre un detalle (tablero comercial -> cartera del asesor). */
.tarjeta.clickable { cursor: pointer; }
.tarjeta.clickable:active { opacity: .7; }

/* Calidad: verde para los mejores, gris a medida que baja. Nunca rojo: un
   candidato B no es un problema, es una prioridad menor. */
.badge.cal-aplus { background: var(--ok); }
.badge.cal-a { background: color-mix(in srgb, var(--ok) 75%, var(--hint)); }
.badge.cal-b { background: var(--alerta); color: #1a1a1a; }
.badge.cal-c { background: var(--hint); }

/* --- tabs inferiores -----------------------------------------------------
   Máximo cuatro slots. Con nueve pestañas (el caso de la dirección) cada una
   medía 40px en un teléfono de 360 y "Oportunidades" y "Operaciones" se
   recortaban las dos a "Ope…": ilegibles y además indistinguibles. Lo que no
   entra en los cuatro slots va a la hoja "Más", que el JS arma con el resto. */
#tabs {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 20;
  display: flex;
  background: var(--bg2);
  border-top: 1px solid var(--borde);
  padding-bottom: var(--piso);
}
.tab {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  min-height: var(--tap);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 7px 3px 8px;
  border: none;
  background: none;
  color: var(--hint);
  font-size: 11px;
}
.tab .tab-ico { font-size: 19px; line-height: 1; }
.tab .tab-txt {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tab.activo { color: var(--acento); font-weight: 700; }
/* La pestaña activa no puede distinguirse SOLO por el color: al sol, con el
   brillo bajo o con daltonismo no hay diferencia. La barrita sí se ve. */
.tab.activo::before {
  content: "";
  position: absolute;
  top: 0;
  left: 22%;
  right: 22%;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--acento);
}

/* --- hoja "Más" --- */
#sheet-fondo {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: rgba(0, 0, 0, .45);
}
#sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 31;
  max-height: 80vh;
  overflow-y: auto;
  padding: 8px 12px calc(14px + var(--piso));
  background: var(--bg);
  border-radius: 16px 16px 0 0;
  animation: subir .18s ease-out;
}
@keyframes subir { from { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) {
  #sheet { animation: none; }
}
#sheet .agarre {
  width: 38px;
  height: 4px;
  margin: 4px auto 12px;
  border-radius: 2px;
  background: var(--borde);
}
.sheet-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--tap);
  padding: 12px 8px;
  border: none;
  border-bottom: 1px solid var(--borde);
  background: none;
  color: var(--texto);
  font-size: 15px;
  text-align: left;
}
.sheet-item:last-child { border-bottom: none; }
.sheet-item .tab-ico { font-size: 19px; }
.sheet-item.activo { color: var(--acento); font-weight: 700; }

/* --- Operaciones (dirección) --------------------------------------------- */
/* El formulario va dentro de un <details> para que la pantalla abra mostrando
   lo que ya está programado: crear es lo que se hace una vez por semana,
   mirar es lo que se hace todos los días. */
details.caja {
  border: 1px solid var(--borde);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 14px 0;
  background: var(--bg2);
}
details.caja > summary {
  cursor: pointer;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  font-weight: 600;
  font-size: 14px;
}
details.caja[open] > summary { margin-bottom: 8px; }
/* Las dos fechas van juntas: se leen como un rango, no como dos campos. */
.fila-fechas { display: flex; gap: 10px; }
.fila-fechas .campo { flex: 1; }
.btn-op-cancelar, .btn-op-resultado { margin-top: 8px; }

/* --- campaña de mora vieja ------------------------------------------------
   La barra es lo único que se mira de reojo: tiene que leerse de un vistazo
   con el teléfono al sol, así que va gruesa y con el riel siempre visible
   (sin riel, un avance del 4 % parece un error de dibujo). */
.meta-barra {
  height: 14px;
  border-radius: 7px;
  background: var(--bg2);
  border: 1px solid var(--borde);
  overflow: hidden;
  margin: 8px 0 6px;
}
.meta-barra > i { display: block; height: 100%; border-radius: 7px; }
.meta-barra > i.eq { background: var(--acento); }
.meta-barra > i.yo { background: var(--alerta); }
.meta-barra > i.ok { background: var(--ok); }
.meta-monto { font-size: 20px; margin: 4px 0; }
.meta-cliente .meta-monto { font-size: 16px; }
/* Cliente ya recuperado en la campaña: presente pero apagado. */
.meta-pagado { opacity: 0.62; }
