/* ===========================================================================
   CRM de analítica — hoja de estilo única.
   Panel financiero sobrio: rojo de marca #b03035, Montserrat, claro y oscuro,
   móvil primero. Sin librerías, sin CDN, sin build. Todo lo que se pinta sale
   de aquí; los gráficos son SVG a mano y usan estas mismas variables.

   Índice
     1  Fuentes
     2  Tokens de color (claro / oscuro)
     3  Base y tipografía
     4  Estructura: barra, navegación, contenedor
     5  Botones y controles
     6  Formularios
     7  Tarjetas y tarjetas de métrica
     8  Tablas
     9  Embudo
    10  Avisos
    11  Procedencia del dato
    12  Gráficos SVG
    13  Modal, toast y estados
    14  Utilidades
    15  Pantallas anchas
   =========================================================================== */

/* --- 1. Fuentes -----------------------------------------------------------
   Montserrat si el equipo la tiene instalada. Como no hay CDN, se pide con
   local(); si no está, cae en la pila del sistema sin pedir nada a la red.
   Para fijarla de verdad: deja los .woff2 en public/css/fuentes/ y añade el
   src url("/css/fuentes/Montserrat-600.woff2") format("woff2") a cada peso. */
@font-face { font-family: "Montserrat CRM"; font-weight: 400; font-style: normal; font-display: swap;
  src: local("Montserrat Regular"), local("Montserrat-Regular"), local("Montserrat"); }
@font-face { font-family: "Montserrat CRM"; font-weight: 500; font-style: normal; font-display: swap;
  src: local("Montserrat Medium"), local("Montserrat-Medium"); }
@font-face { font-family: "Montserrat CRM"; font-weight: 600; font-style: normal; font-display: swap;
  src: local("Montserrat SemiBold"), local("Montserrat-SemiBold"); }
@font-face { font-family: "Montserrat CRM"; font-weight: 700; font-style: normal; font-display: swap;
  src: local("Montserrat Bold"), local("Montserrat-Bold"); }
@font-face { font-family: "Montserrat CRM"; font-weight: 800; font-style: normal; font-display: swap;
  src: local("Montserrat ExtraBold"), local("Montserrat-ExtraBold"); }

/* --- 2. Tokens ------------------------------------------------------------ */
:root {
  --fuente: "Montserrat CRM", "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --fondo: #f5f6f8;
  --fondo-barra: rgba(245, 246, 248, .88);
  --superficie: #ffffff;
  --superficie-2: #fafafb;
  --superficie-3: #f0f1f4;

  --texto: #14161a;
  --texto-2: #5f636b;
  --texto-3: #8b8f98;

  --borde: rgba(17, 19, 23, .10);
  --borde-fuerte: rgba(17, 19, 23, .20);

  --marca: #b03035;          /* rojo de marca: texto, bordes, acentos */
  --marca-solido: #b03035;   /* fondo de los botones primarios */
  --marca-solido-txt: #ffffff;
  --marca-suave: rgba(176, 48, 53, .10);

  --pos: #17743a;            /* va bien */
  --pos-suave: rgba(23, 116, 58, .12);
  --neg: #b0302f;            /* va mal */
  --neg-suave: rgba(176, 48, 47, .12);
  --atencion: #9a6b04;       /* ojo con esto */
  --atencion-suave: rgba(154, 107, 4, .14);
  --info: #2b5f9e;
  --info-suave: rgba(43, 95, 158, .12);

  --sombra-1: 0 1px 2px rgba(17, 19, 23, .05);
  --sombra-2: 0 4px 16px rgba(17, 19, 23, .08);
  --sombra-3: 0 24px 60px rgba(17, 19, 23, .28);

  --radio: 14px;
  --radio-s: 10px;
  --radio-xs: 8px;
  --ancho: 1180px;
  --barra-alto: 56px;
}

