:root {
  --bg: #e6e8eb;
  --card-bg: #ffffff;
  --surface-2: #eef0f2;
  --border: #dbdfe4;
  --text: #0d1117;
  --text-muted: #6b7280;
  --hueco-bg: rgba(13, 17, 23, 0.055);
  --primary: #00b8a9;
  --primary-dark: #0a3d3a;
  /* El botón que analiza el cotizador lleva su propio par de colores: con los
     del botón normal quedaba blanco sobre turquesa vivo en el tema oscuro, que
     no se lee. Aquí se da vuelta en vez de aclararse. */
  --analizar-bg: #0a3d3a;
  --analizar-texto: #ffffff;
  --accent: #00b8a9;
  --accent-soft: #d9f3f0;
  --teal: #00b8a9;
  --teal-soft: #d9f3f0;
  --danger: #d64545;
  --ok-bg: #e3f8f0;
  --ok-text: #0a7d5c;
  --error-bg: #fbe9e7;
  --error-text: #b3311f;
  --notice-bg: #fdf1e0;
  --notice-border: #f0d8a8;
  --notice-text: #92600e;
  --good: #2fb46e;
  --warn: #e8a23a;
  --stage-0: #e5484d;
  --stage-10: #4bbfd0;
  --stage-30: #39c6b1;
  --stage-50: #00b8a9;
  --stage-75: #e8a23a;
  --stage-90: #d97706;
  --stage-100: #2fb46e;
  /* El azul carbón del manual de marca (panel #111F28), no un negro plano: en
     tema oscuro el menú tenía el mismo color exacto que el fondo de la página
     y las dos superficies se fundían en una sola mancha negra. */
  --sidebar-bg: #111f28;
  --sidebar-text: #b8c0cc;
  --sidebar-text-active: #ffffff;
  --sidebar-active-bg: #0a3d3a;
  --sidebar-border: #1e3542;
  --sidebar-width: 200px;
  --sidebar-mini: 54px;   /* la barra encogida a solo iconos */
  --radius: 10px;
  --shadow-card: 0 1px 2px rgba(13, 17, 23, 0.06), 0 1px 1px rgba(13, 17, 23, 0.04);
  --font: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1117;
    --card-bg: #161b22;
    --surface-2: #1c2129;
    --border: #2a313c;
    --text: #f3f4f6;
    --text-muted: #8b95a1;
    --primary-dark: #00d4c2;
    --analizar-bg: #00d4c2;
    --analizar-texto: #06201e;
    --accent-soft: #103a36;
    --teal-soft: #103a36;
    --danger: #ef6a58;
    --ok-bg: #103a2c;
    --ok-text: #4ad195;
    --error-bg: #3a2320;
    --error-text: #ef6a58;
    --notice-bg: #332714;
    --notice-border: #52401f;
    --notice-text: #e8b463;
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 10px rgba(0, 0, 0, 0.25);
    --hueco-bg: #05070b;
  }
}

:root[data-theme="dark"] {
  --bg: #0d1117;
  --card-bg: #161b22;
  --surface-2: #1c2129;
  --border: #2a313c;
  --text: #f3f4f6;
  --text-muted: #8b95a1;
  --primary-dark: #00d4c2;
  --analizar-bg: #00d4c2;
  --analizar-texto: #06201e;
  --accent-soft: #103a36;
  --teal-soft: #103a36;
  --danger: #ef6a58;
  --ok-bg: #103a2c;
  --ok-text: #4ad195;
  --error-bg: #3a2320;
  --error-text: #ef6a58;
  --notice-bg: #332714;
  --notice-border: #52401f;
  --notice-text: #e8b463;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 10px rgba(0, 0, 0, 0.25);
  --hueco-bg: #05070b;
}

:root[data-theme="light"] {
  --bg: #e6e8eb;
  --card-bg: #ffffff;
  --surface-2: #eef0f2;
  --border: #dbdfe4;
  --text: #0d1117;
  --text-muted: #6b7280;
  --hueco-bg: rgba(13, 17, 23, 0.055);
  --primary-dark: #0a3d3a;
  --analizar-bg: #0a3d3a;
  --analizar-texto: #ffffff;
  --accent-soft: #d9f3f0;
  --teal-soft: #d9f3f0;
  --danger: #d64545;
  --ok-bg: #e3f8f0;
  --ok-text: #0a7d5c;
  --error-bg: #fbe9e7;
  --error-text: #b3311f;
  --notice-bg: #fdf1e0;
  --notice-border: #f0d8a8;
  --notice-text: #92600e;
  --shadow-card: 0 1px 2px rgba(13, 17, 23, 0.06), 0 1px 1px rgba(13, 17, 23, 0.04);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
}

h1, h2, .stat-value, .meta-numero {
  font-family: var(--font);
  font-weight: 600;
}

/* ---------- Fondo elegido ----------
   Cada quien elige el suyo y lo ve en todas las pantallas. Va fijo detrás del
   contenido, con un velo encima: sin ese velo el texto se pierde sobre una
   foto clara y el portal se vuelve incómodo de leer a las nueve de la noche.
   Las tarjetas se quedan casi opacas a propósito: el fondo se asoma entre
   ellas, no debajo de los números. */
body.con-fondo::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background-image: var(--fondo-portal);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
body.con-fondo::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--velo-fondo);
}
:root { --velo-fondo: rgba(230, 232, 235, 0.58); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --velo-fondo: rgba(13, 17, 23, 0.62); }
}
:root[data-theme="dark"] { --velo-fondo: rgba(13, 17, 23, 0.62); }
:root[data-theme="light"] { --velo-fondo: rgba(230, 232, 235, 0.58); }
body.con-fondo { background: transparent; }
body.con-fondo .content-area,
body.con-fondo .container { background: transparent; }
/* Las tarjetas dejan pasar un punto de fondo: se nota la imagen sin que los
   números pierdan contraste.
   Sin desenfoque a propósito. Difuminar lo que hay detrás obliga al
   computador a rehacer ese cálculo para cada tarjeta en cada cuadro, y en el
   Funnel hay decenas: era la causa principal de que el portal apareciera
   gastando batería. Un fondo algo más opaco se ve casi igual y no cuesta
   nada. El desenfoque queda solo en los dos desplegables chicos, que son dos
   y solo mientras están abiertos. */
body.con-fondo .card,
body.con-fondo .kpi,
body.con-fondo .board-card {
  background: color-mix(in srgb, var(--card-bg) 93%, transparent);
}
body.con-fondo .topbar { background: transparent; }

