/* ==========================================================================
   Consumo y saldo de WhatsApp (item A14)

   La pantalla que responde a "cuanto llevamos gastado y cuanto queda". Existe por el
   1 de octubre de 2026: ese dia los mensajes dentro de la ventana de 24 h dejan de ser
   gratis y cada mensaje que sale empieza a costar dinero.
   ========================================================================== */

/* --- Cabecera: periodo y actualizar ---------------------------------------- */

.cns-cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.cns-periodos {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.cns-periodo {
  padding: 7px 13px;
  border: none;
  background: var(--bg-elev);
  color: var(--text-dim);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: background-color .14s ease, color .14s ease;
}
.cns-periodo + .cns-periodo { border-left: 1px solid var(--border); }
.cns-periodo:hover { background: var(--bg-hover); color: var(--text); }
.cns-periodo.activo { background: var(--accent-dim); color: var(--text); font-weight: 600; }
.cns-periodo:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.cns-cab .modal-btn { display: inline-flex; align-items: center; gap: 6px; }
.cns-cab .ic { width: 15px; height: 15px; }

/* --- El aviso del 1 de octubre --------------------------------------------- */

/* Va ARRIBA DEL TODO y no al pie: es el motivo por el que esta pantalla existe. */
.cns-aviso {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--info-border);
  background: var(--info-bg);
  margin-bottom: 16px;
}
.cns-aviso .ic { width: 18px; height: 18px; flex: 0 0 auto; color: var(--info); margin-top: 1px; }
.cns-aviso b { display: block; font-size: 13px; color: var(--text); margin-bottom: 3px; }
.cns-aviso span { font-size: 12.5px; line-height: 1.5; color: var(--text-dim); }

/* Cuando la fecha ya paso, el aviso deja de ser informativo y pasa a ser una advertencia. */
.cns-aviso.ya { border-color: var(--warn); background: var(--warn-bg); }
.cns-aviso.ya .ic { color: var(--warn); }

/* --- Las cifras ------------------------------------------------------------ */

.cns-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
}

.cns-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--bg-elev);
}
.cns-card.vacia { border-style: dashed; }
/* Saldo agotado: el numero se pone rojo. NO se recorta a cero en el servidor (ver
   internal/consumo), asi que aqui hay que poder ense~nar un negativo. */
.cns-card.mal .cns-n { color: var(--danger); }

.cns-t {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.cns-n {
  font-size: 24px;
  font-weight: 600;
  line-height: 1.15;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.cns-n.peq { font-size: 16px; }
.cns-p { font-size: 11.5px; line-height: 1.45; color: var(--text-dim); }

/* --- Acciones -------------------------------------------------------------- */

.cns-acciones {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 16px 0;
}
.cns-acciones .modal-btn,
.cns-acciones .ghost-btn { display: inline-flex; align-items: center; gap: 6px; }
.cns-acciones .ic { width: 15px; height: 15px; }
.cns-olvidar { color: var(--text-dim); }
.cns-olvidar:hover { color: var(--danger); }

/* --- El desglose ----------------------------------------------------------- */

.cns-h {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--text);
}

/* La tabla scrollea DENTRO de su caja: el cuerpo de la pagina no se mueve de lado. */
.cns-scroll { overflow-x: auto; }

/* La forma de la tabla la pone el componente (components/tabla.css). Aquí solo lo suyo: */
/* Letra un punto menor: esta tabla vive DENTRO de una tarjeta con su propio relleno, y con
   el tamaño de la de métricas se comía la caja. */
.cns-tabla { font-size: 12.5px; }
.cns-tabla td { color: var(--text); }
.cns-tipo { color: var(--text-dim); }
.cns-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cns-gratis { color: var(--plantilla-ok); font-weight: 600; }

.cns-tabla-caja {
  padding: 14px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--bg-elev);
}

/* --- Nota, vacio, cargando, fallo ------------------------------------------ */

.cns-nota {
  margin: 14px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
}

.cns-vacio {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 16px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  color: var(--text-dim);
}
.cns-vacio .ic { width: 18px; height: 18px; flex: 0 0 auto; }
.cns-vacio p { margin: 0; font-size: 12.5px; line-height: 1.5; }

.cns-cargando,
.cns-fallo {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px 2px;
  font-size: 13px;
  color: var(--text-dim);
}
.cns-cargando .ic { width: 15px; height: 15px; animation: cnsGira 1s linear infinite; }
.cns-fallo { color: var(--danger); }
.cns-fallo .ic { width: 16px; height: 16px; flex: 0 0 auto; }

@keyframes cnsGira { to { transform: rotate(360deg); } }

/* --- El paso a paso -------------------------------------------------------- */