/* Oscuro por preferencia del sistema, salvo que se haya forzado claro. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --fondo: #0d0e11;
    --fondo-barra: rgba(13, 14, 17, .86);
    --superficie: #16181d;
    --superficie-2: #1b1e24;
    --superficie-3: #22262d;

    --texto: #eceef1;
    --texto-2: #a2a7b0;
    --texto-3: #767b85;

    --borde: rgba(255, 255, 255, .10);
    --borde-fuerte: rgba(255, 255, 255, .22);

    --marca: #ef6a6f;
    --marca-solido: #b03035;
    --marca-solido-txt: #ffffff;
    --marca-suave: rgba(239, 106, 111, .14);

    --pos: #4cc47c;
    --pos-suave: rgba(76, 196, 124, .14);
    --neg: #f0716c;
    --neg-suave: rgba(240, 113, 108, .14);
    --atencion: #e0a72e;
    --atencion-suave: rgba(224, 167, 46, .16);
    --info: #6ea8e8;
    --info-suave: rgba(110, 168, 232, .14);

    --sombra-1: 0 1px 2px rgba(0, 0, 0, .4);
    --sombra-2: 0 4px 18px rgba(0, 0, 0, .45);
    --sombra-3: 0 24px 60px rgba(0, 0, 0, .6);
  }
}

/* Oscuro forzado desde el conmutador de tema. */
:root[data-tema="oscuro"] {
  --fondo: #0d0e11;
  --fondo-barra: rgba(13, 14, 17, .86);
  --superficie: #16181d;
  --superficie-2: #1b1e24;
  --superficie-3: #22262d;

  --texto: #eceef1;
  --texto-2: #a2a7b0;
  --texto-3: #767b85;

  --borde: rgba(255, 255, 255, .10);
  --borde-fuerte: rgba(255, 255, 255, .22);

  --marca: #ef6a6f;
  --marca-solido: #b03035;
  --marca-solido-txt: #ffffff;
  --marca-suave: rgba(239, 106, 111, .14);

  --pos: #4cc47c;
  --pos-suave: rgba(76, 196, 124, .14);
  --neg: #f0716c;
  --neg-suave: rgba(240, 113, 108, .14);
  --atencion: #e0a72e;
  --atencion-suave: rgba(224, 167, 46, .16);
  --info: #6ea8e8;
  --info-suave: rgba(110, 168, 232, .14);

  --sombra-1: 0 1px 2px rgba(0, 0, 0, .4);
  --sombra-2: 0 4px 18px rgba(0, 0, 0, .45);
  --sombra-3: 0 24px 60px rgba(0, 0, 0, .6);
}

/* --- 3. Base -------------------------------------------------------------- */
* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font: 400 15px/1.55 var(--fuente);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
a.enlace { color: var(--marca); text-decoration: underline; text-underline-offset: 2px; }

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
h1 { font-size: 24px; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }
p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

small, .pequeno { font-size: 12px; }

code, .mono { font-family: var(--mono); font-size: .92em; }

hr { border: 0; border-top: 1px solid var(--borde); margin: 22px 0; }

::selection { background: var(--marca-suave); }

:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; border-radius: 4px; }

[hidden] { display: none !important; }

/* Todas las cifras alineadas: en un panel de dinero, columnas que bailan son
   columnas que no se pueden comparar de un vistazo. */
