/* ============================================================
   Vive Well — hoja de estilos única
   Estructura visual basada en el mockup de referencia:
   sidebar blanco, fondo gris muy claro, tarjetas redondeadas,
   stat-cards con degradado suave y botón principal tipo píldora.

   Densidad: versión compacta. Mismos colores, degradados y formas
   que el mockup, con menos aire para que quepa más en pantalla.
   Todo el espaciado sale de --esp; súbelo a 20px y vuelve el
   diseño amplio original.
   ============================================================ */

:root {
  /* Color de marca. Para volver al rosa del mockup original,
     cambia estas tres líneas por #ec4899 / #db2777 / #fdf2f8 */
  --pri:        #0f9d76;
  --pri-fuerte: #0b7f5f;
  --pri-suave:  #e8f7f1;

  --azul:       #5b7cfa;
  --azul-suave: #eef2ff;
  --verde:      #16a34a;
  --verde-suave:#eafaf0;
  --rojo:       #ef4444;
  --rojo-suave: #fef2f2;
  --ambar:      #f59e0b;
  --ambar-suave:#fffbeb;

  /* Sólo para gráficas con muchas series (la dona de patologías): cuando
     se acaban los colores del sistema hacen falta dos más que se
     distingan entre sí sin competir con el verde de la marca. */
  --morado:     #8b5cf6;
  --cian:       #06b6d4;

  --tinta:      #1b1f36;
  --tinta-2:    #4b5169;
  --gris:       #8a90a6;
  --gris-claro: #eef0f4;
  --linea:      #edeff3;
  --fondo:      #f4f5f7;
  --blanco:     #ffffff;

  --r-sm: 8px;
  --r:    11px;
  --r-lg: 15px;
  --esp:  14px;   /* separación base entre bloques */
  --sombra: 0 1px 2px rgba(27, 31, 54, .04), 0 6px 18px rgba(27, 31, 54, .05);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 13.5px;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

/* ----------------------------------------------------------
   Layout general
   ---------------------------------------------------------- */
.app { display: flex; min-height: 100vh; }

.sidebar {
  width: 214px;
  flex: 0 0 214px;
  background: var(--blanco);
  border-right: 1px solid var(--linea);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.marca { padding: 0 8px 16px; }
.marca h1 { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.4px; }
.marca h1 span { color: var(--pri); }
.marca p { margin: 2px 0 0; font-size: 11.5px; color: var(--gris); }

.nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }

.nav a, .salir a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 11px;
  border-radius: var(--r);
  color: var(--tinta-2);
  font-weight: 600;
  font-size: 13.5px;
  transition: background .15s, color .15s;
}
.nav a:hover, .salir a:hover { background: var(--gris-claro); }
.nav a.activo { background: var(--pri-suave); color: var(--pri); }
.nav a svg, .salir a svg { width: 17px; height: 17px; stroke-width: 1.9; flex: 0 0 17px; }

.nav-sep {
  margin: 10px 11px 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: #b6bbcb;
}

.salir {
  border-top: 1px solid var(--linea);
  padding-top: 8px;
  margin-top: 8px;
}
.salir small { display: block; padding: 0 11px 6px; color: var(--gris); font-size: 11.5px; }

/* Aviso de "estás viendo la tienda X" cuando el súper admin entró a una
   (modules/tiendas/entrar.php). Desaparece al salir con "Volver a tiendas". */
.tienda-activa {
  margin: 0 8px 14px;
  padding: 9px 11px;
  border-radius: var(--r);
  background: var(--pri-suave);
}
.tienda-activa small { display: block; color: var(--pri); font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }
.tienda-activa strong { display: block; font-size: 13.5px; margin: 1px 0 6px; }
.tienda-activa a { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; color: var(--pri); }
.tienda-activa a:hover { text-decoration: underline; }

.contenido { flex: 1; padding: 18px 24px 34px; min-width: 0; }

/* ----------------------------------------------------------
   Encabezado de página
   ---------------------------------------------------------- */
.cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: var(--esp);
}
.cabecera h2 { margin: 0; font-size: 25px; font-weight: 700; letter-spacing: -.7px; line-height: 1.15; }
.cabecera p  { margin: 2px 0 0; color: var(--gris); font-size: 13px; }