.cns-pasos {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cns-pasos li {
  display: flex;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}
.cns-paso-n {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-dim);
  color: var(--text);
  font-size: 11.5px;
  font-weight: 600;
}
.cns-ir { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.cns-ir .ic { width: 15px; height: 15px; }

/* --- El formulario del apunte ---------------------------------------------- */

.cns-form { display: flex; flex-direction: column; gap: 14px; }
.cns-campo { display: flex; flex-direction: column; gap: 5px; }
.cns-label { font-size: 12px; font-weight: 600; color: var(--text); }
.cns-opt { font-weight: 400; color: var(--text-dim); }
.cns-ayuda { font-size: 11.5px; line-height: 1.45; color: var(--text-dim); }

.cns-in {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 11px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--bg-elev);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  outline: none;
  transition: border-color .14s ease;
}
.cns-in:focus { border-color: var(--accent); }

.cns-importe { display: flex; align-items: center; gap: 8px; }
.cns-moneda { font-size: 12.5px; font-weight: 600; color: var(--text-dim); }

/* Se queda puesto, no es un toast: se corrige el campo mirandolo. */
.cns-problema {
  padding: 9px 12px;
  border-radius: 9px;
  border: 1px solid var(--danger);
  color: var(--danger);
  font-size: 12.5px;
  line-height: 1.45;
}

/* --- Entrada --------------------------------------------------------------- */

/* ANIMACION CSS, NUNCA una transicion disparada desde JavaScript: si el navegador no llega
   a pintar un fotograma, una animacion sin fill-mode termina igual en el estado natural del
   elemento; unos estilos en linea dejarian el aviso invisible para siempre. */
.cns-nuevo { animation: cnsEntra .18s ease-out; }

@keyframes cnsEntra {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- Pantallas estrechas --------------------------------------------------- */

@media (max-width: 560px) {
  .cns-cab { flex-direction: column; align-items: stretch; }
  /* El selector de periodo SI ocupa todo: es un segmentado, y sus tres trozos se reparten el
     ancho. El boton de al lado NO: un boton de una palabra estirado de borde a borde parece
     una barra de otra cosa, y ademas invita a pulsarlo sin querer. Mide lo que dice. */
  .cns-periodos { width: 100%; }
  .cns-cab .cns-refrescar { align-self: flex-start; }
  .cns-periodo { flex: 1 1 0; }
  .cns-acciones .modal-btn { flex: 1 1 auto; justify-content: center; }
}

/* --- Movimiento reducido --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .cns-nuevo,
  .cns-cargando .ic {
    animation: none;
  }
  .cns-periodo,
  .cns-in {
    transition: none;
  }
}

/* --- El aviso del saldo (item A33) ---
   Tres niveles con tres aspectos, y a proposito: rojo cuando no se puede enviar, amarillo
   cuando queda poco y neutro cuando simplemente no se sabe. Un aviso que se ve igual en
   los tres casos obliga a leerlo entero para saber si corre prisa. */
.cns-saldo {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-elev);
  font-size: 13px;
  line-height: 1.5;

  /* ENTRA CON MOVIMIENTO: aparece cuando el saldo cambia de nivel, sustituyendo a lo que
     hubiera. Sin animacion, un aviso rojo que se materializa de golpe no se distingue de
     algo que ya estaba y no se habia mirado. */
  animation: cns-saldo-entra .18s ease-out both;
}
@keyframes cns-saldo-entra {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .cns-saldo { animation: none; }
}
.cns-saldo > svg,
.cns-saldo .ic {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--text-dim);
}
.cns-saldo b {
  display: block;
  font-size: 13.5px;
  margin-bottom: 3px;
}
/* SALVO DENTRO DE UNA FRASE. El display:block de arriba es para el TITULO del aviso, pero
   alcanzaba tambien al <b> que remarca "puedes seguir escribiendo y enviando con
   normalidad" y partia esa frase en tres lineas sueltas: "Mientras tanto" / el trozo en
   negrita / ": LeadSync no te lo va a impedir". Justo la frase que quita el susto de leer
   un aviso rojo (mandato A35: el dinero nunca bloquea el envio, pero se explica). */
.cns-saldo-sigue b {
  display: inline;
  font-size: inherit;
  margin: 0;
}
.cns-saldo span { color: var(--text-dim); }

.cns-saldo.ojo {
  border-color: color-mix(in srgb, var(--warn) 38%, transparent);
  background: var(--warn-bg);
}
.cns-saldo.ojo > svg,
.cns-saldo.ojo .ic { color: var(--warn); }
.cns-saldo.ojo b { color: var(--warn); }

.cns-saldo.grave {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  background: color-mix(in srgb, var(--danger) 11%, transparent);
}
.cns-saldo.grave > svg,
.cns-saldo.grave .ic { color: var(--danger); }
.cns-saldo.grave b { color: var(--danger); }

/* Los pasos van NUMERADOS y no en viñetas: son un orden, no una lista de opciones. */
.cns-saldo-pasos {
  margin: 8px 0 0;
  padding-left: 20px;
  color: var(--text);
}
.cns-saldo-pasos li { margin-bottom: 3px; }

.cns-saldo-sigue {
  margin: 8px 0 0;
  color: var(--text);
}

.cns-saldo-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