.num, .metrica .valor, table.tabla td.num, table.tabla th.num, .escalon-vol {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* --- 4. Estructura -------------------------------------------------------- */
/* La cabecera es el bloque que se queda pegado arriba: barra más tira de pestañas.
   El pegado va AQUÍ y no en .barra a propósito. Un `position:sticky` solo se pega
   dentro de su padre, y el padre de .barra es este div de 98 px: puesto en .barra,
   la cabecera se iba con el primer scroll y la barra de filtros se quedaba
   flotando con cien píxeles de contenido pasando por encima. */
#cabecera {
  position: sticky; top: 0; z-index: 30;
  background: var(--fondo-barra);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
}
.barra {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--barra-alto);
  padding: 8px 16px;
  border-bottom: 1px solid var(--borde);
}
/* Fuera de #cabecera (una barra suelta) sigue pegándose por su cuenta. */
.barra:not(#cabecera .barra) { position: sticky; top: 0; z-index: 30; background: var(--fondo-barra); }
.logotipo { font-weight: 800; font-size: 16px; letter-spacing: -.03em; white-space: nowrap; }
.logotipo i { color: var(--marca); font-style: normal; }
.barra .separador { flex: 1; }

/* En móvil la navegación es una tira que se desliza; en escritorio se queda fija.
   Las dos tiras comparten estilo: la de móvil lleva su propia clase y si no se la
   nombra aquí se queda con el tamaño del texto del cuerpo, sin relleno y sin marcar
   en qué página estás. */
.nav, .nav-movil {
  display: flex; gap: 2px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.nav::-webkit-scrollbar, .nav-movil::-webkit-scrollbar { display: none; }
.nav a, .nav-movil a {
  padding: 7px 12px; border-radius: var(--radio-s);
  font-size: 13px; font-weight: 600; color: var(--texto-2);
  white-space: nowrap;
}
.nav a:hover, .nav-movil a:hover { color: var(--texto); background: var(--superficie-3); }
.nav a[aria-current="page"], .nav a.activo,
.nav-movil a[aria-current="page"], .nav-movil a.activo {
  color: var(--marca); background: var(--marca-suave); box-shadow: none;
}

.nav-movil {
  padding: 6px 16px 8px;
  background: var(--fondo-barra);
  border-bottom: 1px solid var(--borde);
}
/* En una tira que se desliza, el dedo necesita blanco al final para saber que
   hay más: sin esto la última pestaña queda pegada al canto y parece cortada. */
.nav-movil::after { content: ""; flex: none; width: 8px; }

.contenedor { max-width: var(--ancho); margin: 0 auto; padding: 20px 16px 72px; }

.cabecera-pagina { margin-bottom: 18px; }
.cabecera-pagina .sub { color: var(--texto-2); font-size: 13.5px; margin: 4px 0 0; }

.seccion { margin: 28px 0 0; }
.seccion > h2 { margin-bottom: 10px; }
.seccion-cab { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.seccion-cab .sub { color: var(--texto-2); font-size: 12.5px; }

.rejilla { display: grid; gap: 14px; grid-template-columns: 1fr; }
.rejilla-2, .rejilla-3 { display: grid; gap: 14px; grid-template-columns: 1fr; }

.barra-filtros {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 16px;
}

/* --- 5. Botones y controles ---------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid var(--borde); background: var(--superficie); color: var(--texto);
  border-radius: 999px; padding: 9px 16px;
  font: 600 13.5px var(--fuente); cursor: pointer;
  transition: background .15s, border-color .15s, opacity .15s;
  white-space: nowrap;
}
.btn:hover { background: var(--superficie-3); }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn.cargando { opacity: .55; pointer-events: none; }

.btn-primario { background: var(--marca-solido); border-color: var(--marca-solido); color: var(--marca-solido-txt); }
.btn-primario:hover { background: #97282d; border-color: #97282d; }

.btn-plano { border-color: transparent; background: transparent; color: var(--texto-2); }
.btn-plano:hover { background: var(--superficie-3); color: var(--texto); }

.btn-peligro { color: var(--marca); border-color: var(--borde); }
.btn-peligro:hover { background: var(--marca-suave); }

.btn-pequeno { padding: 6px 12px; font-size: 12.5px; }
.btn-bloque { width: 100%; }

/* Selector segmentado: periodo, emisor, escala del gráfico. */
.seg { display: inline-flex; background: var(--superficie-3); border-radius: 12px; padding: 3px; gap: 2px; }
.seg button {
  border: 0; background: transparent; border-radius: 9px;
  padding: 7px 13px; font: 600 12.5px var(--fuente); color: var(--texto-2); cursor: pointer;
  white-space: nowrap;
}
.seg button[aria-pressed="true"], .seg button.activo {
  background: var(--superficie); color: var(--texto); box-shadow: var(--sombra-1);
}

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--borde); border-radius: 999px; background: var(--superficie);
  padding: 5px 12px; font: 600 12px var(--fuente); color: var(--texto-2); cursor: pointer;
}
.chip:hover { border-color: var(--borde-fuerte); color: var(--texto); }
.chip.activo { background: var(--marca-solido); border-color: var(--marca-solido); color: var(--marca-solido-txt); }

/* Conmutador claro / oscuro. */
.tema { width: 34px; height: 34px; padding: 0; border-radius: 50%; }

/* --- 6. Formularios ------------------------------------------------------ */
.campo-grupo { margin-bottom: 12px; }
label.rotulo, .rotulo {
  display: block; font-size: 12px; font-weight: 600; color: var(--texto-2);
  letter-spacing: .02em; margin: 0 0 5px;
}
input.campo, select.campo, textarea.campo {
  width: 100%; border: 1px solid var(--borde); border-radius: var(--radio-s);
  padding: 10px 12px; font: 400 14px var(--fuente);
  background: var(--superficie); color: var(--texto);
  /* 16px en móvil evita el zoom automático de Safari al enfocar. */
}
@media (max-width: 640px) { input.campo, select.campo, textarea.campo { font-size: 16px; } }
input.campo:focus, select.campo:focus, textarea.campo:focus {
  outline: none; border-color: var(--marca); box-shadow: 0 0 0 3px var(--marca-suave);
}
input.campo[readonly], input.campo[disabled] { background: var(--superficie-3); color: var(--texto-2); }
textarea.campo { min-height: 96px; resize: vertical; line-height: 1.5; }
.ayuda { font-size: 12px; color: var(--texto-2); margin: 5px 0 0; line-height: 1.45; }
.error-campo { font-size: 12px; color: var(--marca); font-weight: 600; margin: 5px 0 0; }

.campos-linea { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.campos-linea > * { flex: 1 1 130px; min-width: 0; }

/* Zona para arrastrar el export de campaña. */
.soltar {
  border: 1.5px dashed var(--borde-fuerte); border-radius: var(--radio);
  padding: 26px 18px; text-align: center; color: var(--texto-2);
  background: var(--superficie-2); cursor: pointer;
}
.soltar.encima { border-color: var(--marca); background: var(--marca-suave); color: var(--texto); }
.soltar b { display: block; color: var(--texto); font-size: 14px; margin-bottom: 4px; }

/* --- 7. Tarjetas y métricas ---------------------------------------------- */
.tarjeta {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); box-shadow: var(--sombra-1);
}
.tarjeta-cab {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 16px; border-bottom: 1px solid var(--borde);
}
.tarjeta-cab h2, .tarjeta-cab h3 { margin: 0; }
.tarjeta-cab .separador { flex: 1; }
.tarjeta-cuerpo { padding: 16px; }
.tarjeta-pie { padding: 12px 16px; border-top: 1px solid var(--borde); color: var(--texto-2); font-size: 12.5px; }

.metricas { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin: 0 0 18px; }
.metrica {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); box-shadow: var(--sombra-1);
  padding: 14px 15px 15px; min-width: 0;
}
.metrica .rotulo {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 700; color: var(--texto-2);
  text-transform: uppercase; letter-spacing: .05em; margin: 0 0 6px;
}
/* La cifra no parte nunca a mitad de número: o cabe entera o se encoge (el tamaño
   lo pone tamañoCifra() al pintarla). Un "1.234.568 €" cortado en dos líneas por el
   punto de millar se lee como dos cifras distintas. */