/* ----------------------------------------------------------
   Botones
   ---------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 18px;
  border: 0;
  border-radius: 999px;
  background: var(--pri);
  color: #fff;
  font: inherit;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  transition: background .15s, transform .1s;
  white-space: nowrap;
}
.btn:hover  { background: var(--pri-fuerte); }
.btn:active { transform: translateY(1px); }
.btn svg    { width: 16px; height: 16px; stroke-width: 2.4; }

.btn-claro   { background: var(--gris-claro); color: var(--tinta-2); }
.btn-claro:hover { background: #e3e6ec; }
.btn-rojo    { background: var(--rojo); }
.btn-rojo:hover  { background: #dc2626; }
.btn-sm      { padding: 6px 13px; font-size: 12.5px; gap: 5px; }
.btn-sm svg  { width: 14px; height: 14px; }

/* Botón redondo (el "+" junto al campo de nueva categoría) */
.btn-circulo {
  width: 36px; height: 36px;
  flex: 0 0 36px;
  border: 0; border-radius: 10px;
  background: var(--pri); color: #fff;
  font-size: 19px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.btn-circulo:hover { background: var(--pri-fuerte); }

/* Varios botones juntos (la cabecera de una página, el pie de un modal) */
.botonera { display: flex; gap: 8px; flex-wrap: wrap; }

/* Iconos de acción de la fila (editar / borrar) */
.acciones { display: flex; gap: 3px; }
.icono {
  width: 27px; height: 27px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 7px;
  background: transparent; color: var(--gris);
  cursor: pointer; transition: background .15s, color .15s;
  font: inherit; font-size: 15px; line-height: 1;  /* también se usa como <button> con texto (la ✕ del modal) */
}
.icono:hover      { background: var(--pri-suave); color: var(--pri); }
.icono.peligro:hover { background: var(--rojo-suave); color: var(--rojo); }
.icono svg { width: 15px; height: 15px; stroke-width: 1.9; }

/* ----------------------------------------------------------
   Tarjetas de estadística (fila superior de colores)
   ---------------------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--esp); margin-bottom: var(--esp); }
.stats.cuatro { grid-template-columns: repeat(4, 1fr); }

.stat {
  border-radius: var(--r-lg);
  padding: 14px 16px;
  background: linear-gradient(135deg, #fff, var(--pri-suave));
}
.stat .et {
  margin: 0 0 4px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--pri);
}
.stat .cifra { margin: 0; font-size: 25px; font-weight: 700; letter-spacing: -1px; line-height: 1.1; }
.stat .pie   { margin: 4px 0 0; font-size: 11.5px; color: var(--gris); }

.stat.azul  { background: linear-gradient(135deg, #fff, var(--azul-suave)); }
.stat.azul  .et { color: var(--azul); }
.stat.verde { background: linear-gradient(135deg, #fff, var(--verde-suave)); }
.stat.verde .et    { color: var(--verde); }
.stat.verde .cifra { color: var(--verde); }
.stat.rojo  { background: linear-gradient(135deg, #fff, var(--rojo-suave)); }
.stat.rojo  .et { color: var(--rojo); }
.stat.ambar { background: linear-gradient(135deg, #fff, var(--ambar-suave)); }
.stat.ambar .et { color: var(--ambar); }

/* ----------------------------------------------------------
   Tarjetas normales
   ---------------------------------------------------------- */
.card {
  background: var(--blanco);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra);
  padding: 16px 18px;
  margin-bottom: var(--esp);
}
.card-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.card-cabecera h3 { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -.3px; }
.card-cabecera .filtros { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

/* Rejillas.
   .grid-2     → contenido principal + columna lateral (arriba, sin estirar)
   .grid-mitad → dos bloques del mismo peso (misma altura, se estiran)
   La separación entre columnas es el mismo --esp que separa las tarjetas
   apiladas, así el ritmo horizontal y el vertical coinciden. */
.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: var(--esp); align-items: start; }
.grid-mitad { display: grid; grid-template-columns: 1fr 1fr; gap: var(--esp); align-items: stretch; }

/* La rejilla separa por dentro con el gap, pero por fuera es un bloque más:
   sin este margen, dos rejillas seguidas —o una rejilla y la tarjeta que
   viene detrás— quedaban pegadas. Mismo --esp que apila las tarjetas. */
.grid-2, .grid-mitad { margin-bottom: var(--esp); }

/* Salvo que sea lo último dentro de una tarjeta: ahí el aire lo pone el
   padding de la tarjeta y este margen dejaría un hueco muerto abajo. */
.card > .grid-2:last-child, .card > .grid-mitad:last-child { margin-bottom: 0; }

/* Columna de una rejilla: apila tarjetas con la misma separación del gap. */
.columna { display: flex; flex-direction: column; gap: var(--esp); min-width: 0; }
.columna > .card, .columna > .resumen { margin-bottom: 0; }

/* El gap ya separa: ninguna tarjeta que sea celda de la rejilla —o la última
   de una columna— arrastra margen inferior, que es lo que descuadraba los
   bordes de abajo entre una columna y otra. */
.grid-2 > .card, .grid-2 > .resumen,
.grid-mitad > .card, .grid-mitad > .resumen,
.grid-2 > * > .card:last-child, .grid-2 > * > .resumen:last-child,
.grid-mitad > * > .card:last-child, .grid-mitad > * > .resumen:last-child { margin-bottom: 0; }

/* En .grid-mitad las dos mitades son pares: igualan altura. */
.grid-mitad > .card, .grid-mitad > .resumen { height: 100%; }

/* ----------------------------------------------------------
   Formularios
   ---------------------------------------------------------- */
.campos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px 14px; }
.campos.tres  { grid-template-columns: repeat(3, 1fr); }
.campos.cuatro{ grid-template-columns: repeat(4, 1fr); }
.ancho-total  { grid-column: 1 / -1; }

.campo { display: flex; flex-direction: column; gap: 4px; }
.campo label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--gris);
}