/* La galería para elegirlo, en Mi cuenta. */
.fondos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.6rem;
  margin-top: 0.6rem;
}
.fondo-opcion {
  position: relative;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  background: none;
  aspect-ratio: 16 / 9;
}
.fondo-opcion img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fondo-opcion span {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0.5rem 0.4rem 0.25rem;
  font-size: 0.7rem;
  font-weight: 600;
  color: #ffffff;
  text-align: left;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
}
.fondo-opcion:hover { border-color: var(--primary); }
.fondo-opcion.puesto { border-color: var(--primary); }
.fondo-opcion.puesto::after {
  content: "✓";
  position: absolute;
  top: 0.3rem;
  right: 0.4rem;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--primary);
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fondo-categoria {
  margin: 1rem 0 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---------- Del bruto al líquido ----------
   Los descuentos van en rojo y con su signo: lo que se quiere entender de un
   vistazo es dónde se fue la diferencia entre el bruto y lo que llega. */
.tabla-liquido { width: 100%; border-collapse: collapse; }
.tabla-liquido td, .tabla-liquido th { padding: 0.45rem 0.5rem; border-bottom: 1px solid var(--border); }
.tabla-liquido .numero { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabla-liquido small { display: block; font-size: 0.72rem; margin-top: 0.1rem; }
.tabla-liquido .fila-descuento .numero { color: var(--danger); }
.tabla-liquido .fila-nota td { border-bottom: 0; padding-top: 0; }
.tabla-liquido .fila-subtotal td { background: var(--surface-2); font-weight: 600; }
.tabla-liquido .fila-liquido th {
  border-top: 2px solid var(--primary);
  border-bottom: 0;
  font-size: 1.05rem;
  padding-top: 0.7rem;
}
.tabla-liquido .fila-liquido .numero { color: var(--primary); }
/* El aviso pegado al número, no al pie: quien mira el líquido lo lee en el
   mismo golpe de vista. */
.aviso-aproximado {
  margin: 0.8rem 0 0;
  padding: 0.65rem 0.8rem;
  border-left: 3px solid var(--notice-bg, #e8a33d);
  background: color-mix(in srgb, var(--text) 5%, transparent);
  border-radius: 0 8px 8px 0;
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.aviso-aproximado b { color: var(--text); }
.ajustes-liquido { margin-top: 1rem; }
.ajustes-liquido > summary { cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--primary); }
.form-descuentos { margin-top: 0.8rem; display: grid; gap: 0.8rem; }
.campos-descuentos { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0.8rem; }
.campos-descuentos label { display: grid; gap: 0.25rem; font-size: 0.8rem; }
.campos-descuentos label > span { font-weight: 600; }
.campos-descuentos label[hidden] { display: none; }
.campo-si-no { display: flex !important; align-items: center; gap: 0.45rem; align-self: end; }
.campo-si-no input { width: auto; }
.titulo-otros { margin: 0.4rem 0 0; font-size: 0.95rem; }
.otros-descuentos { display: grid; gap: 0.45rem; }
.otro-fila { display: grid; grid-template-columns: 1fr 140px; gap: 0.45rem; }
.acciones-descuentos { display: flex; gap: 0.5rem; }

/* La tabla de indicadores en Ajustes, y el aviso de error de lectura. */
.tabla-indicadores { width: 100%; font-size: 0.85rem; border-collapse: collapse; margin: 0.5rem 0; }
.tabla-indicadores th { text-align: left; font-size: 0.7rem; text-transform: uppercase; color: var(--text-muted); padding: 0.3rem 0.4rem; }
.tabla-indicadores td { padding: 0.35rem 0.4rem; border-top: 1px solid var(--border); }
.tabla-indicadores .numero { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.texto-error { color: var(--danger); }

/* Con el portal en segundo plano no hay nadie mirando: las animaciones que
   no terminan nunca —el aro de las tarjetas en foco, los latidos— se quedan
   quietas. Repintar para nadie es exactamente lo que gasta batería sin que se
   note para qué. */
body.en-pausa *,
body.en-pausa *::before,
body.en-pausa *::after {
  animation-play-state: paused !important;
}
/* Y quien prefiera el sistema sin movimiento, no lo tiene. */
@media (prefers-reduced-motion: reduce) {
  .board-card-foco,
  .board-card-foco::before,
  .foco-cierre-activo .diana-centro { animation: none !important; }
}

/* ---------- El tablero, armado por quien lo mira ----------
   Una grilla de doce columnas: cada tarjeta ocupa las que le toquen, se
   arrastra de sitio y se estira. Doce y no cuatro porque así caben anchos
   intermedios —un tercio, la mitad, dos tercios— sin inventar filas nuevas. */
.dash-paneles {
  position: relative;   /* las guías de alineación se cuelgan de aquí */
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.dash-paneles > .card {
  grid-column: span var(--ancho, 3);
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}
.dash-paneles > .card[style*="--alto"] { height: var(--alto); overflow: hidden; }

/* El asa para mover: asoma al pasar el cursor por la tarjeta, para no llenar
   el tablero de controles cuando uno solo está mirando los números. */
.panel-asa {
  position: absolute;
  top: 0.35rem;
  left: 0.35rem;
  z-index: 3;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.7rem;
  line-height: 1;
  cursor: grab;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.card:hover > .panel-asa, .panel-asa:focus-visible { opacity: 1; }
.panel-asa:active { cursor: grabbing; }

/* Las asas de estirar: a la derecha para el ancho, abajo para el alto. */
.panel-ancho, .panel-alto {
  position: absolute;
  z-index: 3;
  background: transparent;
  border: 0;
  padding: 0;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.panel-ancho { top: 12%; bottom: 12%; right: -4px; width: 9px; cursor: col-resize; }
.panel-alto { left: 20%; right: 20%; bottom: -4px; height: 9px; cursor: row-resize; }
.card:hover > .panel-ancho, .card:hover > .panel-alto { opacity: 1; }
.panel-ancho::before, .panel-alto::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  border-radius: 3px;
  background: var(--primary);
}
.panel-ancho::before { width: 3px; height: 34px; }
.panel-alto::before { width: 34px; height: 3px; }

/* Mientras se arrastra: la que viaja queda traslúcida y el hueco de destino
   se marca, para ver dónde va a caer antes de soltarla. */
.dash-paneles.ordenando > .card { transition: transform 0.12s ease; }
.card.panel-viajando { opacity: 0.45; }
.card.panel-destino { outline: 2px dashed var(--primary); outline-offset: 2px; }

/* La guía que aparece al estirar: una línea fina, del color de la marca, que
   confirma que el borde quedó a la misma altura o al mismo ancho que el de
   otra tarjeta. Discreta a propósito: es una confirmación, no un aviso. */
.panel-guia {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  background: var(--primary);
  opacity: 0.5;
}
.panel-guia.vertical { top: -4px; bottom: -4px; width: 1px; }
.panel-guia.horizontal { left: -4px; right: -4px; height: 1px; }

/* El botón que cambia el tipo de gráfico, en la cabecera de la tarjeta. */
.grafico-tipo {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.68rem;
  padding: 0.1rem 0.4rem;
  cursor: pointer;
  white-space: nowrap;
}
.grafico-tipo:hover { border-color: var(--primary); color: var(--primary); }

/* Un botón para dejar el tablero como venía, por si alguien se enreda. */
.dash-restablecer {
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.72rem;
  cursor: pointer;
  text-decoration: underline;
}
.dash-restablecer:hover { color: var(--primary); }

/* En pantalla angosta no hay nada que acomodar: las tarjetas van una debajo
   de otra y las asas se esconden. */
@media (max-width: 900px) {
  .dash-paneles { grid-template-columns: minmax(0, 1fr); }
  .dash-paneles > .card { grid-column: span 1 !important; height: auto !important; }
  .panel-asa, .panel-ancho, .panel-alto, .dash-restablecer { display: none; }
}
@media (min-width: 901px) and (max-width: 1250px) {
  /* A media pantalla, lo angosto se ensancha para que siga siendo legible. */
  .dash-paneles > .card { grid-column: span max(var(--ancho, 3), 6); }
}

/* El globito rojo sobre el icono del chat, como en WhatsApp: rojo porque es
   lo único del menú que pide que hagas algo ahora, y pegado al icono para que
   se vea también con el menú encogido a solo iconos. */
.nav-icono-aviso { position: relative; display: inline-flex; flex-shrink: 0; }
.nav-aviso {
  position: absolute;
  top: -5px;
  right: -7px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: #d94f4f;
  color: #ffffff;
  font-size: 0.6rem;
  font-weight: 700;
  font-style: normal;
  line-height: 16px;
  text-align: center;
  /* Un borde del color de la barra lo despega del icono. */
  box-shadow: 0 0 0 2px var(--sidebar-bg);
}
.nav-aviso[hidden] { display: none; }
/* En el panel del teléfono el número va al final de la fila, pero del mismo
   rojo: es el mismo aviso. */
.tabbar-panel .tabbar-notas-cuenta { background: #d94f4f; color: #ffffff; }

/* ---------- Archivos para la venta ----------
   Tarjetas del ancho de su nombre, no de la pantalla: entran varias por fila
   y se reconocen por el sello de color antes de leer nada. Los botones van
   chicos —son de un clic— para que no compitan con el nombre, que es lo que
   uno viene a buscar. */
.archivos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0.6rem;
}
/* Un negocio que está en la papelera: se puede abrir y editar, pero no se ve
   en ninguna parte. Hay que decirlo arriba y con el botón para devolverlo. */
.aviso-papelera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border-color: var(--warning, #e0923d);
  background: color-mix(in srgb, var(--warning, #e0923d) 10%, var(--card-bg));
}
.aviso-papelera .subtitle { margin: 0.2rem 0 0; }

/* La estrella de los archivos: arriba a la derecha, discreta hasta que está
   puesta. Marcar no es una acción sobre el archivo —eso son los botones del
   pie— es una preferencia de quien mira. */
.archivo-estrella {
  position: absolute;
  top: 0.3rem;
  right: 0.35rem;
  z-index: 2;
  display: inline-flex;
  padding: 0.2rem;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--text-muted);
  opacity: 0.35;
  cursor: pointer;
  transition: opacity 0.12s ease, color 0.12s ease;
}
.archivo-estrella svg { width: 15px; height: 15px; fill: none; }
.archivo:hover .archivo-estrella { opacity: 0.8; }
.archivo-estrella:hover { color: var(--warning, #e0923d); opacity: 1; }
.archivo-favorito .archivo-estrella {
  opacity: 1;
  color: var(--warning, #e0923d);
}
.archivo-favorito .archivo-estrella svg { fill: currentColor; }
/* Un marcado se reconoce sin leerlo: el borde lo dice. */
.archivo-favorito { border-color: var(--warning, #e0923d); }

/* Arrastrando para reordenar. */
.archivo[draggable="true"] { cursor: grab; }
.archivo-viajando {
  opacity: 0.45;
  cursor: grabbing;
  border-style: dashed;
}
.archivos-ayuda { margin: 0 0 0.7rem; }

.archivo {
  position: relative;
  /* En columna y no en grilla: así la tarjeta se estira hasta la más alta de
     la fila y la tira de botones se va al pie. Con descripciones de distinto
     largo, en grilla cada fila de botones quedaba a su propia altura. */
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.75rem 0.8rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.archivo:hover { border-color: var(--primary); transform: translateY(-1px); }
.archivo-vacio { border-style: dashed; background: none; }

/* El sello con la extensión: es lo primero que se ve, y su color dice de qué
   tipo de archivo se trata sin tener que leerlo. */
.archivo-sello {
  align-self: flex-start;
  margin-bottom: 0.15rem;
  padding: 0.12rem 0.42rem;
  border-radius: 5px;
  background: var(--text-muted);
  color: #ffffff;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.04em;
}
.archivo-sello[data-ext="xlsx"], .archivo-sello[data-ext="xlsm"],
.archivo-sello[data-ext="xlsb"], .archivo-sello[data-ext="xls"],
.archivo-sello[data-ext="csv"]  { background: #1d7f4c; }
.archivo-sello[data-ext="pdf"]  { background: #c0392b; }
.archivo-sello[data-ext="doc"], .archivo-sello[data-ext="docx"] { background: #2b5b86; }
.archivo-sello[data-ext="ppt"], .archivo-sello[data-ext="pptx"] { background: #b35418; }
.archivo-sello[data-ext="png"], .archivo-sello[data-ext="jpg"],
.archivo-sello[data-ext="jpeg"] { background: #6b4b9a; }
.archivo-sello[data-ext="zip"]  { background: #7a6a45; }

.archivo-nombre {
  font-size: 0.88rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.archivo-nota, .archivo-version {
  font-size: 0.7rem;
  color: var(--text-muted);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.archivo-falta { font-style: italic; }
.archivo-version { margin-bottom: 0.3rem; }

.archivo-botones {
  display: flex;
  /* Bajar a la izquierda, actualizar y eliminar a la derecha: todo el ancho
     de la tarjeta de por medio. Bajar se hace a diario y eliminar no tiene
     vuelta atrás; pegados, el error es cuestión de tiempo. */
  justify-content: space-between;
  align-items: center;
  gap: 0.9rem;
  /* Al pie de la tarjeta, pase lo que pase arriba: así todas las tiras de
     botones quedan en la misma línea a lo ancho de la fila. */
  margin-top: auto;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
}
.archivo-botones-lado { display: flex; align-items: center; gap: 0.3rem; }
.archivo-botones form { margin: 0; }
.archivo-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--card-bg);
  color: var(--text-muted);
  font: inherit;
  font-size: 0.82rem;
  line-height: 1;
  cursor: pointer;
}
.archivo-boton:hover { border-color: var(--primary); color: var(--primary); }
.archivo-bajar { text-decoration: none; color: var(--primary); border-color: var(--primary); }
/* El de eliminar va apagado hasta que uno se le acerca: está ahí cuando se
   necesita, sin invitar a pulsarlo de paso. */
.archivo-quitar { opacity: 0.45; }
.archivo-quitar:hover,
.archivo-quitar:focus-visible {
  opacity: 1;
  border-color: var(--danger);
  color: var(--danger);
}

/* Agregar un archivo es cosa de vez en cuando: un botón chico, y el formulario
   solo cuando se pide. Antes ocupaba media pantalla por debajo de lo que uno
   viene a buscar. */
.archivo-agregar { margin-top: 0.9rem; }
.archivo-agregar-boton {
  display: inline-flex;
  align-items: center;
  width: auto;
  padding: 0.3rem 0.7rem;
  border: 1px dashed var(--border);
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.archivo-agregar-boton::-webkit-details-marker { display: none; }
.archivo-agregar-boton:hover { border-color: var(--primary); color: var(--primary); }
.archivo-agregar[open] > .archivo-agregar-boton {
  border-style: solid;
  border-color: var(--primary);
  color: var(--primary);
  margin-bottom: 0.7rem;
}

.doc-nuevo { display: grid; gap: 0.7rem; }
/* Los tres campos en una fila mientras quepan: ocupa una franja y no media
   pantalla. */
.archivo-agregar-campos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 0.6rem;
}
.doc-nuevo label { display: grid; gap: 0.25rem; font-size: 0.8rem; }
.doc-nuevo label > span { font-weight: 600; }
.doc-nuevo small { font-weight: 400; color: var(--text-muted); }
.archivo-agregar-pie { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.archivo-agregar-pie .subtitle { margin: 0; font-size: 0.72rem; }

/* ---------- Cambiar entre tablero y planilla ----------
   Un interruptor de dos posiciones, no dos botones sueltos: son dos formas de
   mirar lo mismo y conviene que se lean como una sola cosa. */
.vista-cambio {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
}
.vista-boton {
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.22rem 0.62rem;
  cursor: pointer;
}
.vista-boton:hover { color: var(--text); }
.vista-boton.activa {
  background: var(--card-bg);
  color: var(--primary);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.tabla-completa-caja { margin-bottom: 0.75rem; }
/* El atributo «hidden» pierde contra un display propio: el tablero es una
   grilla y la caja de la tabla es una tarjeta, así que sin esto se quedaban
   las dos en pantalla al cambiar de vista. */
.board[hidden],
.board-scrollbar-top[hidden],
.hunting-nube-zona[hidden],
.tabla-completa-caja[hidden] { display: none !important; }

/* ---------- Vista de planilla ----------
   Cuadrícula completa, encabezado que no se va al desplazar y filas apretadas:
   es la forma en que el equipo está acostumbrado a mirar una cartera, y leer
   una fila larga es más fácil cuando cada dato tiene su casilla dibujada. */
.tabla-excel {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}
.tabla-excel th,
.tabla-excel td {
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 0.3rem 0.5rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 260px;
}
.tabla-excel thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-2);
  border-top: 1px solid var(--border);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: left;
}
.tabla-excel th:first-child,
.tabla-excel td:first-child { border-left: 1px solid var(--border); }
/* La primera columna se queda quieta al desplazar a lo ancho: sin ella uno se
   pierde de qué empresa es la fila que está leyendo. */
.tabla-excel .col-fija {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--card-bg);
  font-weight: 600;
}
.tabla-excel thead .col-fija { z-index: 3; background: var(--surface-2); }
.tabla-excel tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--text) 3%, transparent); }
.tabla-excel tbody tr:nth-child(even) .col-fija {
  background: color-mix(in srgb, var(--text) 3%, var(--card-bg));
}
.tabla-excel tbody tr:hover td { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.tabla-excel tbody tr:hover .col-fija {
  background: color-mix(in srgb, var(--primary) 10%, var(--card-bg));
}
/* Aprobado por la mesa: la fila entera en color Cúspide, con un filete a la izquierda
   para que se lea aunque la tabla esté corrida hacia la derecha. Gana sobre el
   rayado par/impar y sobre el hover, porque es lo que se vino a buscar. */
.tabla-excel tbody tr.fila-mesa-ok td {
  background: color-mix(in srgb, var(--primary) 16%, var(--card-bg));
}
.tabla-excel tbody tr.fila-mesa-ok:hover td {
  background: color-mix(in srgb, var(--primary) 24%, var(--card-bg));
}
.tabla-excel tbody tr.fila-mesa-ok .col-fija {
  box-shadow: inset 4px 0 0 var(--primary);
}

/* El interruptor de la mesa, junto al nombre de la empresa. */
.tabla-mesa {
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.64rem;
  font-weight: 600;
  vertical-align: 1px;
  cursor: pointer;
}
.tabla-mesa:hover { border-color: var(--good); color: var(--good); }
.tabla-mesa-ok { border-color: var(--good); background: var(--good); color: #ffffff; }
.tabla-mesa-ok:hover { color: #ffffff; opacity: 0.85; }

/* El estado, como un chip que se abre con un clic. El color agrupa: rojo lo
   que traba la venta, verde azulado el trámite con Claro, azul la venta que
   todavía se negocia. «Activo» queda neutro: es el estado de no decir nada. */
.col-estado { padding-top: 0.2rem !important; padding-bottom: 0.2rem !important; }
.estado-select {
  appearance: none;
  -webkit-appearance: none;
  min-width: 8.5rem;
  padding: 0.18rem 1.4rem 0.18rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23888' stroke-width='1.5'/%3E%3C/svg%3E")
    no-repeat right 0.5rem center;
  color: var(--text);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  cursor: pointer;
}
.estado-select:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.estado-deuda-pendiente, .estado-pendiente-riesgo, .estado-perdido,
.estado-error-de-conexion {
  background-color: var(--error-bg); color: var(--error-text);
  border-color: color-mix(in srgb, var(--error-text) 35%, transparent);
}
/* Activo (100%, habilitado): verde, lo logrado. */
.estado-activo {
  background-color: color-mix(in srgb, var(--good) 18%, var(--card-bg)); color: var(--good);
  border-color: color-mix(in srgb, var(--good) 45%, transparent);
}
/* Aprobado por la mesa: el color Cúspide, lleno, el mismo de la fila
   aprobada. Lleno y no suave para no confundirse con «En mesa». */
select.estado-aprobado-por-mesa {
  background-color: var(--primary); color: #fff;
  border-color: var(--primary);
}
/* La lista que se despliega va con los colores de siempre: si heredara el
   blanco del selector, las opciones quedarían ilegibles. */
select.estado-aprobado-por-mesa option { color: var(--text); background: var(--card-bg); }
.estado-en-mesa, .estado-validacion-moac, .estado-logistica, .estado-portabilidad-en-curso {
  background-color: var(--accent-soft); color: var(--primary-dark);
  border-color: color-mix(in srgb, var(--primary) 40%, transparent);
}
.estado-oferta-inicial, .estado-negociacion, .estado-ok-informal, .estado-demo-senal,
.estado-reunion-programada, .estado-firma-en-curso {
  background-color: color-mix(in srgb, #3b82f6 14%, var(--card-bg));
  color: color-mix(in srgb, #3b82f6 75%, var(--text));
  border-color: color-mix(in srgb, #3b82f6 35%, transparent);
}

/* ---------- El día, hora por hora ----------
   Una línea de tiempo, no una tabla: lo que importa es a qué hora pasó cada
   cosa y si hubo huecos, y eso se lee mejor en una columna de horas. */
.bitacora-cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.8rem;
  flex-wrap: wrap;
}
.bitacora-dia input {
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 0.78rem;
}
.bitacora-resumen {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.7rem 0 0.9rem;
}
.bitacora-persona {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.72rem;
}
.bitacora-persona b { font-size: 0.75rem; }
.bitacora-persona > span {
  font-weight: 700;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.bitacora-persona small { color: var(--text-muted); font-variant-numeric: tabular-nums; }

.bitacora-linea {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.1rem;
  max-height: 23rem;
  overflow-y: auto;
}
.bitacora-item {
  display: grid;
  grid-template-columns: 3.4rem 1fr;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.3rem 0.4rem;
  border-left: 3px solid var(--border);
  font-size: 0.8rem;
  line-height: 1.45;
}
.bitacora-item:hover { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.bitacora-hora {
  color: var(--text-muted);
  font-weight: 700;
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
}
.bitacora-quien { margin-right: 0.3rem; }
.bitacora-texto a { color: var(--primary); text-decoration: none; }
.bitacora-texto a:hover { text-decoration: underline; }
/* Cada clase de registro con su color en el borde: de un vistazo se ve si el
   día fue de llamar, de mover negocios o de papeleo. */
.bitacora-hunting { border-left-color: var(--primary); }
.bitacora-etapa { border-left-color: var(--success, #3fb950); }
.bitacora-accion { border-left-color: var(--warning, #e0923d); }
.bitacora-negocio { border-left-color: var(--primary); }
.bitacora-comentario,
.bitacora-registro { border-left-color: var(--border); }

/* «ver líquido»: el paso del bruto a lo que llega a la cuenta. Va en chico y
   en gris, debajo del monto: está para quien lo busque, sin pelearle la
   atención al número de la tarjeta. */
.kpi-liquido {
  align-self: flex-start;
  margin-top: 0.15rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--text-muted) 45%, transparent);
  cursor: pointer;
}
.kpi-liquido:hover,
.kpi-liquido:focus-visible { color: var(--primary); text-decoration-color: var(--primary); }
.kpi-liquido[hidden] { display: none !important; }
/* Mostrando el líquido: el monto cambia de tono para que no se confunda con
   el bruto de un vistazo. */
.kpi-en-liquido .kpi-valor { color: var(--primary); }

/* Base propia: la subió una persona y solo la ve ella. */
.chip-propia {
  background: color-mix(in srgb, var(--primary) 16%, transparent);
  color: var(--primary);
  border: 1px solid var(--primary);
  font-weight: 700;
}

/* Bajar el formato antes de cargar: el botón y su explicación, lado a lado. */
.formato-base {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  flex-wrap: wrap;
}
.formato-base-texto { flex: 1 1 420px; }
.formato-base-texto h2 { margin-bottom: 0.3rem; }
.formato-base .btn { white-space: nowrap; }

/* Lista de condiciones, sin viñeta de sistema y con aire entre líneas. */
.checklist-simple {
  margin: 0.4rem 0 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.45rem;
  font-size: 0.84rem;
  line-height: 1.5;
  color: var(--text-muted);
}
.checklist-simple b { color: var(--text); }

/* Arriba de la planilla de Hunting: qué parte de la cartera se está mirando. */
.planilla-cabecera {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.6rem;
}
.planilla-cabecera .vista-boton b { margin-left: 0.3rem; font-weight: 700; }

/* El resultado de subir la foto, escrito al lado del botón. Verde cuando
   entró, rojo cuando no: lo que no puede pasar es que no diga nada. */
.foto-resultado {
  margin: 0.5rem 0 0;
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  background: var(--ok-bg, var(--surface-2));
  color: var(--ok-text, var(--text));
  font-size: 0.8rem;
  line-height: 1.35;
}
.foto-resultado-mal { background: var(--notice-bg); color: var(--warn-text, var(--text)); }
.foto-resultado[hidden] { display: none; }

/* El formulario del negocio, compacto.
   ---------------------------------------------------------------
   Un negocio se carga entre dos llamadas. El formulario pedía bajar cuatro
   veces —datos, comercial, folio, contacto, responsables— y eso se traduce en
   fichas a medio llenar. Ahora son dos bloques y los campos van en grilla: se
   acomodan solos al ancho que haya, con la letra y el alto justos para leerse
   sin ocupar media pantalla cada uno. */
.form-ficha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.5rem 0.7rem;
  align-items: end;
  margin-bottom: 0.6rem;
}
.form-ficha:last-child { margin-bottom: 0; }
.form-ficha > label,
.form-ficha > .campo-par {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-muted);
  text-transform: uppercase;
  min-width: 0;
}
.form-ficha input,
.form-ficha select,
.form-ficha textarea {
  width: 100%;
  padding: 0.32rem 0.45rem;
  font-size: 0.85rem;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
}
/* El de la razón social y el del correo piden el doble de espacio: uno lleva el
   nombre completo de una empresa y el otro varios correos. */
.form-ficha > .ancho-2 { grid-column: span 2; }
.form-ficha > .campo-par { grid-column: span 2; }
.form-ficha > .campo-par { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
.form-ficha > .campo-par > label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
  min-width: 0;
}

/* Folio y su vencimiento, pegados: el vencimiento es un dato del folio y antes
   vivía en una tarjeta propia, con título y todo, para una sola fecha. Los dos
   juntos piden el doble de ancho; si no, el folio queda del porte de un dedo.
   Cada uno con su rótulo: una fecha suelta al lado del folio no dice qué es, y
   acá importa que se lea «vence el folio». */
.form-ficha > .campo-folio {
  grid-column: span 2;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.45rem;
  align-items: end;
  min-width: 0;
}
.form-ficha > .campo-folio > label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
  min-width: 0;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-muted);
  text-transform: uppercase;
}
.campo-vence-caja { color: var(--notice-text) !important; }
.campo-vence {
  width: 9.4rem;
  padding: 0.3rem 0.4rem;
  font-size: 0.78rem;
  background: var(--notice-bg);
  border-color: var(--notice-border);
}

/* El rótulo de cada tanda de campos: pesa menos que un <h2> y sirve igual para
   separar «el negocio» de «lo que se vendió». */
.form-subtitulo {
  margin: 0.9rem 0 0.45rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.form-nota { margin: 0.6rem 0 0; font-size: 0.78rem; }

/* El logo del cliente en Ajustes: se ve sobre el fondo de la tarjeta, que puede
   ser claro u oscuro, así que va sobre un recuadro neutro. */
.marca-actual {
  display: flex;
  align-items: center;
  min-height: 3.5rem;
  margin: 0.4rem 0 0.8rem;
  padding: 0.6rem 0.9rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.marca-vista { max-height: 2.6rem; max-width: 14rem; object-fit: contain; }

/* Cartera recién recibida de otra persona.
   ---------------------------------------------------------------
   Quien recibe la base de alguien que se fue tiene que poder separar de un
   vistazo lo que trabaja hace meses de lo que le acaban de pasar. Un tono
   distinto, apenas —un 10% de color sobre el fondo de siempre— y una marca
   chica en la esquina. Se va sola al mes: pasado ese plazo ya es cartera
   propia como cualquier otra. */
/* Se nombra la clase dos veces —y también el caso del fondo propio— para que
   esta regla le gane a «.board-card», que pinta todas las tarjetas y vive más
   abajo en este archivo. */
.board-card.board-card-recibida,
body.con-fondo .board-card.board-card-recibida {
  background: color-mix(in srgb, var(--recibida, #a06cd5) 10%, var(--card-bg));
  border-color: color-mix(in srgb, var(--recibida, #a06cd5) 45%, var(--border));
}
/* La marca es un chip dentro de la tarjeta y no algo flotando encima: en 250
   píxeles de ancho, lo que flota tapa el nombre de la empresa. */
.chip-recibida {
  align-self: flex-start;
  padding: 0.1rem 0.4rem;
  border: 1px solid color-mix(in srgb, var(--recibida, #a06cd5) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--recibida, #a06cd5) 16%, transparent);
  color: var(--recibida, #a06cd5);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
:root { --recibida: #a06cd5; }

/* Reasignar cartera: la pantalla de jefatura para mover los negocios de
   alguien que ya no está. */
.reasignar-elegir { display: flex; flex-direction: column; gap: 0.35rem; }
.reasignar-elegir select { max-width: 32rem; }
.reasignar-ayuda { margin: 0; }
.reasignar-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
.reasignar-resumen { font-size: 0.85rem; color: var(--text-muted); }
.reasignar-acciones { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
.reasignar-destino {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.reasignar-destino select { font-size: 0.82rem; padding: 0.3rem 0.45rem; }
.reasignar-marcados {
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 0.76rem;
  font-weight: 700;
}
.tabla-reasignar .col-marca { width: 2rem; text-align: center; }
.tabla-reasignar .col-marca input { cursor: pointer; }
.tabla-reasignar .col-pasar { min-width: 10rem; }
.tabla-reasignar .pasar-a { width: 100%; font-size: 0.78rem; padding: 0.2rem 0.3rem; }
/* La fila que acaba de cambiar de dueño: se queda a la vista, apagada, para
   saber qué ya se movió sin tener que recargar. */
.tabla-reasignar .fila-reasignada td { opacity: 0.5; }
.reasignado-a { font-size: 0.78rem; font-weight: 700; color: var(--good, #27ae60); }

/* Documentos de ingreso: la lista a un lado, todo lo demás al otro.
   ---------------------------------------------------------------
   La lista es angosta por naturaleza —una casilla y un nombre corto— y a la
   vez la más larga de la pantalla: un traspaso pide catorce documentos. Con
   solo los datos al lado quedaba media pantalla en blanco esperando que la
   lista terminara, así que a la derecha va TODO: los datos, el titular actual,
   los números a portar, la carga por Excel y los adjuntos, uno tras otro.

   El formulario no pinta nada por sí mismo («display: contents»), así que sus
   tarjetas caen directo en esta grilla junto con las dos que viven fuera de él
   (la carga por Excel y los adjuntos son formularios aparte y no pueden ir
   dentro del que guarda los datos). */
.ingreso-pantalla {
  display: grid;
  grid-template-columns: minmax(0, 27rem) minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
}
.ingreso-pantalla > form { display: contents; }
.ingreso-pantalla > *,
.ingreso-pantalla > form > * { grid-column: 2; margin: 0; min-width: 0; }
/* La lista ocupa su columna entera, de arriba abajo. */
.ingreso-pantalla #checklist { grid-column: 1; grid-row: 1 / span 50; order: -1; }

/* El orden de la columna derecha no es el del HTML: la lista de números a
   portar va al final aunque en el formulario venga antes. Con mil líneas
   cargadas empuja hacia abajo todo lo que venga después —la carga por Excel,
   los adjuntos— y lo que queda debajo de mil filas deja de existir para quien
   está mirando. La carga por Excel, en cambio, va justo antes: es como se
   llena esa lista. */
/* La carga desde el cotizador no se parece a ningún otro botón de la pantalla
   a propósito: es el camino corto, hace algo distinto —lee un archivo y llena
   media pantalla sola— y conviene que se vea que es otra cosa. */
.zona-cotizador {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px dashed var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--text-muted);
  font: inherit;
  font-size: 0.86rem;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.zona-cotizador:hover,
.zona-cotizador-encima {
  border-color: var(--primary);
  background: var(--accent-soft);
  color: var(--text);
}
.zona-cotizador-llena {
  border-style: solid;
  border-color: var(--primary);
  color: var(--text);
}
.zona-cotizador-icono { flex: 0 0 auto; display: flex; color: var(--primary); }
.zona-cotizador-icono svg { width: 22px; height: 22px; }
.zona-cotizador-texto { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.zona-cotizador-texto small {
  display: block;
  font-size: 0.76rem;
  color: var(--text-muted);
}

.btn-analizar {
  position: relative;
  overflow: hidden;
  width: 100%;
  margin-top: 0.5rem;
  padding: 0.55rem 0.9rem;
  border: 0;
  border-radius: 8px;
  background: var(--analizar-bg);
  color: var(--analizar-texto);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: opacity 0.15s;
}
.btn-analizar:hover:not(:disabled) { opacity: 0.9; }
.btn-analizar:disabled { opacity: 0.45; cursor: not-allowed; }
/* Mientras lee el archivo, una luz recorre el botón: que se vea que está
   pasando algo, porque una planilla de dos megas tarda un momento. */
.btn-analizar-luz {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: linear-gradient(100deg, transparent 20%,
              rgba(255, 255, 255, 0.28) 50%, transparent 80%);
}
.btn-analizar-trabajando .btn-analizar-luz {
  opacity: 1;
  animation: luz-analizar 1.1s linear infinite;
}
@keyframes luz-analizar {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .btn-analizar-trabajando .btn-analizar-luz { animation: none; opacity: 0.4; }
}

/* Cargar el Evaluador va primero de todo: es el camino corto, y quien llega a
   esta pantalla con la planilla en la mano no tiene por qué escribir nada. */
.ingreso-pantalla #card-evaluador { order: -1; }
.ingreso-evaluador-nota { margin-top: 0.5rem; }
.ingreso-pantalla #card-excel { order: 3; }
.ingreso-pantalla #card-adjuntos { order: 4; }
.ingreso-pantalla #card-numeros { order: 5; }

/* En la columna angosta, lo que falta de cada documento va debajo del nombre y
   no al final de la línea: ahí no cabe. El nombre se queda al lado de su
   casilla y parte su propia línea si hace falta —sin «flex-basis: 0» el nombre
   largo se iba entero al renglón siguiente y dejaba la casilla sola, que es
   peor que leerlo en dos líneas. */
.ingreso-pantalla #checklist .requisito { flex-wrap: wrap; align-items: baseline; }
.ingreso-pantalla #checklist .requisito-titulo { flex: 1 1 0; min-width: 0; }
.ingreso-pantalla #checklist .requisito > input[type="checkbox"] { flex: 0 0 auto; }
.ingreso-pantalla #checklist .requisito-falta {
  width: 100%;
  margin-left: 1.6rem;
  text-align: left;
}
/* El tipo de venta manda sobre toda la pantalla, así que ocupa su ancho
   completo y no se sale de la caja: «Traspaso de propiedad · de empresa a
   empresa» no cabe en un campo a medias. */
.ingreso-pantalla #checklist .ingreso-cabecera { gap: 0.4rem; }
.ingreso-pantalla #checklist .campo-modalidad { flex: 1 1 100%; min-width: 0; }
.ingreso-pantalla #checklist .campo-modalidad select {
  width: 100%;
  max-width: 100%;
  text-overflow: ellipsis;
}
.ingreso-pantalla #checklist .checklist-avance { flex: 1 1 100%; margin: 0; }

@media (max-width: 1100px) {
  .ingreso-pantalla { grid-template-columns: 1fr; }
  .ingreso-pantalla > *,
  .ingreso-pantalla > form > * { grid-column: 1; }
  .ingreso-pantalla #checklist { grid-row: auto; }
  .ingreso-pantalla #checklist .requisito-falta {
    width: auto;
    margin-left: auto;
    text-align: right;
  }
}

/* Documentos de ingreso: la misma grilla compacta del formulario del negocio.
   Es la pantalla más larga del portal —datos de la venta, empresa, firmante,
   titular actual, números a portar— y con los campos de a dos por fila pedía
   bajar media docena de veces. Las tablas de esa pantalla también se aprietan:
   son muchas filas cortas, no un informe para leer. */
.ingreso-compacta .tabla-lineas th,
.ingreso-compacta .tabla-lineas td { padding: 0.25rem 0.35rem; }
.ingreso-compacta .tabla-lineas input,
.ingreso-compacta .tabla-lineas select {
  padding: 0.25rem 0.35rem;
  font-size: 0.8rem;
}
.ingreso-compacta .card { padding: 0.85rem 1rem; }
.ingreso-compacta .card h2 { font-size: 1rem; margin-bottom: 0.4rem; }
.ingreso-compacta .card > .subtitle { margin-top: 0; font-size: 0.78rem; }

/* Cuántos datos quedan sin llenar, arriba y junto a los botones: lo que no se
   completa al cargar el negocio, después no lo completa nadie. */
.chip-pendientes {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--notice-border);
  border-radius: 999px;
  background: var(--notice-bg);
  color: var(--notice-text);
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}
.chip-pendientes[hidden] { display: none; }
/* En la grilla compacta la marca «por completar» va debajo del campo, sin
   empujar al vecino ni descuadrar la fila. */
.form-ficha .campo-pendiente::after,
.form-ficha .campo-listo::after { margin-top: 0.1rem; }
/* Las aclaraciones que viven dentro de un rótulo —«solo si el cliente está
   repartido entre dos»— se escriben como una frase, no como un rótulo más: el
   rótulo va en mayúsculas y la frase, así, era ilegible. */
.form-ficha small,
.form-ficha .subtitle,
.form-ficha label span.pista {
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.25;
  color: var(--text-muted);
  opacity: 0.85;
}
.form-ficha .campo-casilla { flex-direction: column; }
.form-ficha .campo-casilla input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0.15rem 0 0;
}
/* El bloque principal ya no agranda sus campos: lo que lo distingue es la
   línea de color del borde, no el tamaño de las letras. */
.card-principal .form-ficha input,
.card-principal .form-ficha select { font-size: 0.85rem; padding: 0.32rem 0.45rem; }
.card-principal .form-ficha > label { font-size: 0.74rem; }
@media (max-width: 700px) {
  .form-ficha > .ancho-2,
  .form-ficha > .campo-par { grid-column: span 1; }
  .form-ficha > .campo-par { grid-template-columns: 1fr; }
}

/* Casillas que se corrigen en la planilla, con doble clic. Mientras se edita,
   la casilla se ve como lo que es: un campo abierto, no un dato más. */
.tabla-excel td[data-campo] { cursor: text; }
.tabla-excel td[data-campo]:hover { box-shadow: inset 0 0 0 1px var(--border); }
.tabla-excel td.casilla-editando {
  padding: 0;
  box-shadow: inset 0 0 0 2px var(--primary);
  overflow: visible;
}
.casilla-campo {
  width: 100%;
  min-width: 90px;
  padding: 0.25rem 0.45rem;
  border: 0;
  border-radius: 0;
  background: var(--card-bg);
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
}
.casilla-campo:focus { outline: none; }
.tabla-excel td.casilla-guardando { opacity: 0.55; }
.tabla-excel td.casilla-guardada {
  background: color-mix(in srgb, var(--ok, #27ae60) 22%, transparent) !important;
  transition: background 0.5s ease;
}
/* El motivo de que no se haya podido guardar, al lado de la casilla y sin
   tapar la fila: un error que no se lee no sirve de nada. */
.casilla-aviso {
  position: absolute;
  z-index: 20;
  transform: translate(0.3rem, -0.1rem);
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  background: var(--warn, #c0392b);
  color: #fff;
  font-size: 0.72rem;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
}
.tabla-excel td { position: relative; }

/* El «+» de cada columna del tablero: crea un negocio ya puesto en esa etapa.
   Vive al lado del botón de ordenar, discreto hasta que se pasa por encima. */
.board-column-nuevo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-left: 0.1rem;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.55;
}
.board-column-nuevo:hover {
  opacity: 1;
  background: color-mix(in srgb, var(--primary) 18%, transparent);
  color: var(--primary);
  text-decoration: none;
}

/* La barra del Pipeline: filtros y acciones juntos, bajo el título. Antes los
   filtros vivían arriba del todo y las acciones acá: para filtrar había que
   subir, mirar, y volver a bajar al tablero. */
.pipeline-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.2rem 0 0.9rem;
}
.pipeline-barra .dash-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}
.pipeline-barra-acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}
/* El botón de crear: es la acción que más se usa de esta pantalla y tiene que
   verse como tal, no como un botón más de la fila. */
.btn-negocio-nuevo {
  padding: 0.45rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 700;
  box-shadow: 0 2px 10px color-mix(in srgb, var(--primary) 45%, transparent);
}
@media (max-width: 900px) {
  .pipeline-barra-acciones { margin-left: 0; }
}

/* El asa del ancho: una franja fina en el borde derecho del título. Se nota al
   pasar por encima y se agarra con el mouse, como en una planilla. */
.tabla-excel thead th .col-asa {
  position: absolute;
  top: 0;
  right: 0;
  width: 7px;
  height: 100%;
  cursor: col-resize;
  user-select: none;
  touch-action: none;
}
.tabla-excel thead th .col-asa:hover,
.tabla-excel.ajustando-ancho thead th .col-asa:hover {
  background: var(--primary);
  opacity: 0.55;
}
/* Mientras se arrastra, el texto de la planilla no se selecciona ni estorba. */
.tabla-excel.ajustando-ancho { user-select: none; cursor: col-resize; }
@media (max-width: 900px) { .tabla-excel thead th .col-asa { display: none; } }

/* Encabezados que ordenan al pincharlos. La flecha aparece solo en la columna
   por la que está ordenado: el resto se mantiene callado. */
.tabla-excel thead th.orden-pinchable { cursor: pointer; user-select: none; }
.tabla-excel thead th.orden-pinchable:hover { color: var(--primary); }
.tabla-excel thead th.orden-activa { color: var(--primary); }
.tabla-excel .orden-flecha { margin-left: 0.25rem; font-size: 0.6rem; }

/* Columnas que son una suma de otras —el total de líneas, el ARPU total—. Se
   marcan con una línea a la izquierda y el rótulo «= suma» para que se vea que
   no son un dato aparte: sumarlas junto a sus partes cuenta lo mismo dos
   veces. */
.tabla-excel .col-suma {
  border-left: 2px solid var(--primary);
  background: color-mix(in srgb, var(--primary) 6%, transparent);
  font-weight: 600;
}
.tabla-excel thead .col-suma { color: var(--primary); }
.tabla-excel thead .col-suma small {
  display: block;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.75;
}

.tabla-excel a { color: inherit; text-decoration: none; }
.tabla-excel a:hover { text-decoration: underline; }
/* Las celdas marcadas, y la barra que las cuenta: el gesto de Excel que la
   gente ya tiene en los dedos.

   El texto de la celda SÍ se selecciona: antes no, y un RUT que estaba a la
   vista no había manera de copiarlo. El bloqueo queda solo mientras se arrastra
   para marcar un rango, que es cuando la selección de texto estorba. */
.tabla-excel td { user-select: text; cursor: cell; }
.tabla-excel.arrastrando-celdas td { user-select: none; }
.tabla-excel td.celda-marcada {
  background: color-mix(in srgb, var(--primary) 26%, transparent) !important;
  box-shadow: inset 0 0 0 1px var(--primary);
}
.seleccion-barra {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 400;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card-bg);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.seleccion-barra[hidden] { display: none; }
.seleccion-sep { color: var(--border); }
.seleccion-detalle { color: var(--text-muted); font-size: 0.72rem; }
/* En el teléfono no hay arrastre de celdas que valga: la barra estorbaría. */
@media (max-width: 900px) { .seleccion-barra { display: none; } }

/* Alto fijo con su propio desplazamiento: la planilla no empuja la página. Y
   ajustable, porque no a todos les sirve el mismo: se arrastra el asa de abajo
   y cada navegador recuerda el alto que se dejó. */
.planilla-wrap { max-height: var(--alto-planilla, 62vh); overflow: auto; }

.planilla-alto {
  display: block;
  width: 100%;
  height: 12px;
  margin: 0.15rem 0 0.35rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: row-resize;
  opacity: 0.5;
  transition: opacity 0.15s ease;
}
.planilla-alto::before {
  content: "";
  display: block;
  width: 46px;
  height: 3px;
  margin: 4px auto;
  border-radius: 3px;
  background: var(--border);
}
.planilla-alto:hover { opacity: 1; }
.planilla-alto:hover::before { background: var(--primary); }
/* En el teléfono la planilla ya va a pantalla completa: el asa solo estorbaría. */
@media (max-width: 900px) { .planilla-alto { display: none; } }

/* La etapa en la planilla: el chip con «90% NEGOCIO INGRESADO» pesaba más que
   el dato que acompañaba. Se achica la letra y el relleno; los colores quedan
   igual, que es lo que se lee de un vistazo. */
.planilla-wrap .badge {
  padding: 0.08rem 0.4rem;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1px;
}

/* ---------- Accesos del equipo ----------
   Mismo formato de tarjeta que los archivos: el nombre arriba y, debajo, el
   usuario y la clave listos para copiar. La clave sale tapada siempre: una
   pantalla compartida no tiene por qué mostrarla. */
.accesos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.6rem;
}
.acceso {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-2);
}
.acceso:hover { border-color: var(--primary); }
.acceso-datos { display: grid; gap: 0.12rem; }
.acceso-datos b { font-size: 0.9rem; }
.acceso-sitio { font-size: 0.72rem; color: var(--primary); text-decoration: none; }
.acceso-sitio:hover { text-decoration: underline; }
.acceso-nota { font-size: 0.7rem; color: var(--text-muted); }

.acceso-campos { display: grid; gap: 0.4rem; margin-top: auto; }
.acceso-campos label { display: grid; gap: 0.15rem; font-size: 0.68rem; }
.acceso-campos label > span:first-child { color: var(--text-muted); font-weight: 600; }
.acceso-campo { display: flex; align-items: center; gap: 0.25rem; }
.acceso-campo input {
  flex: 1;
  min-width: 0;
  padding: 0.25rem 0.4rem;
  font-size: 0.8rem;
  font-family: var(--font);
}
.acceso-icono {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card-bg);
  color: var(--text-muted);
  font-size: 0.72rem;
  line-height: 1;
  cursor: pointer;
}
.acceso-icono svg { width: 13px; height: 13px; display: block; }
.acceso-icono:hover { border-color: var(--primary); color: var(--primary); }
.acceso-icono-listo { border-color: var(--primary); color: var(--primary); }
.acceso-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.15rem;
}
/* Igual que en los archivos: eliminar lejos de lo que se usa a diario, y
   apagado hasta que se le acerca el cursor. */
.acceso-quitar {
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--card-bg);
  color: var(--text-muted);
  font-size: 0.82rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.45;
}
.acceso-quitar:hover,
.acceso-quitar:focus-visible { opacity: 1; border-color: var(--danger); color: var(--danger); }

/* ---------- El chat del equipo ----------
   Dos columnas: las conversaciones a la izquierda y la charla a la derecha,
   con el campo de escribir pegado abajo. La altura es fija para que la lista
   de mensajes tenga su propio desplazamiento y no arrastre la página entera:
   en un chat uno se queda abajo, no arriba. */
.chat {
  display: grid;
  grid-template-columns: minmax(220px, 300px) 1fr;
  gap: 1rem;
  height: calc(100vh - 210px);
  min-height: 420px;
}
.chat-lista {
  overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem;
}
.chat-conversacion {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.5rem;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}
.chat-conversacion:hover { background: var(--surface-2); }
.chat-conversacion.abierta { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.chat-cara { flex-shrink: 0; }
.chat-cara-equipo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--surface-2);
  font-size: 0.7rem;
}
.chat-conversacion-texto { display: grid; gap: 0.1rem; min-width: 0; flex: 1; }
.chat-conversacion-texto b { font-size: 0.85rem; }
.chat-ultimo {
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-conversacion-lado { display: grid; gap: 0.2rem; justify-items: end; flex-shrink: 0; }
.chat-cuando { font-size: 0.68rem; color: var(--text-muted); white-space: nowrap; }
.chat-sin-leer {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--primary);
  color: #ffffff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.chat-nueva { margin-top: 0.4rem; border-top: 1px solid var(--border); padding-top: 0.4rem; }
.chat-nueva > summary {
  cursor: pointer;
  padding: 0.4rem 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--primary);
}
.chat-equipo { display: grid; gap: 0.1rem; }
.chat-persona {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  font-size: 0.82rem;
}
.chat-persona:hover { background: var(--surface-2); }
.chat-persona small { margin-left: auto; color: var(--text-muted); font-size: 0.68rem; }

.chat-charla {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 0;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.chat-charla-cabecera {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--border);
}
.chat-charla-cabecera .subtitle { margin: 0; font-size: 0.72rem; }
.chat-mensajes {
  overflow-y: auto;
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
}
/* La burbuja: la propia a la derecha y en el color de la marca, como en
   cualquier chat, para saber de un vistazo quién dijo qué. */
.chat-mensaje {
  align-self: flex-start;
  max-width: min(78%, 560px);
  padding: 0.5rem 0.7rem;
  border-radius: 12px 12px 12px 3px;
  background: var(--surface-2);
  display: grid;
  gap: 0.15rem;
}
.chat-mensaje.mio {
  align-self: flex-end;
  border-radius: 12px 12px 3px 12px;
  background: color-mix(in srgb, var(--primary) 20%, transparent);
}
.chat-autor { font-size: 0.72rem; color: var(--primary); font-weight: 700; }
.chat-texto { font-size: 0.88rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.chat-hora { font-size: 0.66rem; color: var(--text-muted); justify-self: end; }
.chat-anteriores {
  align-self: center;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.75rem;
  padding: 0.25rem 0.8rem;
  cursor: pointer;
}
.chat-anteriores[hidden] { display: none; }
.chat-vacio { margin: auto; color: var(--text-muted); font-size: 0.88rem; }
.chat-vacio[hidden] { display: none; }
.chat-escribir {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  padding: 0.6rem 0.7rem;
  border-top: 1px solid var(--border);
}
.chat-escribir textarea {
  flex: 1;
  resize: none;
  min-height: 38px;
  max-height: 140px;
  font: inherit;
  font-size: 0.88rem;
}
body.con-fondo .chat-lista,
body.con-fondo .chat-charla {
  background: color-mix(in srgb, var(--card-bg) 94%, transparent);
}
/* En el teléfono no caben dos columnas: la lista pasa a ser una tira arriba. */
@media (max-width: 900px) {
  .chat { grid-template-columns: 1fr; height: auto; }
  .chat-lista { max-height: 190px; }
  .chat-mensajes { height: 52vh; }
}

/* ---------- Los indicadores del día ----------
   Deliberadamente apagados: van al lado del buscador y se leen de reojo
   cuando hacen falta. Si destacaran, competirían con los números del negocio,
   que son los que importan en esa pantalla. */
.indicadores { position: relative; flex-shrink: 0; }
.indicadores-tira {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.35rem 0.6rem;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.72rem;
  white-space: nowrap;
  cursor: pointer;
  opacity: 0.75;
}
.indicadores-tira:hover { opacity: 1; background: color-mix(in srgb, var(--text) 6%, transparent); }
.indicador b { font-weight: 700; margin-right: 0.22rem; letter-spacing: 0.02em; }
.indicador { font-variant-numeric: tabular-nums; }
.indicadores-panel {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 300;
  min-width: 250px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.22);
  overflow: hidden;
}
.indicadores-panel[hidden] { display: none; }
.indicadores-cabecera {
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.indicadores-lista { list-style: none; margin: 0; padding: 0.3rem 0; }
.indicadores-lista li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.3rem 0.8rem;
  font-size: 0.82rem;
}
.indicador-rotulo { color: var(--text-muted); }
.indicador-valor { font-weight: 700; font-variant-numeric: tabular-nums; }
/* La fecha del dato, siempre a la vista: el dólar de hoy puede ser el del
   viernes, y usarlo creyéndolo de hoy sería el único error caro posible. */
.indicador-fecha { color: var(--text-muted); font-size: 0.7rem; min-width: 44px; text-align: right; }
.indicadores-pie {
  margin: 0;
  padding: 0.5rem 0.8rem 0.6rem;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 0.7rem;
}
body.con-fondo .indicadores-panel { background: color-mix(in srgb, var(--card-bg) 92%, transparent); backdrop-filter: blur(10px); }
/* En pantalla angosta la tira sobra: la franja ya va apretada con el buscador. */
@media (max-width: 900px) { .indicadores { display: none; } }

/* ---------- El buzón: la campanita de la franja del buscador ----------
   Un recuadro chico, no una pantalla: se abre, se mira de reojo y se cierra.
   Lo que alguien te escribió va primero; lo que se vence, después. */
.buzon { position: relative; flex-shrink: 0; }
.buzon-boton {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--card-bg);
  color: var(--text-muted);
  cursor: pointer;
}
.buzon-boton:hover { color: var(--primary); border-color: var(--primary); }
.buzon-boton .nav-icono { width: 19px; height: 19px; }
/* El número de lo que no has visto: rojo, porque es lo único de la franja
   que pide que hagas algo ahora. */
.buzon-cuenta {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: #d94f4f;
  color: #ffffff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.buzon-cuenta[hidden] { display: none; }
.buzon-panel {
  position: absolute;
  /* Pegado a la campanita: el desplegable sale de ella, así que se toca con
     su borde de abajo y se alinea con su borde derecho. */
  top: 100%;
  right: 0;
  z-index: 300;
  width: min(360px, calc(100vw - 2rem));
  max-height: 70vh;
  overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.22);
}
.buzon-panel[hidden] { display: none; }
.buzon-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  position: sticky;
  top: 0;
  background: var(--card-bg);
}
.buzon-cerrar {
  border: 0;
  background: none;
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.buzon-cerrar:hover { color: var(--text); }
.buzon-item {
  display: flex;
  gap: 0.6rem;
  padding: 0.65rem 0.8rem;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
}
.buzon-item:last-child { border-bottom: 0; }
.buzon-item:hover { background: var(--surface-2); }
/* Lo que llegó desde que no miras, marcado al canto. */
.buzon-item.nuevo { background: color-mix(in srgb, var(--primary) 9%, transparent); }
.buzon-item.nuevo::before {
  content: "";
  width: 3px;
  margin: -0.65rem 0 -0.65rem -0.8rem;
  background: var(--primary);
}
.buzon-item.urgente .buzon-texto { color: #d94f4f; font-weight: 600; }
.buzon-icono { flex-shrink: 0; font-size: 1rem; line-height: 1.4; }
.buzon-cuerpo { display: grid; gap: 0.15rem; min-width: 0; font-size: 0.82rem; }
.buzon-cuerpo b { font-weight: 700; }
.buzon-texto {
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.buzon-cuando { color: var(--text-muted); font-size: 0.72rem; }
.buzon-vacio { margin: 0; padding: 1.4rem 0.8rem; text-align: center; color: var(--text-muted); font-size: 0.85rem; }
/* Con un fondo puesto, el recuadro se comporta como las tarjetas: deja pasar
   un punto de imagen, difuminada, sin que el texto pierda contraste. */
body.con-fondo .buzon-panel,
body.con-fondo .buzon-cabecera,
body.con-fondo .buzon-boton {
  background: color-mix(in srgb, var(--card-bg) 92%, transparent);
  backdrop-filter: blur(10px);
}

/* La lista que se abre al escribir «@»: nombrar a alguien sin tener que
   acordarse de cómo se escribe su apellido. */
.menciones-lista {
  position: absolute;
  z-index: 400;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.2);
  overflow: hidden;
}
.mencion-op {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  width: 100%;
  padding: 0.45rem 0.7rem;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}
.mencion-op span { color: var(--text-muted); font-size: 0.72rem; }
.mencion-op.marcado, .mencion-op:hover { background: var(--surface-2); }

/* El @ dentro de un comentario ya escrito: se lee como lo que es, un llamado
   a alguien, sin parecer un enlace a otra parte. */
.mencion {
  color: var(--primary);
  font-weight: 600;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-radius: 4px;
  padding: 0 3px;
}

/* Vista previa de la foto de perfil: el círculo muestra exactamente el trozo
   que se va a guardar, y debajo están el giro y el acercamiento. Es el mismo
   gesto de cualquier teléfono, así que no necesita instrucciones. */
.foto-editor { margin: 0.7rem 0; display: grid; gap: 0.5rem; justify-items: start; }
.foto-editor[hidden] { display: none; }
.foto-marco {
  position: relative;
  width: 190px;
  height: 190px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-2);
  border: 2px solid var(--border);
  cursor: grab;
  touch-action: none;   /* el arrastre es para encuadrar, no para desplazar la página */
  user-select: none;
}
.foto-marco:active { cursor: grabbing; }
.foto-marco img { position: absolute; max-width: none; transform-origin: center; }
.foto-controles { display: flex; align-items: center; gap: 0.5rem; width: 190px; }
.foto-boton {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.foto-boton:hover { border-color: var(--primary); color: var(--primary); }
.foto-controles input[type="range"] { flex: 1; min-width: 0; accent-color: var(--primary); }
.foto-ayuda { margin: 0; max-width: 220px; }

/* Los avatares para elegir: redondos y chicos, como se van a ver después al
   lado de un nombre. En una fila entran muchos, así que la galería completa
   se abarca de una mirada sin tener que desplazarse. */
.avatares-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
  gap: 0.5rem;
  margin-top: 0.6rem;
}
.avatar-opcion {
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  line-height: 0;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.avatar-opcion img { width: 100%; aspect-ratio: 1; border-radius: 50%; display: block; }
.avatar-opcion:hover { transform: scale(1.08); border-color: var(--primary); }
.avatar-opcion:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.avatar-opcion.puesto { border-color: var(--primary); box-shadow: 0 0 0 2px var(--card-bg); }

/* ---------- Layout: sidebar + contenido ---------- */

.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  /* La barra manda sobre el contenido: de ella salen los desplegables. */
  z-index: 150;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  padding: 1.1rem 0.7rem;
}

.sidebar-brand {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0 0.35rem 0.9rem;
  margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--sidebar-border);
}

.sidebar-brand-row { display: flex; align-items: center; gap: 0.65rem; }

.sidebar-brand-mark { flex-shrink: 0; }

.sidebar-brand-text { line-height: 1.15; }
.sidebar-brand-name { font-weight: 700; font-size: 1.05rem; color: #ffffff; letter-spacing: 0.02em; }
.sidebar-brand-tag { font-size: 0.68rem; color: var(--primary); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }

.sidebar-brand-client {
  font-size: 0.66rem;
  color: var(--sidebar-text);
  opacity: 0.65;
  line-height: 1.3;
}

/* Ajuste de sí o no, con un interruptor como el de cualquier configuración:
   pulsarlo guarda al tiro, no hay botón de "Guardar" aparte. */
.ajuste-interruptor {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
}
.ajuste-texto { display: grid; gap: 0.25rem; max-width: 60ch; }
.ajuste-texto strong { font-size: 0.92rem; }
.ajuste-texto span { font-size: 0.8rem; color: var(--text-muted); }
.interruptor {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--border);
  cursor: pointer;
  transition: background 0.2s ease;
}
.interruptor-bola {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.2s ease;
}
.interruptor.encendido { background: var(--primary); }
.interruptor.encendido .interruptor-bola { transform: translateX(20px); }
.interruptor:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }

/* La fila de logos es el enlace al inicio: sin subrayado ni color de enlace,
   y con un leve cambio al acercarse para que se note que se puede pulsar. */
a.sidebar-brand-row {
  text-decoration: none;
  color: inherit;
  border-radius: 8px;
  transition: opacity 0.15s ease;
}
a.sidebar-brand-row:hover { opacity: 0.85; }
a.sidebar-brand-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.sidebar-brand-divider { width: 1px; height: 32px; background: var(--sidebar-border); flex-shrink: 0; }

.sidebar-brand-client-logo {
  background: #ffffff;
  border-radius: 6px;
  padding: 5px 8px;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.sidebar-brand-client-logo img { height: 28px; width: auto; display: block; }

.login-brand-row { justify-content: center; margin-bottom: 0.5rem; }
.login-brand-row .sidebar-brand-name, .login-brand-row .sidebar-brand-tag { color: var(--text); }
.login-brand-row .sidebar-brand-tag { color: var(--primary); }
.login-brand-row .sidebar-brand-mark img { height: 48px; width: auto; }
.login-brand-row .sidebar-brand-divider { height: 48px; }
.login-brand-row .sidebar-brand-client-logo img { height: 48px; }

.sidebar nav { display: flex; flex-direction: column; gap: 0.15rem; }

.sidebar nav a {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.6rem;
  border-radius: 8px;
  color: var(--sidebar-text);
  text-decoration: none;
  font-size: 0.84rem;
}

.nav-icono {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  opacity: 0.75;
}
.sidebar nav a.active .nav-icono { opacity: 1; color: var(--primary); }
.sidebar nav a > span { flex: 1; min-width: 0; }

.sidebar nav a:hover { background: rgba(255, 255, 255, 0.05); color: #ffffff; }

.sidebar nav a.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-text-active);
  font-weight: 600;
}


/* Ítem de menú con submenú: se despliega al pasar el cursor o al enfocar con
   teclado. Cae hacia abajo dentro del ancho de la barra, porque el sidebar
   recorta lo que se sale por el costado. */
.nav-con-submenu { position: relative; }

.nav-con-submenu > a::after {
  content: "›";
  margin-left: auto;
  font-size: 1rem;
  line-height: 1;
  opacity: 0.55;
  transition: opacity 0.15s ease;
}
.nav-con-submenu:hover > a::after,
.nav-con-submenu:focus-within > a::after { opacity: 1; }
/* "Protección de datos" cabe junto a la flecha, pero el navegador lo partía en
   dos líneas y el ítem quedaba más alto que el resto. */
.sidebar nav .nav-con-submenu > a > span { white-space: nowrap; }

.nav-submenu {
  /* Fija, no absoluta: el sidebar recorta lo que se sale por el costado, y así
     el desplegable puede abrirse hacia el lado. La posición la calcula el JS
     de base.html al pasar el cursor. */
  position: fixed;
  top: 0;
  left: 0;
  min-width: 190px;
  /* Por encima de todo el contenido: es un menú, y un menú que queda debajo de
     una tarjeta no sirve de nada. Antes estaba en 40, por debajo de la barra
     superior y de los anillos del dashboard. */
  z-index: 200;
  /* Sin margen: el submenú toca el ítem, así el cursor no cruza un hueco
     donde se perdería el hover. El aire va en el padding. */
  padding: 0.25rem;
  border-radius: 8px;
  background: var(--sidebar-active-bg);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-6px);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.35s;
}
.nav-con-submenu:hover .nav-submenu,
.nav-con-submenu:focus-within .nav-submenu {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s;
}

.sidebar nav .nav-submenu a { font-size: 0.84rem; padding: 0.5rem 0.6rem; }
.sidebar nav .nav-submenu .nav-icono { width: 15px; height: 15px; }

/* En pantalla angosta la barra es horizontal y con scroll lateral, que
   recortaría el desplegable: ahí los dos destinos se muestran en línea. */
@media (max-width: 900px) {
  .nav-con-submenu { display: contents; }
  .nav-con-submenu > a { display: none; }
  .nav-submenu {
    display: contents;
    position: static;
    background: none;
    box-shadow: none;
    padding: 0;
    /* Aquí no hay desplegable: los enlaces van siempre visibles en la barra. */
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }
}

.sidebar-footer { margin-top: auto; padding-top: 0.7rem; }

/* Jefe comercial y subgerente en la ficha: una lista, y debajo el campo para
   escribir a alguien que todavía no está en ella. */
.campo-persona { display: grid; gap: 0.35rem; }

/* ---------- Barra compacta: solo iconos, se abre al pasar el cursor ----------
   En el tablero el ancho es lo que falta, y la barra se lleva 240 px fijos
   para repetir nueve palabras que uno ya se sabe. Encogida deja los iconos y
   devuelve ese ancho a las columnas; al acercar el cursor se abre entera, con
   los nombres, y se vuelve a cerrar sola al salir.

   Fuera del flujo a propósito: si al abrirse empujara el contenido, el tablero
   se reacomodaría cada vez que el cursor roza el borde. Así pasa por encima y
   nada se mueve debajo. El teléfono no entra aquí: allí la barra es horizontal
   y no hay cursor que la abra. */
@media (min-width: 901px) {
  .barra-compacta .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: var(--sidebar-mini);
    padding: 1.1rem 0.45rem;
    overflow-x: hidden;
    transition: width 0.16s ease, padding 0.16s ease, box-shadow 0.16s ease;
  }
  /* El hueco que deja la barra al salir del flujo. */
  .barra-compacta .sidebar ~ .content-area { margin-left: var(--sidebar-mini); }

  .barra-compacta .sidebar:hover,
  .barra-compacta .sidebar:focus-within {
    width: var(--sidebar-width);
    padding: 1.1rem 0.7rem;
    box-shadow: 0 0 28px rgba(0, 0, 0, 0.4);
  }

  /* Encogida: queda el icono y nada más. Se oculta con display y no con
     opacidad para que ninguna palabra asome cortada por el borde. */
  .barra-compacta .sidebar:not(:hover):not(:focus-within) nav a > span,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .sidebar-brand-text,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .sidebar-brand-divider,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .sidebar-brand-client-logo,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .nav-notas-cuenta,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .notas-hueco,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .user-info,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .user-flecha {
    display: none;
  }
  .barra-compacta .sidebar:not(:hover):not(:focus-within) nav a,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .user-boton,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .barra-encoger {
    justify-content: center;
    padding-left: 0.35rem;
    padding-right: 0.35rem;
  }
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .barra-encoger { margin-right: auto; }
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .sidebar-brand-row { justify-content: center; }
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .nav-con-submenu > a::after { display: none; }
}

/* El botón que la encoge y la vuelve a abrir, al pie del propio menú: es donde
   uno va a buscar cómo deshacer lo que el menú hizo. Solo el icono —la flecha
   dice por sí sola hacia dónde va la barra— para no gastar una línea entera en
   un texto que se lee una vez. */
.barra-encoger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  /* Pegado al borde derecho del menú, en la misma vertical que la flecha del
     desplegable del nombre: los dos controles del pie quedan en una columna. */
  margin-left: auto;
  margin-bottom: 0.3rem;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--sidebar-text);
  font: inherit;
  cursor: pointer;
  opacity: 0.55;
}
.barra-encoger:hover { background: rgba(255, 255, 255, 0.07); color: #ffffff; opacity: 1; }
.barra-encoger:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.barra-encoger svg { width: 17px; height: 17px; flex-shrink: 0; }
/* La flecha apunta a donde va a quedar la barra: hacia adentro para cerrarla,
   hacia afuera para abrirla. */
.barra-compacta .barra-encoger svg { transform: scaleX(-1); }
/* En el teléfono la barra es horizontal: no hay nada que encoger. */
@media (max-width: 900px) { .barra-encoger { display: none; } }

/* El mismo interruptor en el borde de afuera del menú, a media altura: una
   pestaña que monta sobre la línea entre el menú y el contenido. Discreta
   hasta que se le acerca el cursor, para no competir con lo que uno está
   mirando. Va fuera de la barra a propósito: así apuntarle no la despliega. */
.barra-borde {
  position: fixed;
  top: 50%;
  left: var(--sidebar-width);
  transform: translate(-50%, -50%);
  z-index: 160;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 46px;
  padding: 0;
  border: 1px solid var(--sidebar-border);
  border-radius: 999px;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.16s ease, left 0.16s ease, background 0.16s ease;
}
.barra-borde:hover { opacity: 1; background: var(--primary); color: #ffffff; }
.barra-borde:focus-visible { opacity: 1; outline: 2px solid var(--primary); outline-offset: 2px; }
.barra-borde svg { width: 14px; height: 14px; }
/* Encogida, la pestaña sigue al borde nuevo y la flecha se da vuelta. */
.barra-compacta .barra-borde { left: var(--sidebar-mini); }
.barra-compacta .barra-borde svg { transform: scaleX(-1); }
/* Mientras el menú encogido está abierto por el cursor, la pestaña se quita
   de en medio: si no, quedaría encima de los nombres que uno fue a leer. */
.barra-compacta .sidebar:hover ~ .barra-borde,
.barra-compacta .sidebar:focus-within ~ .barra-borde {
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 900px) { .barra-borde { display: none; } }

.content-area { flex: 1; min-width: 0; }

.topbar {
  background: transparent;
  /* Ajustado para que el contenido arranque más arriba: la franja del buscador
     se llevaba un dedo de pantalla en cada visita. */
  padding: 0.35rem 1.75rem 0;
  /* Sobre la nube de Hunting: las tarjetas pasan por detrás del buscador,
     incluso la que se agranda al pasarle el cursor (que sube a z-index 50). */
  position: relative;
  z-index: 60;
}

.topbar-inner {
  display: grid;
  grid-template-columns: 1fr minmax(260px, 420px) 1fr;
  align-items: center;
  gap: 1rem;
}

.topbar-spacer { min-width: 0; }

.topbar-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  justify-self: end;
}

.global-search {
  position: relative;
  justify-self: center;
  width: 100%;
  max-width: 420px;
}

.global-search-icon {
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.85rem;
  opacity: 0.6;
  pointer-events: none;
}

.global-search input {
  width: 100%;
  padding: 0.5rem 0.8rem 0.5rem 2.1rem;
  border-radius: 999px;
  background: var(--card-bg);
  font-size: 0.88rem;
  /* El contorno en el turquesa de la marca: lo justo para encontrarlo de
     inmediato, sin que compita con el contenido. */
  border: 1.5px solid var(--primary);
}
.global-search input:hover { border-color: var(--primary-dark); }
.global-search input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.global-search:focus-within .global-search-icon { opacity: 1; }

.global-search-results {
  display: none;
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  max-height: 360px;
  overflow-y: auto;
  z-index: 50;
}

.global-search-results.abierto { display: block; }

.global-search-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.9rem;
  text-decoration: none;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}
.global-search-item:last-child { border-bottom: none; }
.global-search-item:hover { background: var(--surface-2); }

.global-search-item-info {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.global-search-item-info strong { font-size: 0.88rem; }
.global-search-item-meta { font-size: 0.76rem; color: var(--text-muted); }
.global-search-inactivo { color: var(--text-muted); font-weight: 400; font-size: 0.78rem; }

.global-search-vacio {
  padding: 0.8rem 0.9rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

@media (max-width: 700px) {
  .topbar-inner { grid-template-columns: 1fr; row-gap: 0.75rem; }
  .topbar-spacer { display: none; }
  .global-search { max-width: none; justify-self: stretch; }
  .topbar-controls { justify-self: end; }
}

.espacio-pill { font-size: 0.82rem; color: var(--text-muted); }
.espacio-pill strong { color: var(--text); font-weight: 600; }

.user-box {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-size: 0.88rem;
  color: var(--text-muted);
  background: var(--card-bg);
  border: 1px solid var(--border);
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
}
.theme-toggle:hover { color: var(--text); }

.logout { color: var(--danger); text-decoration: none; }

/* El contenido usa la pantalla entera, con el menú abierto o encogido. Antes
   estaba topado en 1500 px y en un monitor ancho quedaba una franja en blanco
   a la derecha mientras el tablero se cortaba por la izquierda. */
.container {
  max-width: none;
  /* El título de cada pantalla arranca justo debajo del buscador: el aire de
     antes empujaba todo y obligaba a bajar para ver lo primero. */
  padding: 0.35rem 1.75rem 3rem;
}

/* Los títulos mandan en la pantalla: dicen dónde está uno de un vistazo, sin
   tener que leer. Por eso pesan más que el texto y llevan la marca turquesa
   del portal: una barra corta en el h1 y una línea bajo el h2. */
h1 {
  font-size: 1.72rem;
  margin-bottom: 0.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
h1::before {
  content: "";
  width: 5px;
  align-self: stretch;
  min-height: 1.3em;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--primary), var(--primary-dark));
  flex-shrink: 0;
}
h2 {
  font-size: 1.16rem;
  margin: 0 0 0.9rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  padding-bottom: 0.35rem;
  border-bottom: 2px solid var(--border);
  position: relative;
}
/* El trozo turquesa del subrayado: marca dónde empieza la sección. */
h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 34px;
  height: 2px;
  background: var(--primary);
}
h3 { font-size: 0.95rem; font-weight: 700; margin: 0 0 0.5rem; }
/* El título de una tarjeta que ya vive dentro de un marco no necesita la
   barra: ahí basta el subrayado. */
.card h1::before, .login-card h1::before, .flash h1::before { display: none; }

.seccion-titulo {
  margin: 2rem 0 1rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.subtitle { color: var(--text-muted); margin-top: 0; margin-bottom: 1.25rem; }

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
  box-shadow: var(--shadow-card);
}

.card-header-row { display: flex; justify-content: space-between; align-items: center; }

.base-card {
  display: block;
  position: relative;
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.base-card:hover { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 8px 16px rgba(0, 0, 0, 0.12); }
.base-card h2 { margin-bottom: 0.3rem; }
.base-card-todas { border-color: var(--primary); }
/* El enlace ocupa la tarjeta entera; la estrella va encima, con su propio clic. */
.base-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  padding-right: 1.8rem;
}

/* Las dos acciones de la tarjeta —renombrar y favorita— juntas arriba a la
   derecha, fuera del enlace para que no abran la base al pulsarlas. */
.base-acciones {
  position: absolute;
  top: 0.5rem;
  right: 0.55rem;
  z-index: 2;
  display: flex;
  gap: 0.1rem;
}
.base-lapiz {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.base-lapiz:hover { opacity: 1; color: var(--primary); background: var(--surface-2); }

/* Estrella de favoritas: contorno cuando no lo es, rellena cuando sí. */
.base-estrella {
  position: static;
  z-index: 2;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.base-estrella svg { width: 17px; height: 17px; fill: none; }
.base-estrella:hover { opacity: 1; color: var(--warn-text, #d99e2b); background: var(--surface-2); }
.base-estrella:disabled { cursor: progress; }

/* Lo que decide si entrar a una base es cuántas quedan por llamar, así que esa
   cifra va grande y primero. El total y las fechas, en letra chica: son
   contexto, no la pregunta. */
.base-cifra {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  margin: 0.35rem 0 0.4rem;
}
.base-cifra b { font-size: 1.6rem; font-weight: 600; line-height: 1; }
.base-cifra em { font-style: normal; font-size: 0.78rem; color: var(--text-muted); }
.base-cifra-resto { margin-left: auto; font-size: 0.72rem; color: var(--text-muted); }

/* Cuánto se lleva avanzado de la base, de un vistazo. */
.base-barra {
  height: 4px;
  margin-bottom: 0.5rem;
  border-radius: 999px;
  background: var(--hueco-bg);
  overflow: hidden;
}
.base-barra span { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.base-fecha { font-size: 0.7rem; color: var(--text-muted); }

/* La base que te repartió la jefatura: va primero y se nota. Buscarla entre
   veinte tarjetas iguales es lo que hace que no se llame. */
.base-asignada { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary) inset; }
.base-cinta {
  position: absolute;
  top: -0.6rem;
  left: 0.9rem;
  z-index: 2;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--primary);
  color: #ffffff;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* El botón con el que se encadena una llamada tras otra. Más grande que el de
   al lado porque es el que se pulsa veinte veces seguidas. */
.btn-siguiente {
  padding: 0.5rem 1rem;
  font-weight: 600;
}
.btn-siguiente span { margin-left: 0.2rem; }

/* Los títulos que separan «Asignado por jefatura» del resto de las bases. */
.bases-seccion {
  margin: 0.4rem 0 0.6rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Cargarle empresas a un vendedor desde su propia tarjeta. */
.base-cargar {
  display: inline-block;
  margin-top: 0.55rem;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
}
.base-cargar:hover { text-decoration: underline; }

.base-favorita { border-color: #d99e2b; }
.base-favorita .base-estrella {
  opacity: 1;
  color: #d99e2b;
  transform: scale(1.05);
}
.base-favorita .base-estrella svg { fill: #d99e2b; }
.base-favorita h2::after {
  content: 'Favorita';
  margin-left: 0.5rem;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #d99e2b;
  border: 1px solid rgba(217, 158, 43, 0.5);
  vertical-align: middle;
}

.flash {
  padding: 0.7rem 1rem;
  border-radius: var(--radius);
  margin-bottom: 1rem;
  font-size: 0.92rem;
}

.flash-ok { background: var(--ok-bg); color: var(--ok-text); }
.flash-error { background: var(--error-bg); color: var(--error-text); }

label {
  display: flex;
  flex-direction: column;
  font-size: 0.85rem;
  color: var(--text-muted);
  gap: 0.3rem;
  font-weight: 500;
}

input, select, textarea {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  background: var(--card-bg);
}

textarea { resize: vertical; width: 100%; }

input:focus, select:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

.btn {
  display: inline-block;
  border: none;
  border-radius: 7px;
  padding: 0.55rem 1.1rem;
  font-size: 0.92rem;
  font-family: inherit;
  line-height: 1.2;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  vertical-align: middle;
  box-sizing: border-box;
}

.btn-primary { background: var(--primary); color: #ffffff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-secondary { background: var(--surface-2); color: var(--text); }
.btn-danger { background: var(--error-bg); color: var(--error-text); }
/* Registrar algo ya hecho: verde, el mismo color con que el portal marca lo
   cumplido. Distinto del turquesa de "agendar", que es lo que queda por hacer. */
.btn-hecha { background: var(--good); color: #ffffff; }
.btn-hecha:hover { filter: brightness(0.92); }
/* Cuando el dato del documento no coincide con el de la ficha. No es un error
   —la razón social puede ser distinta del nombre comercial— pero hay que
   verlo, porque el documento sale con el de acá. */
.aviso-distinto {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--warning, #e0923d);
}
.aviso-distinto b { color: var(--text); }
.enlace-boton {
  padding: 0;
  border: 0;
  background: none;
  color: var(--primary);
  font-size: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* Bajar un formato en blanco: con el color de la casa, porque es el paso que
   hay que dar primero y en gris se perdía. Va sin relleno para no competir con
   el botón que ejecuta la acción, que sí va sólido. */
.btn-formato {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  border: 1.5px solid var(--primary);
  font-weight: 700;
}
.btn-formato:hover,
.btn-formato:focus-visible { background: var(--primary); color: #ffffff; }

.btn-block { width: 100%; }
.btn-small { padding: 0.3rem 0.7rem; font-size: 0.82rem; }

.date-picker {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}

.prospecto-accion-destacada {
  border: 1px solid var(--good);
  background: var(--ok-bg);
}
.prospecto-accion-destacada h2,
.prospecto-accion-destacada .subtitle { color: var(--ok-text); }

/* Matriz de cumplimiento: ejecutivos en filas, meses en columnas. */
.tabla-matriz { font-size: 0.82rem; white-space: nowrap; }
.tabla-matriz th, .tabla-matriz td { text-align: center; padding: 0.45rem 0.5rem; }
.tabla-matriz th small { font-weight: 400; opacity: 0.6; font-size: 0.72em; }
.tabla-matriz .matriz-nombre { text-align: left; white-space: nowrap; }

.tabla-matriz .matriz-sin-ingreso { background: var(--surface-2); }
.tabla-matriz .matriz-en-curso { font-style: italic; opacity: 0.75; }
.tabla-matriz .matriz-otros { font-style: italic; color: var(--text-muted); }
.tabla-matriz .matriz-agregado { font-weight: 600; background: var(--surface-2); }
.tabla-matriz .matriz-total th { border-top: 2px solid var(--border); background: var(--surface-2); }

/* Conmutador de tipo de gráfico. */
.grafico-tipo-toggle { display: flex; gap: 0.35rem; }
.grafico-tipo-toggle button.activo {
  background: var(--teal-soft);
  border-color: var(--teal);
  color: var(--ok-text);
  font-weight: 600;
}

.celda-activa {
  background: var(--ok-bg);
  color: var(--ok-text);
  font-weight: 700;
}

/* Desglose de las líneas bajo el chip del total, en letra pequeña. */
.lineas-desglose {
  font-size: 0.62rem;
  color: var(--text-muted);
  margin-top: -0.15rem;
  line-height: 1.2;
}

/* Clasificación de líneas nuevas/BAM: se prende y apaga desde la tarjeta del
   tablero, igual que los chips de portabilidad. Encendido = crecimiento (suma
   al mix de captación); apagado = cliente nuevo. */
.chip-crecimiento {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.14rem 0.4rem;
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  cursor: pointer;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  white-space: nowrap;
  flex: 0 0 auto;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.chip-crecimiento:hover { border-color: var(--teal); color: var(--teal); }
.chip-crecimiento-activo {
  border: 1px solid var(--teal);
  background: var(--teal-soft);
  color: var(--ok-text);
}
.chip-crecimiento-activo:hover { color: var(--ok-text); }

/* «CN · C»: las dos opciones juntas, la elegida encendida y con un halo. */
.chip-cn-c {
  padding: 0;
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.chip-cn-c:hover { border-color: var(--border); color: inherit; }
.chip-cn-c b {
  padding: 0.13rem 0.42rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}
.chip-cn-c b:hover { color: var(--text); }
.chip-cn-c:not(.chip-crecimiento-activo) .cnc-cn {
  background: #4b8ef0;
  color: #ffffff;
  box-shadow: 0 0 8px rgba(75, 142, 240, 0.75);
}
.chip-cn-c.chip-crecimiento-activo {
  border-color: var(--border);
  background: var(--surface-2);
}
.chip-cn-c.chip-crecimiento-activo .cnc-c {
  background: var(--teal, #00b8a9);
  color: #ffffff;
  box-shadow: 0 0 8px color-mix(in srgb, var(--teal, #00b8a9) 80%, transparent);
}

/* ---------- Foco de cierre: en la mira ----------
   Marca el negocio más propenso a cerrarse. Apagado es una diana gris y tenue
   al costado de la tarjeta, que casi no se ve hasta que uno pasa el cursor.
   Encendido, el borde de la tarjeta gira como un radar en verde agua —el color
   de la marca y el de "va bien"—: llama la atención como oportunidad, no como
   alarma. (El 🔥 ya significa "Urgente" en las etiquetas.) */
.foco-cierre {
  position: absolute;
  top: 3px;
  right: 22px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.35;
  transition: opacity 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.board-card:hover .foco-cierre { opacity: 0.6; }
.foco-cierre:hover { opacity: 1; color: var(--primary); transform: scale(1.15); }
.foco-cierre:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; opacity: 1; }
/* El nombre deja sitio a la diana y al menú de la esquina. */
.board-card-con-foco .empresa { padding-right: 2.3rem; }

.foco-cierre-activo { opacity: 1; color: var(--primary); }
.foco-cierre-activo .diana-centro { animation: diana-latido 1.4s ease-in-out infinite; transform-origin: 12px 12px; }
.foco-cierre-activo svg { filter: drop-shadow(0 0 3px color-mix(in srgb, var(--primary) 70%, transparent)); }
@keyframes diana-latido {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.45); }
}

/* El radar. Un degradado cónico que gira alrededor del borde; la máscara deja
   ver solo el contorno, así el contenido de la tarjeta no cambia. */
@property --giro-foco {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
.board-card-foco {
  border-color: transparent;
  animation: foco-latido 2s ease-in-out infinite;
}
.board-card-foco::before {
  content: "";
  position: absolute;
  inset: -3px;
  z-index: 1;
  padding: 3px;
  border-radius: 11px;
  pointer-events: none;
  background: conic-gradient(from var(--giro-foco),
    #00e5d0, #00b8a9 18%, rgba(0, 184, 169, 0.12) 42%,
    rgba(0, 184, 169, 0) 62%, rgba(0, 184, 169, 0.35) 82%, #00e5d0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  animation: foco-giro 2.8s linear infinite;
}
@keyframes foco-giro { to { --giro-foco: 360deg; } }

/* Las otras dos luces de la diana. Mismo radar, otros colores. */
.board-card-foco-fuego { animation-name: foco-latido-fuego; }
.board-card-foco-fuego::before {
  background: conic-gradient(from var(--giro-foco),
    #ffe082, #ff6d00 15%, #ff1f1f 32%, rgba(180, 20, 0, 0.15) 50%,
    rgba(255, 61, 0, 0) 62%, rgba(255, 112, 0, 0.45) 82%, #ffe082);
}
.board-card-foco-fuego .foco-cierre-activo { color: #ff3d00; }
.board-card-foco-morado { animation-name: foco-latido-morado; }
.board-card-foco-morado::before {
  background: conic-gradient(from var(--giro-foco),
    #b388ff, #7c4dff 18%, #3d5afe 34%, rgba(61, 90, 254, 0.12) 50%,
    rgba(124, 77, 255, 0) 62%, rgba(124, 77, 255, 0.4) 82%, #b388ff);
}
.board-card-foco-morado .foco-cierre-activo { color: #7c4dff; }
@keyframes foco-latido-fuego {
  0%, 100% { box-shadow: 0 0 12px -3px rgba(255, 61, 0, 0.55), 0 0 2px rgba(255, 112, 0, 0.5); }
  50%      { box-shadow: 0 0 22px 0 rgba(255, 61, 0, 0.7), 0 0 5px rgba(255, 171, 0, 0.6); }
}
@keyframes foco-latido-morado {
  0%, 100% { box-shadow: 0 0 12px -3px rgba(124, 77, 255, 0.55), 0 0 2px rgba(61, 90, 254, 0.5); }
  50%      { box-shadow: 0 0 22px 0 rgba(124, 77, 255, 0.7), 0 0 5px rgba(179, 136, 255, 0.6); }
}
@keyframes foco-latido {
  0%, 100% { box-shadow: 0 0 12px -3px rgba(0, 229, 208, 0.5), 0 0 2px rgba(0, 184, 169, 0.45); }
  50%      { box-shadow: 0 0 22px 0 rgba(0, 229, 208, 0.62), 0 0 5px rgba(0, 184, 169, 0.55); }
}

/* En un equipo modesto, o para quien pidió menos movimiento, la marca queda
   quieta: el borde sigue encendido, pero no gira ni late. */
.equipo-modesto .board-card-foco,
.equipo-modesto .board-card-foco::before,
.equipo-modesto .foco-cierre-activo .diana-centro { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .board-card-foco,
  .board-card-foco::before,
  .foco-cierre-activo .diana-centro { animation: none; }
}

.alerta-link {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--warn);
  text-underline-offset: 2px;
}
.alerta-link:hover { color: var(--warn); }

.filtro-sin-movimiento-toggle {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.65rem;
  border-radius: 999px;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.filtro-sin-movimiento-toggle input { width: 13px; height: 13px; }
.filtro-sin-movimiento-toggle:hover { border-color: var(--warn); color: var(--warn); }
.filtro-sin-movimiento-toggle input { accent-color: var(--warn); cursor: pointer; }
.filtro-sin-movimiento-toggle:has(input:checked) {
  border: 1px solid var(--warn);
  background: rgba(230, 162, 60, 0.12);
  color: var(--warn);
}

.tareas-indicadores {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.indicador-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--text);
  text-decoration: none;
  /* El rótulo va chico y el número grande: lo que se lee de un vistazo es la
     cifra, y el nombre de la lista solo hace falta para saber cuál es. */
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: var(--shadow-card);
}
.indicador-chip strong { font-size: 1.05rem; }
.tareas-ver-mas { margin: 0.8rem 0 0; font-size: 0.8rem; color: var(--text-muted); }
.tareas-ver-mas a { color: var(--primary); font-weight: 600; text-decoration: none; margin-left: 0.3rem; }
.tareas-ver-mas a:hover { text-decoration: underline; }
.indicador-chip:hover { border-color: var(--primary); }
.indicador-vencida strong { color: var(--danger); }
.indicador-hoy strong { color: var(--warn); }
.indicador-proxima strong { color: var(--stage-10); }
.indicador-folio strong { color: var(--text); }

.tareas-filtros {
  display: flex;
  align-items: flex-end;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}
.tareas-filtros select, .tareas-filtros input { min-width: 140px; }

.tarea-acciones-botones { display: flex; flex-wrap: nowrap; gap: 0.4rem; }
.tarea-acciones-botones .btn { white-space: nowrap; }
.tarea-realizada-marca { color: var(--good); font-size: 0.78rem; font-weight: 600; white-space: nowrap; }

/* Tabla de Tareas compacta: menos padding, texto puede envolver (Empresa/Nota) para
   que el Estado y la Acción se vean sin desplazarse hacia el lado. */
.tabla-tareas-compacta { font-size: 0.8rem; }
.tabla-tareas-compacta th, .tabla-tareas-compacta td { padding: 0.4rem 0.5rem; white-space: normal; }
.tabla-tareas-compacta th:first-child, .tabla-tareas-compacta td:first-child { white-space: nowrap; }
.tabla-tareas-compacta .badge { font-size: 0.66rem; padding: 0.15rem 0.4rem; white-space: nowrap; }
.tabla-tareas-compacta .tarea-acciones-botones .btn { font-size: 0.68rem; padding: 0.25rem 0.5rem; }
.tabla-tareas-compacta .tarea-nota { max-width: 220px; color: var(--text-muted); }

.form-inline {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  flex-wrap: wrap;
}

.form-inline-tight {
  display: flex;
  gap: 0.4rem;
}

.form-inline-tight input { width: 150px; padding: 0.35rem 0.5rem; }

.form-inline-tight-stack { flex-direction: column; align-items: flex-start; }
.form-inline-tight-stack input { width: 170px; }

.form-gestion .grid-items {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.item-field input { font-size: 1.1rem; padding: 0.6rem; }

/* Formulario de negocio: filas de 2 columnas en escritorio, 1 en móvil. */
.form-negocio-fila {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
.form-negocio-fila:last-child { margin-bottom: 0; }

/* Dos campos que comparten una celda de la grilla (el segundo puede ocultarse
   sin dejar un hueco, como el tramo de Gran Empresa). */
.campo-par { display: flex; gap: 1rem; }
.campo-par > label { flex: 1; min-width: 0; }

/* Fila de campos cortos (cantidades y selectores breves): columnas parejas que
   ocupan solo lo necesario y se reacomodan solas al angostar la ventana. */
.form-negocio-compacta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(155px, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.form-negocio-compacta:last-child { margin-bottom: 0; }

@media (max-width: 700px) {
  .form-negocio-fila { grid-template-columns: 1fr; }
  .campo-par { flex-direction: column; gap: 1rem; }
}

/* Barra de acciones del formulario de negocio: queda pegada arriba mientras se
   baja por el formulario, para que Guardar esté siempre a la vista. */
.form-barra-acciones {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  background: var(--bg);
  padding: 0.75rem 0;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.form-barra-acciones h1 { margin: 0; }
.form-barra-botones { display: flex; gap: 0.5rem; align-items: center; flex-shrink: 0; }

/* Zona para soltar archivos: al soltar se sube sola, sin apretar botón. */
.zona-soltar {
  margin-top: 0.6rem;
  padding: 1.1rem;
  border: 2px dashed var(--border);
  border-radius: 10px;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.zona-soltar:hover { border-color: var(--primary); color: var(--text); }
.zona-soltar-activa {
  border-color: var(--primary);
  background: var(--teal-soft);
  color: var(--ok-text);
}
.zona-soltar-estado { display: block; margin-top: 0.35rem; font-size: 0.8rem; }
.zona-soltar-error { color: var(--danger); }

/* Casilla dentro de la grilla de campos: la marca va bajo la etiqueta, para
   que quede alineada con los campos numéricos de al lado. */
.campo-casilla { display: flex; flex-direction: column; gap: 0.35rem; }
.campo-casilla input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 0.5rem 0 0;
  accent-color: var(--primary);
  cursor: pointer;
}

.card-principal {
  border-left: 4px solid var(--primary);
}
.card-principal label { font-size: 0.92rem; }
.card-principal input, .card-principal select { font-size: 1.05rem; padding: 0.65rem 0.7rem; }

/* Próximas acciones: chips que se despliegan para mostrar su fecha/hora. */
.accion-chips-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin-bottom: 1rem;
}
@media (max-width: 700px) {
  .accion-chips-grid { grid-template-columns: 1fr; }
}

.accion-chip {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-2);
}
.accion-chip summary {
  list-style: none;
  cursor: pointer;
  padding: 0.65rem 0.9rem;
  font-weight: 600;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--text);
}
.accion-chip summary::-webkit-details-marker { display: none; }
.accion-chip summary::after {
  content: '+';
  font-weight: 700;
  color: var(--text-muted);
}
.accion-chip[open] summary::after { content: '−'; }
.accion-chip[open] summary { border-bottom: 1px solid var(--border); background: var(--card-bg); }
.accion-chip-body { padding: 0.75rem 0.9rem; background: var(--card-bg); }
.accion-chip-body label { margin: 0; }
.accion-chip-body input { width: 100%; }

.folio-alerta-box {
  background: var(--notice-bg);
  border: 1px solid var(--notice-border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.folio-alerta-box label { color: var(--notice-text); font-weight: 600; margin: 0; }

/* Vence folio en la ficha: chip plegable, ocupa una sola línea hasta que se abre. */
.folio-chip { border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2); }
.folio-chip summary {
  list-style: none;
  cursor: pointer;
  padding: 0.45rem 0.7rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text);
}
.folio-chip summary::-webkit-details-marker { display: none; }
.folio-chip-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0 0.7rem 0.6rem;
}
.folio-chip-form input { font-size: 0.8rem; padding: 0.35rem 0.45rem; }

.notice {
  background: var(--notice-bg);
  border-color: var(--notice-border);
  color: var(--notice-text);
}

/* Aviso corto de una línea (ej. contacto incompleto): ~35% menos alto que .card. */
.alerta-compacta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.8rem 1rem;
  margin-bottom: 0.9rem;
  font-size: 0.88rem;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.9rem;
  margin-bottom: 1.25rem;
}

.stat-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  text-align: center;
  box-shadow: var(--shadow-card);
}

.stat-value { display: block; font-size: 1.6rem; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.stat-label { display: block; font-size: 0.78rem; color: var(--text-muted); margin-top: 0.2rem; }

.chart-card { padding: 1.5rem; }

/* Los negocios que salieron de Hunting, bajo el gráfico de sus llamadas. */
/* Título de la tarjeta de Hunting con el botón que alterna gráfico y lista. */
.hunting-cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.hunting-alternar {
  flex-shrink: 0;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-family: var(--font);
  font-size: 0.66rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.hunting-alternar strong { color: var(--stage-10); }
.hunting-alternar:hover, .hunting-alternar.abierto { border-color: var(--primary); color: var(--primary); }
/* El gráfico y la lista comparten el mismo espacio: la lista, cuando se abre,
   se pone encima del gráfico y se desplaza por dentro si no cabe. */
.hunting-vista { position: relative; }
.hunting-funnel-panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  background: var(--card-bg);
  padding-right: 0.2rem;
}
.hunting-funnel-panel[hidden] { display: none; }
.hunting-funnel-panel .hunting-funnel-titulo { margin-top: 0; }
.hunting-funnel-titulo { margin: 0.9rem 0 0.4rem; font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.hunting-funnel { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; font-size: 0.8rem; }
.hunting-funnel li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.5rem; }
.hunting-funnel a { color: var(--text); font-weight: 600; text-decoration: none; }
.hunting-funnel a:hover { color: var(--primary); text-decoration: underline; }
.hunting-funnel small { color: var(--text-muted); font-size: 0.7rem; }
.hunting-funnel-etapa {
  font-size: 0.66rem;
  font-weight: 700;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  color: var(--stage-color);
  border: 1px solid var(--stage-color);
  background: color-mix(in srgb, var(--stage-color) 12%, transparent);
}

/* Dos gráficos que se leen juntos van uno al lado del otro: volumen y
   efectividad separados por media pantalla de scroll no se comparan. En el
   teléfono no cabe la pareja, así que vuelven a apilarse. */
.duo-graficos {
  display: grid;
  /* minmax(0, …) y no 1fr a secas: el canvas del gráfico impone un ancho
     mínimo propio y, sin esto, las dos columnas se estiran y desbordan. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}
/* Las dos tarjetas se estiran igual y el gráfico queda abajo, a la misma
   altura en las dos: si cada bajada empuja lo suyo, los ejes se desalinean y
   la comparación —que es todo el punto de ponerlas juntas— se pierde. */
.duo-graficos > .card {
  margin-bottom: 1.25rem;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.duo-graficos > .card > .subtitle { flex: 1; }
.duo-graficos .grafico-barra-compacto { height: 260px; }
@media (max-width: 900px) {
  .duo-graficos { grid-template-columns: 1fr; gap: 0; }
  .duo-graficos > .card { height: auto; }
  .duo-graficos > .card > .subtitle { flex: none; }
  .duo-graficos .grafico-barra-compacto { height: 220px; }
}

.pipeline-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
  align-items: stretch;
}

.pipeline-grid > .card { display: flex; flex-direction: column; min-width: 0; }
.pipeline-grid > .card .grafico-barra-compacto { flex: 1; min-width: 0; }

@media (max-width: 900px) {
  .pipeline-grid { grid-template-columns: 1fr; }
}

.grafico-circular-wrap {
  position: relative;
  width: 100%;
  max-width: 220px;
  height: 220px;
  margin: 0 auto;
}

.grafico-circular-chico {
  /* Un solo tamaño para todos los anillos del dashboard. La leyenda va debajo,
     así que la altura reserva espacio para el anillo más sus etiquetas. */
  max-width: 100%;
  height: 235px;
}

.grafico-barra-compacto {
  position: relative;
  width: 100%;
  height: 200px;
}

.pipeline-grid-mini {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-bottom: 1.25rem;
  align-items: stretch;
}

@media (max-width: 600px) {
  .pipeline-grid-mini { grid-template-columns: 1fr; }
}

.table-wrap { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }

th, td {
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

th { color: var(--text-muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; }

td a, .notice a, .comentarios-lista a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--border);
}
td a:hover, .notice a:hover, .comentarios-lista a:hover { color: var(--primary); }

.login-wrap {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  z-index: 100;
}

.login-card { width: 100%; max-width: 340px; display: flex; flex-direction: column; gap: 1rem; }
.login-card h1 { margin: 0; text-align: center; }
.login-card .subtitle { text-align: center; }

/* Funnel de ventas */

.meta-card { padding: 1.25rem 1.5rem; }

.meta-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.6rem;
}

.meta-numero { font-size: 1.3rem; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.meta-pct { font-size: 0.85rem; font-weight: 600; color: var(--text-muted); }

.meta-barra {
  width: 100%;
  height: 14px;
  background: var(--surface-2);
  border-radius: 999px;
  overflow: hidden;
}

.meta-barra-relleno {
  height: 100%;
  background: var(--primary);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.meta-alertas { margin: 0.75rem 0 0; color: var(--notice-text); font-size: 0.88rem; font-weight: 600; }
.meta-proyeccion { margin: 0.75rem 0 0; color: var(--primary-dark); font-size: 0.88rem; font-weight: 600; }
@media (prefers-color-scheme: dark) { .meta-proyeccion { color: var(--primary); } }
:root[data-theme="dark"] .meta-proyeccion { color: var(--primary); }

.badge {
  display: inline-block;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
  color: #fff;
}

/* Colores de etapa: fijos en ambos temas, cada uno con su propio significado
   (ver guía de marca). El rojo queda reservado para alertas, nunca para una etapa. */
.badge-etapa-0 { background: var(--stage-0); }
.badge-etapa-10 { background: var(--stage-10); }
.badge-etapa-30 { background: var(--stage-30); }
.badge-etapa-50 { background: var(--stage-50); }
.badge-etapa-75 { background: var(--stage-75); }
.badge-etapa-90 { background: var(--stage-90); }
.badge-etapa-100 { background: var(--stage-100); }

.fila-alerta { background: var(--notice-bg); }

.coaching-card { border-left: 4px solid var(--primary); }
.coaching-card.coaching-alerta { border-left-color: var(--warn); background: var(--notice-bg); }

.coaching-card-compacta {
  border-left: 4px solid var(--primary);
  padding: 0.85rem 1.1rem;
}
.coaching-card-compacta.coaching-alerta { border-left-color: var(--warn); background: var(--notice-bg); }
.coaching-card-compacta h2 { font-size: 0.95rem; margin-bottom: 0.4rem; }
.coaching-card-compacta p { margin: 0 0 0.6rem; font-size: 0.88rem; }
.coaching-card-compacta .btn:last-child { margin-bottom: 0; }

.badge-recordatorio-ok { background: var(--primary); }
.badge-recordatorio-hoy { background: var(--warn); }
.badge-recordatorio-esta_semana { background: var(--stage-10); }
.badge-recordatorio-por_vencer { background: var(--warn); }
.badge-recordatorio-vencido { background: var(--danger); }

.recordatorio-card { padding: 1rem 1.25rem; }
.recordatorio-card h2 { font-size: 0.95rem; margin-bottom: 0.65rem; }

.recordatorio-form-compacta {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  max-width: 300px;
  margin-bottom: 0.75rem;
}
.recordatorio-fila {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.recordatorio-fila label {
  flex-shrink: 0;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text);
}
.recordatorio-fila input {
  flex: 1;
  min-width: 0;
  max-width: 190px;
  padding: 0.3rem 0.4rem;
  font-size: 0.74rem;
}
.recordatorio-form-compacta .btn { align-self: flex-start; padding: 0.4rem 0.8rem; font-size: 0.82rem; }

.recordatorio-estado-row { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.recordatorio-estado-row .badge { font-size: 0.68rem; padding: 0.15rem 0.45rem; }

.acciones-lista { list-style: none; margin: 0 0 0.75rem; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.acciones-lista li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.acciones-lista .badge { font-size: 0.74rem; padding: 0.25rem 0.55rem; white-space: normal; text-align: left; }
.acciones-lista-botones { display: flex; gap: 0.4rem; flex-shrink: 0; }
.acciones-lista-botones .btn { padding: 0.3rem 0.6rem; font-size: 0.74rem; }
.acciones-vacio { border: none !important; color: var(--text-muted); font-size: 0.85rem; padding: 0.25rem 0 !important; }

.acciones-lista-historial li { opacity: 0.75; }

/* Tarea individual: cabecera + nota + fecha en líneas separadas, con acciones abajo. */
.acciones-lista li.accion-item { display: block; }
.accion-item-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}
.accion-item-tipo { font-size: 0.8rem; font-weight: 700; letter-spacing: 0.02em; color: var(--text); }
.accion-item-nota { margin: 0 0 0.2rem; font-size: 0.85rem; color: var(--text); }
.accion-item-fecha { margin: 0 0 0.5rem; font-size: 0.78rem; color: var(--text-muted); }
.accion-item-botones { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.accion-item-botones .btn { padding: 0.3rem 0.6rem; font-size: 0.74rem; }

.accion-completar, .accion-reagendar { display: inline-block; }
.accion-completar summary, .accion-reagendar summary { list-style: none; cursor: pointer; }
.accion-completar summary::-webkit-details-marker, .accion-reagendar summary::-webkit-details-marker { display: none; }

.accion-completar-form {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  max-width: 320px;
}
.accion-completar-form label { font-size: 0.76rem; gap: 0.15rem; }
.accion-completar-form input, .accion-completar-form select, .accion-completar-form textarea {
  font-size: 0.8rem;
  padding: 0.35rem 0.45rem;
}

.accion-reagendar-form {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
.accion-reagendar-form input { font-size: 0.8rem; padding: 0.35rem 0.45rem; }

.accion-nueva-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}
/* Documentos de ingreso: el formulario largo con que se arma la solicitud de
   portabilidad. La tabla de números puede tener 280 filas, así que va en su
   propio marco con desplazamiento y con campos apretados. */
.btn-icono { width: 15px; height: 15px; vertical-align: -3px; margin-right: 0.35rem; }
.ingreso-cabecera { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.ingreso-cabecera-botones { display: flex; gap: 0.4rem; flex-shrink: 0; }
.tabla-scroll { max-height: 420px; overflow: auto; border: 1px solid var(--border); border-radius: 8px; }
.tabla-lineas { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.tabla-lineas th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-2);
  text-align: left;
  padding: 0.4rem 0.5rem;
  font-size: 0.7rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tabla-lineas td { padding: 0.15rem 0.25rem; border-top: 1px solid var(--border); }
.tabla-lineas td.linea-n { width: 34px; text-align: right; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* Con dos columnas la tabla no tiene por qué cruzar la pantalla: se deja del
   ancho de lo que contiene. */
.tabla-lineas-corta { width: auto; min-width: 380px; }
.tabla-lineas-corta td:nth-child(2) input { min-width: 170px; }
.tabla-lineas input { width: 100%; padding: 0.3rem 0.4rem; font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.tabla-lineas .btn { padding: 0.15rem 0.45rem; }
.ingreso-lineas-pie { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.5rem; flex-wrap: wrap; }
.ingreso-lineas-pie .subtitle { margin: 0; }
.ingreso-documentos { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.ingreso-documentos .subtitle { margin: 0; flex: 1 1 260px; }
.requisitos { list-style: none; margin: 0.4rem 0 0; padding: 0; display: grid; gap: 0.35rem; }
.requisitos li { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; font-size: 0.84rem; }
.requisito-titulo { font-weight: 600; }
.requisito-detalle { color: var(--text-muted); font-size: 0.78rem; flex: 1 1 100%; }
.requisitos-subtitulo { margin: 1rem 0 0; font-size: 0.85rem; }

/* La lista de documentos, una línea por documento. Son diez o doce y se miran
   de arriba abajo mientras se juntan los papeles: en tarjetas ocupaban media
   pantalla y había que desplazarse para saber qué faltaba. Lo ya reunido se
   tacha y baja de intensidad; lo que queda por conseguir es lo que tiene que
   saltar a la vista. */
.checklist { list-style: none; margin: 0.6rem 0 0; padding: 0; }
.checklist .requisito {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.1rem;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
  line-height: 1.3;
}
.checklist .requisito:first-child { border-top: 0; }
/* Un "display" en la regla le gana al atributo hidden, y lo que no toca a esta
   venta —las filas del traspaso, los campos de portabilidad— se seguía
   viendo. Vale para los campos de cualquier formulario del portal. */
.checklist .requisito[hidden],
.form-negocio-fila label[hidden],
.form-negocio-fila [hidden] { display: none; }
.checklist .requisito > input[type="checkbox"] {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  accent-color: var(--good);
  cursor: pointer;
}
.requisito-titulo { font-weight: 600; }
.requisito-fuente {
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.requisito-peso {
  font-size: 0.68rem;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.05rem 0.4rem;
  white-space: nowrap;
}
.requisito.cumplido .requisito-titulo { text-decoration: line-through; color: var(--text-muted); }
.requisito.cumplido .requisito-fuente,
.requisito.cumplido .requisito-peso { opacity: 0.45; }
/* Lo que impide generar un documento va al final de su propia línea y en
   ámbar: no es un error, es el siguiente paso. */
.requisito-falta {
  margin-left: auto;
  font-size: 0.74rem;
  color: var(--warn);
  font-weight: 600;
  text-align: right;
}
.requisito-boton { margin-left: auto; flex-shrink: 0; padding: 0.15rem 0.5rem; font-size: 0.74rem; }
.requisito-botones { margin-left: auto; display: flex; gap: 0.3rem; flex-shrink: 0; }
/* La aclaración de que son dos documentos: en la línea de abajo, apagada, que
   la fila del requisito ya va llena. */
.requisito-nota {
  flex-basis: 100%;
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: 0.72rem;
}
.requisito-botones .requisito-boton { margin-left: 0; }
.checklist-avance { margin: 0; font-size: 0.84rem; color: var(--text-muted); white-space: nowrap; }
.checklist-avance b { color: var(--text); font-size: 1.05rem; }
/* En una ficha, lo que uno busca al llegar es de qué cliente es. El nombre de
   la empresa manda sobre el nombre de la pantalla: esta última se lee una vez
   y ya se sabe dónde está uno. */
.rotulo-pantalla {
  margin: 0 0 0.15rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.titulo-cliente {
  font-size: 1.9rem;
  line-height: 1.1;
  margin-bottom: 0.1rem;
}
.titulo-cliente .rut-cliente {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0;
  margin-top: 0.15rem;
}

.campo-modalidad { flex: 1 1 320px; max-width: 420px; }
/* Separador dentro de un cuadro: los datos de la solicitud van todos juntos,
   y estos rótulos dicen de quién es cada grupo sin partirlo en tarjetas. */
.bloque-titulo {
  margin: 0.8rem 0 0.4rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Un dato de contacto que falta no es un error, pero sí lo que hay que hacer
   ahora: el campo se marca en ámbar y la etiqueta lo dice. Sin él no se puede
   llamar al cliente ni generar los documentos. */
.campo-pendiente > input,
.campo-pendiente > select {
  border-color: var(--warn);
  background: var(--notice-bg);
}
.campo-pendiente > input:focus,
.campo-pendiente > select:focus {
  border-color: var(--primary);
  background: var(--card-bg);
}
.campo-pendiente::after {
  content: "por completar";
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--notice-text);
}
/* Cuando se escribe algo, la marca desaparece sola. */
.campo-listo::after {
  content: "✓";
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--good);
}

.bloque-titulo span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.74rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}
/* Un bloque que casi siempre va vacío —el segundo representante legal— se
   pliega para no ocupar media pantalla en las ventas que tienen uno solo. El
   título se ve igual que los demás, con la flecha de abrir al lado. */
.bloque-plegable { margin: 0.8rem 0 0.4rem; }
.bloque-plegable > summary {
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
}
.bloque-plegable > summary:hover { color: var(--text); }
.bloque-plegable > summary span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.74rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}
.bloque-plegable > .form-ficha { margin-top: 0.4rem; }

/* La foto de cada quien en la lista del equipo. Se pulsa para cambiarla: el
   lápiz aparece encima al pasar por arriba, para que no haya que explicar que
   la foto es un botón. */
.celda-foto { text-align: center; }
.foto-equipo { display: inline-block; }
.foto-equipo-boton {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}
.avatar-equipo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.78rem;
  font-weight: 700;
}
.foto-equipo-lapiz {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--primary);
  color: #ffffff;
  font-size: 0.62rem;
  line-height: 17px;
  opacity: 0;
  transition: opacity 0.15s;
}
.foto-equipo-boton:hover .foto-equipo-lapiz,
.foto-equipo-boton:focus-visible .foto-equipo-lapiz { opacity: 1; }
.foto-equipo-cargando { opacity: 0.5; pointer-events: none; }
/* «Quitar» debajo de la foto: es una acción menor y no tiene que competir con
   los botones de la fila. */
.boton-enlace {
  margin-top: 0.15rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.72rem;
  text-decoration: underline;
  cursor: pointer;
}
.boton-enlace:hover { color: var(--text); }

/* Quién viene bajo su propia meta en el tramo. Es una marca sobria a
   propósito: sirve para mirar un caso, no para señalar a nadie en una
   reunión. El número exacto va en el título, al pasar por encima. */
/* De dónde salió un prospecto de Hunting. Son tres cosas distintas y conviene
   distinguirlas de un vistazo: lo que nadie tiene todavía, lo que repartió la
   jefatura, y lo que venía de la cartera de un colega —ese ya tiene historia
   y hay que leerla antes de llamar—. */
.chip-procedencia { background: var(--notice-bg); color: var(--notice-text); }
.chip-sugerida { background: var(--accent-soft); color: var(--primary-dark); }

/* Cuánto tiene cada quien, en fichas pulsables: la de arriba filtra la tabla
   de abajo. Repartir es mirar primero y mover después. */
.cartera-chip {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.15s, background 0.15s;
}
.cartera-chip:hover { border-color: var(--primary); }
.cartera-chip-activo { border-color: var(--primary); background: var(--accent-soft); }
.cartera-chip b { font-size: 1.15rem; font-weight: 600; line-height: 1.1; }
.cartera-chip em { font-style: normal; font-size: 0.74rem; }
.cartera-chip small { font-size: 0.64rem; color: var(--text-muted); }

/* La barra para mover en bloque. Va pegada arriba de la tabla: con doscientas
   filas, un botón al final obliga a bajar hasta el fondo para aplicar. */
.barra-repartir {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}
.barra-repartir-todos { display: flex; align-items: center; gap: 0.35rem; font-size: 0.8rem; }
.barra-repartir-sep { flex: 1 1 auto; }

.marca-rendimiento {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.35rem;
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.marca-bajo { background: var(--error-bg); color: var(--error-text); }
.marca-ajustado { background: var(--notice-bg); color: var(--notice-text); }

.tabla-scroll-corta { max-height: 220px; }
.texto-alerta { color: var(--warn); font-weight: 600; }

/* Encabezado de lo pendiente: el punto ámbar es la misma señal del tablero. */
.accion-seccion-titulo {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.45rem;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.accion-seccion-punto {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--warn);
  flex-shrink: 0;
}
/* Sin nada pendiente el punto no tiene por qué llamar la atención. */
.accion-seccion-titulo.en-calma .accion-seccion-punto { background: var(--border); }

/* El historial: cerrado ocupa una línea, y el check verde dice de qué se trata
   sin tener que abrirlo. */
.accion-historial { margin-top: 0.75rem; }
.accion-historial > summary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--good);
}
.accion-historial > summary svg { width: 15px; height: 15px; flex-shrink: 0; }
.accion-historial .acciones-lista { margin-top: 0.5rem; }
.accion-hecha-texto { font-size: 0.8rem; color: var(--text); }
.accion-hecha-fecha { font-size: 0.72rem; color: var(--text-muted); white-space: nowrap; }

/* Nueva acción en la ficha: dos cosas distintas que antes se veían iguales.
   Arriba se elige cuál —programar algo para después, o anotar algo ya hecho— y
   abajo se ve solo esa. Cada una con su color: turquesa lo que queda por hacer,
   verde lo cumplido, igual que en el resto del portal. */
.accion-alta {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  padding: 0.5rem;
  margin-bottom: 0.6rem;
}
.accion-alta-pestanas {
  display: flex;
  gap: 0.3rem;
  margin-bottom: 0.5rem;
}
.accion-alta-pestana {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.45rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
.accion-alta-pestana svg { width: 15px; height: 15px; flex-shrink: 0; }
.accion-alta-pestana:hover { color: var(--text); }
.accion-alta-pestana.activa {
  background: var(--card-bg);
  border-color: var(--border);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(13, 17, 23, 0.06);
}
/* La pestaña activa se reconoce por su color aunque se mire de reojo. */
.accion-alta-pestana[data-hoja="programar"].activa { color: var(--primary); border-color: var(--primary); }
.accion-alta-pestana[data-hoja="hecha"].activa { color: var(--good); border-color: var(--good); }
.accion-alta-pestana:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.accion-alta-hoja .accion-nueva-form { margin-bottom: 0; }
.accion-alta-pie {
  margin: 0 0 0.45rem;
  font-size: 0.74rem;
  color: var(--text-muted);
}

.accion-nueva-form select { flex: 1 1 160px; }
.accion-nueva-form input[type="datetime-local"] { flex: 1 1 170px; }
.accion-nueva-form input[type="text"] { flex: 1 1 140px; }
.accion-nueva-form input, .accion-nueva-form select { padding: 0.4rem 0.5rem; font-size: 0.82rem; }

.etiquetas-toggle-grid { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.etiqueta-toggle {
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 0.4rem 0.8rem;
  font-size: 0.82rem;
  cursor: pointer;
}
.etiqueta-toggle.etiqueta-activa {
  background: var(--accent-soft);
  border-color: var(--primary);
  color: var(--text);
  font-weight: 600;
}

.ficha-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.6rem 1.5rem;
  font-size: 0.92rem;
  margin-bottom: 1.1rem;
}
.ficha-grid:last-of-type { margin-bottom: 0; }

.ficha-subtitulo {
  margin: 0 0 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.actividad-item-accion { background: var(--surface-2); }
.actividad-item-accion p { color: var(--text-muted); font-size: 0.85rem; }

.comentario-form {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin-bottom: 1.25rem;
}

.comentarios-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; }

.comentarios-lista li {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
}

.comentario-meta {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-bottom: 0.3rem;
}

.comentarios-lista p { margin: 0; }

.archivo-form {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.archivos-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }

.archivos-lista li {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
}

.archivo-icono { font-size: 1.3rem; flex-shrink: 0; }

.archivo-info { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; min-width: 0; }
.archivo-info a { font-weight: 600; color: var(--text); }
.archivo-meta { font-size: 0.75rem; color: var(--text-muted); }

.archivo-vacio { border: none; color: var(--text-muted); padding: 0.4rem 0.9rem; }

/* ---------- Tablero kanban del pipeline ---------- */

.board {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 250px;
  gap: 0.9rem;
  overflow-x: auto;
  padding-bottom: 0.75rem;
  /* Sin esto, al llegar al extremo el gesto horizontal se lo lleva el
     navegador —que lo entiende como "atrás"— y el tablero se siente frenado
     justo cuando uno insiste para seguir avanzando. */
  overscroll-behavior-x: contain;
  /* Una sola barra, la de arriba. El tablero se sigue recorriendo con el
     trackpad, la rueda o el dedo; solo deja de dibujar la suya abajo. */
  scrollbar-width: none;
}
.board::-webkit-scrollbar { display: none; }

/* Color de la barra del tablero: en el tema claro el gris de los bordes casi no
   se veía, así que tiene su propio tono, más oscuro. */
:root {
  --barra-tablero: #8a94a0;
  --barra-tablero-hover: #5f6a77;
  --barra-tablero-riel: #d9dee4;
}
@media (prefers-color-scheme: dark) {
  :root {
    --barra-tablero: #4a5563;
    --barra-tablero-hover: #6b7684;
    --barra-tablero-riel: #1c2129;
  }
}
:root[data-theme="dark"] {
  --barra-tablero: #4a5563;
  --barra-tablero-hover: #6b7684;
  --barra-tablero-riel: #1c2129;
}
:root[data-theme="light"] {
  --barra-tablero: #8a94a0;
  --barra-tablero-hover: #5f6a77;
  --barra-tablero-riel: #d9dee4;
}

.board-scrollbar-top {
  overflow-x: auto;
  overflow-y: hidden;
  height: 12px;
  margin-bottom: 0.4rem;
  border-radius: 999px;
  background: var(--barra-tablero-riel);
  scrollbar-width: auto;
  scrollbar-color: var(--barra-tablero) transparent;
}
.board-scrollbar-top > div { height: 1px; }
/* Con estilo propio la barra se ve siempre, también en Mac, donde las barras
   normales se esconden hasta que uno desplaza. */
.board-scrollbar-top::-webkit-scrollbar { height: 12px; }
.board-scrollbar-top::-webkit-scrollbar-track { background: transparent; }
.board-scrollbar-top::-webkit-scrollbar-thumb {
  background: var(--barra-tablero);
  border-radius: 999px;
  border: 2px solid var(--barra-tablero-riel);
}
.board-scrollbar-top::-webkit-scrollbar-thumb:hover { background: var(--barra-tablero-hover); }

/* Mientras el tablero corre de lado, las tarjetas no reaccionan al cursor: si
   no, cada tarjeta que pasa bajo el puntero enciende y apaga su resplandor en
   cada cuadro y el desplazamiento se entrecorta. */
.board-desplazando .board-card { pointer-events: none; }

.board-column {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  min-height: 120px;
}

.board-column-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.15rem 0.5rem;
  border-bottom: 1px solid var(--border);
}

.board-column-title {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.board-column-count { font-size: 0.72rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.board-column-lineas { font-size: 0.72rem; color: var(--text-muted); padding: 0 0.15rem; font-variant-numeric: tabular-nums; }

.board-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-left: 3px solid var(--stage-color, var(--border));
  border-radius: 8px;
  padding: 0.65rem 0.75rem;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-decoration: none;
  color: var(--text);
  cursor: grab;
  position: relative;
  transition: transform 0.12s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

/* Al pasar el cursor la tarjeta se enciende con el color de su etapa, en vez
   de levantar una sombra gris: así el tablero dice de un vistazo en qué etapa
   está lo que se está por tomar, que es la pregunta de siempre. El anillo
   rodea la tarjeta completa y los dos halos abiertos son el resplandor. */
.board-card:hover,
.board-card:focus-visible {
  transform: translateY(-1px);
  border-color: var(--stage-color, var(--primary));
  box-shadow:
    0 0 0 1px var(--stage-color, var(--primary)),
    0 0 10px -1px color-mix(in srgb, var(--stage-color, var(--primary)) 60%, transparent),
    0 0 26px 2px color-mix(in srgb, var(--stage-color, var(--primary)) 30%, transparent);
}
/* El borde izquierdo grueso es la marca de etapa: no lo pisa el anillo. */
.board-card:hover { border-left-color: var(--stage-color, var(--primary)); }

.board-card:active { cursor: grabbing; }

/* Punto de la esquina de la tarjeta: discreto, se marca al pasar el cursor. */
.card-menu-punto {
  position: absolute;
  top: 2px;
  right: 4px;
  z-index: 2;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.board-card:hover .card-menu-punto,
.card-menu-punto:focus-visible { opacity: 0.7; }
.card-menu-punto:hover { opacity: 1; color: var(--primary); background: var(--surface-2); }

/* Menú diminuto del punto. Va en position fixed porque las columnas recortan
   lo que se sale de su caja. */
.card-menu {
  position: fixed;
  z-index: 60;
  min-width: 132px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.card-menu[hidden] { display: none; }
.card-menu-paso { display: flex; flex-direction: column; gap: 1px; }
.card-menu-paso[hidden] { display: none; }
.card-menu-titulo {
  margin: 0.15rem 0.5rem 0.25rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.card-menu hr {
  margin: 0.25rem 0.3rem;
  border: 0;
  border-top: 1px solid var(--border);
}
.card-menu-tenue { color: var(--text-muted) !important; }
/* Un guiño al registrar: la tarjeta parpadea y se sabe que quedó anotado. */
.board-card-gestionada { animation: gestionAnotada 0.85s ease-out; }
@keyframes gestionAnotada {
  0% { box-shadow: 0 0 0 2px var(--primary); }
  100% { box-shadow: none; }
}
.card-menu button {
  padding: 0.34rem 0.5rem;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-family: var(--font);
  font-size: 0.7rem;
  text-align: left;
  cursor: pointer;
}
.card-menu button:hover { background: var(--surface-2); color: var(--primary); }

/* Salida de la tarjeta cuando se va a otro mes. */
.board-card-yendose {
  animation: cartaSeVa 0.25s ease-in forwards;
  pointer-events: none;
}
@keyframes cartaSeVa {
  to { transform: translateX(14px) scale(0.95); opacity: 0; }
}

/* Aviso de conexión: cruza el ancho arriba del contenido y no se va solo.
   Es lo que antes no existía —el portal se quedaba mudo— así que tiene que
   verse y traer el botón que lo arregla. */
.aviso-conexion {
  position: sticky;
  top: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
  margin: 0 auto 0.8rem;
  padding: 0.6rem 0.9rem;
  max-width: 1400px;
  border: 1px solid var(--danger);
  border-radius: 10px;
  background: color-mix(in srgb, var(--danger) 12%, var(--card-bg));
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 600;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
}
.aviso-conexion[hidden] { display: none !important; }
.aviso-conexion-texto { flex: 1 1 240px; }

/* Aviso breve al pie: para lo que pasa fuera de la vista, como un negocio que
   se fue a otro mes. */
.aviso-flotante {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: 80;
  transform: translate(-50%, 12px);
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 0.74rem;
  font-weight: 600;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.aviso-flotante.visible { opacity: 1; transform: translate(-50%, 0); }

.board-column-vacia {
  font-size: 0.78rem;
  color: var(--text-muted);
  padding: 0 0.15rem;
}

/* Mientras el servidor confirma el cambio de etapa, la tarjeta ya está en su
   columna nueva pero se ve a media tinta: si algo falla, vuelve sola. */
.board-card-esperando { opacity: 0.6; }

/* Llegada a la columna nueva: un asentamiento corto, lo justo para seguir la
   tarjeta con la vista sin que parezca que la pantalla se recargó. */
.board-card-llegando { animation: cartaLlega 0.32s ease-out; }
@keyframes cartaLlega {
  0% { transform: translateY(-6px) scale(0.97); opacity: 0.4; }
  100% { transform: none; opacity: 1; }
}

/* Celebración al llegar a habilitado: anillo verde y chispas del color de la
   etapa. Es el único momento del tablero con animación larga; dura poco más de
   un segundo y se limpia sola. */
/* Celebración al mover una tarjeta: cada etapa con su color y su intensidad.
   El color lo pone el JS en --fiesta, según la etapa a la que llegó. */
.board-card-fiesta { position: relative; z-index: 2; }
.board-card-fiesta::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 10px;
  border: 1.5px solid var(--fiesta, var(--primary));
  pointer-events: none;
  animation: aureolaFiesta 0.7s ease-out 1;
}
/* Habilitado es la venta cerrada: anillo más marcado y dos vueltas. */
.board-card-victoria::after {
  border-width: 2px;
  animation: aureolaFiesta 0.8s ease-out 2;
}
@keyframes aureolaFiesta {
  0% { opacity: 0.9; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}

.victoria {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
}
.victoria i {
  position: absolute;
  width: var(--tam, 5px);
  height: var(--tam, 5px);
  margin: calc(var(--tam, 5px) / -2) 0 0 calc(var(--tam, 5px) / -2);
  border-radius: 50%;
  background: var(--fiesta, var(--primary));
  box-shadow: 0 0 9px var(--fiesta, var(--primary));
  opacity: 0;
  animation: chispaVictoria 0.9s ease-out var(--demora, 0ms) both;
}
@keyframes chispaVictoria {
  0% { transform: rotate(var(--giro)) translateY(0) scale(0.3); opacity: 0; }
  20% { opacity: 1; }
  100% { transform: rotate(var(--giro)) translateY(calc(var(--vuelo, 60px) * -1)) scale(0.85); opacity: 0; }
}

/* La columna se enciende del color de su etapa. */
.board-column-encendida {
  position: relative;
  z-index: 3;
  animation: ledColumna 0.9s ease-out 1;
  border-radius: 12px;
}
/* En habilitado late dos veces y sale el cartel. No cambia de tamaño: mover
   la columna corría todo el tablero y molestaba más de lo que celebraba. */
.board-column-gloria {
  animation: ledColumna 0.9s ease-out 2;
}
@keyframes ledColumna {
  0% { box-shadow: 0 0 0 1px var(--fiesta, var(--primary)), 0 0 12px 1px var(--fiesta, var(--primary)); }
  60% { box-shadow: 0 0 0 2px var(--fiesta, var(--primary)), 0 0 26px 5px var(--fiesta, var(--primary)); }
  100% { box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent; }
}

/* Al llegar a habilitado la columna se cubre un momento: las tarjetas quedan
   detrás y solo se ve el mensaje. Dura poco más de un segundo y se va sola. */
.velo-victoria {
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface-2);
  animation: veloVictoria 2s ease-in-out both;
  pointer-events: none;
}
/* Tiñe el recuadro del verde de la etapa, sin tapar del todo lo que hay debajo. */
.velo-victoria::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--stage-100);
  opacity: 0.18;
}
/* Luces sueltas dentro del recuadro, subiendo despacio. */
.velo-victoria i {
  position: absolute;
  width: var(--tam, 5px);
  height: var(--tam, 5px);
  margin: calc(var(--tam, 5px) / -2) 0 0 calc(var(--tam, 5px) / -2);
  border-radius: 50%;
  background: var(--stage-100);
  box-shadow: 0 0 12px var(--stage-100), 0 0 24px var(--stage-100);
  opacity: 0;
  animation: brasaVictoria 1.9s ease-out var(--demora, 0ms) both;
}
@keyframes brasaVictoria {
  0% { transform: translateY(14px) scale(0.4); opacity: 0; }
  25% { opacity: 0.95; }
  70% { opacity: 0.8; }
  100% { transform: translateY(var(--sube, -50px)) scale(1); opacity: 0; }
}
@keyframes veloVictoria {
  0% { opacity: 0; }
  12% { opacity: 1; }
  72% { opacity: 1; }
  100% { opacity: 0; }
}

/* Cartel de felicitación, solo al llegar a habilitado. */
.cartel-victoria {
  position: absolute;
  left: 50%;
  /* Cerca del borde de arriba y no al medio: la columna puede ser larguísima y
     el mensaje tiene que caer donde se está mirando. */
  top: 56px;
  z-index: 5;
  transform: translateX(-50%);
  /* Escrito hacia abajo, letra sobre letra. Va suelto sobre el velo, sin caja
     que lo apriete: así las letras pueden ser grandes de verdad. */
  writing-mode: vertical-rl;
  text-orientation: upright;
  color: var(--stage-100);
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.1em;
  white-space: nowrap;
  text-shadow: 0 0 18px var(--stage-100), 0 0 42px var(--stage-100);
  pointer-events: none;
  animation: cartelVictoria 2s ease-out both;
}
/* Cada letra cae en su turno, así el mensaje se va escribiendo hacia abajo.
   Van en inline-block y no en block: con la escritura vertical, un bloque abre
   una columna nueva y el texto terminaba saliendo de lado. */
.cartel-victoria b {
  display: inline-block;
  font-weight: inherit;
  opacity: 0;
  animation: letraVictoria 0.45s cubic-bezier(0.2, 1.3, 0.5, 1) var(--demora, 0ms) both;
}
@keyframes letraVictoria {
  0% { opacity: 0; transform: translateY(-16px); }
  100% { opacity: 1; transform: none; }
}
/* El cartel entra desde arriba y se va hacia abajo, en el sentido en que baja
   la vista por la columna a mirar lo que se acaba de habilitar. */
@keyframes cartelVictoria {
  0% { opacity: 1; }
  82% { opacity: 1; }
  100% { opacity: 0; }
}

/* Las luces que suelta la columna por los costados y hacia arriba. */
.led-columna {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
}
.led-columna i {
  position: absolute;
  width: var(--tam, 4px);
  height: var(--tam, 4px);
  margin: calc(var(--tam, 4px) / -2) 0 0 calc(var(--tam, 4px) / -2);
  border-radius: 50%;
  background: var(--fiesta, var(--primary));
  box-shadow: 0 0 10px var(--fiesta, var(--primary));
  opacity: 0;
  animation: luzColumna 1.1s ease-out var(--demora, 0ms) both;
}
@keyframes luzColumna {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  25% { opacity: 1; }
  100% { transform: translate(var(--dx, 0), var(--dy, 0)) scale(0.9); opacity: 0; }
}

/* Con el sistema en "menos movimiento", nada de esto se anima. */
@media (prefers-reduced-motion: reduce) {
  .board-card-llegando,
  .board-card-fiesta::after,
  .board-column-encendida,
  .board-column-gloria,
  .victoria i,
  .led-columna i { animation: none; }
  .cartel-victoria b { animation: none; opacity: 1; }
  .victoria,
  .led-columna,
  .velo-victoria { display: none; }
}

.board-card-arrastrando {
  cursor: grabbing;
  opacity: 0.45;
}

.board-column {
  transition: background-color 0.12s ease, box-shadow 0.12s ease;
}

.board-column-hover {
  background-color: var(--accent-soft);
  box-shadow: inset 0 0 0 2px var(--primary);
  cursor: grabbing;
}

.board-card .empresa { font-size: 0.84rem; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.board-card > * { min-width: 0; max-width: 100%; }
.lineas-desglose { overflow-wrap: anywhere; }

.board-etiquetas {
  display: inline-flex;
  gap: 0.2rem;
  margin-left: 0.3rem;
  font-size: 0.78rem;
  vertical-align: middle;
}

.board-card .meta-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.74rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.14rem 0.5rem;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 600;
  white-space: nowrap;
}

.chip-segmento { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); }

.board-card .chip-lineas,
.board-card .chip-arpu {
  background: none;
  border: none;
  padding: 0;
  font-weight: 700;
  color: var(--stage-color, var(--primary));
}

/* El pie se parte en varias líneas cuando hace falta: con tarea pendiente y
   varios marcadores (crecimiento, mesa, foco de cierre) no cabía todo en una
   fila y los chips se salían de la tarjeta. Ahora la tarjeta crece hacia abajo,
   que es el único lado donde tiene espacio. */
.board-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.35rem 0.4rem;
  margin-top: 0.1rem;
  min-width: 0;
}
.board-card-footer > * { min-width: 0; max-width: 100%; }

.board-card-footer-right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.3rem 0.35rem;
  min-width: 0;
  margin-left: auto;
}

/* ---- Teléfono para marcar de una ----
   En el celular abre el marcador con el número puesto, que es lo que se hace
   con un teléfono de contacto: llamarlo. Se ve como un dato, no como un botón,
   hasta que uno se acerca; en táctil el área de toque igual es cómoda. */
.tel-llamar {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: inherit;
  text-decoration: none;
  border-radius: 6px;
  padding: 0.1rem 0.3rem;
  margin: -0.1rem -0.3rem;
  transition: color 0.15s ease, background 0.15s ease;
}
.tel-llamar svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--primary); }
.tel-llamar span { text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; }
.tel-llamar:hover, .tel-llamar:focus-visible { color: var(--primary); background: var(--accent-soft); }
.tel-llamar:hover span { text-decoration-style: solid; }
/* En el teléfono el toque tiene que ser cómodo, no del porte del texto. */
@media (hover: none) {
  .tel-llamar { padding: 0.25rem 0.4rem; margin: -0.25rem -0.4rem; }
}
/* Dentro de una tarjeta de Hunting va como una línea más de la ficha. */
.tel-llamar-linea { font-size: inherit; }

.chip-portar {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.14rem 0.4rem;
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  cursor: pointer;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  white-space: nowrap;
}
.chip-portar:hover { border-color: var(--good); color: var(--good); }
.chip-portar-activo {
  border: 1px solid var(--good);
  background: var(--ok-bg);
  color: var(--good);
}
.chip-portar-activo:hover { color: var(--good); }

.portar-mesa-moac-stack {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  align-items: stretch;
}
.portar-mesa-moac-stack .chip-portar { width: 100%; }
.mesa-moac-row { display: flex; gap: 0.25rem; width: 100%; }
.mesa-moac-row > .chip-mesa,
.mesa-moac-row > .chip-moac { flex: 1; }

.chip-mesa,
.chip-moac {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.14rem 0.4rem;
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  cursor: pointer;
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  white-space: nowrap;
}
.chip-mesa:hover { border-color: var(--primary); color: var(--primary); }
.chip-mesa-activo {
  border: 1px solid var(--primary);
  background: var(--accent-soft);
  color: var(--primary);
}
.chip-mesa-activo:hover { color: var(--primary); }

.chip-moac:hover { border-color: var(--stage-90); color: var(--stage-90); }
.chip-moac-activo {
  border: 1px solid var(--stage-90);
  background: var(--accent-soft);
  color: var(--stage-90);
}
.chip-moac-activo:hover { color: var(--stage-90); }

.portar-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1rem 1.5rem;
}
.portar-card-activo { border-color: var(--good); background: var(--ok-bg); }
.portar-card-activo strong, .portar-card-activo .subtitle { color: var(--ok-text); }
.btn-portar-activo { background: var(--good); color: #ffffff; }

.board-card-prospecto { cursor: default; }
.board-card-prospecto:hover { transform: none; box-shadow: var(--shadow-card); }

.prospecto-card-link {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-decoration: none;
  color: inherit;
}

.prospecto-rut,
.prospecto-linea {
  font-size: 0.74rem;
  color: var(--text-muted);
}

.board-exec-avatar {
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6rem;
  font-weight: 700;
  flex-shrink: 0;
}

.board-alert {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--danger);
}
.board-alert::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--danger); flex-shrink: 0; }

.board-reminder {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--warn);
}

::-webkit-scrollbar { height: 8px; width: 8px; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
::-webkit-scrollbar-track { background: transparent; }

@media (max-width: 900px) {
  .app-shell { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: relative; flex-direction: row; align-items: center; overflow-x: auto; padding: 0.75rem 1rem; }
  .sidebar-brand { border-bottom: none; margin-bottom: 0; padding: 0 1rem 0 0; }
  .sidebar nav { flex-direction: row; }
  .sidebar-footer { display: none; }
}

/* Contenedor de altura fija para gráficos de barras: sin esto, un canvas
   con maintainAspectRatio:false crece sin control en cada redibujo. */
.grafico-barras-wrap { position: relative; width: 100%; }
.grafico-barras-wrap canvas { position: absolute; inset: 0; }

/* En Hunting la base es común: se marca quién está trabajando cada
   prospecto, como aviso, sin bloquear a nadie. */
.prospecto-gestor {
  font-size: 0.6rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 130px;
  display: inline-block;
}

/* Prospecto ya convertido por otra persona: queda como registro de que se
   cerró, atenuado y sin datos del cliente. */
.board-card-reservada { opacity: 0.62; }
.board-card-reservada .prospecto-card-link { cursor: default; }
.prospecto-cerrado { font-size: 0.62rem; color: var(--text-muted); white-space: nowrap; }


/* ---------- KPI compacto (estilo del dashboard de referencia) ---------- */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.kpi {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.85rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
  position: relative;
}
/* Un indicador opcional apagado viaja igual en el HTML, oculto: así ponerlo o
   sacarlo es inmediato. El display de .kpi le gana a [hidden], hay que decirlo. */
.kpi[hidden] { display: none; }

.kpi-icono {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--surface-2);
  color: var(--primary);
}
.kpi-icono svg { width: 17px; height: 17px; }
.kpi-cuerpo { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.kpi-label {
  font-size: 0.66rem;
  color: var(--text-muted);
  line-height: 1.2;
  display: flex;
  align-items: center;
  gap: 0.3rem;
}
.kpi-valor { font-size: 1.32rem; font-weight: 600; line-height: 1.15; }
.kpi-nota { font-size: 0.62rem; color: var(--text-muted); }

/* Botón de ayuda: explica qué mide el indicador, sin ocupar espacio fijo. */
.kpi-info {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.58rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  font-family: var(--font);
}
.kpi-info:hover { border-color: var(--primary); color: var(--primary); }
.kpi-ayuda {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 25;
  padding: 0.6rem 0.7rem;
  font-size: 0.7rem;
  line-height: 1.35;
  color: var(--text);
  background: var(--card-bg);
  border: 1px solid var(--primary);
  border-radius: 9px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
.kpi-ayuda.abierta { display: block; }

/* Ranking de vendedores */
.ranking { display: flex; flex-direction: column; gap: 0.5rem; }
.ranking-fila {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 0.6rem;
  border-radius: 9px;
  background: var(--surface-2);
}
.ranking-puesto {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--card-bg);
  color: var(--text-muted);
}
.ranking-fila-1 .ranking-puesto { background: #f5c451; color: #3a2c05; }
.ranking-fila-2 .ranking-puesto { background: #c7ccd4; color: #2a2f36; }
.ranking-fila-3 .ranking-puesto { background: #d9a06b; color: #3a2410; }
.ranking-nombre { font-size: 0.84rem; font-weight: 500; }
.ranking-barra { height: 4px; border-radius: 999px; background: var(--border); margin-top: 4px; overflow: hidden; }
.ranking-barra span { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.ranking-valor { text-align: right; font-size: 0.82rem; font-weight: 600; white-space: nowrap; }
.ranking-valor small { display: block; font-size: 0.62rem; font-weight: 400; color: var(--text-muted); }


/* Tira de cifras de apoyo: muchas juntas, en una sola línea delgada. */
.mini-kpi-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
}
.mini-kpi {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.mini-kpi b { font-size: 0.95rem; font-weight: 600; }
.mini-kpi b i { font-style: normal; font-size: 0.72rem; font-weight: 400; color: var(--text-muted); }
.mini-kpi em { font-style: normal; font-size: 0.68rem; color: var(--text-muted); }


/* ---------- Dashboard compacto ---------- */
.dash-cabecera {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 0.7rem;
}
.dash-titulo h1 { margin: 0; font-size: 1.35rem; line-height: 1.2; }
.dash-titulo .subtitle { margin: 0; font-size: 0.72rem; }

/* Filtros arrinconados: chicos y en una sola línea. */
.dash-filtros { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; }
.dash-filtros select {
  padding: 0.3rem 0.45rem 0.3rem 0.55rem;
  font-size: 0.72rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  /* La franja de color va pegada al borde izquierdo, y de ahí sale el color
     de cada filtro. */
  border-left: 3px solid var(--color-filtro, var(--border));
  background: var(--card-bg);
  color: var(--text);
  font-family: var(--font);
  font-weight: 600;
  cursor: pointer;
}
.dash-filtros select:hover { border-color: var(--color-filtro, var(--primary)); }

/* Cada filtro con su color, para reconocerlos sin leerlos: el periodo en
   turquesa, la etapa en ámbar —como las etapas del tablero—, la persona en
   azul y el segmento en violeta. */
.dash-filtros [data-filtro="periodo"] { --color-filtro: var(--primary); }
.dash-filtros [data-filtro="etapa"] { --color-filtro: var(--warn); }
.dash-filtros [data-filtro="persona"] { --color-filtro: #4b8ef0; }
.dash-filtros [data-filtro="segmento"] { --color-filtro: #a06ae0; }
.dash-filtros [data-filtro="corte"] { --color-filtro: var(--good); }

/* Un filtro puesto se ve puesto: se pinta entero, no solo su borde. Antes
   había que abrir cada desplegable para saber por qué el tablero mostraba lo
   que mostraba. */
.dash-filtros select.filtro-activo {
  background: var(--color-filtro, var(--primary));
  border-color: var(--color-filtro, var(--primary));
  color: #ffffff;
}
.dash-filtros .dash-buscar {
  border-left: 3px solid var(--border);
  font-weight: 600;
}
.dash-filtros .dash-buscar.filtro-activo {
  border-left-color: var(--primary);
  background: var(--accent-soft);
}
.dash-filtros .btn { padding: 0.34rem 0.6rem; font-size: 0.72rem; font-weight: 600; }
/* El botón que aplica y los que abren algo, cada uno con su papel: filtrar es
   la acción de esta barra, agregar un negocio es otra cosa. */
.dash-filtros .btn-filtrar {
  background: var(--primary);
  color: #ffffff;
}
.dash-filtros .btn-filtrar:hover { background: var(--primary-dark); }

/* ---------- La luz de los filtros ----------
   Una luz que recorre el borde de cada filtro, como el radar de los negocios
   marcados en el tablero. Es un degradado cónico que gira detrás de un relleno
   del color del filtro: el relleno tapa el centro y solo se ve el contorno, así
   que el texto no se mueve ni pierde contraste. Cada persona elige cuál en Mis
   ajustes (Neón o ninguna).

   Las reglas van en pares —la página y la muestra de Mis ajustes— para que la
   muestra enseñe su propio efecto aunque la página tenga otro. */
@property --giro-filtro {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@keyframes giro-filtro { to { --giro-filtro: 360deg; } }

html:not([data-efecto-filtros="ninguno"]) .dash-filtros :is(select, .dash-buscar, .btn-filtrar),
.muestra-efecto:not([data-efecto-filtros="ninguno"]) .muestra-filtro {
  border: 2px solid transparent;
  background:
    linear-gradient(var(--relleno-filtro, var(--card-bg)), var(--relleno-filtro, var(--card-bg))) padding-box,
    var(--anillo-filtro) border-box;
  /* La franja de color de cada filtro sigue ahí, por dentro: la luz es de
     adorno, el color es lo que dice qué filtro es. */
  box-shadow: inset 3px 0 0 var(--color-filtro, transparent),
              0 0 12px -3px var(--brillo-filtro, transparent);
  animation: giro-filtro var(--vuelta-filtro, 3s) linear infinite;
}
/* El relleno de un filtro puesto, y el del botón, se conservan. */
html .dash-filtros select.filtro-activo { --relleno-filtro: var(--color-filtro, var(--primary)); }
html .dash-filtros .dash-buscar.filtro-activo { --relleno-filtro: var(--accent-soft); }
html .dash-filtros .btn-filtrar { --relleno-filtro: var(--primary); }
html .dash-filtros .btn-filtrar:hover { --relleno-filtro: var(--primary-dark); }

/* Neón: una sola luz del color de cada filtro, como los negocios marcados. */
html[data-efecto-filtros="neon"] .dash-filtros :is(select, .dash-buscar, .btn-filtrar),
html[data-efecto-filtros="neon"] .pipeline-barra-acciones > :is(.btn, .vista-cambio)::after,
html[data-efecto-tarjetas="neon"] .board-card:not(.board-card-foco)::after,
.kpi[data-luz="neon"]::after,
.muestra-efecto[data-efecto-filtros="neon"] .muestra-filtro {
  --vuelta-filtro: 2.8s;
  --brillo-filtro: color-mix(in srgb, var(--color-filtro, var(--primary)) 70%, transparent);
  --anillo-filtro: conic-gradient(from var(--giro-filtro),
    var(--color-filtro, var(--primary)),
    color-mix(in srgb, var(--color-filtro, var(--primary)) 20%, transparent) 25%,
    color-mix(in srgb, var(--color-filtro, var(--primary)) 20%, transparent) 75%,
    var(--color-filtro, var(--primary)));
}

/* Tarjetas e indicadores: el anillo va en un ::after encima del borde, con
   una máscara que deja ver solo el contorno —la misma técnica del radar de los
   negocios marcados—. Así el fondo de cada tarjeta, su franja de etapa y su
   color de KPI quedan intactos debajo.

   Los negocios marcados no llevan esta luz: ya tienen su radar, y si todas las
   tarjetas brillaran, la marca dejaría de servir para encontrarlos. */
html:not([data-efecto-tarjetas="ninguno"]) .board-card:not(.board-card-foco),
html:not([data-efecto-filtros="ninguno"]) .pipeline-barra-acciones > :is(.btn, .vista-cambio),
.kpi[data-luz] { position: relative; }
html:not([data-efecto-tarjetas="ninguno"]) .board-card:not(.board-card-foco)::after,
html:not([data-efecto-filtros="ninguno"]) .pipeline-barra-acciones > :is(.btn, .vista-cambio)::after,
.kpi[data-luz]::after {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 2;
  padding: 2px;
  border-radius: inherit;
  pointer-events: none;
  background: var(--anillo-filtro);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  animation: giro-filtro var(--vuelta-filtro, 3s) linear infinite;
}
/* Con Neón, cada una se ilumina en su propio color: la tarjeta en el de su
   etapa, el indicador en el que se le eligió. */
.board-card::after { --color-filtro: var(--stage-color, var(--primary)); }
.kpi::after { --color-filtro: var(--kpi-realce, var(--primary)); }
/* Los botones de la barra del Funnel van con la luz de los filtros: es la
   misma franja de arriba, y se prenden juntas. Sin color propio, en el del
   portal; el «+ Negocio», que ya es de ese color, en blanco para que se vea. */
.pipeline-barra-acciones > ::after { --color-filtro: var(--primary); }
.pipeline-barra-acciones > .btn-primary::after { --color-filtro: #ffffff; }
/* Un resplandor suave alrededor, del tono de cada luz. */
html[data-efecto-tarjetas="neon"] .board-card:not(.board-card-foco) { box-shadow: 0 0 12px -5px var(--stage-color, var(--primary)); }
.kpi[data-luz="neon"] { box-shadow: 0 0 14px -5px var(--kpi-realce, var(--primary)); }

/* Equipo modesto o pedido de menos movimiento: la luz queda quieta. El borde
   de colores sigue, pero no gira ni titila. */
.equipo-modesto .dash-filtros :is(select, .dash-buscar, .btn-filtrar),
.equipo-modesto .board-card::after,
.equipo-modesto .pipeline-barra-acciones > ::after,
.equipo-modesto .kpi::after,
.equipo-modesto .muestra-filtro { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  .dash-filtros :is(select, .dash-buscar, .btn-filtrar),
  .board-card::after,
  .kpi::after,
  .muestra-filtro { animation: none !important; }
}

/* El botón ✨ que cambia la luz al vuelo: discreto, para no competir. */
.dash-filtros .btn-efecto {
  background: transparent;
  border: 1px solid var(--border);
  padding: 0.28rem 0.45rem;
  line-height: 1;
}
.dash-filtros .btn-efecto:hover { border-color: var(--primary); }

/* La muestra de cada efecto en Mis ajustes. */
.efectos-filtros {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.6rem;
}
.muestra-efecto {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.65rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.muestra-efecto:hover { border-color: var(--primary); }
.muestra-efecto.elegido { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary) inset; }
.muestra-efecto b { font-size: 0.82rem; }
.muestra-efecto small { font-size: 0.68rem; color: var(--text-muted); line-height: 1.35; }
.muestra-filtro {
  display: block;
  padding: 0.3rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 7px;
  font-size: 0.72rem;
  font-weight: 600;
}

.muestra-alta { padding: 0.75rem 0.6rem; border-radius: 9px; }

/* Rejilla de KPI más apretada: caben más en el mismo ancho. */
.kpi-row-densa { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 0.5rem; }
.kpi-row-densa .kpi { padding: 0.5rem 0.6rem; gap: 0.5rem; border-radius: 10px; }
.kpi-row-densa .kpi-icono { width: 27px; height: 27px; border-radius: 7px; }
.kpi-row-densa .kpi-icono svg { width: 14px; height: 14px; }
.kpi-row-densa .kpi-label { font-size: 0.61rem; }
.kpi-row-densa .kpi-valor { font-size: 1.1rem; }
.kpi-row-densa .kpi-nota { font-size: 0.58rem; }

/* Meta y proyección en una franja de una línea. */
.meta-franja {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.8rem;
  margin-bottom: 0.9rem;
  border-radius: 10px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  font-size: 0.76rem;
}
.meta-franja-txt strong { font-size: 0.95rem; }
.meta-franja-txt em { font-style: normal; color: var(--text-muted); }
.meta-franja-barra {
  flex: 1;
  min-width: 110px;
  height: 5px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}
.meta-franja-barra > span { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.meta-franja-proy { color: var(--text-muted); white-space: nowrap; }

/* Tarjetas y secciones algo más juntas, para que quepa más sin apretar. */
.container .card { padding: 0.85rem 1rem; margin-bottom: 0.75rem; }
.container .card h2 { font-size: 0.95rem; margin: 0 0 0.6rem; }
.seccion-titulo { margin-top: 1.1rem; }


/* Ranking, funnel y los dos anillos comparten una sola fila de cuatro. */
.dash-fila-tarjetas {
  display: grid;
  /* minmax(0, …) y no "fr" a secas: si no, un título o una tabla de adentro
     estira su columna y la última tarjeta se sale de la pantalla. */
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1.05fr) minmax(0, 0.95fr) minmax(0, 0.95fr);
  gap: 0.75rem;
  align-items: stretch;
}
@media (max-width: 1250px) {
  .dash-fila-tarjetas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 850px) {
  .dash-fila-tarjetas { grid-template-columns: minmax(0, 1fr); }
}
.dash-fila-tarjetas > .card {
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.ranking-densa { gap: 0.22rem; }
.ranking-densa .ranking-fila {
  grid-template-columns: 20px 1fr auto;
  gap: 0.5rem;
  padding: 0.28rem 0.45rem;
  border-radius: 7px;
}
.ranking-densa .ranking-puesto { width: 20px; height: 20px; font-size: 0.64rem; }
.ranking-densa .ranking-nombre { font-size: 0.75rem; }
.ranking-densa .ranking-medio { min-width: 0; }
.ranking-densa .ranking-barra { height: 3px; margin-top: 3px; }
.ranking-densa .ranking-valor { font-size: 0.76rem; display: flex; align-items: baseline; gap: 0.3rem; }
.ranking-densa .ranking-valor small { font-size: 0.6rem; }


/* ---------- Usuario al pie de la barra lateral ---------- */
.sidebar-footer {
  margin-top: auto;
  padding-top: 0.9rem;
  border-top: 1px solid var(--sidebar-border);
}
.user-menu { position: relative; }

.user-boton {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem 0.55rem;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--sidebar-text);
  cursor: pointer;
  font-family: var(--font);
  text-align: left;
}
.user-boton:hover { background: rgba(255, 255, 255, 0.06); }

.user-avatar {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--sidebar-active-bg);
  color: var(--primary);
  font-size: 0.82rem;
  font-weight: 600;
}
/* Con foto o avatar puesto, el círculo lo muestra en vez de la inicial. */
.user-avatar-foto { object-fit: cover; background: none; }
.user-info { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 0.35rem; }
.user-nombre {
  font-size: 0.85rem;
  font-weight: 500;
  color: #ffffff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.user-rol { font-size: 0.68rem; color: var(--sidebar-text); opacity: 0.7; white-space: nowrap; }
.user-rol::before { content: "· "; }
.user-flecha { font-size: 0.85rem; opacity: 0.6; flex-shrink: 0; transition: transform 0.15s ease; }
.user-menu.abierto .user-flecha { transform: rotate(180deg); }

.user-desplegable {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 45;
  padding: 0.3rem;
  border-radius: 9px;
  background: var(--sidebar-active-bg);
  box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.4);
}
.user-menu.abierto .user-desplegable { display: block; }

.user-desplegable-nombre {
  display: block;
  padding: 0.35rem 0.5rem 0.45rem;
  font-size: 0.7rem;
  color: var(--sidebar-text);
  opacity: 0.75;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  margin-bottom: 0.25rem;
}
.user-opcion {
  display: block;
  width: 100%;
  padding: 0.45rem 0.5rem;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--sidebar-text);
  font-size: 0.78rem;
  font-family: var(--font);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.user-opcion:hover { background: rgba(255, 255, 255, 0.07); color: #ffffff; }
.user-opcion-salir { color: #ef6a58; }
.user-opcion-salir:hover { color: #ff8a7a; }

/* En pantalla angosta la barra es horizontal: el usuario va al final de la fila. */
@media (max-width: 900px) {
  .sidebar-footer {
    display: block;
    margin: 0 0 0 auto;
    padding: 0 0 0 0.75rem;
    border-top: none;
    border-left: 1px solid var(--sidebar-border);
    flex-shrink: 0;
  }
  .user-boton { width: auto; }
  .user-desplegable { left: auto; right: 0; min-width: 190px; }
}


/* Anillos con leyenda al costado: necesitan más ancho que alto. */
.grafico-circular-wrap.grafico-circular-chico { height: 235px; }


/* ---------- Tarjetas de gráfico: mismo lenguaje que los KPI ---------- */
/* Título tenue en mayúsculas, como la etiqueta de un KPI, para que el dato
   sea lo que pese en la pantalla y no el encabezado. */
.pipeline-grid-mini .card h2,
.dash-fila-tarjetas .card h2,
.grafico-card h2 {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}
.pipeline-grid-mini .card,
.grafico-card {
  border-radius: 12px;
  padding: 0.8rem 0.9rem;
}
.pipeline-grid-mini .card .subtitle,
.grafico-card .subtitle { font-size: 0.66rem; }

/* Rejilla de gráficos algo más apretada. */
.pipeline-grid-mini { gap: 0.7rem; }


/* ---------- Pipeline por etapa: paleta sobria ---------- */
/* En la tabla del dashboard las etapas ya se distinguen por su texto, así que
   los siete colores solo hacían ruido. Se usa un chip neutro y el color queda
   reservado para los extremos: perdido y habilitado. */
#pipeline-vista-tabla .badge {
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid var(--border);
  font-weight: 500;
}
#pipeline-vista-tabla .badge-etapa-100 {
  background: var(--ok-bg);
  color: var(--ok-text);
  border-color: transparent;
}
#pipeline-vista-tabla .badge-etapa-0 {
  background: transparent;
  color: var(--text-muted);
  border-style: dashed;
}
#pipeline-vista-tabla td { font-size: 0.8rem; }
#pipeline-vista-tabla th { font-size: 0.64rem; }


/* Aire entre la fila de tarjetas principales y los gráficos que siguen. */
.dash-fila-tarjetas { margin-bottom: 1.4rem; }
.dash-fila-tarjetas + .pipeline-grid-mini { margin-top: 0.2rem; }
.dash-fila-tarjetas .card h2 { font-size: 0.72rem; }


/* ---------- El anillo llena el cuadro que le toca ---------- */
/* En vez de un alto fijo que dejaba franjas vacías bajo la leyenda, el gráfico
   se estira hasta el borde inferior de su tarjeta. Como las tarjetas de una
   misma fila comparten alto, los anillos quedan del mismo tamaño entre sí. */
.dash-fila-tarjetas .grafico-circular-wrap,
.pipeline-grid-mini .grafico-circular-wrap {
  flex: 1;
  height: auto;
  min-height: 190px;
  padding: 0;
}
.pipeline-grid-mini > .card {
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin-bottom: 0;
}
/* Todas las tarjetas de la fila inferior con el mismo alto, como la de arriba. */
.pipeline-grid-mini { align-items: stretch; }


/* ---------- Encabezado de gráfico: título, una línea de contexto y la "i" ---------- */
/* La explicación larga se guarda tras el botón de info para no gastar dos o tres
   renglones en cada tarjeta. */
.grafico-cabecera {
  position: relative;
  margin-bottom: 0.5rem;
}
.grafico-cabecera h2 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.grafico-resumen {
  margin: 0.15rem 0 0;
  font-size: 0.68rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.grafico-cabecera .kpi-ayuda { margin-top: 0.4rem; }
.grafico-cabecera-acciones {
  position: absolute;
  top: -0.1rem;
  right: 0;
  display: flex;
  gap: 0.4rem;
  align-items: center;
}


/* ---------- Paso 1/2 - 2/2 de un gráfico ---------- */
/* Deja mirar la misma tarjeta con otra medida (líneas en vez de negocios, RUT
   en vez de líneas) sin gastar una tarjeta extra en la pantalla. */
.grafico-paso {
  position: absolute;
  top: -0.15rem;
  right: 0;
  display: flex;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px;
}
.grafico-paso button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.6rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.22rem 0.4rem;
  border-radius: 999px;
  cursor: pointer;
}
.grafico-paso button:hover { color: var(--text); }
.grafico-paso button.activo {
  background: var(--primary);
  color: var(--on-primary, #06231f);
}
/* El título deja sitio al control para no pasar por debajo. */
.grafico-cabecera:has(.grafico-paso) h2 { padding-right: 3.4rem; }


/* Cierre del dashboard: el anillo de compañía a un ancho fijo cómodo y la tabla
   del equipo tomando el resto. Sin esto el anillo solo se estiraba a toda la fila. */
.dash-fila-cierre {
  display: grid;
  grid-template-columns: minmax(240px, 0.85fr) minmax(0, 2fr);
  gap: 0.75rem;
  align-items: stretch;
  margin-bottom: 1.25rem;
}
@media (max-width: 900px) {
  .dash-fila-cierre { grid-template-columns: minmax(0, 1fr); }
}
.dash-fila-cierre > .card {
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.dash-fila-cierre .grafico-circular-wrap {
  flex: 1;
  height: auto;
  min-height: 200px;
}
.dash-fila-cierre .card h2 { font-size: 0.72rem; }
.dash-fila-cierre .table-wrap { flex: 1; overflow-y: auto; }
.tabla-densa { font-size: 0.78rem; }
.tabla-densa th { font-size: 0.62rem; }
.tabla-densa td, .tabla-densa th { padding: 0.3rem 0.45rem; }


/* Avisos del Pipeline: una línea, no una tarjeta, para no empujar el tablero. */
.pipeline-aviso {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.pipeline-tablero-cabecera { margin: 0.2rem 0 0.6rem; }
.pipeline-tablero-cabecera h2 { font-size: 0.9rem; margin: 0; }
/* Alertas y detalle quedan bajo el tablero: son de consulta, no de entrada. */
.pipeline-posterior { margin-top: 1.5rem; }
/* Buscador dentro de la tira de filtros compactos. */
.dash-buscar {
  font-size: 0.72rem;
  padding: 0.25rem 0.5rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  min-width: 150px;
}

/* Aviso de tareas pendientes: un enlace en la línea del subtítulo, no una tarjeta. */
.aviso-inline {
  color: var(--warn);
  text-decoration: none;
  font-weight: 600;
}
.aviso-inline:hover { text-decoration: underline; }


/* ---------- Avisos rotativos del Funnel ---------- */
/* Una sola línea: los avisos se turnan en el mismo sitio en vez de apilarse en
   una tarjeta que empujaría el tablero fuera de la pantalla. */
.alertas-rotativas {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.4rem 0.7rem;
  margin-bottom: 0.6rem;
  font-size: 0.78rem;
  min-height: 34px;
}
.alertas-etiqueta {
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  flex-shrink: 0;
}
/* El visor mantiene su alto con un solo aviso encima de otro. */
.alertas-visor {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 1.2rem;
}
.alerta-item {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.35s ease, transform 0.35s ease;
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.alerta-item.activa {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.alerta-item a { color: inherit; text-decoration: none; }
.alerta-item a:hover { text-decoration: underline; }
.alerta-icono { flex-shrink: 0; }
.alerta-riesgo { color: var(--danger); }
.alerta-aviso { color: var(--warn); }
.alerta-bien { color: var(--good); }
.alerta-info { color: var(--text); }

.alertas-puntos { display: flex; gap: 4px; flex-shrink: 0; }
.alertas-puntos button {
  width: 5px;
  height: 5px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--border);
  cursor: pointer;
}
.alertas-puntos button.activo { background: var(--primary); }

/* ---------- Franja de prensa (jefatura) ---------- */
/* Misma franja que las alertas. Cada titular lleva la sigla de su medio en
   una etiqueta de periódico —letra con serifa— para distinguir de un vistazo
   lo que es noticia de afuera de lo que es aviso del propio portal. El DF
   conserva su rosado salmón; los demás van en neutro. */
.franja-df-medio {
  flex-shrink: 0;
  min-width: 2.1rem;
  text-align: center;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.02rem 0.3rem;
}
.franja-df-medio.medio-df { color: #1a1a1a; background: #f2c7b2; border-color: #e7b49b; }
/* LinkedIn: su azul y letra sin serifa, que no es un diario sino una red. */
.franja-df-medio.medio-linkedin {
  color: #ffffff;
  background: #0a66c2;
  border-color: #0a66c2;
  font-family: var(--font);
  letter-spacing: 0.02em;
}
.franja-df-item { gap: 0.5rem; }
.franja-df-item a { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.franja-df-cuando {
  flex-shrink: 0;
  font-size: 0.68rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.franja-df-motivo {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 0.6rem;
  font-weight: 600;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--primary-dark);
}
@media (max-width: 820px) {
  /* En el teléfono no cabe todo: el titular manda. */
  .franja-df-motivo { display: none; }
}

/* Estado de la lectura en Ajustes. */
.df-estado { list-style: none; margin: 0.4rem 0 0.8rem; padding: 0; display: grid; gap: 0.35rem; font-size: 0.85rem; }
.df-estado li { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 1px solid var(--border); padding-bottom: 0.3rem; }
.df-estado li span { color: var(--text-muted); }
.df-estado-error strong { color: var(--error-text); font-weight: 600; text-align: right; }
.df-palabras { display: grid; gap: 0.5rem; }
/* Separa el filtro de lo que no se quiere ver del de las palabras del rubro:
   son dos listas opuestas y pegadas se confunden. */
.df-subtitulo {
  margin: 1.4rem 0 0.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  font-size: 0.95rem;
}
.df-palabras textarea { width: 100%; font-size: 0.85rem; }
.df-muestra-titulo { margin: 1rem 0 0.4rem; font-size: 0.78rem; font-weight: 600; }
.df-muestra { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; font-size: 0.8rem; }
.df-muestra li { display: flex; align-items: baseline; gap: 0.5rem; }
.df-muestra a { color: var(--text); text-decoration: none; flex: 1; min-width: 0; }
.df-muestra a:hover { text-decoration: underline; }
/* Lo que completa la franja se ve más apagado que lo del rubro. */
.franja-df-motivo.franja-df-economia { background: var(--surface-2); color: var(--text-muted); font-weight: 500; }
.df-medios { width: 100%; font-size: 0.8rem; border-collapse: collapse; margin: 0.4rem 0 0.7rem; }
.df-medios th { text-align: left; font-size: 0.68rem; font-weight: 600; color: var(--text-muted); padding: 0.3rem 0.5rem; }
.df-medios td { padding: 0.35rem 0.5rem; border-top: 1px solid var(--border); white-space: nowrap; }
.df-medios td:nth-child(3), .df-medios td:nth-child(4) { font-variant-numeric: tabular-nums; }
.df-medio-apagado td { opacity: 0.5; }
.df-completar { flex-direction: row; align-items: flex-start; gap: 0.5rem; margin: 0 0 0.7rem; font-size: 0.8rem; color: var(--text); }
.df-ok { color: var(--ok-text); font-weight: 600; }
.df-error { color: var(--error-text); white-space: normal; }

@media (prefers-reduced-motion: reduce) {
  .alerta-item { transition: none; }
}


/* ---------- Ranking: ocho filas que llenan la tarjeta ---------- */
/* El equipo son ocho personas y no van a ser más, así que en vez de dejar las
   filas apiladas arriba con un hueco abajo, se reparten el alto disponible. */
.dash-fila-tarjetas .ranking {
  flex: 1;
  min-height: 0;
  justify-content: space-between;
}
.dash-fila-tarjetas .ranking-fila {
  flex: 1;
  min-height: 0;
  align-content: center;
}

/* Dentro de la fila del dashboard, el gráfico del funnel se estira hasta el
   borde de su tarjeta en vez de quedarse en 200px con espacio sobrante debajo. */
.dash-fila-tarjetas #pipeline-vista-grafico {
  flex: 1;
  display: flex;
  min-height: 0;
}
.dash-fila-tarjetas .grafico-barra-compacto {
  flex: 1;
  height: auto;
  min-height: 190px;
}


/* ---------- Iconos de etiqueta en trazo ---------- */
/* Reemplazan a los emoji, que se veían de otra familia visual que el resto. */
.etiqueta-icono {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  vertical-align: -2px;
}
.etiqueta-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
/* En el tablero las etiquetas van sueltas, más pequeñas. */
.board-etiquetas .etiqueta-icono { width: 12px; height: 12px; }


/* Columna derecha de la ficha: Tareas con su folio y, debajo, las etiquetas. */
.detalle-columna {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}
.detalle-columna > .card { margin-bottom: 0; }

/* Gráficos de alto medio (Histórico y Comisiones): acotados como en el dashboard. */
.grafico-medio { height: 260px; }

/* Barras horizontales con muchas categorías: necesitan alto suficiente para
   que quepan todos los nombres, o el gráfico esconde la mitad. */
.grafico-barras-largo { height: 330px; }


/* ---------- Ficha del negocio: dos columnas parejas ---------- */
/* Izquierda: ficha, aviso de contacto y sugerencia. Derecha: tareas con su
   folio y las etiquetas. Ambas terminan a la misma altura. */
.detalle-grid { align-items: stretch; }
/* La ficha se estira para que la sugerencia quede abajo, alineada con las
   etiquetas del otro lado. */
.detalle-grid > .detalle-columna { height: 100%; }
/* En cada columna crece una tarjeta —la ficha a la izquierda, tareas a la
   derecha— para que ambas cierren a la misma altura. */
.detalle-grid .card-ficha,
.detalle-grid .recordatorio-card { flex: 1; }
/* El aviso de contacto incompleto, ya dentro de la columna, va sin margen extra. */
.detalle-columna .alerta-compacta { margin-bottom: 0; }

/* Fila de totales de una tabla densa. */
.tabla-densa-total th { font-weight: 700; border-top: 1px solid var(--border); }


/* ---------- Bitácora ---------- */
.bitacora-fecha { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-muted); }
.bitacora-antes { color: var(--text-muted); text-decoration: line-through; }
.bitacora-despues { font-weight: 600; }
.bitacora-paginas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
}


/* La propia fila del ranking, para que cada ejecutivo se ubique de un vistazo. */
.ranking-fila-propia {
  background: var(--surface-3, var(--surface-2));
  box-shadow: inset 2px 0 0 var(--primary);
}
.ranking-fila-propia .ranking-nombre { font-weight: 700; color: var(--primary); }


/* ---------- Envíos programados ---------- */
.envios-estado {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}
.envio-tramo {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.4rem 0.7rem;
  border-radius: 9px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 0.76rem;
}
.envio-hora { font-weight: 700; font-variant-numeric: tabular-nums; }
.envio-nombre { color: var(--text-muted); }
.envio-marca { font-size: 0.7rem; }
.envio-hecho { border-color: var(--good); }
.envio-hecho .envio-marca { color: var(--good); }
.envio-pendiente .envio-marca { color: var(--text-muted); }
.envio-inactivo { opacity: 0.5; }

.envios-cron {
  padding: 0.7rem 0.85rem;
  border-radius: 10px;
  background: var(--surface-2);
}
.envios-comando {
  display: block;
  padding: 0.5rem 0.6rem;
  border-radius: 7px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 0.72rem;
  word-break: break-all;
}
.envios-aviso {
  margin: 0.6rem 0 0;
  font-size: 0.76rem;
  color: var(--warn);
}


/* ---------- Editor de plantillas de correo ---------- */
.plantilla-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}
.plantilla-tab {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0.45rem 0.7rem;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--surface);
  text-decoration: none;
  color: var(--text);
}
.plantilla-tab:hover { border-color: var(--primary); }
.plantilla-tab.activa { border-color: var(--primary); background: var(--surface-2); }
.plantilla-tab-nombre { font-size: 0.78rem; font-weight: 600; }
.plantilla-tab-meta { font-size: 0.62rem; color: var(--text-muted); }
.plantilla-desc { margin: 0 0 1rem; font-size: 0.76rem; }

.plantilla-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1.1fr;
  gap: 0.75rem;
  align-items: start;
}
@media (max-width: 1150px) {
  .plantilla-grid { grid-template-columns: 1fr; }
}

.bloque-lista {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-height: 120px;
  padding: 0.3rem;
  border-radius: 9px;
}
/* La lista del correo se marca como zona donde se puede soltar. */
.bloque-lista-destino {
  border: 1px dashed var(--border);
  min-height: 220px;
}
.lista-activa { border-color: var(--primary); background: var(--surface-2); }

.bloque-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  cursor: grab;
}
.bloque-item.arrastrando { opacity: 0.4; }
.bloque-elegido { border-left: 3px solid var(--primary); }
.bloque-arrastre { color: var(--text-muted); cursor: grab; font-size: 0.9rem; }
.bloque-icono { font-size: 0.95rem; }
.bloque-texto { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.bloque-texto strong { font-size: 0.76rem; }
.bloque-texto small { font-size: 0.64rem; color: var(--text-muted); line-height: 1.3; }
.bloque-accion {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  padding: 0.15rem 0.35rem;
  border-radius: 6px;
  cursor: pointer;
}
.bloque-accion:hover { background: var(--surface); color: var(--primary); }
.bloque-vacio { font-size: 0.7rem; color: var(--text-muted); text-align: center; padding: 1.2rem 0.5rem; margin: 0; }

.plantilla-campo {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 0.7rem;
  font-size: 0.72rem;
}
.plantilla-campo small { color: var(--text-muted); font-weight: 400; }
.plantilla-campo textarea {
  font-size: 0.75rem;
  padding: 0.4rem 0.5rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  resize: vertical;
}
.plantilla-acciones { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.8rem; }

/* La vista previa va sobre fondo claro: el correo es siempre claro. */
/* Revisión antes de enviar: a quién le llega el correo y el de quién se ve. */
.revision { display: grid; gap: 0.5rem; margin-bottom: 0.8rem; }
.revision-fila { display: flex; align-items: flex-end; gap: 0.5rem; flex-wrap: wrap; }
.revision-quien { flex: 1 1 200px; font-size: 0.75rem; }
.revision-quien select { width: 100%; font-size: 0.85rem; }
.revision-estado {
  margin: 0;
  padding: 0.45rem 0.7rem;
  border-radius: 8px;
  font-size: 0.8rem;
  background: var(--surface-2);
  color: var(--text-muted);
}
.revision-estado.revision-si { background: var(--ok-bg); color: var(--ok-text); }
.revision-estado.revision-no { background: var(--notice-bg); color: var(--notice-text); }
.revision-lista summary { cursor: pointer; font-size: 0.78rem; font-weight: 600; color: var(--text); }
.revision-lista ul { margin: 0.4rem 0 0; padding-left: 1.1rem; display: grid; gap: 0.25rem; font-size: 0.76rem; color: var(--text-muted); }
.revision-lista li.revision-si::marker { color: var(--good); }
.revision-lista li.revision-no::marker { color: var(--warn); }
.revision-cuenta { font-size: 0.68rem; font-weight: 600; color: var(--primary); }
.revision-avisos p {
  margin: 0;
  padding: 0.45rem 0.7rem;
  border-radius: 8px;
  font-size: 0.78rem;
  background: var(--error-bg);
  color: var(--error-text);
}

.plantilla-vista {
  width: 100%;
  height: 620px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: #eef0f2;
}

/* Selector de días para un correo periódico. */
.dias-selector {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.6rem;
}
.dias-titulo { font-size: 0.72rem; color: var(--text-muted); margin-right: 0.2rem; }
.dia-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 0.72rem;
  cursor: pointer;
}
.dia-chip:has(input:checked) { border-color: var(--primary); color: var(--primary); }

/* Aviso de algo que impide funcionar, no solo una advertencia. */
.notice-bloqueante {
  margin-bottom: 1.25rem;
  padding: 0.7rem 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--danger);
}


/* ---------- Secciones plegables de Ajustes ---------- */
/* Ajustes tiene cuatro áreas largas; plegadas se ve todo el mapa de una vez
   y se abre solo aquello que se va a tocar. */
.seccion-plegable {
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface);
  margin-bottom: 0.6rem;
  overflow: hidden;
}
.seccion-cabecera {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0.7rem 0.9rem;
  cursor: pointer;
  list-style: none;
  position: relative;
  padding-right: 2.2rem;
}
.seccion-cabecera::-webkit-details-marker { display: none; }
/* Flecha propia, que gira al abrir. */
.seccion-cabecera::after {
  content: "⌄";
  position: absolute;
  right: 1rem;
  top: 0.7rem;
  color: var(--text-muted);
  transition: transform 0.2s ease;
}
.seccion-plegable[open] .seccion-cabecera::after { transform: rotate(180deg); }
.seccion-cabecera:hover { background: var(--surface-2); }
.seccion-nombre { font-size: 0.92rem; font-weight: 600; }
.seccion-desc { font-size: 0.7rem; color: var(--text-muted); }
.seccion-cuerpo {
  padding: 0.2rem 0.9rem 0.9rem;
  border-top: 1px solid var(--border);
}
.seccion-cuerpo > .card:first-child { margin-top: 0.9rem; }

/* Registro de errores: texto técnico, monoespaciado y con scroll propio. */
.log-errores {
  margin: 0;
  padding: 0.8rem;
  border-radius: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.7rem;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 65vh;
  overflow: auto;
}


/* ---------- Formulario SMTP ---------- */
/* Los valores son largos (correos completos, nombres de servidor) y en la
   rejilla genérica quedaban cortados. Aquí las columnas se dimensionan por lo
   que realmente contienen y los textos ya no se salen de su caja. */
.form-smtp .grid-items {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.9rem 1.1rem;
}
.form-smtp .item-field { min-width: 0; }
.form-smtp .item-field label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.78rem;
  line-height: 1.35;
}
.form-smtp .item-field input[type="text"],
.form-smtp .item-field input[type="password"],
.form-smtp .item-field input[type="number"],
.form-smtp .item-field input[type="email"] {
  width: 100%;
  box-sizing: border-box;
  font-size: 0.88rem;
  padding: 0.5rem 0.6rem;
  text-overflow: ellipsis;
}
/* El puerto es un número corto: no necesita una columna entera. */
.form-smtp .item-field-corto { max-width: 150px; }
/* La casilla de TLS se alinea con los campos, no con sus etiquetas. */
.form-smtp .item-field-casilla label {
  flex-direction: row;
  align-items: flex-start;
  gap: 0.45rem;
  margin-top: 1.4rem;
}
.form-smtp .item-field-casilla input { margin-top: 0.15rem; flex-shrink: 0; }

/* ---------- Horarios de envío editables ---------- */
.horarios-lista { display: flex; flex-direction: column; gap: 0.4rem; }
.horario-fila {
  display: grid;
  grid-template-columns: minmax(180px, 1.4fr) auto auto auto auto;
  align-items: center;
  gap: 0.9rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}
@media (max-width: 900px) {
  .horario-fila { grid-template-columns: 1fr; gap: 0.5rem; }
}
.horario-apagado { opacity: 0.55; }
.horario-nombre { display: flex; flex-direction: column; min-width: 0; }
.horario-nombre strong { font-size: 0.82rem; }
.horario-nombre small { font-size: 0.66rem; color: var(--text-muted); }
.horario-hora { display: flex; flex-direction: column; gap: 0.2rem; }
.horario-hora span { font-size: 0.62rem; color: var(--text-muted); }
.horario-hora input {
  font-size: 0.8rem;
  padding: 0.25rem 0.4rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
.horario-dias { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; }
.horario-dias .dia-chip { padding: 0.2rem 0.4rem; font-size: 0.68rem; }
.horario-activo {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  color: var(--text-muted);
  white-space: nowrap;
}
/* El botón de eliminar va aparte para que no se pulse por error al guardar. */
.horario-eliminar { margin: -0.2rem 0 0.3rem auto; }

/* Selector de destinatarios dentro del editor de correos. */
.plantilla-campo select {
  font-size: 0.78rem;
  padding: 0.4rem 0.5rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
}


/* ---------- Hunting: nube de prospectos por llamar ---------- */
/* La base sin gestionar es lo que hay que trabajar, así que es lo primero que
   se ve y ocupa la mayor parte de la pantalla. Las burbujas se reparten en
   anillos alrededor del centro —donde queda la barra de búsqueda— y flotan
   apenas: unos pocos píxeles, muy lento, para que la pantalla se sienta viva
   sin que cueste hacer clic. */
/* Con los filtros arriba, la nube arranca donde terminan: el tirón hacia
   arriba ahora lo lleva la tira de filtros, que es lo que sube a la altura del
   buscador de la cabecera. */
.hunting-nube-zona {
  position: relative;
  margin: 0 0 0.8rem;
  padding: 0;
}
/* Interruptor de forma, al estilo del de día/noche: dos siluetas y una pastilla
   que se desliza a la elegida. */
.forma-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  cursor: pointer;
  position: relative;
}
.forma-opcion {
  width: 18px;
  height: 18px;
  display: block;
  border: 2px solid var(--text-muted);
  transition: border-color 0.18s ease, background 0.18s ease;
}
.forma-rect { border-radius: 4px; }
.forma-circulo { border-radius: 50%; }
/* La forma activa se marca rellena. */
.forma-toggle .forma-rect { border-color: var(--primary); background: var(--primary); }
.forma-toggle.en-circulo .forma-rect { border-color: var(--text-muted); background: transparent; }
.forma-toggle.en-circulo .forma-circulo { border-color: var(--primary); background: var(--primary); }
.forma-toggle:hover { border-color: var(--primary); }

.hunting-nube {
  position: relative;
  width: 100%;
  height: 62vh;
  min-height: 380px;
  overflow: hidden;
  /* Por debajo del buscador: las tarjetas le pasan por detrás. */
  z-index: 0;
}
.hunting-vacio {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* Tamaño de las tarjetas de la nube. Va en variables porque el JS lo lee de
   aquí para calcular cuántas caben: si estuviera escrito en los dos lados,
   tarde o temprano dirían cosas distintas. Se achican en pantallas chicas para
   que quepan más y la nube se vea variada, que es su gracia. */
:root {
  --nube-ancho: 150px;
  --nube-alto: 84px;
  --nube-alto-abierta: 122px;
  --nube-circulo: 96px;
  --nube-circulo-abierto: 142px;
}

/* Tarjeta flotante: rectangular con esquinas suaves. Cabe más dato a la vista
   que en un círculo, y el texto se lee en líneas rectas. */
.nube-card {
  position: absolute;
  width: var(--nube-ancho);
  height: var(--nube-alto);
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.2rem;
  padding: 0.5rem 0.7rem;
  border-radius: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  text-decoration: none;
  color: var(--text);
  opacity: 0;
  box-shadow: 0 2px 12px rgb(0 0 0 / 0.16);
  overflow: hidden;
  /* Mientras no se ve, no recibe clics. Sin esto, una tarjeta que todavía está
     apareciendo —invisible pero ya colocada— se robaba el clic de la que sí
     estaba visible debajo, y abría otra empresa. */
  pointer-events: none;
}
/* Recién cuando terminó de aparecer pasa a ser clicable. */
.nube-card.lista { pointer-events: auto; }
.nube-card.entrando {
  animation: nube-entrar 0.5s ease forwards,
             nube-flotar var(--dur, 9s) ease-in-out infinite;
  animation-delay: inherit, var(--desfase, 0s);
}
.nube-quieta .nube-card.entrando { animation: nube-entrar 0.4s ease forwards; }
/* En un equipo modesto la nube no flota: cada tarjeta animada ocupa memoria
   de la tarjeta gráfica todo el rato, y con cien a la vez se nota. */
.equipo-modesto .nube-card.entrando { animation: nube-entrar 0.4s ease forwards; }

/* Al pasar el cursor se detiene, crece y muestra el resto de los datos: hace
   falta para poder leerla y hacer clic con comodidad. */
/* Profundidad de reparto: unas quedan por delante de otras. */
.nube-card.capa-1 { z-index: 1; }
.nube-card.capa-2 { z-index: 2; }
.nube-card.capa-3 { z-index: 3; }
.nube-card.capa-4 { z-index: 4; }

/* La que se está mirando pasa al frente de todas, por encima de cualquier capa. */
.nube-card:hover,
.nube-card:focus-visible {
  animation-play-state: paused;
  z-index: 50;
  height: var(--nube-alto-abierta);
  border-color: var(--primary);
  box-shadow: 0 8px 26px rgb(0 0 0 / 0.32);
}
.nube-card { transition: height 0.18s ease, border-color 0.18s ease; }

@keyframes nube-entrar {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.72); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes nube-flotar {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg); }
  50%      { transform: translate(-50%, calc(-50% - var(--sube, 8px))) rotate(var(--giro, 1deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .nube-card.entrando { animation: nube-entrar 0.3s ease forwards; }
}

.nube-empresa {
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.2;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.nube-fila { display: flex; align-items: baseline; gap: 0.4rem; }
.nube-lineas {
  display: flex;
  align-items: baseline;
  gap: 0.2rem;
  line-height: 1;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--primary);
}
.nube-lineas small { font-size: 0.52rem; font-weight: 400; color: var(--text-muted); }
.nube-segmento {
  font-size: 0.54rem;
  padding: 0.08rem 0.3rem;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.nube-datos {
  font-size: 0.6rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* El detalle solo aparece cuando la tarjeta crece. */
.nube-detalle {
  display: none;
  font-size: 0.6rem;
  line-height: 1.35;
  color: var(--text-muted);
}
.nube-detalle b { color: var(--primary); }
.nube-detalle span { display: block; }
.nube-card:hover .nube-detalle { display: block; }

/* Filtros de Hunting: van arriba de todo, porque son la forma de llegar a una
   empresa en una base de miles. Sin tirón hacia arriba: ese espacio lo ocupaba
   la nube, cuyas tarjetas rodean el buscador de la cabecera sin taparlo. Una
   tira de filtros, en cambio, es maciza: subida ahí se metía debajo de la
   cabecera y quedaba cortada. */
.hunting-filtros { margin: 0 0 0.9rem; }
/* Lo que acomoda la nube va al final de la tira y en gris: está a mano para
   quien lo use, pero no compite con los filtros. */
.hunting-extras {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: auto;
  padding-left: 0.6rem;
  border-left: 1px solid var(--border);
  opacity: 0.65;
  transition: opacity 0.15s ease;
}
.hunting-extras:hover,
.hunting-extras:focus-within { opacity: 1; }
/* Resumen breve de la base, junto a los filtros. */
.hunting-resumen {
  margin: 0 0 0.45rem;
  font-size: 0.72rem;
  color: var(--text-muted);
}
.hunting-resumen strong { color: var(--text); }
.dash-filtros-hunting {
  justify-content: flex-start;
  flex-wrap: wrap;
}

/* El buscador de Hunting: primero en la fila, más alto que los filtros y con
   su lupa, para que se encuentre sin buscarlo. */
.hunting-buscar {
  display: inline-flex;
  /* Es un <label> y los label del formulario van en columna: aquí no. */
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  flex: 0 1 280px;
  min-width: 220px;
  padding: 0.38rem 0.7rem;
  border: 1.5px solid var(--primary);
  border-radius: 999px;
  background: var(--card-bg);
  box-shadow: 0 0 0 3px var(--accent-soft);
  cursor: text;
  transition: box-shadow 0.15s ease;
}
.hunting-buscar:focus-within { box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 30%, transparent); }
.hunting-buscar svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--primary); }
.hunting-buscar input {
  flex: 1;
  min-width: 0;
  padding: 0;
  text-align: left;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font);
  font-size: 0.82rem;
  font-weight: 500;
}
.hunting-buscar input::placeholder { color: var(--text-muted); font-weight: 400; }

/* Rubro y ciudad traen nombres largos que estiraban la fila entera: se
   acortan y el nombre completo se ve al abrir la lista. */
.dash-filtros select.filtro-angosto {
  width: 7.5rem;
  max-width: 7.5rem;
  text-overflow: ellipsis;
}

/* ---------- Hunting: el resto de los estados, abajo y bajo ---------- */
/* Son de consulta: se les da la franja menor para que el foco quede arriba. */
.board-bajo { max-height: 34vh; }
.board-bajo .board-column { max-height: 32vh; overflow-y: auto; }
.board-bajo .board-card { padding: 0.45rem 0.55rem; }
.board-bajo .board-card .empresa { font-size: 0.72rem; }
.board-bajo .prospecto-linea { font-size: 0.66rem; }
.board-bajo .chip { font-size: 0.6rem; padding: 0.1rem 0.35rem; }
.board-vacio { font-size: 0.72rem; color: var(--text-muted); padding: 0 0.15rem; }

/* En Hunting las tarjetas pasan por detrás del buscador, así que este necesita
   fondo sólido y un halo que lo despegue de lo que flota atrás. */
.global-search input {
  box-shadow: 0 0 0 6px var(--bg), 0 2px 14px rgb(0 0 0 / 0.35);
}

/* ---------- Hunting: variante circular ---------- */
/* Mismo reparto y mismo movimiento; solo cambia la silueta y qué datos caben. */
.nube-circulos .nube-card {
  width: var(--nube-circulo);
  height: var(--nube-circulo);
  border-radius: 50%;
  align-items: center;
  text-align: center;
  padding: 0.5rem;
  gap: 0.15rem;
}
.nube-circulos .nube-card:hover {
  width: var(--nube-circulo-abierto);
  height: var(--nube-circulo-abierto);
}
.nube-circulos .nube-empresa { font-size: 0.62rem; -webkit-line-clamp: 3; }
.nube-circulos .nube-fila { justify-content: center; }
.nube-circulos .nube-lineas { font-size: 0.86rem; }
/* En el círculo no cabe la línea de operador y ciudad: se guarda para el hover. */
.nube-circulos .nube-datos { display: none; }
.nube-circulos .nube-card:hover .nube-datos { display: block; font-size: 0.55rem; }
.nube-circulos .nube-card:hover .nube-empresa { -webkit-line-clamp: 2; }
.nube-circulos .nube-card { transition: width 0.18s ease, height 0.18s ease, border-color 0.18s ease; }

/* Campo numérico corto dentro de una tira de filtros. */
.dash-numero {
  width: 66px;
  font-size: 0.72rem;
  padding: 0.25rem 0.4rem;
  border-radius: 7px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
}

/* Aviso de prospectos devueltos automáticamente a la base. */
.hunting-reciclados {
  margin: 0 0 0.6rem;
  padding: 0.45rem 0.7rem;
  border-radius: 9px;
  background: var(--surface-2);
  border-left: 3px solid var(--primary);
  font-size: 0.74rem;
  color: var(--text-muted);
}
.hunting-reciclados strong { color: var(--text); }
.hunting-regla { font-size: 0.66rem; opacity: 0.85; }

/* Los cuatro campos de tamaño van juntos, para que se lean como un solo filtro. */
.filtro-lineas {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 4px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
}
.filtro-lineas select { border: 0; background: transparent; }
.filtro-lineas .dash-numero { width: 58px; border: 0; background: transparent; }
.filtro-lineas .dash-numero:focus { background: var(--surface-2); }

/* ---------- Nombres largos en las tarjetas ---------- */
/* Un nombre de empresa puede ser larguísimo. Primero se achica la letra, y si
   aun así no cabe se recorta con puntos suspensivos, siempre dentro del margen
   de la tarjeta: nunca se desborda. */
.nube-empresa {
  /* Parte también palabras sin espacios, que son las que desbordaban. */
  overflow-wrap: anywhere;
  word-break: break-word;
  max-width: 100%;
}
.nube-empresa.nombre-largo { font-size: 0.64rem; line-height: 1.2; }
.nube-empresa.nombre-muy-largo { font-size: 0.58rem; line-height: 1.15; }
.nube-circulos .nube-empresa.nombre-largo { font-size: 0.56rem; }
.nube-circulos .nube-empresa.nombre-muy-largo { font-size: 0.5rem; }
/* Al agrandarse la tarjeta hay sitio para leerlo completo. */
.nube-card:hover .nube-empresa { -webkit-line-clamp: 3; }

/* ---------- Compromiso editable en la tabla del equipo ---------- */
/* Se ve como una celda más hasta que se hace foco: así la tabla se lee sin
   parecer un formulario, pero se edita con un clic. */
.celda-compromiso {
  width: 60px;
  padding: 0.15rem 0.3rem;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: 0.78rem;
  font-family: inherit;
  text-align: left;
}
.celda-compromiso:hover { border-color: var(--border); background: var(--surface-2); }
.celda-compromiso:focus {
  outline: none;
  border-color: var(--primary);
  background: var(--surface-2);
}
/* Destello verde al guardar, para saber que quedó. */
.celda-compromiso.guardado { border-color: var(--good); background: var(--ok-bg, var(--surface-2)); }
.celda-compromiso.con-error { border-color: var(--danger); }
/* Tabla de ventas del mes: ancho fijo para que las siete cifras midan lo
   mismo, y títulos en dos líneas parejas (nombre arriba, detalle abajo). En
   pantallas angostas la tabla conserva su ancho y se desliza de lado. */
.tabla-ventas { table-layout: fixed; width: 100%; min-width: 620px; }
.tabla-ventas .col-nombre { width: 21%; }
.tabla-ventas .col-cifra { width: calc(79% / 7); }
/* Títulos en dos líneas parejas: nombre arriba y detalle abajo, cada uno en
   una sola línea (un poco más compactos que en otras tablas, para que quepan
   enteros aunque la tarjeta vaya angosta, sin cortar palabras con guion). */
.tabla-ventas thead th {
  vertical-align: bottom;
  text-align: left;
  line-height: 1.3;
  font-size: 0.54rem;
  letter-spacing: 0;
  padding-left: 0.3rem;
  padding-right: 0.3rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tabla-ventas thead th small { display: block; font-weight: 500; opacity: 0.75; }
/* Todas las filas a la misma altura: el nombre va en una línea (completo al
   pasar el cursor) y la celda de avance reserva sitio para su segunda línea. */
.tabla-ventas tbody td {
  height: 2.6rem;
  vertical-align: middle;
  padding-left: 0.3rem;
  padding-right: 0.3rem;
}
/* Totales del equipo más grandes que las filas: son la cifra que se mira
   primero en la reunión. También se pueden marcar con color. */
.tabla-ventas tfoot th {
  padding: 0.55rem 0.3rem;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: left;
  vertical-align: middle;
  color: var(--text);
}
.tabla-ventas tfoot th:first-child { font-size: 0.72rem; letter-spacing: 0.04em; }
.tabla-ventas td:first-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tabla-ventas .celda-compromiso { width: 100%; max-width: 64px; }
.tabla-ventas .avance-compromiso { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }

/* Cifras con color en la tabla de ventas: cada clic pasa al tono siguiente
   (los mismos con que se destacan los KPI). La celda se tiñe suave y el
   número se refuerza, para que siga leyéndose igual de bien. */
.celda-color { cursor: pointer; transition: background 0.15s ease; }
.celda-color:hover { background: var(--surface-2); }
.celda-color[data-color="verde"] { --celda-realce: var(--good); }
.celda-color[data-color="amarillo"] { --celda-realce: var(--warn); }
.celda-color[data-color="rojo"] { --celda-realce: var(--danger); }
.celda-color[data-color="cuspide"] { --celda-realce: var(--primary); }
.celda-color[data-color],
.celda-color[data-color]:hover {
  background: color-mix(in srgb, var(--celda-realce) 18%, transparent);
  box-shadow: inset 3px 0 0 var(--celda-realce);
  font-weight: 600;
}
.celda-color[data-color] .celda-compromiso { font-weight: 600; }
/* En las celdas con campo, el número es para escribir (cursor de texto) y el
   resto de la casilla cambia el color, igual que en las demás columnas. */
.celda-color .celda-compromiso { cursor: text; }
.avance-compromiso {
  display: block;
  font-size: 0.6rem;
  color: var(--text-muted);
}

/* Las tarjetas que flotan se animan en su propia capa: sin esto, el navegador
   repinta toda la zona en cada cuadro y con muchas en pantalla se nota. */
.nube-card.entrando {
  will-change: transform, opacity;
}
/* Detenido el movimiento, se libera esa capa. */
.nube-quieta .nube-card { will-change: auto; }
/* Cada tarjeta se aísla: un cambio dentro de una no obliga a recalcular el resto. */
.nube-card { contain: layout paint; }


/* ---------- Informe de cierre mensual ---------- */
.informe-seccion {
  margin: 1.6rem 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.3rem;
}
.informe-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  align-items: start;
}
@media (max-width: 900px) {
  .informe-grid { grid-template-columns: 1fr; }
}
.informe-grid > .card { margin-bottom: 0; }
.informe-aviso {
  margin: 0 0 1rem;
  padding: 0.6rem 0.85rem;
  border-radius: 10px;
  background: var(--surface-2);
  border-left: 3px solid var(--warn);
  font-size: 0.76rem;
  color: var(--text-muted);
}
.fila-perdida th, .fila-perdida td { color: var(--danger); }
.pct-bajo { color: var(--warn); font-weight: 600; }
.pct-ok { color: var(--good); font-weight: 600; }
.cierre-pendientes { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cierre-pendiente {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.7rem;
  border-radius: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 0.8rem;
}

/* Lo que solo aparece en el papel. */
.solo-imprimir { display: none; }

/* ---------- Impresión / guardar como PDF ---------- */
@media print {
  /* Fuera todo lo que no es el informe: menú, buscador, botones. */
  .sidebar, .topbar, .no-imprimir, .kpi-info, .kpi-ayuda { display: none !important; }
  .content-area, main.container { margin: 0 !important; padding: 0 !important; max-width: none !important; }
  body { background: #fff !important; color: #111 !important; }

  .solo-imprimir { display: block; }
  .informe-membrete {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    border-bottom: 2px solid #c00;
    padding-bottom: 0.4rem;
    margin-bottom: 1rem;
    font-size: 11pt;
  }

  /* Fondos claros y bordes finos: en papel el tema oscuro no se lee. */
  .card, .kpi, .informe-aviso, .cierre-pendiente {
    background: #fff !important;
    border: 1px solid #ccc !important;
    box-shadow: none !important;
    break-inside: avoid;
  }
  .kpi-label, .kpi-nota, .subtitle, .grafico-resumen, .informe-seccion { color: #555 !important; }
  .kpi-valor, .tabla-densa td, .tabla-densa th, h1, h2 { color: #111 !important; }
  .tabla-densa th, .tabla-densa td { border-bottom: 1px solid #e5e5e5; }
  .tabla-densa-total th { border-top: 1px solid #999; }
  .pct-bajo { color: #b45309 !important; }
  .pct-ok { color: #15803d !important; }
  .fila-perdida th, .fila-perdida td { color: #b91c1c !important; }

  /* Ocho KPI por fila no caben en una hoja: se reparten en cuatro. */
  .kpi-row-densa { display: grid !important; grid-template-columns: repeat(4, 1fr); gap: 6pt; }
  .informe-grid { display: grid !important; grid-template-columns: 1fr 1fr; gap: 8pt; }
  .informe-seccion { break-after: avoid; }
  .table-wrap { overflow: visible !important; }
  .informe-pie { margin-top: 1rem; font-size: 8pt; color: #666 !important; text-align: center; }

  @page { margin: 12mm; size: A4 portrait; }
}

/* Procedencia del negocio, en su ficha. */
.ficha-origen {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
  margin: 0 0 0.9rem;
  padding: 0.35rem 0.6rem;
  border-radius: 8px;
  background: var(--surface-2);
  font-size: 0.72rem;
  color: var(--text-muted);
}
.ficha-origen-icono { font-size: 0.85rem; }
.ficha-origen-link { color: var(--primary); text-decoration: none; }
.ficha-origen-link:hover { text-decoration: underline; }

/* Nota explicativa dentro del informe. */
.informe-nota {
  margin: 0 0 0.8rem;
  font-size: 0.74rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.fila-fuerte th, .fila-fuerte td { font-weight: 700; }
.fila-buena th, .fila-buena td { color: var(--good); }
/* Las dos tasas del mes, en grande: son la conclusión de la sección. */
.tasa-destacada { display: flex; gap: 1.5rem; padding: 0.4rem 0; }
.tasa-bloque { display: flex; flex-direction: column; }
.tasa-valor { font-size: 1.9rem; font-weight: 700; line-height: 1; color: var(--primary); }
.tasa-label { font-size: 0.72rem; color: var(--text-muted); margin-top: 0.15rem; }
.tasa-bloque small { font-size: 0.64rem; color: var(--text-muted); }
@media print {
  .tasa-valor { color: #0d7d6c !important; }
  .fila-buena th, .fila-buena td { color: #15803d !important; }
}

/* ---------- Recorrido del negocio ---------- */
.recorrido > summary {
  cursor: pointer;
  font-weight: 600;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.recorrido-total { font-weight: 400; color: var(--text-muted); font-size: 0.7rem; }
.recorrido-lista {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0 0 0 0.9rem;
  border-left: 2px solid var(--border);
  font-size: 0.74rem;
}
.recorrido-paso {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.22rem 0;
  position: relative;
}
/* Punto en la línea de tiempo. */
.recorrido-paso::before {
  content: "";
  position: absolute;
  left: -1.24rem;
  top: 0.55rem;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--primary);
}
.recorrido-deducido::before { background: var(--text-muted); }
.recorrido-deducido { color: var(--text-muted); }
.recorrido-etapa { font-weight: 600; }
.recorrido-fecha { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.recorrido-lapso {
  font-size: 0.64rem;
  padding: 0.05rem 0.3rem;
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
}
.recorrido-quien { font-size: 0.66rem; color: var(--text-muted); }
.recorrido-aviso { margin: 0.5rem 0 0; font-size: 0.66rem; color: var(--text-muted); }

/* Cuando la columna viene recortada, su contador es el atajo para abrirla. */
.board-column-count-mas {
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
  cursor: pointer;
}
.board-column-count-mas:hover { color: var(--primary); }

/* Puntos del ranking rotativo: marcan en qué etapa va y permiten cambiarla. */
.ranking-pasos {
  display: flex;
  gap: 4px;
  margin-top: 0.35rem;
}
.ranking-punto {
  width: 6px;
  height: 6px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--border);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.ranking-punto:hover { background: var(--text-muted); }
.ranking-punto.activo {
  background: var(--primary);
  transform: scale(1.25);
}

/* Pie de una columna del tablero: cuántas quedaron fuera y cómo verlas. */
.board-vermas {
  display: block;
  margin-top: 0.35rem;
  padding: 0.4rem;
  border: 1px dashed var(--border);
  border-radius: 8px;
  text-align: center;
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.board-vermas:hover { color: var(--primary); border-color: var(--primary); }

/* Acciones de la esquina de un indicador: el corte de etapas y el ojo que lo
   tapa. Van juntas y del mismo tamaño, para que se lean como un solo grupo. */
/* La etiqueta se aparta de la esquina para no quedar debajo de los botones. */
.kpi-con-acciones .kpi-label { padding-right: 44px; }
.kpi-acciones {
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 1px;
}
/* Un botón que rota entre los cortes: enseña el que está puesto y con cada
   pulsación pasa al siguiente. Del porte del ojo, para no comerse el número. */
.kpi-corte {
  height: 20px;
  min-width: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 2px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.kpi-corte:hover { opacity: 1; color: var(--primary); background: var(--surface-2); }
/* Solo se ve el corte activo; los demás esperan su turno. */
.kpi-corte-op { display: none; }
.kpi-corte-op.activo { display: inline; }
/* Bajo el velo no tiene sentido cambiar un número que no se ve. */
.kpi-privado.oculto .kpi-corte { display: none; }

/* ---- Destacar un indicador con color ----
   No todos los indicadores pesan lo mismo para todos. Cada quien marca los
   suyos y la tira deja de ser una fila pareja donde hay que buscar. El color
   entra por el borde y una barra al costado, no por el fondo: el número tiene
   que seguir leyéndose igual de bien. */
.kpi[data-color] {
  /* El marco rodea la tarjeta con el mismo grosor por los cuatro lados: antes
     una barra al costado izquierdo lo engrosaba de un solo lado y la tarjeta
     se veía torcida. */
  border-color: var(--kpi-realce);
  box-shadow: 0 0 0 1px var(--kpi-realce), 0 2px 10px -6px var(--kpi-realce);
}
.kpi[data-color="verde"] { --kpi-realce: var(--good); }
.kpi[data-color="amarillo"] { --kpi-realce: var(--warn); }
.kpi[data-color="rojo"] { --kpi-realce: var(--danger); }
.kpi[data-color="cuspide"] { --kpi-realce: var(--primary); }

/* El botón de la paleta asoma al acercarse; si ya hay color puesto se queda a
   la vista, que es la única forma de volver a abrirlo para sacarlo. */
.kpi-pintar {
  height: 20px;
  width: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.kpi-pintar svg { width: 14px; height: 14px; }
.kpi:hover .kpi-pintar,
.kpi:focus-within .kpi-pintar { opacity: 0.45; }
.kpi-pintar:hover, .kpi-pintar:focus-visible { opacity: 1; color: var(--primary); background: var(--surface-2); }
.kpi[data-color] .kpi-pintar { opacity: 0.75; color: var(--kpi-realce); }
/* En táctil no hay cursor que acercar: el botón vive visible, tenue. */
@media (hover: none) {
  .kpi-pintar { opacity: 0.4; }
}
/* Bajo el velo la tarjeta no se pinta: primero se destapa. */
.kpi-privado.oculto .kpi-pintar { display: none; }

/* La paleta: una sola para toda la tira, colocada junto a la que la abrió. */
.kpi-paleta {
  position: fixed;
  z-index: 70;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.5rem 0.6rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px -8px rgba(13, 17, 23, 0.35);
}
/* El display de la paleta le gana a [hidden]: hay que decirlo, si no se queda
   a la vista en una esquina desde que carga la página. */
.kpi-paleta[hidden] { display: none; }
.kpi-paleta-titulo {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kpi-paleta-tonos { display: flex; gap: 0.3rem; }
.kpi-paleta-luces { display: flex; flex-wrap: wrap; gap: 0.25rem; max-width: 12rem; }
.kpi-luz {
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 0.66rem;
  font-weight: 600;
  cursor: pointer;
}
.kpi-luz:hover { border-color: var(--primary); }
.kpi-luz.puesto { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary) inset; }
.kpi-luz-ninguna { color: var(--text-muted); }
.kpi-tono {
  width: 22px;
  height: 22px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.kpi-tono:hover, .kpi-tono:focus-visible { transform: scale(1.15); border-color: var(--text); }
.kpi-tono[data-tono="verde"] { background: var(--good); }
.kpi-tono[data-tono="amarillo"] { background: var(--warn); }
.kpi-tono[data-tono="rojo"] { background: var(--danger); }
.kpi-tono[data-tono="cuspide"] { background: var(--primary); }
.kpi-tono-ninguno {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text-muted);
  font-size: 0.8rem;
  line-height: 1;
}
/* El que ya está puesto se reconoce sin tener que recordarlo. */
.kpi-tono.puesto { border-color: var(--text); transform: scale(1.1); }
/* Al cambiar de corte el número es otro: un parpadeo corto lo delata, para que
   nadie se quede leyendo el valor del corte anterior. */
.kpi-cambiado .kpi-valor { animation: kpi-latido 0.45s ease-out; }
@keyframes kpi-latido {
  0% { opacity: 0.25; transform: translateY(-2px); }
  100% { opacity: 1; transform: none; }
}

/* Indicadores que además de un promedio saben el total: el número se puede dar
   vuelta y mostrar la multiplicación. El punteado bajo el valor es la única
   señal de que ahí se puede pulsar; más que eso competiría con la cifra. */
.kpi[data-total] .kpi-valor {
  cursor: pointer;
  text-decoration: underline dotted;
  text-decoration-color: var(--border);
  text-underline-offset: 4px;
  font-variant-numeric: tabular-nums;
}
.kpi[data-total] .kpi-valor:hover,
.kpi[data-total] .kpi-valor:focus-visible { text-decoration-color: var(--primary); }
/* Dado vuelta, el total es más largo que el valor de una línea: entra con un
   punto menos y la operación pasa a leerse como el dato principal. */
.kpi-desglosado .kpi-valor { font-size: 1.16rem; animation: kpi-latido 0.35s ease-out; }
.kpi-desglosado .kpi-nota { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

/* Referencia bajo cada campo del registro diario: lo que el portal anotó solo
   desde las fichas. Es una ayuda, no el dato que se guarda. */
.item-detectado {
  margin-top: 0.25rem;
  padding: 0.12rem 0.4rem;
  align-self: flex-start;
  border: 1px dashed var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font);
  font-size: 0.6rem;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.item-detectado:hover { color: var(--primary); border-color: var(--primary); }

/* Quitar un indicador agregado, desde su propia tarjeta. */
.kpi-quitar {
  height: 20px;
  min-width: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 2px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.kpi:hover .kpi-quitar { opacity: 0.55; }
.kpi-quitar:hover { opacity: 1; color: var(--danger); background: var(--surface-2); }

/* Menú para sumar indicadores al Dashboard. Los de arriba vienen fijos; aquí
   cada uno agrega los que le sirven, sin llenar la tira para todos. */
.kpi-menu {
  position: fixed;
  z-index: 70;
  width: min(360px, calc(100vw - 16px));
  max-height: min(70vh, 520px);
  overflow-y: auto;
  padding: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card-bg);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.3);
}
.kpi-menu[hidden] { display: none; }
.kpi-menu-cabecera {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0.15rem 0.35rem 0.5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.4rem;
}
.kpi-menu-cabecera strong { font-size: 0.82rem; }
.kpi-menu-cabecera span { font-size: 0.66rem; color: var(--text-muted); }
.kpi-menu-lista { display: flex; flex-direction: column; gap: 1px; }
.kpi-menu-seccion {
  margin: 0.5rem 0.35rem 0.15rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--border);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kpi-menu-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 0.5rem;
  padding: 0.4rem 0.35rem;
  border-radius: 8px;
  cursor: pointer;
}
.kpi-menu-item:hover { background: var(--surface-2); }
.kpi-menu-item input { margin-top: 2px; accent-color: var(--primary); cursor: pointer; }
.kpi-menu-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kpi-menu-txt strong { font-size: 0.74rem; font-weight: 600; }
.kpi-menu-txt small { font-size: 0.63rem; color: var(--text-muted); line-height: 1.3; }
.kpi-menu-valor {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--primary);
  white-space: nowrap;
}

/* ---------- Indicadores movibles y huecos para los que vengan ---------- */
/* Cada tarjeta se puede arrastrar a la posición que uno quiera. El asa es la
   tarjeta entera: con recuadros de este tamaño, un asa aparte sería más difícil
   de agarrar que la tarjeta misma. */
.kpi[draggable="true"] { cursor: grab; }
.kpi.kpi-arrastrando {
  cursor: grabbing;
  opacity: 0.55;
  transform: scale(0.98);
}
/* Mientras se mueve una, las demás avisan que van a correrse. */
.kpi-row-moviendo .kpi { transition: transform 0.12s ease; }
.kpi-row-moviendo .kpi:not(.kpi-arrastrando) { border-style: dashed; }

/* Los espacios que sobran al final de la fila no quedan en blanco: se marcan
   como sitio reservado para los indicadores que se agreguen más adelante. */
/* Los huecos del final no son adorno: se pulsan para abrir el menú y agregar
   otro indicador, que es justo lo que uno quiere hacer al verlos vacíos. */
.kpi-hueco {
  min-height: 62px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--hueco-bg);
  font-family: var(--font);
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.kpi-hueco:hover { border-color: var(--primary); }
.kpi-hueco:hover::after { color: var(--primary); opacity: 0.85; }
/* Un "+" apenas insinuado: se entiende que ahí cabe otro indicador, sin que el
   ojo se vaya a un recuadro que todavía no dice nada. */
.kpi-hueco::after {
  content: '+';
  font-size: 1.1rem;
  font-weight: 300;
  line-height: 1;
  color: var(--text-muted);
  opacity: 0.35;
}

/* El espacio que uno dejó a propósito entre indicadores: casi invisible, que
   es de lo que se trata. El "+" sobra ahí —ese hueco no es para agregar—, y al
   acercar el cursor aparece la "×" que lo saca. */
.kpi-hueco-fijo { border-color: transparent; background: transparent; cursor: grab; }
.kpi-hueco-fijo::after { content: '·'; opacity: 0.25; }
.kpi-hueco-fijo:hover { border-color: var(--border); background: var(--hueco-bg); }
.kpi-hueco-fijo:hover::after { content: '×'; opacity: 0.6; }
.kpi-hueco-fijo:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Mientras se arrastra, todos los huecos se marcan: ahí se puede soltar, y lo
   que quede atrás se convierte en espacio en blanco. */
.kpi-row-moviendo .kpi-hueco {
  border-color: var(--primary);
  border-style: dashed;
  background: var(--hueco-bg);
}
.kpi-row-moviendo .kpi-hueco::after { content: '+'; opacity: 0.5; color: var(--primary); }
.kpi-row-densa .kpi-hueco { border-radius: 10px; min-height: 54px; }
/* ---------- KPI con dato de sueldo: velo oscuro a voluntad ---------- */
/* El pago por línea se muestra como un indicador más, pero con un ojo para
   taparlo cuando se proyecta la pantalla. No se difumina como en Comisiones:
   ahí son muchas cifras a la vez y aquí es una sola tarjeta, así que queda
   más limpio cubrirla entera y que se note que hay algo escondido. */
.kpi-privado { overflow: hidden; }
.kpi-ojo {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  opacity: 0.45;
  cursor: pointer;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.kpi-ojo svg { width: 13px; height: 13px; }
.kpi-ojo:hover { opacity: 1; color: var(--primary); background: var(--surface-2); }
.kpi-ojo .ojo-cerrado { display: none; }
.kpi-privado.oculto .kpi-ojo { color: #96a3b8; opacity: 0.8; }
.kpi-privado.oculto .kpi-ojo:hover { color: #fff; background: rgba(255, 255, 255, 0.12); }
.kpi-privado.oculto .kpi-ojo .ojo-abierto { display: none; }
.kpi-privado.oculto .kpi-ojo .ojo-cerrado { display: block; }

.kpi-velo {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: #161c27;
  color: #55637a;
  cursor: pointer;
}
.kpi-velo svg { width: 17px; height: 17px; }
.kpi-privado.oculto .kpi-velo { display: flex; }
/* Mientras carga la preferencia guardada, el velo va puesto sin transición:
   así el monto no alcanza a verse ni un instante al abrir la página. */
.kpi-privado.oculto .kpi-valor,
.kpi-privado.oculto .kpi-nota { visibility: hidden; }

/* ---------- Ocultar montos al compartir pantalla ---------- */
/* Difumina las cifras sin cambiar el tamaño de nada, así la pantalla se ve
   igual y no se puede leer ningún sueldo ni comisión. */
.ocultar-montos .monto {
  filter: blur(6px);
  user-select: none;
  cursor: default;
}
/* Al pasar el cursor se puede consultar un dato puntual sin apagar el modo. */
.ocultar-montos .monto:hover { filter: none; }

/* La fórmula de la semana corrida, escrita como se lee. */
.semana-formula {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.84rem;
}
.semana-formula span { color: var(--text-muted); font-weight: 700; }
.semana-formula strong { color: var(--primary); font-size: 1rem; }
.dias-descanso {
  margin: 0.5rem 0 0;
  padding-left: 1.1rem;
  font-size: 0.72rem;
  color: var(--text-muted);
  columns: 2;
}

/* ---------- Simulador de comisión ---------- */
.simulador-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 0.75rem;
  margin-top: 0.6rem;
}
.simulador-campo {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.76rem;
}
.simulador-campo input,
.simulador-campo select {
  font-size: 0.88rem;
  padding: 0.45rem 0.55rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
}
.simulador-campo small { font-size: 0.64rem; color: var(--text-muted); }
.simulador-acciones { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.9rem; }


/* ---------- Tareas: tarjetas agrupadas por urgencia ---------- */
/* Antes era una tabla de ocho columnas con los formularios metidos dentro de
   una celda. Como tarjeta, cada acción se lee de un vistazo y los botones
   caben sin apretar nada. */
.tareas-grupo { margin-bottom: 1rem; }
.tareas-grupo-cuenta {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 700;
  vertical-align: middle;
}
/* El grupo se distingue por una franja de color en el borde de arriba. */
.tareas-grupo-vencida { border-top: 3px solid var(--danger); }
.tareas-grupo-hoy { border-top: 3px solid var(--notice-text, #e8b463); }
.tareas-grupo-proxima { border-top: 3px solid var(--primary); }
.tareas-grupo-sin_fecha { border-top: 3px solid var(--border); }
.tareas-grupo-realizada { border-top: 3px solid var(--ok-text); }

.tareas-tarjetas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.6rem;
  margin-top: 0.7rem;
}
.tarea-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  box-shadow: var(--shadow-card);
}
.tarea-card-vencida { border-left-color: var(--danger); }
.tarea-card-hoy { border-left-color: var(--notice-text, #e8b463); }
.tarea-card-proxima { border-left-color: var(--primary); }
.tarea-card-realizada { border-left-color: var(--ok-text); opacity: 0.75; }

.tarea-card-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.tarea-card-accion { font-size: 0.68rem; font-weight: 700; color: var(--text-muted); }
.tarea-card-fecha {
  font-size: 0.66rem;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tarea-card-empresa {
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
  text-decoration: none;
}
.tarea-card-empresa:hover { color: var(--primary); }
.tarea-card-nota {
  margin: 0;
  font-size: 0.7rem;
  line-height: 1.35;
  color: var(--text-muted);
}
.tarea-card-pie {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.15rem;
}

/* ---------- Carga del equipo (vista de jefatura) ---------- */
.carga-lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.4rem;
  margin-top: 0.6rem;
}
.carga-persona {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface-2);
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease, transform 0.12s ease;
}
.carga-persona:hover { border-color: var(--primary); transform: translateY(-1px); }
.carga-persona-activa { border-color: var(--primary); background: var(--accent-soft); }
.carga-nombre { font-size: 0.76rem; font-weight: 600; }
.carga-cifras { display: flex; gap: 3px; }
.carga-dato {
  min-width: 22px;
  padding: 0.1rem 0.3rem;
  border-radius: 6px;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.carga-vencidas { background: var(--error-bg); color: var(--error-text); }
.carga-hoy { background: var(--notice-bg); color: var(--notice-text); }
.carga-proximas { background: var(--accent-soft); color: var(--primary-dark); }
/* Un cero no tiene por qué gritar: se apaga y deja resaltar lo que sí hay. */
.carga-dato.en-cero { background: transparent; color: var(--text-muted); opacity: 0.5; }
.carga-muestra {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  vertical-align: -1px;
}
.carga-leyenda {
  margin: 0.6rem 0 0;
  font-size: 0.64rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}
.carga-leyenda .carga-muestra + span,
.carga-leyenda span { margin-right: 0.5rem; }

/* Botones de volver de la ficha: el del Pipeline siempre, y el de la pantalla
   desde la que se llegó cuando corresponde. */
.ficha-volver {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

/* Mientras el servidor confirma, la tarjeta de tarea se ve a media tinta. */
.tarea-card-esperando { opacity: 0.55; }
.tarea-card-yendose {
  animation: tareaSeVa 0.25s ease-in forwards;
  pointer-events: none;
}
@keyframes tareaSeVa {
  to { transform: translateX(12px) scale(0.96); opacity: 0; }
}

/* Campo dentro de un menú rápido: el próximo paso propuesto, que se puede
   cambiar antes de elegir cuándo. */
.card-menu-campo {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0.25rem 0.4rem 0.4rem;
}
.card-menu-campo span {
  font-size: 0.58rem;
  color: var(--text-muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.card-menu-campo select {
  padding: 0.25rem 0.3rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font);
  font-size: 0.7rem;
}


/* ================= Teléfono y tablet =================
   El portal se usa en el escritorio, pero también en la calle: entre visitas,
   en el auto, antes de entrar a un cliente. En el teléfono la barra lateral no
   cabe —quedaba una tira horizontal cortada— así que la navegación se va abajo,
   al alcance del pulgar, como en cualquier app. */

/* En pantalla grande la barra de abajo no existe. */
.tabbar, .tabbar-panel { display: none; }

@media (max-width: 820px) {
  /* La barra lateral desaparece: su sitio lo toma la barra de abajo. */
  .sidebar { display: none; }
  .app-shell { display: block; }

  .topbar { padding: 0.5rem 0.75rem 0; }
  .topbar-inner { grid-template-columns: 1fr; row-gap: 0.5rem; }
  .global-search input { font-size: 0.9rem; }

  .container { padding: 0.75rem 0.75rem 5.5rem; }

  /* La cabecera de cada pantalla, en dos líneas y sin apretar. */
  .dash-cabecera {
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
  }
  .dash-titulo h1 { font-size: 1.35rem; }
  .dash-filtros {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 0.25rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .dash-filtros::-webkit-scrollbar { display: none; }
  .dash-filtros select,
  .dash-filtros input,
  .dash-filtros .btn { flex-shrink: 0; }

  /* Indicadores: dos por fila, que es lo que se lee bien con el pulgar. */
  .kpi-row, .kpi-row-densa { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
  .kpi-row-densa .kpi-valor { font-size: 1.05rem; }
  .kpi-label { font-size: 0.6rem; }

  /* Todo lo que era de dos o más columnas pasa a una.
     Va en minmax(0, 1fr) y no en 1fr: "1fr" deja que el contenido más ancho de
     adentro —una tabla, un título largo— estire la columna, y ahí es cuando las
     tarjetas se salen de la pantalla. Con el 0 la columna manda sobre su
     contenido, que es lo que se necesita en un teléfono. */
  .pipeline-grid,
  .dash-fila-tarjetas,
  .dash-fila-cierre,
  .informe-grid,
  .detalle-grid,
  .pipeline-grid-mini,
  .tareas-tarjetas,
  .grid-items,
  .kpi-row { grid-template-columns: minmax(0, 1fr); }
  /* Los indicadores sí van de a dos, pero con el mismo cuidado del minmax. */
  .kpi-row, .kpi-row-densa { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Un grid con columnas fijas se convierte en una sola en el teléfono. */
  .board { grid-template-columns: none; }
  /* Los gráficos no pueden pasarse del ancho de su tarjeta. */
  .grafico-circular-wrap,
  .grafico-barra-compacto,
  canvas { max-width: 100%; }
  .carga-lista { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Un hijo de flex no se encoge por debajo de su contenido salvo que se le
     diga. Sin esto, la cabecera y sus filtros empujan la página a lo ancho. */
  .dash-cabecera,
  .card-header-row,
  .meta-franja { flex-wrap: wrap; }
  .dash-cabecera > *,
  .card-header-row > *,
  .dash-titulo,
  .content-area,
  .container > * { min-width: 0; max-width: 100%; }

  /* Nada dentro de una tarjeta puede pasarse de su ancho. */
  .card, .kpi, .tarea-card, .board-card { max-width: 100%; }
  .card h1, .card h2, .dash-titulo h1, .tarea-card-empresa { overflow-wrap: anywhere; }

  /* Las tablas se deslizan dentro de su caja en vez de estirar la página. */
  .table-wrap { max-width: 100%; overflow-x: auto; }
  .table-wrap table { min-width: max-content; }

  /* Las tablas anchas se deslizan solas en vez de romper la pantalla. */
  .table-wrap { -webkit-overflow-scrolling: touch; }

  /* El tablero se recorre de lado, una columna a la vez. El ancho se cambia en
     la grilla y no en la columna: al ensancharla con min-width, la celda seguía
     midiendo 250px y las columnas terminaban montadas una sobre otra. */
  .board {
    /* Tres columnas a la vista: se entiende de una en qué etapa está cada
       negocio sin tener que deslizar para descubrir que hay más al lado. */
    grid-auto-columns: 38vw;
    /* Sin anclaje por columna: alineaba bonito al soltar, pero cortaba el
       impulso a media pasada y recorrer el tablero se sentía trabado. */
  }
  .board-column {
    min-width: 0;
    /* Sin techo, una columna vacía se estira a la altura de la más llena y
       deja media pantalla en blanco. */
    max-height: 68vh;
    overflow-y: auto;
  }

  /* La nube de Hunting, más baja: en vertical no hay espacio para tanto aire. */
  .hunting-nube { height: 46vh; }

  /* Los menús flotantes no pueden quedar pegados a un borde. */
  .card-menu, .kpi-menu { max-width: calc(100vw - 16px); }
}

/* ---------- Barra inferior, estilo app ---------- */
@media (max-width: 820px) {
  .tabbar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    align-items: stretch;
    background: var(--sidebar-bg);
    border-top: 1px solid var(--border);
    /* Respeta la franja del gesto de inicio en los iPhone modernos. */
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .tabbar a, .tabbar button {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 0.45rem 0.15rem 0.5rem;
    border: 0;
    background: transparent;
    color: var(--sidebar-text);
    font-family: var(--font);
    font-size: 0.58rem;
    font-weight: 600;
    text-decoration: none;
    opacity: 0.65;
    cursor: pointer;
  }
  .tabbar a.active, .tabbar button.active { opacity: 1; color: var(--primary); }
  .tabbar .nav-icono { width: 19px; height: 19px; }

  .tabbar-panel {
    display: flex;
    flex-direction: column;
    position: fixed;
    right: 8px;
    bottom: calc(60px + env(safe-area-inset-bottom, 0px));
    z-index: 95;
    min-width: 190px;
    padding: 0.3rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card-bg);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  }
  .tabbar-panel[hidden] { display: none; }
  .tabbar-panel a {
    padding: 0.55rem 0.6rem;
    border-radius: 8px;
    color: var(--text);
    font-size: 0.82rem;
    text-decoration: none;
  }
  .tabbar-panel a:hover { background: var(--surface-2); }
  .tabbar-salir { color: var(--danger) !important; }
}

/* ---------- Teléfono angosto ---------- */
@media (max-width: 480px) {
  .kpi-row, .kpi-row-densa { gap: 0.4rem; }
  .card { padding: 0.8rem; }
  .board { grid-auto-columns: 42vw; }
  .carga-lista { grid-template-columns: 1fr; }
  /* Los botones se tocan con el dedo, no con el cursor. */
  .btn-small { padding: 0.4rem 0.7rem; }
  .tarea-card-pie .btn { flex: 1; text-align: center; }
}

/* ---------- Tablet ---------- */
@media (min-width: 821px) and (max-width: 1180px) {
  /* En tablet la barra arranca encogida —el ancho es lo escaso ahí—, pero eso
     ya no lo decide el tamaño de la pantalla: lo pone el propio portal como
     punto de partida y se cambia desde el botón del menú. Las reglas de la
     barra encogida viven en .barra-compacta, más abajo. */
  .kpi-row, .kpi-row-densa { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .dash-fila-tarjetas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .board { grid-auto-columns: 240px; }
}

/* ---------- Foto de perfil ---------- */
.avatar-foto {
  object-fit: cover;
  border-radius: 50%;
  display: block;
}
/* En la tarjeta ocupa el mismo sitio que ocupaban las iniciales. */
.board-exec-avatar.avatar-foto { padding: 0; }

/* En Hunting la cara va pegada al nombre, en la misma línea: la tarjeta es
   angosta y el pie no da para dos renglones. */
.prospecto-gestor { display: inline-flex; align-items: center; gap: 0.25rem; }
.prospecto-gestor .board-exec-avatar { width: 18px; height: 18px; font-size: 0.55rem; }
.prospecto-asignado,
.registro-quien { display: flex; align-items: center; gap: 0.4rem; }
.prospecto-asignado strong { margin-right: 0.1rem; }

.perfil-foto-fila {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}
.perfil-foto-marco {
  width: 76px;
  height: 76px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.perfil-foto-marco img { width: 100%; height: 100%; object-fit: cover; }
.perfil-foto-iniciales {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-muted);
}
.perfil-foto-acciones {
  flex: 1;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.perfil-foto-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.perfil-foto-form input[type="file"] {
  font-size: 0.74rem;
  color: var(--text-muted);
  max-width: 100%;
}

/* Chip con la cara de quien lleva el negocio. */
.chip-persona {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.45rem 0.1rem 0.15rem;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.62rem;
}
.chip-avatar {
  width: 17px;
  height: 17px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--card-bg);
  font-size: 0.5rem;
  font-weight: 700;
}
img.chip-avatar { object-fit: cover; }

/* ---------- Marca Cúspide Digital CRM ---------- */
/* El lockup oficial reemplaza al isotipo con el texto dibujado aparte. Vienen
   dos versiones —texto blanco y texto oscuro— y se muestra la que corresponde
   al tema, porque el mismo archivo no se lee bien sobre los dos fondos.
   Los selectores llevan el `img` a propósito: sin él, la regla general de
   `.marca-cuspide img` le gana por especificidad y se ven las dos a la vez. */
.marca-cuspide {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}
.marca-cuspide img {
  height: 34px;
  /* El ancho sale del alto, en la proporción real del archivo (4:1). Sin el
     flex-shrink, la fila lo comprimía y el logo salía estirado. */
  width: auto;
  flex-shrink: 0;
  object-fit: contain;
}
.marca-cuspide { flex-shrink: 0; }

/* Sin elección propia, manda el tema del sistema. */
.marca-cuspide img.marca-oscura { display: block; }
.marca-cuspide img.marca-clara,
.marca-cuspide img.marca-isotipo { display: none; }
@media (prefers-color-scheme: light) {
  .marca-cuspide img.marca-oscura { display: none; }
  .marca-cuspide img.marca-clara { display: block; }
}
/* Y si la persona eligió un tema a mano, ese gana. */
:root[data-theme="dark"] .marca-cuspide img.marca-oscura { display: block; }
:root[data-theme="dark"] .marca-cuspide img.marca-clara { display: none; }
:root[data-theme="light"] .marca-cuspide img.marca-oscura { display: none; }
:root[data-theme="light"] .marca-cuspide img.marca-clara { display: block; }

/* En el login la marca va más grande: es lo primero que se ve al entrar. */
.login-brand-row .marca-cuspide img { height: 42px; }

/* La barra lateral es angosta y comparte fila con el logo de Claro: el lockup
   baja de alto para que los dos entren enteros, sin aplastar ninguno. */
.sidebar .marca-cuspide img { height: 22px; }

/* La barra lateral es oscura en los dos temas —su fondo no cambia—, así que
   ahí va siempre la versión de letras blancas. Alternarla por tema dejaba el
   logo en negro sobre negro y no se leía. */
.sidebar .marca-cuspide img.marca-oscura,
:root[data-theme="light"] .sidebar .marca-cuspide img.marca-oscura { display: block; }
.sidebar .marca-cuspide img.marca-clara,
:root[data-theme="light"] .sidebar .marca-cuspide img.marca-clara { display: none; }
@media (prefers-color-scheme: light) {
  .sidebar .marca-cuspide img.marca-oscura { display: block; }
  .sidebar .marca-cuspide img.marca-clara { display: none; }
}
.sidebar .sidebar-brand-row { gap: 0.5rem; }
.sidebar .sidebar-brand-client-logo img { max-height: 22px; width: auto; }

/* Barra encogida a solo iconos: ahí el lockup no cabe y va el isotipo, que es
   la versión de la marca para espacios angostos. Al abrirse con el cursor
   vuelve el lockup entero, así que la marca acompaña el gesto.

   Solo de 901 px para arriba, como todo lo de la barra encogida: en el
   teléfono el menú es una barra horizontal que se maneja con el dedo y ahí
   nada se encoge, aunque en ese navegador quedara guardada la preferencia. */
@media (min-width: 901px) {
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .marca-cuspide img.marca-oscura,
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .marca-cuspide img.marca-clara { display: none; }
  .barra-compacta .sidebar:not(:hover):not(:focus-within) .marca-cuspide img.marca-isotipo {
    display: block;
    height: 30px;
    width: 30px;
  }
}
@media (max-width: 900px) {
  .sidebar .marca-cuspide img { height: 22px; }
}

/* Secciones dentro del panel "Más" del teléfono. */
.tabbar-panel-seccion {
  margin: 0.6rem 0.75rem 0.2rem;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tabbar-panel-seccion:first-child { margin-top: 0.2rem; }

/* ---------- Nube de Hunting: tamaños por pantalla ---------- */
@media (max-width: 1180px) {
  :root {
    --nube-ancho: 134px;
    --nube-alto: 78px;
    --nube-alto-abierta: 116px;
    --nube-circulo: 88px;
    --nube-circulo-abierto: 132px;
  }
}
@media (max-width: 820px) {
  :root {
    --nube-ancho: 96px;
    --nube-alto: 84px;
    --nube-alto-abierta: 124px;
    --nube-circulo: 76px;
    --nube-circulo-abierto: 120px;
  }
  /* Con la tarjeta más chica, el texto también se ajusta. */
  .nube-empresa { font-size: 0.66rem; }
  .nube-lineas { font-size: 0.9rem; }
  .nube-segmento, .nube-datos { font-size: 0.56rem; }
  .nube-card { padding: 0.35rem 0.45rem; gap: 0.1rem; }
}
@media (max-width: 480px) {
  :root {
    --nube-ancho: 88px;
    --nube-alto: 80px;
    --nube-alto-abierta: 118px;
    --nube-circulo: 68px;
    --nube-circulo-abierto: 112px;
  }
  .nube-empresa { font-size: 0.58rem; line-height: 1.15; }
  .nube-lineas { font-size: 0.78rem; }
  .nube-card { padding: 0.3rem 0.35rem; }
}

/* El submenú de Inicio se abre sobre su propio botón, no en la esquina. */
.tabbar-panel-inicio { right: auto; left: 8px; min-width: 190px; }
/* Botón de la barra inferior con su panel abierto. */
.tabbar .abierto { color: var(--primary); }

/* Nube en el teléfono: tarjeta casi cuadrada. El nombre manda y usa las líneas
   que necesite; el operador y la ciudad se dejan fuera, que ahí no caben. */
@media (max-width: 820px) {
  .nube-empresa { -webkit-line-clamp: 3; line-clamp: 3; }
  .nube-fila { flex-wrap: wrap; gap: 0.15rem; }
  .nube-datos { display: none; }
}

/* ---------- Columnas de estado de Hunting en el teléfono ---------- */
/* Una columna por pantalla obligaba a deslizar para saber si había algo en la
   siguiente. Más angostas entran dos y media: se ve de una que hay contactados,
   que no contesta y que empieza la de más allá. */
@media (max-width: 820px) {
  .board-bajo { grid-auto-columns: 42vw; max-height: none; }
  .board-bajo .board-column { max-height: 44vh; }

  /* La tarjeta se compacta para caber en la mitad del ancho: el nombre manda,
     y lo que se puede mirar dentro de la ficha sale de aquí. */
  .board-bajo .board-card { padding: 0.4rem 0.45rem; gap: 0.2rem; }
  .board-bajo .board-card .empresa {
    font-size: 0.68rem;
    line-height: 1.2;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .board-bajo .meta-row { gap: 0.2rem; }
  .board-bajo .chip { font-size: 0.55rem; padding: 0.05rem 0.3rem; }
  /* El teléfono y el ejecutivo se ven al abrir la ficha; aquí solo estorban. */
  .board-bajo .prospecto-linea,
  .board-bajo .prospecto-gestor { display: none; }
  .board-bajo .board-card-footer { gap: 0.2rem; }
  .board-bajo .board-card-footer .btn {
    width: 100%;
    padding: 0.3rem 0.35rem;
    font-size: 0.62rem;
    text-align: center;
  }
  .board-bajo .board-column-head { gap: 0.25rem; }
  .board-bajo .board-column-title { font-size: 0.62rem; }
}
@media (max-width: 480px) {
  /* En pantalla angosta se aprieta un poco más: tres columnas asomando. */
  .board-bajo { grid-auto-columns: 38vw; }
  .board-bajo .board-card .empresa { font-size: 0.64rem; }
}

/* ---------- Tarjetas del Funnel en el teléfono ---------- */
/* Con tres columnas a la vista, cada tarjeta tiene un tercio del ancho: se
   queda lo que identifica el negocio —nombre, líneas, etapa— y lo demás se ve
   al abrir la ficha. Quedan casi cuadradas y se aprovecha mejor la pantalla. */
@media (max-width: 820px) {
  #tablero-pipeline .board-card {
    padding: 0.4rem 0.45rem;
    gap: 0.2rem;
  }
  #tablero-pipeline .board-card .empresa {
    font-size: 0.68rem;
    line-height: 1.2;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  #tablero-pipeline .meta-row { gap: 0.2rem; }
  #tablero-pipeline .chip { font-size: 0.55rem; padding: 0.05rem 0.3rem; }
  /* El desglose de líneas, el ARPU y el aviso de días se miran dentro del
     negocio; aquí no caben sin volver ilegible el nombre. */
  #tablero-pipeline .lineas-desglose,
  #tablero-pipeline .chip-arpu,
  #tablero-pipeline .board-reminder,
  #tablero-pipeline .board-alert,
  #tablero-pipeline .chip-crecimiento { display: none; }

  /* Los sellos del 90% sí se quedan: en esa etapa lo único que importa es por
     dónde va el trámite —portar, mesa, MOAC— y en el teléfono no había forma
     de saberlo ni de marcarlo sin entrar al negocio. Con la columna a 38vw no
     cabe el texto, así que cada uno queda en su inicial: apagada mientras está
     pendiente y encendida con su color cuando ya salió. */
  #tablero-pipeline .portar-mesa-moac-stack {
    flex-direction: row;
    gap: 0.2rem;
    align-items: center;
  }
  #tablero-pipeline .mesa-moac-row { width: auto; gap: 0.2rem; }
  #tablero-pipeline .chip-portar,
  #tablero-pipeline .chip-mesa,
  #tablero-pipeline .chip-moac {
    width: 19px;
    min-width: 19px;
    height: 19px;
    padding: 0;
    flex: none;
    font-size: 0.55rem;
    /* El rótulo largo se esconde y asoma la inicial que lleva en data-corto. */
    color: transparent;
    overflow: hidden;
  }
  #tablero-pipeline .chip-portar::before,
  #tablero-pipeline .chip-mesa::before,
  #tablero-pipeline .chip-moac::before {
    content: attr(data-corto);
    color: var(--text-muted);
  }
  #tablero-pipeline .chip-portar-activo::before { color: var(--good); }
  #tablero-pipeline .chip-mesa-activo::before { color: var(--primary); }
  #tablero-pipeline .chip-moac-activo::before { color: var(--stage-90); }
  /* El foco de cierre ya es un punto: cabe tal cual. */
  #tablero-pipeline .board-card-footer { justify-content: flex-end; }
  #tablero-pipeline .board-exec-avatar {
    width: 20px;
    height: 20px;
    font-size: 0.55rem;
  }
  #tablero-pipeline .board-column-title { font-size: 0.62rem; }
}
@media (max-width: 480px) {
  #tablero-pipeline .board-card .empresa { font-size: 0.64rem; }
}

/* Cuando una tarjeta cae a 0% —perdido— la señal es de aviso, no de logro: el
   anillo y las luces van en rojo, del mismo color que ahora tiene la etapa. */
.board-column[data-etapa="0"] .board-column-title { color: var(--stage-0); }

/* ---------- Ordenar una columna ---------- */
/* Vive en la cabecera de la columna y casi no se ve hasta que se necesita. Si la
   columna quedó con un orden propio, la flecha se enciende: así uno sabe que lo
   que está mirando no es el orden de siempre. */
.orden-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.1rem;
  margin-left: auto;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted);
  opacity: 0.4;
  cursor: pointer;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.board-column:hover .orden-boton { opacity: 0.75; }
.orden-boton:hover { opacity: 1; color: var(--primary); }
.orden-boton.activo { opacity: 1; color: var(--primary); }
.orden-boton:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
/* La cuenta de la columna queda pegada al borde, con la flecha a su izquierda. */
.board-column-head .board-column-count { margin-left: 0.4rem; }

.orden-menu {
  position: fixed;
  z-index: 70;
  min-width: 190px;
  padding: 0.25rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-bg);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.32);
}
.orden-menu[hidden] { display: none; }
.orden-menu button {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  padding: 0.4rem 0.5rem;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
  text-align: left;
  cursor: pointer;
}
.orden-menu button:hover { background: var(--surface-2); }
.orden-menu button.elegido { color: var(--primary); font-weight: 600; }
.orden-menu button.elegido::before { content: "✓"; font-size: 0.7rem; }
.orden-menu button:not(.elegido)::before { content: ""; width: 0.7rem; }

/* ---------- Favorito y tarea, en la tarjeta ---------- */
/* La estrella va al final del nombre, pegada a la última palabra. */
.board-card .empresa-cola { white-space: nowrap; }
.board-card .estrella {
  background: none;
  border: 0;
  padding: 0 0 0 0.25rem;
  vertical-align: baseline;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.15s ease, transform 0.15s ease;
}
.board-card .estrella:hover { color: #e8a93c; transform: scale(1.18); }
.board-card .estrella.marcada { color: #e8a93c; }
.board-card .estrella:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

/* El pie de la tarjeta dice "Tarea pendiente" con todas sus letras: el nombre es
   la mitad del recordatorio. Al tocarlo o pasar el cursor se resuelve ahí mismo. */
.chip-tarea {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.02rem;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
  padding: 0.18rem 0.42rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.chip-tarea b { font-size: 0.6rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; }
.chip-tarea span { font-size: 0.6rem; color: var(--text-muted); max-width: 100%; line-height: 1.25; overflow-wrap: anywhere; }
.chip-tarea:hover { border-color: var(--primary); }
.chip-tarea-vencido { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.chip-tarea-vencido b { color: var(--danger); }
.chip-tarea-hoy { border-color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.chip-tarea-hoy b { color: var(--warn); }
/* Sin tarea: presente pero callado, para no llenar el tablero de avisos. Una
   sola línea chica y sin recuadro: con treinta tarjetas sin acción, treinta
   cajas punteadas eran lo que más se veía del tablero, y no es lo importante. */
.chip-tarea-sin {
  flex: 0 1 auto;
  flex-direction: row;
  align-items: baseline;
  gap: 0.25rem;
  padding: 0.05rem 0.3rem;
  border: 0;
  background: transparent;
  opacity: 0.5;
}
.chip-tarea-sin b { font-size: 0.55rem; font-weight: 600; letter-spacing: 0.02em; }
.chip-tarea-sin span { font-size: 0.55rem; }
.chip-tarea-sin:hover { opacity: 1; background: var(--surface-2); }

/* El estado en la tarjeta: el mismo chip de la tabla, más chico. */
.board-card .estado-select-tarjeta {
  align-self: flex-start;
  min-width: 0;
  max-width: 100%;
  padding: 0.1rem 1.2rem 0.1rem 0.45rem;
  font-size: 0.64rem;
  background-position: right 0.4rem center;
}

/* Un dato que falta en la tarjeta: presente, punteado y apagado. */
.board-card .chip-falta {
  border: 1px dashed var(--border);
  background: transparent;
  color: var(--text-muted);
  font-weight: 500;
  opacity: 0.75;
}

/* El RUT bajo el nombre de la empresa, chico y en cifras parejas. */
.board-card .board-rut {
  align-self: flex-start;
  margin-top: -0.15rem;
  font-size: 0.66rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  cursor: copy;
}
.board-card .board-rut:hover { color: var(--primary); }
.board-card .board-rut.copiado::after { content: " ✓ copiado"; color: var(--good); }

/* Panel que pregunta. Va en position fixed porque las columnas recortan. */
.tarea-pop {
  position: fixed;
  z-index: 70;
  display: none;
  width: 250px;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.32);
}
.tarea-pop.abierto { display: block; animation: tareaPopEntra 0.16s ease-out; }
/* Orilla invisible alrededor del aviso: el cursor puede ir en diagonal desde el
   chip sin caer en un vacío y perderlo. No se ve; solo amplía dónde cuenta como
   "sigo aquí". */
.tarea-pop::before {
  content: "";
  position: absolute;
  inset: -12px;
  z-index: -1;
}
@keyframes tareaPopEntra { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.tarea-pop-titulo { font-size: 0.78rem; font-weight: 600; margin-bottom: 0.15rem; }
.tarea-pop-sub { font-size: 0.7rem; color: var(--text-muted); margin-bottom: 0.55rem; }
.tarea-pop-opciones { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.tarea-pop-opciones button {
  flex: 1 1 auto;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 0.72rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tarea-pop-opciones button:hover { border-color: var(--primary); background: var(--accent-soft); }
.tarea-pop-opciones button.principal { background: var(--primary); border-color: var(--primary); color: #04211f; font-weight: 600; }
.tarea-pop-aviso { font-size: 0.72rem; color: var(--good); }
.tarea-pop-aviso.error { color: var(--danger); }

/* ---------- Arrastre de tarjetas (dedo y mouse) ---------- */
/* El hueco marca dónde va a caer la tarjeta, para que la columna no se
   desarme mientras viaja y se vea a dónde va. */
.board-hueco {
  border: 2px dashed var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  opacity: 0.6;
  margin-bottom: 0.1rem;
}
/* La tarjeta levantada sigue al dedo por encima de todo, apenas inclinada. */
.board-card-volando {
  position: fixed !important;
  z-index: 120;
  margin: 0;
  pointer-events: none;
  box-shadow: 0 18px 40px rgb(0 0 0 / 0.35);
  opacity: 0.96;
  cursor: grabbing;
  transition: none;
}
/* Un toque sobre la tarjeta no la abre: la deja preguntando. El aviso vive en
   la propia tarjeta y dura lo que dura la ventana del segundo toque, para que
   nadie tenga que adivinar por qué no pasó nada. */
.board-card-preguntando {
  position: relative;
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}
.board-card-preguntando::after {
  content: 'Toca otra vez para abrir';
  position: absolute;
  left: 50%;
  bottom: -0.55rem;
  transform: translateX(-50%);
  z-index: 5;
  white-space: nowrap;
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: 0 4px 10px rgb(0 0 0 / 0.25);
  animation: asomar-aviso 0.16s ease-out;
}
@keyframes asomar-aviso {
  from { opacity: 0; transform: translate(-50%, -4px); }
}

/* En el teléfono el gesto cambia, así que el tablero lo dice una vez arriba en
   lugar de repetirlo en cada tarjeta. */
.board-gesto { display: none; }
@media (hover: none) and (pointer: coarse) {
  .board-gesto {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0.5rem;
    font-size: 0.68rem;
    color: var(--text-muted);
  }
}

/* Mientras se arrastra, la pantalla no hace scroll ni selecciona texto. */
body.arrastrando-tarjeta {
  user-select: none;
  -webkit-user-select: none;
  overflow: hidden;
  touch-action: none;
}
body.arrastrando-tarjeta .board-card:not(.board-card-volando) {
  transition: transform 0.14s ease;
}
/* En táctil, la tarjeta no debe iniciar el gesto de "arrastrar imagen" ni el
   menú del sistema al mantener pulsado: eso interrumpía el levantado. */
.board-card {
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}

/* Los botones del encabezado de un gráfico son secundarios: el título manda.
   Con el tamaño normal se comían la cabecera y empujaban el nombre a dos
   líneas. */
.grafico-cabecera-acciones .btn {
  padding: 0.22rem 0.5rem;
  font-size: 0.66rem;
  line-height: 1.3;
}
.grafico-cabecera-acciones { gap: 0.3rem; }
.grafico-tipo-toggle { gap: 0.15rem; }
@media (max-width: 820px) {
  .grafico-cabecera-acciones .btn {
    padding: 0.2rem 0.42rem;
    font-size: 0.62rem;
  }
}

/* Si los botones no caben junto al título, bajan a la línea siguiente en vez
   de recortarlo: el nombre del gráfico tiene que leerse entero. */
.grafico-cabecera { flex-wrap: wrap; }
.grafico-cabecera > h2 { min-width: 0; }

/* ---------- Ranking de marca de gestión ---------- */
.marca-puesto {
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  width: 1.6rem;
}
.marca-barra {
  display: inline-block;
  width: 60px;
  height: 6px;
  margin-right: 0.35rem;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
  vertical-align: middle;
}
.marca-barra > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--primary);
}
/* Quien no registró ni un día se ve distinto: es lo que hay que mirar. */
.fila-sin-marca { color: var(--text-muted); }
.fila-sin-marca .marca-barra > span { background: var(--danger); }

/* ---------- Filtros de Hunting en el teléfono ---------- */
/* En una sola fila con desplazamiento lateral, la mitad de los filtros quedaba
   fuera de la pantalla y nadie sabía que existían. En el teléfono se reparten
   en dos por línea, y los que necesitan más aire ocupan la línea entera. */
@media (max-width: 820px) {
  .dash-filtros-hunting {
    flex-wrap: wrap;
    overflow: visible;
    gap: 0.35rem;
  }
  .dash-filtros-hunting > select,
  .dash-filtros-hunting > .filtro-lineas {
    flex: 1 1 calc(50% - 0.2rem);
    min-width: 0;
  }
  .dash-filtros-hunting > select { max-width: none; }
  /* El buscador y los botones, a lo ancho: son los que más se usan. */
  .dash-filtros-hunting > .hunting-buscar { flex: 1 1 100%; min-width: 0; }
  /* Equipo, rubro y ciudad comparten una fila a tercios: rubro y ciudad solos
     se llevaban media pantalla —o una fila entera— para mostrar un nombre. */
  .dash-filtros-hunting > select.filtro-angosto,
  .dash-filtros-hunting > select[name="ejecutivo"] {
    flex: 1 1 calc(33.33% - 0.25rem);
    width: auto;
    max-width: none;
  }
  .dash-filtros-hunting > .btn,
  .dash-filtros-hunting > .forma-toggle,
  .dash-filtros-hunting > a.btn { flex: 0 0 auto; }
  /* El rango de líneas ocupa su línea completa: son tres campos juntos. */
  .dash-filtros-hunting > .filtro-lineas {
    flex: 1 1 100%;
    display: flex;
    align-items: center;
    gap: 0.25rem;
  }
  .filtro-lineas .dash-numero { width: 100%; min-width: 0; flex: 1; }
  .filtro-lineas select { flex: 1 1 auto; min-width: 0; }
}

/* ---------- Notas del día ---------- */
/* El mismo bloque vive en dos fondos: el menú, que es oscuro en los dos
   temas, y la página /notas, que sigue el tema. Por eso los colores van en
   variables propias del bloque y cada lugar pone las suyas. */
.notas-bloque {
  --n-texto: var(--text);
  --n-suave: var(--text-muted);
  --n-linea: var(--border);
  --n-campo: var(--surface-2);
  --n-hover: var(--hueco-bg);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 0;
  color: var(--n-texto);
}
.notas-hueco { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.sidebar .notas-bloque {
  --n-texto: #dfe4ea;
  --n-suave: #7f8b99;
  --n-linea: var(--sidebar-border);
  --n-campo: rgba(255, 255, 255, 0.05);
  --n-hover: rgba(255, 255, 255, 0.04);
  flex: 1 1 auto;
  min-height: 160px;
  margin-top: 1rem;
  padding: 0.9rem 0.25rem 0.6rem;
  border-top: 1px solid var(--sidebar-border);
}

.notas-cabeza { display: flex; align-items: center; gap: 0.45rem; padding: 0 0.35rem; }
.notas-titulo {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--n-suave);
  text-decoration: none;
}
a.notas-titulo:hover { color: var(--n-texto); }
.notas-cuenta {
  min-width: 1.15rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: var(--primary);
  color: #06201d;
  font-size: 0.64rem;
  font-weight: 700;
  line-height: 1.15rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.notas-avance {
  margin-left: auto;
  font-size: 0.64rem;
  color: var(--n-suave);
  font-variant-numeric: tabular-nums;
}
.notas-cuenta[hidden], .notas-avance[hidden] { display: none; }

.notas-nueva { display: flex; gap: 0.3rem; }
.notas-nueva input {
  flex: 1;
  min-width: 0;
  padding: 0.42rem 0.6rem;
  border: 1px solid var(--n-linea);
  border-radius: 7px;
  background: var(--n-campo);
  color: var(--n-texto);
  font: inherit;
  font-size: 0.8rem;
}
.notas-nueva input::placeholder { color: var(--n-suave); }
.notas-nueva input:focus { outline: none; border-color: var(--primary); }
.notas-nueva input.notas-error { border-color: var(--danger); }
.notas-agregar {
  flex-shrink: 0;
  width: 2rem;
  border: 1px solid var(--n-linea);
  border-radius: 7px;
  background: transparent;
  color: var(--n-suave);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.notas-agregar:hover, .notas-agregar:focus-visible { color: var(--primary); border-color: var(--primary); }

.notas-cuerpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.notas-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.nota {
  display: flex;
  align-items: flex-start;
  gap: 0.3rem;
  padding: 0.32rem 0.35rem;
  border-radius: 6px;
  transition: opacity 0.15s;
}
.nota:hover { background: var(--n-hover); }
.nota.saliendo { opacity: 0.3; }
.nota-marca {
  /* label trae columna por defecto en el portal: aquí va en fila. */
  flex-direction: row;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0;
  cursor: pointer;
  font-weight: 400;
}
.nota-check {
  /* Círculo perfecto: sin el relleno que el portal les da a todos los campos
     (distinto a lo ancho y a lo alto, lo dejaba ovalado). */
  appearance: none;
  box-sizing: border-box;
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  min-width: 13px;
  aspect-ratio: 1;
  padding: 0;
  font-size: 0;
  margin: 0.2rem 0 0;
  border: 1.5px solid var(--n-suave);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-content: center;
}
.nota-check:hover { border-color: var(--primary); }
.nota-check:focus { outline: none; }
.nota-check:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.nota-check:checked { background: var(--primary); border-color: var(--primary); }
.nota-check:checked::after {
  content: "";
  width: 6px;
  height: 3px;
  margin-top: -2px;
  border: solid #06201d;
  border-width: 0 0 1.5px 1.5px;
  transform: rotate(-45deg);
}
.nota-contenido { display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; min-width: 0; }
.nota-texto {
  font-size: 0.8rem;
  line-height: 1.35;
  color: var(--n-texto);
  overflow-wrap: break-word;
  max-width: 100%;
}
.nota.hecha .nota-texto { color: var(--n-suave); text-decoration: line-through; }
.nota-edad {
  padding: 0 0.3rem;
  border-radius: 4px;
  background: rgba(232, 162, 58, 0.16);
  color: var(--warn);
  font-size: 0.6rem;
  font-weight: 600;
  line-height: 1.1rem;
  white-space: nowrap;
}
.nota-borrar {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--n-suave);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
}
.nota:hover .nota-borrar, .nota-borrar:focus-visible { opacity: 1; }
.nota-borrar:hover { color: var(--danger); }
@media (hover: none) { .nota-borrar { opacity: 0.6; } }

.notas-vacio { margin: 0.2rem 0.35rem; font-size: 0.74rem; color: var(--n-suave); }
.notas-separador {
  margin: 0.6rem 0.35rem 0.15rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--n-suave);
}
.notas-vacio[hidden], .notas-separador[hidden] { display: none; }

/* La página /notas: el mismo bloque, en grande. */
.notas-pagina { max-width: 720px; }
.notas-grande { gap: 0.75rem; }
.notas-grande .notas-titulo { font-size: 0.72rem; }
.notas-grande .notas-nueva input { padding: 0.65rem 0.8rem; font-size: 0.95rem; }
.notas-grande .notas-agregar { width: 2.6rem; font-size: 1.2rem; }
.notas-grande .nota { padding: 0.55rem 0.5rem; }
.notas-grande .nota-texto { font-size: 0.95rem; }
.notas-grande .nota-check { width: 16px; height: 16px; min-width: 16px; margin-top: 0.2rem; }
.notas-grande .nota-borrar { font-size: 1.15rem; width: 1.5rem; height: 1.5rem; }
.notas-grande .notas-vacio { font-size: 0.88rem; }
.notas-ayuda { margin: 1rem 0 0; font-size: 0.78rem; color: var(--text-muted); }

/* Acceso a Notas en el menú: solo con la barra encogida a iconos, donde el
   bloque no cabe. */
.sidebar nav a.nav-notas-acceso { display: none; position: relative; }
.nav-notas-cuenta, .tabbar-notas-cuenta {
  padding: 0 0.3rem;
  border-radius: 999px;
  background: var(--primary);
  color: #06201d;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1rem;
  font-variant-numeric: tabular-nums;
}
.nav-notas-cuenta[hidden], .tabbar-notas-cuenta[hidden] { display: none; }
.tabbar-notas-cuenta { margin-left: 0.35rem; }
@media (max-width: 1180px) {
  .sidebar .notas-bloque, .notas-hueco { display: none; }
  .sidebar nav a.nav-notas-acceso { display: flex; }
  .nav-notas-cuenta { position: absolute; top: 2px; right: 4px; }
}
@media (prefers-reduced-motion: reduce) { .nota { transition: none; } }

/* Botones para mover las notas (solo jefatura). */
.notas-controles { display: flex; gap: 0.15rem; margin-left: 0.2rem; }
.notas-avance[hidden] + .notas-controles { margin-left: auto; }
.notas-ctrl {
  display: grid;
  place-content: center;
  width: 1.45rem;
  height: 1.45rem;
  padding: 0;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--n-suave);
  cursor: pointer;
}
.notas-ctrl svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.notas-ctrl:hover, .notas-ctrl:focus-visible { background: var(--n-hover); color: var(--n-texto); }
.notas-ctrl:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.notas-anclar[aria-pressed="true"] { color: var(--primary); }
.notas-anclar[aria-pressed="true"] svg { fill: currentColor; }
.solo-ventana { display: none; }
.notas-ventana .solo-ventana { display: grid; }
.notas-ventana .solo-menu { display: none; }

/* La ventana flotante: sobre el contenido y también sobre la barra lateral,
   con la esquina de la derecha para cambiarle el tamaño. Sigue el tema, como
   una tarjeta más del tablero.

   Por encima de la barra (150) a propósito: antes quedaba debajo, así que al
   arrimarla al menú la barra se le ponía encima y ya no había cabecera que
   agarrar —la ventana quedaba trabada ahí, sin poder bajarla ni moverla. Sigue
   bajo los desplegables del menú (200), que son momentáneos. */
.notas-ventana {
  position: fixed;
  z-index: 160;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  min-height: 180px;
  max-width: calc(100vw - 16px);
  max-height: calc(100vh - 16px);
  padding: 0.7rem 0.55rem 0.9rem;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 14px 34px rgba(13, 17, 23, 0.18), 0 2px 6px rgba(13, 17, 23, 0.08);
  resize: both;
  overflow: hidden;
}
.notas-ventana .notas-bloque { flex: 1 1 auto; min-height: 0; }
.notas-ventana .notas-cabeza { padding-bottom: 0.15rem; }
.notas-ventana:not(.anclada) .notas-cabeza { cursor: grab; touch-action: none; }
.notas-ventana.arrastrando { opacity: 0.94; user-select: none; }
.notas-ventana.arrastrando .notas-cabeza { cursor: grabbing; }
/* Anclada: queda fija donde se dejó, sin esquina de tamaño ni arrastre. */
.notas-ventana.anclada { resize: none; }
@media (max-width: 820px) { .notas-ventana { display: none; } }

/* Ajustes → Prensa: publicaciones de LinkedIn sumadas a mano. */
.df-linkedin-form { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto; gap: 0.5rem; align-items: end; margin: 0.6rem 0 0.4rem; }
.df-linkedin-form label { gap: 0.25rem; font-size: 0.74rem; }
.df-linkedin-form input { width: 100%; font-size: 0.85rem; }
@media (max-width: 820px) { .df-linkedin-form { grid-template-columns: 1fr; } }
.df-linkedin-lista { list-style: none; margin: 0.8rem 0 0; padding: 0; display: grid; gap: 0.35rem; font-size: 0.8rem; }
.df-linkedin-lista li { display: flex; align-items: center; gap: 0.5rem; padding-bottom: 0.35rem; border-bottom: 1px solid var(--border); }
.df-linkedin-lista a { flex: 1; min-width: 0; color: var(--text); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-linkedin-lista a:hover { text-decoration: underline; }
.df-linkedin-lista .df-vencida { opacity: 0.55; }
.df-linkedin-lista form { margin: 0; }

/* ── Hunting · asignar desde el tablero (jefatura) ───────────────────────
   Con el modo puesto, las tarjetas se marcan en vez de abrirse, dejan de
   flotar para que no se escapen del cursor y la barra queda pegada arriba. */
.btn-asignar {
  background: var(--card-bg);
  border: 1px solid var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.btn-asignar:hover, .btn-asignar.activo { background: var(--accent); color: #fff; }
.barra-asignar {
  position: sticky;
  top: 0.5rem;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.7rem;
  margin: 0 0 0.9rem;
  padding: 0.55rem 0.8rem;
  background: var(--card-bg);
  border: 1px solid var(--accent);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  font-size: 0.85rem;
}
.barra-asignar[hidden] { display: none; }
.barra-asignar-que { display: inline-flex; gap: 0.7rem; }
.barra-asignar label { display: inline-flex; flex-direction: row; align-items: center; margin: 0; font-weight: 500; gap: 0.3rem; cursor: pointer; white-space: nowrap; }
.barra-asignar label.apagado { opacity: 0.45; cursor: default; }
.barra-asignar input[type="radio"], .barra-asignar input[type="checkbox"] { width: auto; margin: 0; accent-color: var(--accent); }
#asignar-contador { font-weight: 700; font-variant-numeric: tabular-nums; }
.barra-asignar select { min-width: 12rem; }
.modo-asignar .nube-card,
.modo-asignar .board-card-prospecto[data-id] { cursor: copy; }
.modo-asignar .nube-card.entrando { animation: nube-entrar 0.3s ease forwards; }
.modo-asignar .board-card-prospecto:not([data-id]) { opacity: 0.45; }
.asignar-marcada {
  outline: 3px solid var(--accent) !important;
  outline-offset: 2px;
  background: var(--accent-soft) !important;
}
.asignar-marcada::before {
  content: "✓";
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 3;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font: 700 12px/20px system-ui, sans-serif;
  text-align: center;
}
.board-card-prospecto { position: relative; }

/* Documentos de ingreso: una tilde que no se pudo guardar se avisa en la
   misma fila, en vez de desmarcarse callada. */
.ingreso-pantalla #checklist .requisito-no-guardo {
  outline: 1px solid var(--error-text);
  border-radius: 6px;
}
.ingreso-pantalla #checklist .requisito-no-guardo::after {
  content: attr(data-aviso);
  flex: 1 0 100%;
  color: var(--error-text);
  font-size: 0.72rem;
  padding: 0.15rem 0 0.1rem 1.6rem;
}

/* Planilla de Hunting: el selector de ejecutivo, con el que la jefatura
   asigna cada empresa eligiendo el nombre. */
.tabla-excel td.col-asignar { padding: 0.15rem 0.3rem; }
.asignar-ejecutivo {
  width: 100%;
  min-width: 10rem;
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card-bg);
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}
.asignar-ejecutivo:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.tabla-excel td.asignar-ok { box-shadow: inset 0 0 0 2px var(--good); }
.tabla-excel td.asignar-error { box-shadow: inset 0 0 0 2px var(--error-text); }
/* Las casillas para marcar filas solo aparecen con el modo «Asignar». */
.tabla-excel .marca-prospecto,
.tabla-excel .marca-todas { display: none; }
.modo-asignar .tabla-excel .marca-prospecto,
.modo-asignar .tabla-excel .marca-todas {
  display: inline-block;
  width: 15px;
  height: 15px;
  margin: 0 0.45rem 0 0;
  vertical-align: -2px;
  accent-color: var(--primary);
  cursor: pointer;
}
.modo-asignar #planilla-prospectos tbody tr { cursor: copy; }
.tabla-excel tbody tr.fila-marcada td {
  background: color-mix(in srgb, var(--primary) 16%, var(--card-bg));
}