.metrica .valor { font-size: 25px; font-weight: 700; letter-spacing: -.03em; line-height: 1.1; white-space: nowrap; }
.metrica .valor .unidad { font-size: 15px; font-weight: 600; color: var(--texto-2); margin-left: 2px; }
.metrica .pie { font-size: 12px; color: var(--texto-2); margin-top: 5px; line-height: 1.4; }
.metrica.destacada { border-color: var(--marca); box-shadow: 0 0 0 3px var(--marca-suave); }

/* Variación contra el periodo anterior. `.delta-mal` se pone a mano: en coste
   por agendamiento subir es malo, en ingresos es bueno. El color lo decide el
   negocio, no el signo. */
.delta {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 12px; font-weight: 700; border-radius: 999px; padding: 2px 8px;
  background: var(--superficie-3); color: var(--texto-2);
}
.delta-bien { background: var(--pos-suave); color: var(--pos); }
.delta-mal { background: var(--neg-suave); color: var(--neg); }
.delta-neutro { background: var(--superficie-3); color: var(--texto-2); }

/* Cuando no hay denominador se pinta un guion, nunca un 0 ni un infinito. */
.sin-dato { color: var(--texto-3); font-weight: 500; }

/* --- 8. Tablas ------------------------------------------------------------ */
/* La tabla se desplaza dentro de su caja: la página nunca se mueve en lateral. */
.tabla-envoltorio {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie);
}
table.tabla { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 520px; }
table.tabla thead th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: 11px 14px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--texto-2); background: var(--superficie-2);
  border-bottom: 1px solid var(--borde); white-space: nowrap;
}
table.tabla tbody td { padding: 11px 14px; border-bottom: 1px solid var(--borde); vertical-align: middle; }
table.tabla tbody tr:last-child td { border-bottom: 0; }
table.tabla tbody tr:hover td { background: var(--superficie-2); }
table.tabla td.num, table.tabla th.num { text-align: right; }
table.tabla td.fuerte { font-weight: 700; }
table.tabla tfoot td {
  padding: 12px 14px; font-weight: 700; border-top: 1px solid var(--borde-fuerte);
  background: var(--superficie-2);
}
table.tabla th.ordenable { cursor: pointer; user-select: none; }
table.tabla th.ordenable:hover { color: var(--texto); }
table.tabla tr.fila-clic { cursor: pointer; }