input[type=text], input[type=number], input[type=date], input[type=email],
input[type=password], input[type=search], select, textarea {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  background: #fbfcfd;
  font: inherit;
  font-size: 13.5px;
  color: var(--tinta);
  outline: none;
  transition: border-color .15s, background .15s;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--pri);
  background: #fff;
}
input::placeholder, textarea::placeholder { color: #b0b5c6; }
textarea { resize: vertical; min-height: 58px; }
select { appearance: none; background-image: none; cursor: pointer; }

/* Los filtros se miden por su contenido, no por el 100% que heredan de
   input/select: dentro de un flex, ese 100% dejaba un filtro por línea. */
.filtros input, .filtros select {
  width: auto;
  padding: 6px 12px;
  border-radius: 999px;
  background: #fff;
  font-size: 12.5px;
  min-width: 120px;
}
.filtros input[type=search] { min-width: 170px; }
/* Las fechas ya son angostas por sí solas (el propio selector nativo del
   navegador ocupa poco): con el min-width genérico de arriba sobraba
   espacio en blanco junto al día/mes/año. */
.filtros input[type=date] { min-width: 0; width: 140px; }

.opciones { display: flex; gap: 14px; flex-wrap: wrap; padding-top: 2px; }
.opcion { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; cursor: pointer; }
.opcion input { width: 15px; height: 15px; accent-color: var(--pri); cursor: pointer; }

.acciones-form {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: var(--esp);
  padding-top: 12px;
  border-top: 1px solid var(--linea);
}

/* ----------------------------------------------------------
   Buscador dentro de un <select> largo
   El JS pone esta caja encima de los [data-buscable] (hoy, la
   patología de cada línea) y filtra la lista según se escribe.

   La lista va en position: fixed a propósito: el combo vive
   dentro de .tabla-scroll y de .modal-cuerpo, que tienen overflow
   y la recortarían. El JS le calcula sitio al abrirla.
   ---------------------------------------------------------- */
.combo { position: relative; }

/* La flecha del <select> aquí sobra: esto se escribe, no se despliega. */
.combo-caja { cursor: text; }

.combo-lista {
  position: fixed;
  z-index: 40;
  max-height: 232px;
  overflow-y: auto;
  padding: 4px;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  box-shadow: 0 10px 28px rgba(27, 31, 54, .16);
}

.combo-op {
  display: block;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 13px;
  line-height: 1.35;
  text-align: left;
  color: var(--tinta);
  cursor: pointer;
}
.combo-op:hover,
.combo-op.marcado { background: var(--pri-suave); color: var(--pri); }

/* El alta al vuelo: se separa de las coincidencias del catálogo. */
.combo-nueva {
  margin-top: 2px;
  border-top: 1px solid var(--linea);
  border-radius: 0 0 6px 6px;
  font-weight: 600;
}

.combo-vacia { display: block; padding: 8px 9px; font-size: 12.5px; color: var(--gris); }

/* ----------------------------------------------------------
   Tablas
   ---------------------------------------------------------- */
.tabla-scroll { overflow-x: auto; margin: 0 -4px; }
table.tabla { width: 100%; border-collapse: collapse; }

/* Barra de scroll horizontal "espejo" arriba de .tabla-scroll: el scroll
   nativo queda pegado al borde de abajo de la tabla, y en una tabla con
   muchas columnas hay que bajar hasta el final para encontrarlo. El JS
   (bloque correspondiente en assets/js/app.js) la sincroniza con el
   scroll real y la esconde cuando la tabla no necesita scroll. */
.tabla-scroll-arriba { overflow-x: auto; overflow-y: hidden; margin: 0 -4px 6px; height: 14px; }
.tabla-scroll-arriba > div { height: 1px; }

table.tabla th {
  text-align: left;
  padding: 0 10px 8px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .7px;
  text-transform: uppercase;
  color: var(--gris);
  white-space: nowrap;
  border-bottom: 1px solid var(--linea);
}
table.tabla td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--linea);
  font-size: 13.5px;
  vertical-align: middle;
}
table.tabla tbody tr:last-child td { border-bottom: 0; }
table.tabla tbody tr:hover { background: #fafbfc; }
table.tabla .der { text-align: right; }
table.tabla .cen { text-align: center; }

/* En una tabla ancha el navegador reparte el sobrante partiendo el texto
   más largo, que suele ser justo el que se lee. Con esto la columna del
   nombre manda y las cortas no se parten en dos líneas. */
table.tabla .nombre { min-width: 165px; }
table.tabla .nowrap { white-space: nowrap; }

/* Cabeceras que ordenan. La flecha sólo se pinta en la columna activa:
   con una por columna, la tabla parecería un tablero de ajedrez. */
table.tabla th a { display: inline-flex; align-items: center; gap: 4px; color: inherit; }
table.tabla th a:hover  { color: var(--pri); }

/* Columnas ocultables (bloque "Columnas ocultables" en assets/js/app.js):
   la "x" vive dentro de la cabecera y sólo se ve bien al pasar el ratón,
   para no ensuciar la tabla con botones todo el tiempo. */
.th-envoltura { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.col-ocultar {
  flex: 0 0 auto;
  width: 15px; height: 15px;
  border: 0; border-radius: 4px;
  background: transparent; color: var(--gris);
  font-size: 12px; line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity .1s, background .15s, color .15s;
  display: inline-flex; align-items: center; justify-content: center;
}
table.tabla th:hover .col-ocultar { opacity: .6; }
.col-ocultar:hover     { opacity: 1 !important; background: var(--rojo-suave); color: var(--rojo); }

/* Barra de columnas ocultas: un chip por columna, para restaurarla con un clic.
   :empty la esconde del todo cuando no hay ninguna oculta. */
.cols-ocultas { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 0 2px 8px; }
.cols-ocultas:empty { display: none; padding: 0; }
.col-restaurar {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px;
  border: 1px dashed var(--linea);
  border-radius: 999px;
  background: none;
  font-size: 12px; font-weight: 600;
  color: var(--gris);
  cursor: pointer;
}
.col-restaurar:hover { border-color: var(--pri); color: var(--pri); }
table.tabla th.activa a { color: var(--pri); }
table.tabla th .flecha  { font-size: 8px; line-height: 1; }

/* La fila del producto abierto en un panel de abajo. Gana al :hover
   para que no parpadee al pasar el ratón por encima. */
table.tabla tbody tr.marcada,
table.tabla tbody tr.marcada:hover { background: var(--pri-suave); }

/* Pie de tabla: los totales de lo que hay en pantalla, no de la base. */
table.tabla tfoot td {
  padding: 10px;
  border-top: 1px solid var(--linea);
  font-size: 13px;
  font-weight: 700;
}

/* Columnas de campaña (?m=clientes): un chulo de "contactado" y una
   respuesta corta, una columna por campaña, guardadas al vuelo por JS. */
table.tabla .campana-col { min-width: 150px; }
.campana-check {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--tinta-2);
  white-space: nowrap;
  cursor: pointer;
}
.campana-check input { width: 14px; height: 14px; accent-color: var(--pri); cursor: pointer; }
.campana-resp {
  width: 100%;
  margin-top: 4px;
  padding: 4px 8px;
  border: 1px solid var(--linea);
  border-radius: 8px;
  font: inherit;
  font-size: 12px;
}
/* Aviso silencioso si el guardado por AJAX falla (sin conexión, etc.):
   basta con el borde rojo, no hace falta interrumpir con un alert(). */
.campana-error .campana-resp { border-color: var(--rojo); }

/* ----------------------------------------------------------
   Paginador
   Arriba y abajo de la tabla, para no obligar a subir tras
   cambiar de página en un listado largo.
   ---------------------------------------------------------- */
.paginador {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 2px;
}
.paginas { display: flex; align-items: center; gap: 3px; flex-wrap: wrap; }
.pagina {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 8px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tinta-2);
  text-decoration: none;
  white-space: nowrap;
}
.pagina:hover               { background: var(--gris-claro); }
.pagina.activa              { background: var(--pri); color: var(--blanco); }
.pagina.deshabilitada       { color: var(--gris); opacity: .5; }
.pagina.puntos              { color: var(--gris); }