/* --- Lo que gasta el bot (item A44) -----------------------------------------
   Va en la misma pantalla que el consumo de WhatsApp porque la pregunta es la misma, y en
   SU PROPIA CAJA porque son dos monederos: se recarga OpenRouter sin tocar Meta y al reves,
   asi que un total que los sumara no se podria gastar. El borde lo separa sin necesidad de
   una pantalla mas. */
.gia-caja {
  margin-top: 22px;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px 16px;
}

.gia-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.gia-cab h3 {
  margin: 0;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.gia-cab h3 .ic { width: 16px; height: 16px; }
.gia-periodo { font-size: 11.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }

.gia-tarjetas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}

.gia-tarjeta {
  background: var(--bg-elev);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Sin saldo el numero se pinta en rojo: es la unica cifra de esta pantalla que obliga a
   hacer algo hoy, y con el mismo color que las demas se lee como una mas. */
.gia-bajo .gia-n { color: var(--danger); }

.gia-n {
  font-size: 19px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.gia-lab { font-size: 11.5px; color: var(--text-dim); }

/* --- La tarjeta del cupo prepago (item A88) ------------------------------- */

/* Al 75 % el numero se pone ambar y al agotarse rojo (.gia-bajo, que ya existia). Son
   los dos unicos estados que obligan a hacer algo: por debajo es informacion. */
.gia-ojo .gia-n { color: var(--warn); }

/* La cuenta pequenia: lo gastado, el tope y el porcentaje. Va DEBAJO de la barra porque
   es la comprobacion del numero grande, no el numero que se mira. */
.gia-sub {
  font-size: 11px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* La barra del cupo se separa de las de por-modelo: ahi comparan entre si, aqui mide
   contra un techo. Y su relleno cambia de color con el estado, que es todo el punto. */
.gia-barra-cupo {
  margin: 5px 0 3px;
  background: color-mix(in srgb, var(--text-dim) 22%, transparent);
}

/* La transicion acompania al relleno cuando el porcentaje sube con la pantalla delante:
   sin ella el dato salta y no se ve que se movio. */
.gia-barra-cupo span { transition: width .2s ease, background-color .2s ease; }
@media (prefers-reduced-motion: reduce) {
  .gia-barra-cupo span { transition: none; }
}
.gia-ojo .gia-barra-cupo span { background: var(--warn); }
.gia-bajo .gia-barra-cupo span { background: var(--danger); }

.gia-modelos { margin-top: 16px; }

.gia-modelos h4 {
  margin: 0 0 8px;
  font-size: 12px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.gia-modelo { margin-bottom: 9px; }

.gia-modelo-cab {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 12.5px;
  margin-bottom: 4px;
}

.gia-modelo-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gia-modelo-c { color: var(--text-dim); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* La barra dice de un vistazo QUIEN SE LLEVA EL DINERO. Con solo las cifras hay que
   compararlas mentalmente, y con cuatro decimales eso no se hace de un vistazo. */
.gia-barra {
  height: 5px;
  border-radius: 3px;
  background: var(--bg-elev);
  overflow: hidden;
}

.gia-barra span {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 3px;
}

.gia-nota {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin: 14px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
}

.gia-nota .ic { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 2px; }

.gia-acciones {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

.gia-cargando {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px;
  color: var(--text-dim);
  font-size: 13px;
}

/* --- El desmentido: cuando la realidad contradice al apunte ---
   El saldo que se enseña sale de restarle a un numero escrito a mano lo que Meta dice que
   se gasto, y ese numero puede estar mal en las dos direcciones. Lo que rompe el empate son
   los ENVIOS: uno aceptado demuestra que habia dinero, uno rechazado por pago demuestra que
   no. Cuando eso contradice al apunte, es lo mas util que puede decir esta pantalla —porque
   explica por que el numero de abajo no cuadra— y por eso va lo primero y se ve distinto a
   todo lo demas. */
.cns-desmentido {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 14px;
  padding: 14px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;

  /* LA BARRA LATERAL ES LO QUE LO DISTINGUE del aviso de saldo, que lleva borde entero. Son
     dos cosas distintas -"el dato esta mal" frente a "queda poco"- y verse iguales las
     haria leer como una repeticion. */
  border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--border));
  border-left: 3px solid var(--warn);
  background: color-mix(in srgb, var(--warn) 8%, var(--bg-elev));
  animation: cns-saldo-entra .18s ease-out both;
}
@media (prefers-reduced-motion: reduce) {
  .cns-desmentido { animation: none; }
}
.cns-desmentido > svg,
.cns-desmentido .ic {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--warn);
}
.cns-desmentido b {
  display: block;
  font-size: 13.5px;
  margin-bottom: 3px;
  color: var(--text);
}
.cns-desmentido span { color: var(--text-dim); }

/* EL AVISO GRAVE ES ROJO Y NO AMBAR, y la diferencia no es de tono: el ambar dice
   "vigila esto" y el rojo dice "esta pasando ahora". Con el cupo agotado el bot NO esta
   contestando, asi que no es una advertencia, es un hecho. */
.cns-desmentido.cns-grave {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
  border-left-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, var(--bg-elev));
}
.cns-grave > svg,
.cns-grave .ic { color: var(--danger); }