/* En el móvil una tabla de nueve columnas enseña dos. La columna que decide —la
   variación, el coste por resultado— queda a 700 px a la derecha, la barra de
   desplazamiento va oculta en táctil y nada dice que haya más. El renglón de abajo
   lo dice con palabras y nombra la última columna.

   Aquí se probó dejar fija la primera columna, como en una hoja de cálculo, y hubo
   que quitarlo: tapaba 58 px de «1.234.567,89 €» y en pantalla se leía «34.567,89 €».
   Un número tapado a medias sigue pareciendo un número. En un panel de dinero eso
   no se arriesga por una comodidad. */
.tabla-pista {
  display: none;
  margin: 6px 2px 0; font-size: 12px; color: var(--texto-2);
}
@media (max-width: 899px) {
  .tabla-pista { display: block; }
}

/* Lista compacta para móvil, alternativa a la tabla. */
.filas { border: 1px solid var(--borde); border-radius: var(--radio); background: var(--superficie); overflow: hidden; }
.fila { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-top: 1px solid var(--borde); }
.fila:first-child { border-top: 0; }
.fila .principal { flex: 1; min-width: 0; }
.fila .titulo { font-weight: 600; font-size: 14px; }
.fila .meta { font-size: 12.5px; color: var(--texto-2); }
.fila .importe { font-weight: 700; white-space: nowrap; }

/* --- 9. Embudo ------------------------------------------------------------
   Un escalón por peldaño: impresión, clic, visita, alta, agendamiento, cita,
   trato, factura, cobro. La barra se escala con --pct (0-100). */