/* ----------------------------------------------------------
   Segmentadores
   Los mismos filtros de siempre, pero a un clic y con el conteo
   a la vista. Son enlaces y no un <select> a propósito: así el
   estado se puede compartir por URL y el botón atrás funciona.
   ---------------------------------------------------------- */
.segmentos { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }

.segmento {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: var(--blanco);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tinta-2);
  white-space: nowrap;
  transition: border-color .15s, background .15s, color .15s;
}
.segmento:hover { border-color: var(--pri); color: var(--pri); }
.segmento .n    { font-size: 11px; font-weight: 700; color: var(--gris); }

.segmento.activo          { background: var(--pri); border-color: var(--pri); color: var(--blanco); }
.segmento.activo .n       { color: rgba(255, 255, 255, .75); }
.fuerte  { font-weight: 700; }
.tenue   { color: var(--gris); font-size: 12px; }
.positivo{ color: var(--verde); font-weight: 700; }
.negativo{ color: var(--rojo); font-weight: 700; }

/* ----------------------------------------------------------
   Etiquetas / píldoras
   ---------------------------------------------------------- */
.tag {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--gris-claro);
  color: var(--tinta-2);
  white-space: nowrap;
}
.tag.pri   { background: var(--pri-suave);   color: var(--pri); }
.tag.azul  { background: var(--azul-suave);  color: var(--azul); }
.tag.verde { background: var(--verde-suave); color: var(--verde); }
.tag.rojo  { background: var(--rojo-suave);  color: var(--rojo); }
.tag.ambar { background: var(--ambar-suave); color: #b45309; }

/* ----------------------------------------------------------
   Item de lista tipo mockup (bloque con mini-cajas de cifras)
   ---------------------------------------------------------- */
.item {
  border: 1px solid var(--linea);
  border-radius: var(--r);
  padding: 11px 13px;
  margin-bottom: 8px;
}
.item:hover { border-color: #dfe3ea; }
.item-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.item-top .ref { font-weight: 700; color: var(--tinta-2); font-size: 13px; }
.item-top .acciones { margin-left: auto; }
.item h4 { margin: 6px 0 9px; font-size: 14.5px; font-weight: 600; }

.cifras { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.cifra-box {
  background: #f7f8fa;
  border-radius: var(--r-sm);
  padding: 8px 10px;
  text-align: center;
}
.cifra-box .et {
  margin: 0 0 2px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--gris);
}
.cifra-box .val { margin: 0; font-size: 15.5px; font-weight: 700; letter-spacing: -.3px; }
.cifra-box.bien     { background: var(--verde-suave); }
.cifra-box.bien .et { color: var(--verde); }
.cifra-box.bien .val{ color: var(--verde); }
.cifra-box.mal      { background: var(--rojo-suave); }
.cifra-box.mal .et  { color: var(--rojo); }
.cifra-box.mal .val { color: var(--rojo); }
.cifra-box .pct { font-size: 11.5px; font-weight: 600; opacity: .75; }

/* Bloque resumen por dueño/vendedor del mockup.
   Misma caja que .card (relleno, radio y sombra) para que no haya dos
   densidades distintas conviviendo en la misma pantalla. */
.resumen {
  background: var(--blanco);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra);
  padding: 16px 18px;
  margin-bottom: var(--esp);
}
.resumen-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.resumen-top .tenue { font-size: 12px; }
/* Si el resumen es una celda estirada, su contenido se reparte la altura. */
.grid-mitad > .resumen { display: flex; flex-direction: column; }
.grid-mitad > .resumen > .cifras { margin-top: auto; }

/* ----------------------------------------------------------
   Categorías (lista lateral editable)
   ---------------------------------------------------------- */
.cat-nueva { display: flex; gap: 8px; margin-bottom: 10px; }
.cat-nueva input { border-radius: var(--r-sm); }

.cat-fila {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  padding: 4px 5px 4px 11px;
  margin-bottom: 6px;
}
.cat-fila input {
  border: 0; background: transparent; padding: 4px 0; font-weight: 600;
}
.cat-fila input:focus { background: transparent; }
.cat-fila button.txt {
  border: 0; background: transparent; color: var(--gris);
  font: inherit; font-size: 12.5px; cursor: pointer; padding: 4px 6px;
}
.cat-fila button.txt:hover { color: var(--pri); }

/* Variante de varios campos (laboratorios: nombre, contacto, teléfono, email).
   El nombre pesa el doble; el resto se reparte y baja de línea si no cabe. */
.cat-fila.multi { flex-wrap: wrap; }
.cat-fila.multi input { flex: 1 1 130px; min-width: 0; font-weight: 400; }
.cat-fila.multi input.principal { flex: 2 1 190px; font-weight: 700; }

/* ----------------------------------------------------------
   Avisos y vacíos
   ---------------------------------------------------------- */
.alerta {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 14px;
  border-radius: var(--r);
  margin-bottom: var(--esp);
  font-weight: 600;
  font-size: 13px;
}
.alerta.ok    { background: var(--verde-suave); color: #15803d; }
.alerta.error { background: var(--rojo-suave);  color: #b91c1c; }
.alerta.info  { background: var(--azul-suave);  color: #4338ca; }

.vacio { text-align: center; padding: 30px 16px; color: var(--gris); }
.vacio p { margin: 0 0 4px; font-size: 14.5px; font-weight: 600; color: var(--tinta-2); }
.vacio small { font-size: 12.5px; }

/* ----------------------------------------------------------
   Modales
   Se apoyan en <dialog>: el navegador ya da centrado, capa
   superior, cierre con Esc y foco atrapado. Aquí sólo va la piel.
   ---------------------------------------------------------- */
.modal {
  width: min(440px, calc(100vw - 28px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 0;
  border-radius: var(--r-lg);
  background: var(--blanco);
  color: var(--tinta);
  box-shadow: 0 18px 50px rgba(27, 31, 54, .22);
  overflow: hidden;
}
.modal.ancho  { width: min(660px, calc(100vw - 28px)); }
.modal.grande { width: min(880px, calc(100vw - 28px)); }

.modal::backdrop { background: rgba(27, 31, 54, .40); }
.modal[open] { animation: modal-entra .16s ease-out; }
@keyframes modal-entra {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .modal[open] { animation: none; } }

/* Con el modal abierto la página de atrás no se desplaza. */
body.modal-abierto { overflow: hidden; }

.modal-cab {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--linea);
}
.modal-cab h3 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -.3px; }
.modal-cab .tenue { display: block; margin-top: 1px; font-size: 12px; }

.modal-cuerpo { padding: 16px; overflow-y: auto; max-height: calc(100vh - 190px); }
.modal-cuerpo > p:first-child { margin-top: 0; }
.modal-cuerpo > p:last-child  { margin-bottom: 0; }
.modal-cuerpo p { margin: 0 0 8px; line-height: 1.5; }

.modal-pie {
  display: flex; align-items: center; gap: 8px; justify-content: flex-end;
  padding: 12px 16px;
  border-top: 1px solid var(--linea);
  background: #fafbfc;
}
.modal-pie .a-la-izquierda { margin-right: auto; }

/* Separador de secciones dentro de un modal largo (Productos / Cobro) */
.modal-seccion {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: var(--esp) 0 8px;
  padding-top: var(--esp);
  border-top: 1px solid var(--linea);
}
.modal-seccion:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.modal-seccion h4 {
  margin: 0;
  font-size: 11px; font-weight: 700; letter-spacing: .8px;
  text-transform: uppercase; color: var(--gris);
}

/* Total vivo en el pie del modal, junto a los botones */
.modal-total { display: flex; flex-direction: column; line-height: 1.15; }
.modal-total .et {
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--gris);
}
.modal-total .cifra { font-size: 21px; font-weight: 700; letter-spacing: -.6px; color: var(--pri); }

/* Estado de cuenta de la persona, dentro del modal de venta.
   Ámbar y no rojo: es un aviso para decidir si fiar, no un error. */
.estado-cliente {
  margin-top: 10px;
  background: var(--ambar-suave);
  border-radius: var(--r-sm);
  padding: 10px 12px;
}
.estado-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
.estado-top .et {
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: #b45309;
}
.estado-top .val { font-size: 17px; font-weight: 700; color: #b45309; letter-spacing: -.4px; }

/* Segunda línea del bloque: el cupo. Más pequeña que la deuda a
   propósito — lo primero que hay que leer es cuánto debe. */
.estado-cupo { margin-top: 4px; }
.estado-cupo .val { font-size: 14px; }

/* Se pasó del cupo. El bloque entero cambia de ámbar a rojo porque el
   aviso ya no es «mira cuánto debe» sino «pasó del tope que le fijaste»,
   y en un modal de venta rápida eso tiene que verse sin leer. Sigue sin
   bloquear nada: la decisión de fiar es del vendedor. */
.estado-cliente.sobrecupo { background: var(--rojo-suave); }
.estado-cliente.sobrecupo .estado-top .et,
.estado-cliente.sobrecupo .estado-top .val { color: #b91c1c; }
.estado-cliente.sobrecupo .estado-pagos { border-top-color: rgba(185, 28, 28, .16); }

.estado-pagos { margin-top: 6px; border-top: 1px solid rgba(180, 83, 9, .16); padding-top: 6px; }
.estado-pago {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12px; padding: 2px 0;
}
.estado-pago .tenue { font-size: 12px; }

/* Vista previa del plan de cuotas (modal de venta y formulario de pedido).
   Verde de marca y no ámbar: aquí no se avisa de nada, se muestra el trato
   que se está cerrando. El aviso, cuando lo hay, se pinta en rojo aparte. */
.plan-cuotas {
  margin-top: 12px;
  background: var(--pri-suave);
  border-radius: var(--r-sm);
  padding: 10px 12px;
}
.plan-cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.plan-cab strong { font-size: 14px; color: var(--pri); letter-spacing: -.2px; }

/* Cuando no hay plan posible el panel deja de ser informativo y pasa a
   ser un impedimento: cambia de color entero, no sólo la letra. */
.plan-cuotas.sin-plan { background: var(--rojo-suave); }

.plan-aviso { font-size: 12px; color: var(--gris); margin: 0; }
.plan-aviso.negativo { color: var(--rojo); font-weight: 600; }

/* Sin bordes ni cabecera: dentro de la tarjeta verde son tres columnas
   sueltas (cuota, fecha, valor), no una tabla de listado. */
.plan-tabla { margin: 0; }
.plan-tabla td {
  padding: 3px 0;
  border: 0;
  font-size: 13px;
  background: transparent;
}

/* Ficha de contexto dentro del modal (a qué pedido/cliente afecta) */
.modal-dato {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: #f7f8fa;
  border-radius: var(--r-sm);
  padding: 9px 12px;
  margin-bottom: 12px;
}
.modal-dato .val { font-weight: 700; }

@media (max-width: 560px) {
  .modal, .modal.ancho, .modal.grande { width: calc(100vw - 20px); }
  .modal-pie { flex-wrap: wrap; }
  .modal-pie .modal-total { width: 100%; margin-right: 0; }
  .modal-pie .btn { flex: 1; justify-content: center; }
}

/* ----------------------------------------------------------
   Login — panel partido: marca a la izquierda, formulario a la
   derecha. En pantallas angostas el panel de marca se oculta y
   sólo queda el formulario (ver el @media al final del bloque).
   ---------------------------------------------------------- */
.login-fondo { min-height: 100vh; display: flex; background: var(--fondo); }

.login-marca {
  flex: 1 1 50%;
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center;
  padding: 48px 56px;
  color: #fff;
  background: linear-gradient(160deg, var(--pri-fuerte) 0%, #063d30 100%);
}
.login-marca-top { position: absolute; top: 48px; left: 56px; }
/* Brillo suave arriba a la derecha, sólo decorativo. */
.login-marca::after {
  content: ''; position: absolute; top: -160px; right: -160px;
  width: 420px; height: 420px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.08), transparent 70%);
}

.login-marca-top h1 { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.4px; color: #fff; }
.login-marca-top h1 span { color: var(--ambar); }
.login-marca-top p {
  margin: 4px 0 0; font-size: 11px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; color: rgba(255,255,255,.6);
}

.login-marca-medio { position: relative; }
.login-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 999px;
  background: rgba(255,255,255,.12);
  font-size: 11px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
}
.login-badge svg { width: 14px; height: 14px; stroke-width: 2.6; }

.login-marca h2 { margin: 20px 0 0; font-size: 40px; font-weight: 700; line-height: 1.14; letter-spacing: -1px; }
.login-marca h2 span { color: var(--ambar); }
.login-marca .desc { margin: 16px 0 0; max-width: 420px; font-size: 14px; line-height: 1.6; color: rgba(255,255,255,.78); }

.login-features { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 26px; margin-top: 34px; }
.login-feature { display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 600; }
.login-feature .icono-feat {
  display: flex; align-items: center; justify-content: center; flex: 0 0 32px;
  width: 32px; height: 32px; border-radius: 9px; background: rgba(255,255,255,.14);
}
.login-feature svg { width: 16px; height: 16px; stroke: var(--ambar); stroke-width: 2.2; }

.login-panel-form { flex: 1 1 50%; display: flex; align-items: center; justify-content: center; padding: 40px 24px; background: #fff; }
.login-caja { width: 100%; max-width: 380px; }

.badge-seguro {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--pri-suave); color: var(--pri);
  font-size: 11px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
}
.badge-seguro svg { width: 13px; height: 13px; stroke-width: 2.6; }

.login-caja h1 { margin: 16px 0 0; font-size: 26px; font-weight: 700; text-align: left; }
.login-caja .sub { margin: 6px 0 24px; text-align: left; color: var(--gris); font-size: 13.5px; }
.login-caja .btn { width: 100%; justify-content: center; margin-top: 8px; }

.login-campo { margin-bottom: 14px; }
.login-campo label {
  display: block; margin-bottom: 5px; font-size: 11px; font-weight: 700;
  color: var(--tinta-2); text-transform: uppercase; letter-spacing: .4px;
}
.login-campo .campo-input { position: relative; }
.login-campo .icono-campo {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--gris); pointer-events: none; display: flex;
}
.login-campo .icono-campo svg { width: 16px; height: 16px; }
.login-campo input { padding-left: 38px; }
.login-campo .ojo {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: none; padding: 6px; cursor: pointer; color: var(--gris); display: flex;
}
.login-campo .ojo svg { width: 16px; height: 16px; }
.login-campo .ojo:hover { color: var(--tinta-2); }
.login-campo input[type=password] { padding-right: 34px; }

.login-copy { margin-top: 22px; text-align: center; font-size: 11.5px; color: var(--gris); }

@media (max-width: 880px) {
  .login-marca { display: none; }
  .login-fondo { background: linear-gradient(135deg, var(--pri-suave), var(--fondo) 55%, var(--azul-suave)); }
  .login-panel-form { padding: 20px; }
}

/* ----------------------------------------------------------
   Barras de reportes
   ---------------------------------------------------------- */
.barra-fila { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.barra-fila .nom { width: 155px; font-size: 13px; font-weight: 600; flex: 0 0 155px; }
.barra-pista { flex: 1; height: 8px; background: var(--gris-claro); border-radius: 999px; overflow: hidden; }
.barra-valor { height: 100%; border-radius: 999px; background: var(--pri); }
.barra-fila .cif { width: 105px; text-align: right; font-weight: 700; font-size: 13px; flex: 0 0 105px; }

/* Barra partida en costo y utilidad. El grupo mide lo que ese ítem pesa
   frente al primero del ranking; dentro, el reparto de esa venta. */
.barra-grupo { display: flex; height: 100%; border-radius: 999px; overflow: hidden; }
.barra-valor.costo { border-radius: 0; background: var(--rojo); opacity: .8; }
.barra-valor.util  { border-radius: 0; background: var(--verde); }

/* Barra de fondo dentro de una celda: la cifra se lee y el peso se ve.
   Crece desde la derecha porque la cifra va alineada a la derecha; si
   creciera desde la izquierda, barra y número apuntarían a lados distintos. */
.tabla .celda-barra { position: relative; }
.tabla .celda-barra .fondo {
  position: absolute;
  right: 0; top: 5px; bottom: 5px;
  border-radius: 4px;
  background: var(--verde-suave);
  z-index: 0;
}
.tabla .celda-barra > span { position: relative; z-index: 1; }

/* ----------------------------------------------------------
   Gráficas SVG de reportes
   Los colores viven aquí y no en el PHP: las figuras salen con
   una clase (g-verde, g-rojo…) y el tono se decide en la hoja,
   así cambiar la marca sigue siendo tocar :root.

   El código de color es del negocio y no decorativo:
   verde = lo que queda · rojo = lo que se va o falta.
   ---------------------------------------------------------- */
.grafico { display: block; width: 100%; height: auto; overflow: visible; }

.g-rejilla { stroke: var(--linea); stroke-width: 1; }
.g-eje     { fill: var(--gris); font-size: 11px; font-weight: 600; }
.g-centro  { text-anchor: middle; }
.g-valor   { fill: var(--tinta-2); font-size: 11.5px; font-weight: 700; text-anchor: middle; }

.g-barra          { transition: opacity .15s; }
.g-barra.g-rojo   { fill: var(--rojo); opacity: .78; }
.g-barra.g-verde  { fill: var(--verde); }

/* Pista de la columna: deja ver el mes vacío —que es un dato— y cuánto le
   faltó al mes para llegar al máximo. Translúcida para que la rejilla siga
   leyéndose por debajo. */
.g-pista-col { fill: var(--gris-claro); opacity: .5; }
.g-pista-col.g-actual { fill: var(--pri-suave); opacity: .9; }

/* Al pasar por encima, la columna apuntada se aviva y las demás se apagan:
   el tooltip nativo dice el detalle y el color dice de cuál habla. */
.g-columna { transition: opacity .15s; }
.grafico:hover .g-columna { opacity: .45; }
.grafico .g-columna:hover { opacity: 1; }
.g-zona { fill: transparent; pointer-events: all; }

/* La utilidad escrita dentro de su propio tramo verde. */
.g-dentro { fill: var(--blanco); font-size: 11.5px; font-weight: 700; text-anchor: middle; }

/* Variación contra el mes anterior, encima de la cifra. */
.g-cambio { font-size: 10.5px; font-weight: 700; text-anchor: middle; }
.g-cambio.g-verde { fill: var(--verde); }
.g-cambio.g-rojo  { fill: var(--rojo); }

/* El mes en curso va marcado: es el único que todavía puede cambiar. */
.g-mes-actual { fill: var(--pri); font-weight: 700; }

.g-suelo { stroke: var(--linea); stroke-width: 1.5; }

.g-linea    { fill: none; stroke: var(--verde); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.g-promedio { stroke: var(--gris); stroke-width: 1; stroke-dasharray: 5 5; }
.g-punto    { stroke: var(--blanco); stroke-width: 2.5; }

.g-degradado-alto { stop-color: var(--verde); stop-opacity: .34; }
.g-degradado-bajo { stop-color: var(--verde); stop-opacity: 0; }

.g-valor.g-verde, .g-punto.g-verde { fill: var(--verde); }
.g-valor.g-rojo,  .g-punto.g-rojo  { fill: var(--rojo); }

/* Anillos. El arco se dibuja con dasharray desde las 3 en punto, así que
   hay que girarlo un cuarto de vuelta para que arranque arriba. */
.dona { width: 132px; height: 132px; flex: 0 0 132px; }
.g-pista { fill: none; stroke: var(--gris-claro); stroke-width: 18; }
.g-arco  {
  fill: none;
  stroke-width: 18;
  transform: rotate(-90deg);
  transform-origin: 60px 60px;
}
.g-arco.g-pri    { stroke: var(--pri); }
.g-arco.g-verde  { stroke: var(--verde); }
.g-arco.g-rojo   { stroke: var(--rojo); }
.g-arco.g-azul   { stroke: var(--azul); }
.g-arco.g-ambar  { stroke: var(--ambar); }
.g-arco.g-morado { stroke: var(--morado); }
.g-arco.g-cian   { stroke: var(--cian); }
.g-arco.g-gris   { stroke: var(--gris); }

.g-centro-val { font-size: 18px; font-weight: 700; text-anchor: middle; fill: var(--tinta); letter-spacing: -.5px; }
.g-centro-et  { font-size: 9px; font-weight: 700; text-anchor: middle; fill: var(--gris); letter-spacing: .8px; text-transform: uppercase; }

/* Medidor: media circunferencia. El <g> la voltea para que el arco crezca
   de izquierda a derecha por arriba. */
.medidor { display: block; width: 100%; max-width: 210px; height: auto; margin: 0 auto; }
.g-medio { transform: none; stroke-width: 13; stroke-linecap: round; }
.g-medidor-val { font-size: 32px; font-weight: 700; text-anchor: middle; letter-spacing: -1.5px; }
.g-medidor-val.g-verde { fill: var(--verde); }
.g-medidor-val.g-ambar { fill: #b45309; }
.g-medidor-val.g-rojo  { fill: var(--rojo); }
.g-arco.g-medio.g-verde { stroke: var(--verde); }
.g-arco.g-medio.g-ambar { stroke: var(--ambar); }
.g-arco.g-medio.g-rojo  { stroke: var(--rojo); }

/* Dona + leyenda, uno al lado del otro mientras quepan. */
.grafico-caja { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.grafico-caja .leyenda { flex: 1 1 180px; }

.leyenda { list-style: none; margin: 0; padding: 0; }
.leyenda li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-size: 12.5px;
  border-bottom: 1px solid var(--linea);
}
.leyenda li:last-child { border-bottom: 0; }
.leyenda .punto { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 9px; }
.leyenda .et  { flex: 1; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leyenda .val { font-weight: 700; white-space: nowrap; }
.leyenda .pct { width: 38px; text-align: right; color: var(--gris); font-size: 11.5px; font-weight: 700; }

/* Variante en línea para las cabeceras de tarjeta: sólo color y nombre. */
.leyenda-fila { display: flex; gap: 14px; flex-wrap: wrap; }
.leyenda-fila li { padding: 0; border-bottom: 0; font-size: 11.5px; color: var(--gris); }
.leyenda-fila .et { flex: 0 0 auto; font-weight: 600; }

.punto.g-pri    { background: var(--pri); }
.punto.g-verde  { background: var(--verde); }
.punto.g-rojo   { background: var(--rojo); }
.punto.g-azul   { background: var(--azul); }
.punto.g-ambar  { background: var(--ambar); }
.punto.g-morado { background: var(--morado); }
.punto.g-cian   { background: var(--cian); }
.punto.g-gris   { background: var(--gris); }

/* Variación contra el período anterior. Verde subir, rojo bajar — salvo en
   costo y cartera, donde el PHP invierte el criterio. */
.delta {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
.delta.sube   { background: var(--verde-suave); color: var(--verde); }
.delta.baja   { background: var(--rojo-suave);  color: var(--rojo); }
.delta.neutro { background: var(--gris-claro);  color: var(--tinta-2); }
.delta.nuevo  { background: var(--azul-suave);  color: var(--azul); }

/* ----------------------------------------------------------
   Entrada de las gráficas: todas crecen de cero a su valor.

   Se anima `transform` y no `width`/`height`, así que el navegador
   no vuelve a calcular la maqueta en cada fotograma y las barras no
   necesitan saber su medida final: escalan desde su propio tamaño.
   Los arcos, que no escalan bien, van por stroke-dasharray, y por
   eso el PHP les manda su trazo final en la variable --dash.

   Sólo al cargar: nada se mueve solo después.
   ---------------------------------------------------------- */
@keyframes g-crecer-x { from { transform: scaleX(0); } }
@keyframes g-crecer-y { from { transform: scaleY(0); } }
@keyframes g-aparecer { from { opacity: 0; } }
@keyframes g-trazar   { from { stroke-dashoffset: var(--largo); } }
@keyframes g-arco     { from { stroke-dasharray: 0 var(--circ); } }

/* Todo cierra a los 2s justos. Lo que arranca con retardo dura menos, para
   que ninguna figura se quede terminando sola después del resto. */

/* Columnas: crecen desde la línea base, no desde el centro. */
.g-barra {
  transform-box: fill-box;
  transform-origin: bottom;
  animation: g-crecer-y 1.4s cubic-bezier(.22, 1, .36, 1) both;
}

/* La línea se dibuja de izquierda a derecha; el relleno la sigue. */
.g-linea {
  stroke-dasharray: var(--largo);
  animation: g-trazar 2s ease-in-out both;
}
.g-area { animation: g-aparecer 1.4s ease-out .6s both; }

/* Cifras, puntos y referencias entran cuando ya hay algo debajo. */
.g-tarda { animation: g-aparecer .8s ease-out 1.2s both; }

/* La cifra de cada columna espera a su propia barra, que entra escalonada:
   el retardo se lo pone el PHP, columna por columna. */
.g-tarda-col { animation: g-aparecer .5s ease-out both; }

/* Los arcos crecen desde su propio comienzo, cada uno en su sitio. */
.g-arco {
  stroke-dasharray: var(--dash);
  animation: g-arco 2s cubic-bezier(.22, 1, .36, 1) both;
}

/* Barras horizontales de HTML: crecen desde la izquierda, salvo la del
   fondo de celda, que está anclada a la derecha junto a su cifra. */
.barra-valor, .barra-grupo { transform-origin: left; animation: g-crecer-x 2s cubic-bezier(.22, 1, .36, 1) both; }
.barra-grupo > .barra-valor { animation: none; }
.celda-barra .fondo { transform-origin: right; animation: g-crecer-x 2s cubic-bezier(.22, 1, .36, 1) both; }

/* Quien pidió menos movimiento ve la gráfica ya terminada. */
@media (prefers-reduced-motion: reduce) {
  .g-barra, .g-linea, .g-area, .g-tarda, .g-tarda-col, .g-arco,
  .barra-valor, .barra-grupo, .celda-barra .fondo { animation: none; }
}

/* ----------------------------------------------------------
   Orden de pedido imprimible
   (medidas calibradas para tamaño carta: no se compactan)
   ---------------------------------------------------------- */
.orden {
  max-width: 800px; margin: 0 auto 30px;
  background: #fff; border-radius: var(--r-lg);
  box-shadow: var(--sombra); padding: 40px 44px;
}
.orden-top { display: flex; justify-content: space-between; gap: 30px; border-bottom: 2px solid var(--tinta); padding-bottom: 18px; }
.orden-top .logo h1 { margin: 0; font-size: 30px; font-weight: 700; letter-spacing: -.6px; }
.orden-top .logo h1 span { color: var(--pri); }
.orden-top .datos { font-size: 12.5px; color: var(--tinta-2); line-height: 1.6; text-align: right; }
.orden-top .datos strong { display: block; color: var(--tinta); font-size: 13.5px; }
.orden-num { margin-top: 10px; border: 1.5px solid var(--tinta); border-radius: 8px; padding: 7px 14px; display: inline-block; font-weight: 700; }

.orden h5 {
  margin: 26px 0 12px;
  background: var(--tinta); color: #fff;
  display: inline-block; padding: 6px 16px; border-radius: 6px;
  font-size: 12.5px; letter-spacing: .6px; text-transform: uppercase;
}
.orden-datos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px 30px; font-size: 13.5px; }
.orden-datos div { border-bottom: 1px dotted #b9bece; padding-bottom: 5px; }
.orden-datos span { color: var(--gris); margin-right: 6px; }

table.orden-tabla { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: 13.5px; }
table.orden-tabla th {
  background: var(--tinta); color: #fff;
  padding: 9px 12px; text-align: left; font-size: 12px;
  letter-spacing: .5px; text-transform: uppercase;
}
table.orden-tabla td { border: 1px solid #d7dbe4; padding: 9px 12px; }
table.orden-tabla .der { text-align: right; }
table.orden-tabla .cen { text-align: center; }

.orden-totales { display: flex; justify-content: flex-end; margin-top: 16px; }
.orden-totales table { font-size: 14px; }
.orden-totales td { padding: 7px 14px; }
.orden-totales tr:last-child td { border-top: 2px solid var(--tinta); font-size: 17px; font-weight: 700; }

.orden-pie { margin-top: 28px; font-size: 11px; color: var(--gris); text-align: center; border-top: 1px solid var(--linea); padding-top: 14px; }

/* ----------------------------------------------------------
   Impresión
   ---------------------------------------------------------- */
@media print {
  @page { size: letter; margin: 12mm; }
  body { background: #fff; }
  .sidebar, .cabecera, .no-imprimir, .alerta { display: none !important; }
  .contenido { padding: 0; }
  .orden { box-shadow: none; padding: 0; max-width: none; border-radius: 0; }
  table.orden-tabla th { background: #1b1f36 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .orden h5 { background: #1b1f36 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ----------------------------------------------------------
   Responsive
   ---------------------------------------------------------- */
@media (max-width: 1180px) {
  .stats.cuatro { grid-template-columns: repeat(2, 1fr); }
  .grid-2 { grid-template-columns: 1fr; }
  .campos.cuatro { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  .app { flex-direction: column; }
  .sidebar { width: 100%; flex: none; height: auto; position: static; border-right: 0; border-bottom: 1px solid var(--linea); padding: 12px; }
  .marca { padding: 0 8px 10px; }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .salir { border-top: 0; margin-top: 0; padding-top: 0; }
  .contenido { padding: 16px 14px 30px; }
  .cabecera { flex-direction: column; align-items: flex-start; gap: 10px; }
  .cabecera h2 { font-size: 22px; }
  .stats, .stats.cuatro, .campos, .campos.tres, .campos.cuatro, .grid-mitad { grid-template-columns: 1fr; }
}