.embudo { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.escalon {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio-s); padding: 12px 14px;
}
.escalon + .escalon { position: relative; }
.escalon-cab { display: flex; align-items: baseline; gap: 10px; }
.escalon-nombre { font-weight: 600; font-size: 13.5px; flex: 1; min-width: 0; }
.escalon-vol { font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.escalon-barra {
  position: relative; height: 8px; border-radius: 999px;
  background: var(--superficie-3); margin: 9px 0 8px; overflow: hidden;
}
.escalon-barra i {
  display: block; height: 100%; width: var(--pct, 0%);
  background: var(--marca-solido); border-radius: 999px;
  transition: width .35s ease;
}
.escalon-pie {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12px; color: var(--texto-2);
}
.escalon-pie .conversion { font-weight: 700; color: var(--texto); }
.escalon-pie .coste { font-weight: 600; }
.escalon.escalon-dinero .escalon-barra i { background: var(--pos); }
.escalon.escalon-flojo { border-color: var(--neg); box-shadow: 0 0 0 2px var(--neg-suave); }

/* El salto entre escalones: dónde se cae la gente. */
.caida {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font-size: 11.5px; font-weight: 700; color: var(--texto-3);
  padding: 3px 0;
}
.caida b { color: var(--neg); }

/* --- 10. Avisos ----------------------------------------------------------- */
.aviso {
  display: flex; gap: 10px; align-items: flex-start;
  border-radius: var(--radio-s); padding: 12px 14px;
  font-size: 13px; line-height: 1.5;
  border: 1px solid var(--borde); background: var(--superficie-2); color: var(--texto);
  margin: 0 0 14px;
}
.aviso b { display: block; margin-bottom: 2px; }
.aviso p { margin: 0; color: var(--texto-2); }
.aviso .icono { flex: none; font-weight: 800; line-height: 1.4; }
.aviso-info { background: var(--info-suave); border-color: transparent; }
.aviso-info .icono { color: var(--info); }
.aviso-ok { background: var(--pos-suave); border-color: transparent; }
.aviso-ok .icono { color: var(--pos); }
.aviso-atencion { background: var(--atencion-suave); border-color: transparent; }
.aviso-atencion .icono { color: var(--atencion); }
.aviso-error { background: var(--neg-suave); border-color: transparent; }
.aviso-error .icono { color: var(--neg); }

/* Alarma de negocio: gasto que sube mientras el coste por cita se dispara.
   Tiene que verse antes que ninguna otra cosa de la pantalla. */
.alarma {
  border: 1px solid var(--marca); background: var(--marca-suave);
  border-radius: var(--radio); padding: 14px 16px; margin: 0 0 16px;
}
.alarma h3 { color: var(--marca); font-size: 14px; margin-bottom: 4px; }
.alarma p { font-size: 13px; color: var(--texto); margin: 0; }

/* --- 11. Procedencia del dato --------------------------------------------
   Cada cifra dice de dónde sale. Un dato en caché de hace dos horas y uno
   recién traído no valen lo mismo para decidir, y un dato dudoso hay que
   marcarlo aunque quede feo. */
.fuente {
  display: inline-flex; align-items: center; gap: 5px;
  border-radius: 999px; padding: 2px 8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; white-space: nowrap;
  background: var(--superficie-3); color: var(--texto-2);
  vertical-align: middle;
}
.fuente::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.fuente-vivo { background: var(--pos-suave); color: var(--pos); }
.fuente-cache { background: var(--superficie-3); color: var(--texto-2); }
.fuente-fichero { background: var(--info-suave); color: var(--info); }
.fuente-manual { background: var(--atencion-suave); color: var(--atencion); }
.fuente-ia { background: var(--marca-suave); color: var(--marca); }
.fuente-estimado { background: var(--atencion-suave); color: var(--atencion); }
/* Dato que existe pero del que no hay que fiarse (asistencia a citas sin cerrar,
   visitas a la landing sin píxel). */
.fuente-dudoso { background: var(--neg-suave); color: var(--neg); }
.fuente-error { background: var(--neg-suave); color: var(--neg); }
.fuente-sin { background: var(--superficie-3); color: var(--texto-3); }

/* Etiqueta de estado genérica (trato abierto, factura cobrada...). */
.pastilla {
  display: inline-block; border-radius: 999px; padding: 2px 9px;
  font-size: 11px; font-weight: 700; background: var(--superficie-3); color: var(--texto-2);
}
.pastilla-ok { background: var(--pos-suave); color: var(--pos); }
.pastilla-pendiente { background: var(--atencion-suave); color: var(--atencion); }
.pastilla-mal { background: var(--neg-suave); color: var(--neg); }
.pastilla-marca { background: var(--marca-suave); color: var(--marca); }

/* --- 12. Gráficos SVG -----------------------------------------------------
   Los gráficos se dibujan a mano. Estas clases les dan los colores del tema
   para que el claro y el oscuro no necesiten dos versiones del SVG. */
.grafico { display: block; width: 100%; height: auto; overflow: visible; }
.grafico .rejilla-linea { stroke: var(--borde); stroke-width: 1; }
.grafico .eje { stroke: var(--borde-fuerte); stroke-width: 1; }
.grafico .eje-texto { fill: var(--texto-3); font: 600 10px var(--fuente); }
.grafico .serie { fill: none; stroke: var(--marca); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.grafico .serie-2 { fill: none; stroke: var(--info); stroke-width: 2; stroke-dasharray: 4 3; }
.grafico .serie-3 { fill: none; stroke: var(--pos); stroke-width: 2; }
.grafico .area { fill: var(--marca-suave); stroke: none; }
.grafico .barra { fill: var(--marca); }
.grafico .barra-suave { fill: var(--marca-suave); }
.grafico .barra-pos { fill: var(--pos); }
.grafico .punto { fill: var(--superficie); stroke: var(--marca); stroke-width: 2; }
.grafico .marca-hoy { stroke: var(--texto-3); stroke-width: 1; stroke-dasharray: 3 3; }
.grafico .etiqueta { fill: var(--texto-2); font: 600 11px var(--fuente); }

.leyenda { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--texto-2); margin-top: 8px; }
.leyenda span { display: inline-flex; align-items: center; gap: 6px; }
.leyenda i { width: 10px; height: 10px; border-radius: 3px; background: var(--marca); display: inline-block; }
.leyenda i.i-2 { background: var(--info); }
.leyenda i.i-3 { background: var(--pos); }

/* --- 13. Modal, toast y estados ------------------------------------------ */
.modal-fondo {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(8, 9, 12, .5);
  backdrop-filter: blur(3px);
  display: grid; place-items: end center;
  padding: 0;
}
.modal {
  width: 100%; max-height: 92vh; overflow: auto;
  background: var(--superficie); color: var(--texto);
  border-radius: 20px 20px 0 0; padding: 22px 18px 28px;
  box-shadow: var(--sombra-3);
}
.modal h2 { margin: 0 0 14px; font-size: 17px; }
.modal-pie { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

.toast {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 70; max-width: calc(100vw - 32px);
  background: var(--texto); color: var(--fondo);
  border-radius: 999px; padding: 10px 18px;
  font-size: 13px; font-weight: 600; box-shadow: var(--sombra-2);
}
.toast-mal { background: var(--marca-solido); color: #fff; }

.vacio { padding: 44px 20px; text-align: center; color: var(--texto-2); }
.vacio b { display: block; color: var(--texto); font-size: 15px; margin-bottom: 4px; }

.esqueleto {
  background: linear-gradient(90deg, var(--superficie-3) 25%, var(--superficie-2) 37%, var(--superficie-3) 63%);
  background-size: 400% 100%;
  animation: brillo 1.4s ease infinite;
  border-radius: 6px; color: transparent !important;
}
@keyframes brillo { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.girando { animation: girar .9s linear infinite; display: inline-block; }
@keyframes girar { to { transform: rotate(360deg); } }

/* Diff propuesto por la IA, pendiente de aprobación. Nunca se aplica solo. */
.diff { border: 1px solid var(--borde); border-radius: var(--radio-s); overflow: hidden; margin-bottom: 10px; }
.diff-cab { padding: 10px 12px; background: var(--superficie-2); font-size: 12.5px; font-weight: 600; }
.diff-cuerpo { padding: 10px 12px; font-family: var(--mono); font-size: 12.5px; line-height: 1.6; }
.diff-antes { color: var(--neg); text-decoration: line-through; }
.diff-despues { color: var(--pos); font-weight: 700; }
.diff-motivo { padding: 0 12px 10px; font-size: 12.5px; color: var(--texto-2); }
.diff-acciones { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--borde); background: var(--superficie-2); }

/* Conversación con el analista. */
.charla { display: flex; flex-direction: column; gap: 12px; }
.burbuja { max-width: 88%; padding: 11px 14px; border-radius: 16px; font-size: 14px; line-height: 1.55; }
.burbuja-yo { align-self: flex-end; background: var(--marca-solido); color: #fff; border-bottom-right-radius: 5px; }
.burbuja-ia { align-self: flex-start; background: var(--superficie); border: 1px solid var(--borde); border-bottom-left-radius: 5px; }
.burbuja-ia p:last-child { margin-bottom: 0; }

/* --- Acceso --------------------------------------------------------------- */
.acceso { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 24px 16px; }
.acceso-caja { width: min(400px, 100%); background: var(--superficie); border: 1px solid var(--borde); border-radius: 20px; padding: 26px 22px; box-shadow: var(--sombra-2); }
.acceso-caja h1 { font-size: 20px; margin-bottom: 4px; }
.acceso-caja .sub { color: var(--texto-2); font-size: 13px; margin-bottom: 20px; }

/* --- 14. Utilidades ------------------------------------------------------- */
.oculto-visual {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.apagado { color: var(--texto-2); }
.tenue { color: var(--texto-3); }
.fuerte { font-weight: 700; }
.marca-color { color: var(--marca); }
.pos { color: var(--pos); }
.neg { color: var(--neg); }
.centro { text-align: center; }
.derecha { text-align: right; }
.entre { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.fila-flex { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.separador { flex: 1; }
.sin-margen { margin: 0 !important; }
.mt-8 { margin-top: 8px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.mb-8 { margin-bottom: 8px; } .mb-16 { margin-bottom: 16px; } .mb-24 { margin-bottom: 24px; }
.nowrap { white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* --- 15. Pantallas anchas ------------------------------------------------- */
@media (min-width: 640px) {
  body { font-size: 15px; }
  h1 { font-size: 28px; }
  .contenedor { padding: 26px 22px 80px; }
  .rejilla-2 { grid-template-columns: 1fr 1fr; }
  .metricas { gap: 14px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
  .modal-fondo { place-items: center; padding: 20px; }
  .modal { width: min(600px, 100%); border-radius: 20px; padding: 26px; max-height: 88vh; }
  .escalon { padding: 14px 16px; }
  .escalon-vol { font-size: 19px; }
}

@media (min-width: 900px) {
  .barra { padding: 8px 24px; gap: 18px; }
  .nav-movil { display: none; }
  .contenedor { padding: 30px 24px 90px; }
  .rejilla-3 { grid-template-columns: repeat(3, 1fr); }
  .rejilla-2-1 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 18px; align-items: start; }
  table.tabla { font-size: 13.5px; }
}

@media (min-width: 1200px) {
  .contenedor { padding: 34px 28px 100px; }
  .metricas { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}
