/* Waysuccess app — panel de gestión para agencias de contenido
   Diseño y desarrollo: Adrian Linares · https://adrianlinaresdev.com */
:root {
  --bg-sidebar: #f7f6f3;
  --bg-content: #ffffff;
  --bg-hover: #efefed;
  --borde: #e9e9e7;
  --texto: #37352f;
  --texto-tenue: #6d6c68;
  /* Los acentos van al tono exacto que alcanza 4,5:1 sobre su propio fondo
     teñido; los anteriores se quedaban entre 3,5 y 4,5, por debajo de AA. */
  --azul: #1583de;
  --azul-fondo: #e6f4fd;
  --verde: #2e794e;
  --verde-fondo: #ddf3e4;
  /* El paso de AHORA en la tarjeta de cliente. Aparte de --verde porque en
     oscuro la pareja se invierte: allí el verde es claro y la letra, oscura. */
  --paso-fondo: #4f46e5;
  --paso-texto: #ffffff;
  --amarillo: #97620a;
  --amarillo-fondo: #fbf0d3;
  --rojo: #bd3c24;
  --rojo-fondo: #fbe4e0;
  --gris-fondo: #f1f1ef;
  --sombra: 0 1px 2px rgba(15, 15, 15, 0.05), 0 1px 1px rgba(15, 15, 15, 0.04);
  --sombra-media: 0 4px 12px rgba(15, 15, 15, 0.08), 0 1px 2px rgba(15, 15, 15, 0.06);
  --sombra-grande: 0 12px 32px rgba(15, 15, 15, 0.14), 0 2px 6px rgba(15, 15, 15, 0.06);
  --radio: 8px;
  --transicion: 140ms cubic-bezier(0.4, 0, 0.2, 1);

  /* --- Escala de espaciado (base 4) ---
     Antes había catorce valores sueltos (3, 5, 7, 18, 20...) y como casi todo
     acababa en 18px, nada se agrupaba: la separación entre dos cifras de la
     misma tarjeta era igual que la que había entre secciones distintas. Con
     una escala, el espacio vuelve a significar algo: pegado = va junto,
     separado = es otra cosa. */
  --espacio-xs: 4px;
  --espacio-sm: 8px;
  --espacio-md: 12px;
  --espacio-lg: 16px;
  --espacio-xl: 24px;
  --espacio-2xl: 32px;
  --espacio-3xl: 48px;

  /* --- Series de datos ---
     Van aparte del azul de marca a propósito. En las gráficas de cliente,
     TikTok y YouTube salían en #1e9bec y #0f72d8: los mismos azules que los
     botones, así que una barra parecía pulsable. Y dos tonos del mismo azul
     es justo el par que no distingue quien tiene deuteranopia. Cuatro tonos
     distintos arreglan las dos cosas de una vez. */
  --serie-1: #0e7490;
  --serie-2: #7048c8;
  --serie-3: #0f8f6f;
  --serie-4: #b26212;

  /* Marca WaySuccess: los tres azules del logo — claro arriba-izquierda,
     profundo abajo-derecha — y el degradado que los une. Todo acento de
     marca sale de aquí para que la app se lea como un solo sistema.

     NOTA DE CONTRASTE (decisión tomada a propósito): el texto blanco sobre
     #1e9bec da 3,02:1 y sobre #3fc6f5 da 1,98:1, por debajo del 4,5 que pide
     WCAG AA. Se mantiene el azul de marca porque es una herramienta interna
     y la identidad pesa más aquí. Si algún día hay que cumplir AA, la vía es
     --marca-degradado-boton arrancando en #0f72d8 (4,75:1). */
  --marca-claro: #3fc6f5;
  --marca: #1e9bec;
  --marca-profundo: #0a6ad6;
  --marca-degradado: linear-gradient(140deg, #3fc6f5 0%, #1e9bec 45%, #0a6ad6 100%);
  /* En piezas anchas y bajas (botones, barras) el ángulo de 140° comprime
     las paradas y se ve como una banda cortada: para esas va casi horizontal. */
  --marca-degradado-ancho: linear-gradient(100deg, #3fc6f5 0%, #1e9bec 52%, #0a6ad6 100%);
  /* Para botones con texto blanco se arranca en el azul medio, no en el
     claro: sobre #3fc6f5 el blanco no se lee en absoluto. */
  --marca-degradado-boton: linear-gradient(100deg, #1e9bec 0%, #0a6ad6 100%);
  /* Azul de relleno para botones. Va aparte de --marca-profundo porque ese es
     un color de TEXTO y en tema oscuro se aclara: si el botón lo usara como
     fondo, acabaría en azul claro con letras blancas encima. */
  --marca-solido: #0f72d8;
  /* El mismo azul, pero para TEXTO. Va aparte porque en oscuro tiene que
     aclararse y --marca-solido no puede: es el fondo de los botones. */
  --marca-texto: #0f72d8;
  --marca-halo: 0 4px 14px rgba(30, 155, 236, 0.28);

  /* Colores de plataforma, para tags/acentos reconocibles de un vistazo. */
  --pf-instagram: #bd3477;
  --pf-instagram-fondo: #fbe7f1;
  --pf-tiktok: #1f2937;
  --pf-tiktok-fondo: #dfe3ea;
  --pf-youtube: #c92828;
  --pf-youtube-fondo: #fbe4e4;
  --pf-facebook: #1257a8;
  --pf-facebook-fondo: #e4eefb;
  --pf-linkedin: #0a66a3;
  --pf-linkedin-fondo: #e2effa;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--texto);
  background: var(--bg-content);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

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

/* Foco visible y consistente en toda la app (teclado y lectores de pantalla). */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--azul);
  outline-offset: 2px;
  border-radius: 4px;
}

/* --- Enlace para saltar al contenido (teclado) ---
   Fuera de la vista hasta que recibe el foco; no se usa display:none ni
   visibility:hidden porque eso lo sacaría del orden de tabulación. --- */
.salto-contenido {
  position: fixed; top: 8px; left: 8px; z-index: 300;
  transform: translateY(-160%);
  background: var(--marca-solido); color: #fff;
  padding: 10px 16px; border-radius: var(--radio);
  font-size: 13px; font-weight: 600; box-shadow: var(--sombra-grande);
  transition: transform var(--transicion);
}
.salto-contenido:focus { transform: translateY(0); }
/* El contenido recibe el foco al saltar, pero sin dibujarle un recuadro
   alrededor de toda la página. */
.pagina:focus { outline: none; }

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

.sidebar {
  width: 250px;
  flex-shrink: 0;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--borde);
  display: flex;
  flex-direction: column;
  padding: 16px 10px;
  /* Se queda fija a la vista mientras el contenido hace scroll. */
  position: sticky;
  top: 0;
  height: 100vh;
  align-self: flex-start;
  overflow-y: auto;
}

/* --- Barra y menú móvil (ocultos en escritorio) --- */
.topbar-movil { display: none; }
.fondo-sidebar { display: none; }
.btn-hamburguesa {
  background: none; border: none; padding: 7px; margin: -7px 0 -7px -7px;
  cursor: pointer; display: flex; color: var(--texto); border-radius: var(--radio);
  transition: background var(--transicion);
}
.btn-hamburguesa:hover { background: var(--bg-hover); }
.btn-hamburguesa svg { width: 22px; height: 22px; }
.marca-movil { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 15px; }

.sidebar .marca {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 18px;
  font-weight: 700;
  font-size: 15px;
}
/* El sello de marca es circular y en degradado, como el logo. */
.sidebar .marca .logo-cuadro,
.marca-movil .logo-cuadro {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--marca-degradado); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0;
  box-shadow: var(--marca-halo);
}

.nav-grupo { margin-bottom: 14px; }
.nav-titulo {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--texto-tenue); padding: 4px 8px; font-weight: 600;
}
.nav-link {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: var(--radio);
  font-size: 14px; color: var(--texto); cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.nav-link svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--texto-tenue); transition: color var(--transicion); }
.nav-link:hover { background: var(--bg-hover); }
/* La sección activa se marca con una barra de marca a la izquierda, como
   el trazo ascendente del logo. */
.nav-link.activo {
  background: var(--azul-fondo); color: var(--marca-profundo); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--marca);
}
.nav-link.activo svg { color: var(--marca); }

.nav-badge {
  margin-left: auto;
  background: var(--rojo);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  border-radius: 999px;
  padding: 1px 6px;
  min-width: 16px;
  text-align: center;
}

.sidebar-pie {
  margin-top: auto;
  border-top: 1px solid var(--borde);
  padding-top: 12px;
}
.usuario-pie { display: flex; align-items: center; gap: 8px; padding: 6px 8px; }
.usuario-avatar {
  width: 26px; height: 26px; border-radius: 50%; background: var(--marca-degradado);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0; overflow: hidden;
}
.usuario-avatar img { width: 100%; height: 100%; object-fit: cover; }
.usuario-info { min-width: 0; }
.usuario-nombre { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Sin capitalize: los roles ya traen su etiqueta con el formato correcto
   ("Portal de cliente", no "Portal De Cliente"). */
.usuario-rol { font-size: 11px; color: var(--texto-tenue); }
.salir-link {
  font-size: 12px; color: var(--texto-tenue); padding: 5px 8px; display: block;
  border-radius: var(--radio); transition: background var(--transicion), color var(--transicion);
}
.salir-link:hover { color: var(--texto); background: var(--bg-hover); }

/* --- Contenido --- */
.contenido { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding: 16px 32px; border-bottom: 1px solid var(--borde);
}
.topbar h1 { font-size: 22px; margin: 0; font-weight: 700; letter-spacing: -0.01em; }
.topbar .subtitulo { color: var(--texto-tenue); font-size: 13px; margin-top: 2px; }
.topbar > div:last-child { display: flex; gap: 8px; flex-wrap: wrap; }

/* El hueco de abajo cuenta con la burbuja: sin el, la ultima linea de
   cualquier pantalla se queda debajo y no hay forma de apartarla. */
.pagina { padding: 28px 32px var(--hueco-burbuja); max-width: 1180px; }

/* --- Botones --- */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid transparent; border-radius: var(--radio);
  padding: 7px 14px; font-size: 13px; font-weight: 600;
  cursor: pointer; background: var(--gris-fondo); color: var(--texto);
  transition: background var(--transicion), box-shadow var(--transicion), transform var(--transicion);
}
/* El texto no parte en varias líneas dentro del botón: en las celdas
   estrechas del móvil, "Google Calendar" se rompía en tres renglones. */
.btn { white-space: nowrap; }
.btn:hover { background: var(--bg-hover); }
.btn:active { transform: translateY(1px); }
/* Cada variante repite su fondo en :hover a propósito. `.btn:hover` tiene
   especificidad (0,2,0) y gana a `.btn-primario` (0,1,0), así que si la
   variante no lo redeclara, al pasar el ratón el botón se quedaba con el gris
   de `--bg-hover` y el texto blanco encima: ilegible.
   background-origin en border-box evita que el degradado se repita bajo el
   borde transparente de 1px y deje un corte en el canto. */
.btn-primario,
.btn-primario:hover {
  background: var(--marca-degradado-boton); color: #fff;
  background-origin: border-box; background-repeat: no-repeat;
}
/* Se oscurece, no se aclara: con texto blanco encima, aclarar bajaba el
   contraste justo cuando el botón recibe la atención. */
.btn-primario:hover { filter: brightness(0.93); box-shadow: var(--marca-halo); }

.btn-azul, .btn-azul:hover { background: var(--marca-solido); color: #fff; }
.btn-azul:hover { filter: brightness(0.93); box-shadow: var(--marca-halo); }

.btn-peligro, .btn-peligro:hover { background: var(--rojo-fondo); color: var(--rojo); }
.btn-peligro:hover { filter: brightness(0.96); }

.btn-verde, .btn-verde:hover { background: var(--verde-fondo); color: var(--verde); }
.btn-verde:hover { filter: brightness(0.96); }
.btn-secundario { background: var(--gris-fondo); color: var(--texto); }
.btn-pequeno { padding: 4px 10px; font-size: 12px; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* --- Tarjetas / cards --- */
.card {
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 10px; padding: var(--espacio-lg) var(--espacio-xl); margin-bottom: var(--espacio-xl);
  box-shadow: var(--sombra);
  transition: box-shadow var(--transicion), border-color var(--transicion);
}
.card h2, .card h3 { margin: 0 0 var(--espacio-md); font-size: 14px; font-weight: 700; }

/* Las rejillas separan piezas hermanas: van más juntas (--espacio-md) que las
   secciones apiladas (--espacio-xl), que es lo que crea el ritmo. */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--espacio-md); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--espacio-md); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--espacio-md); }
/* Dentro de una rejilla la tarjeta ya no arrastra su margen inferior: lo
   gestiona el gap, y si no, las filas quedaban con doble separación. */
.grid-2 > .card, .grid-3 > .card, .grid-4 > .card { margin-bottom: 0; }
/* Los hijos de una rejilla traen min-width:auto, así que no se encogen por
   debajo del ancho natural de su contenido: una tabla dentro de una tarjeta
   ensanchaba su columna y hacía que TODA la página se desplazara en
   horizontal en el móvil. Con min-width:0 la tarjeta respeta la columna y es
   la tabla la que hace su propio scroll dentro de .tabla-wrap. */
.grid-2 > *, .grid-3 > *, .grid-4 > * { min-width: 0; }

@media (max-width: 900px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .grid-4 { grid-template-columns: 1fr; } }

/* --- Tira de resumen ---
   Sustituye a la fila de tarjetas KPI. Seis tarjetas iguales afirman que las
   seis cifras pesan lo mismo y merecen cada una su caja; en la práctica son
   contexto de fondo, y se comían entre 130 y 260px de alto justo encima de la
   tabla que es el trabajo de verdad. Aquí van en una sola banda de ~68px,
   separadas por filetes. La cifra que sí dispara una decisión (alertas,
   clientes en riesgo) se tiñe; las demás se quedan neutras, porque si todo
   grita no se oye nada. */
.tira-resumen {
  display: flex; flex-wrap: wrap;
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 10px; box-shadow: var(--sombra);
  margin-bottom: var(--espacio-xl); overflow: hidden;
}
.tira-dato {
  flex: 1 1 148px; min-width: 0;
  padding: var(--espacio-md) var(--espacio-lg);
  border-left: 1px solid var(--borde);
}
.tira-dato:first-child { border-left: 0; }
.tira-etiqueta {
  font-size: 11.5px; color: var(--texto-tenue); font-weight: 500;
  display: block; margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tira-cifra {
  font-size: 20px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  display: block; overflow-wrap: break-word;
}
.tira-nota { font-size: 11.5px; color: var(--texto-tenue); display: block; margin-top: 2px; }
.tira-dato.tono-rojo .tira-cifra { color: var(--rojo); }
.tira-dato.tono-amarillo .tira-cifra { color: var(--amarillo); }
.tira-dato.tono-verde .tira-cifra { color: var(--verde); }
/* Un dato que además lleva a algún sitio se comporta como enlace. */
a.tira-dato { text-decoration: none; color: inherit; transition: background var(--transicion); }
a.tira-dato:hover { background: var(--gris-fondo); }

@media (max-width: 640px) {
  .tira-dato { flex-basis: 50%; }
  /* Con dos por fila, el filete izquierdo sobra en la primera de cada fila. */
  .tira-dato:nth-child(odd) { border-left: 0; }
  .tira-dato:nth-child(n + 3) { border-top: 1px solid var(--borde); }
}

.metrica-grande { font-size: 26px; font-weight: 700; letter-spacing: -0.01em; }
.metrica-etiqueta { font-size: 12px; color: var(--texto-tenue); margin-bottom: var(--espacio-xs); }
.metrica-delta { font-size: 12px; font-weight: 600; }
.metrica-delta.subio { color: var(--verde); }
.metrica-delta.bajo { color: var(--rojo); }
/* Cero no es subir. En verde, una cartera entera parada se leía como que
   todos los clientes crecían. */
.metrica-delta.sin-cambio { color: var(--texto-tenue); }

/* --- Tabla estilo "database view" de Notion --- */
.tabla-wrap {
  border: 1px solid var(--borde); border-radius: 10px;
  overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
  /* Sombra de desplazamiento: aparece en el borde solo cuando queda tabla por
     ver, y desaparece al llegar al final. Sin ella, en móvil no había forma de
     saber que quedaban columnas a la derecha. Es puro CSS: las capas "local"
     viajan con el scroll y tapan a las "scroll", que son las que dan sombra. */
  background:
    linear-gradient(to right, var(--bg-content) 30%, rgba(255, 255, 255, 0)),
    linear-gradient(to right, rgba(255, 255, 255, 0), var(--bg-content) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(15, 15, 15, .13), rgba(15, 15, 15, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(15, 15, 15, .13), rgba(15, 15, 15, 0)) 100% 0;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* Columna de desglose: la que se sacrifica primero cuando no cabe todo.
   En la tabla de Score son Ejecución/Performance/Retención, que son el
   detalle; lo que hay que ver sí o sí es el score final y su lectura. */
@media (max-width: 720px) {
  .col-secundaria { display: none; }
}
table.tabla-notion { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tabla-notion th {
  text-align: left; padding: 9px 14px; background: var(--gris-fondo);
  color: var(--texto-tenue); font-weight: 600; font-size: 12px;
  border-bottom: 1px solid var(--borde); white-space: nowrap;
}
table.tabla-notion td { padding: 10px 14px; border-bottom: 1px solid var(--borde); }
table.tabla-notion tr:last-child td { border-bottom: none; }
table.tabla-notion tr:hover td { background: var(--bg-hover); }
table.tabla-notion a.fila-link { display: block; }
table.tabla-zebra tbody tr.fila-par td { background: var(--gris-fondo); }
table.tabla-zebra tbody tr:hover td { background: var(--bg-hover); }
table.tabla-notion td.col-num { text-align: right; font-variant-numeric: tabular-nums; }
table.tabla-notion th.col-num { text-align: right; }
.titulo-truncado {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; max-width: 260px;
}

/* --- Tags / pills de estado --- */
.tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 4px; font-size: 12px; font-weight: 600;
}
.tag-gris { background: var(--gris-fondo); color: var(--texto-tenue); }
.tag-azul { background: var(--azul-fondo); color: var(--marca-profundo); }
.tag-verde { background: var(--verde-fondo); color: var(--verde); }
.tag-amarillo { background: var(--amarillo-fondo); color: var(--amarillo); }
.tag-rojo { background: var(--rojo-fondo); color: var(--rojo); }

.plataforma-tag { text-transform: capitalize; }
.tag-plataforma-instagram { background: var(--pf-instagram-fondo); color: var(--pf-instagram); }
.tag-plataforma-tiktok { background: var(--pf-tiktok-fondo); color: var(--pf-tiktok); }
.tag-plataforma-youtube { background: var(--pf-youtube-fondo); color: var(--pf-youtube); }
.tag-plataforma-facebook { background: var(--pf-facebook-fondo); color: var(--pf-facebook); }
.tag-plataforma-linkedin { background: var(--pf-linkedin-fondo); color: var(--pf-linkedin); }

.tag-punto::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex-shrink: 0;
}

/* --- Galería de clientes (tarjetas estilo Notion) --- */
.clientes-galeria {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}
.cliente-card {
  display: flex; flex-direction: column;
  background: var(--bg-content); border: 1px solid var(--borde); border-radius: 10px;
  overflow: hidden; box-shadow: var(--sombra);
  transition: box-shadow var(--transicion), border-color var(--transicion), transform var(--transicion);
}
.cliente-card:hover { box-shadow: var(--sombra-media); transform: translateY(-1px); }
.cliente-card-portada {
  height: 84px; flex-shrink: 0; display: flex; align-items: center; gap: 8px;
  padding: 0 16px; color: #fff; font-weight: 700; font-size: 15px; letter-spacing: 0.02em;
  background: var(--marca-degradado);
}
.cliente-card-portada .logo-cuadro {
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.22); color: #fff;
}
/* Con foto, la portada es la foto. El nombre va encima con un velo oscuro
   detras y no con text-shadow: sobre una foto clara el shadow no salva el
   contraste, el velo si. */
.cliente-card-portada.con-foto {
  background-size: cover; background-position: center; position: relative;
  align-items: flex-end; padding: 0;
}
.cliente-card-portada.con-foto::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.62) 0%, rgba(0,0,0,0) 62%);
}
.portada-quien {
  position: relative; z-index: 1; padding: 0 16px 9px; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cliente-card-cuerpo { padding: 12px 16px; flex: 1; }
.cliente-card-titulo { display: flex; align-items: center; gap: 8px; font-size: 14px; margin-bottom: 8px; }
.cliente-card-icono {
  width: 20px; height: 20px; border-radius: 5px; background: var(--gris-fondo);
  color: var(--texto-tenue); display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; flex-shrink: 0;
}
.cliente-card-plataformas { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.cliente-card-estado { display: flex; align-items: center; gap: 8px; }
.cliente-card-pie {
  display: flex; align-items: center; gap: 12px; padding: 8px 16px;
  border-top: 1px solid var(--borde); font-size: 12px; color: var(--texto-tenue);
}
.cliente-card-meta { display: flex; align-items: center; gap: 4px; }
.cliente-card-meta svg { width: 14px; height: 14px; }
.cliente-card-meta.texto-tenue { margin-left: auto; }
.cliente-card-alerta { color: var(--rojo); font-weight: 600; }

/* --- Calendario de reuniones --- */
.calendario-cabecera { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.calendario-grid-wrap { overflow-x: auto; margin-top: 14px; }
.calendario-grid {
  display: grid; grid-template-columns: repeat(7, minmax(128px, 1fr)); gap: 1px;
  background: var(--borde); border: 1px solid var(--borde); border-radius: 10px; overflow: hidden;
}
.calendario-diasemana {
  background: var(--gris-fondo); color: var(--texto-tenue); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em; padding: 8px 6px; text-align: center;
}
.calendario-celda {
  background: var(--bg-content); min-height: 108px; padding: 6px; display: flex; flex-direction: column; gap: 4px;
}
.calendario-celda.fuera-de-mes { background: var(--gris-fondo); }
.calendario-celda.fuera-de-mes .calendario-numero { color: var(--texto-tenue); }
.calendario-celda.hoy { box-shadow: inset 0 0 0 2px var(--azul); }
.calendario-numero {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 6px;
  font-size: 12px; font-weight: 700; color: var(--texto);
  transition: background var(--transicion);
}
.calendario-numero:hover { background: var(--bg-hover); }
.calendario-celda.hoy .calendario-numero { background: var(--marca-profundo); color: #fff; }
.calendario-evento {
  display: block; font-size: 12px; line-height: 1.5; padding: 3px 6px; border-radius: 5px;
  background: var(--azul-fondo); color: var(--marca-profundo); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-left: 3px solid var(--azul); transition: background var(--transicion), color var(--transicion);
}
.calendario-evento-hora { font-weight: 700; }
a.calendario-evento:hover { background: var(--azul); color: #fff; }
.calendario-evento-interna { background: var(--gris-fondo); color: var(--texto-tenue); border-left-color: var(--texto-tenue); }
a.calendario-evento-interna:hover { background: var(--texto-tenue); color: var(--bg-content); }
.calendario-mas {
  font-size: 11px; font-weight: 600; color: var(--texto-tenue); padding: 0 6px;
  transition: color var(--transicion);
}
.calendario-mas:hover { color: var(--azul); text-decoration: underline; }
.calendario-eventos-escritorio { display: flex; flex-direction: column; gap: 4px; }
.calendario-puntos-movil { display: none; }

/* --- Pestañas secundarias (ej. Score AM: General / Fórmulas) --- */
.tabs-secundarias { display: flex; gap: 4px; margin-bottom: 18px; border-bottom: 1px solid var(--borde); }
.tab-secundaria {
  padding: 8px 14px; font-size: 13px; font-weight: 600; color: var(--texto-tenue);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--transicion), border-color var(--transicion);
}
.tab-secundaria:hover { color: var(--texto); }
.tab-secundaria.activo { color: var(--azul); border-bottom-color: var(--azul); }

/* --- Formularios --- */
label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 5px; margin-top: 14px; }
label:first-child { margin-top: 0; }
input[type="text"], input[type="email"], input[type="password"], input[type="date"],
input[type="number"], input[type="time"], select, textarea {
  width: 100%; padding: 8px 10px; border: 1px solid var(--borde); border-radius: var(--radio);
  font-size: 14px; font-family: inherit; background: var(--bg-content); color: var(--texto);
  transition: border-color var(--transicion), box-shadow var(--transicion);
}
input[type="text"]:hover, input[type="email"]:hover, input[type="password"]:hover,
input[type="date"]:hover, input[type="number"]:hover, select:hover, textarea:hover {
  border-color: var(--texto-tenue);
}
input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus,
input[type="date"]:focus, input[type="number"]:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--azul);
  box-shadow: 0 0 0 3px rgba(35, 131, 226, 0.18);
}
textarea { resize: vertical; min-height: 70px; }
.campo-ayuda { font-size: 12px; color: var(--texto-tenue); margin-top: 4px; }
.check-linea { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.check-linea input { width: auto; }
.check-linea label { margin: 0; }

.form-acciones { margin-top: 20px; display: flex; gap: 10px; }

.buscador { max-width: 320px; margin-bottom: 18px; }

/* --- Barra de progreso (ciclo/meta) --- */
.barra-progreso { background: var(--gris-fondo); border-radius: 999px; height: 8px; overflow: hidden; }
.barra-progreso > div { height: 100%; background: var(--marca-degradado-ancho); }
.barra-progreso.completo > div { background: var(--verde); }

/* --- Notas tipo CRM --- */
.nota { border-bottom: 1px solid var(--borde); padding: 10px 0; }
.nota:last-child { border-bottom: none; }
.nota-meta { font-size: 12px; color: var(--texto-tenue); margin-bottom: 3px; }
.nota-texto { font-size: 13px; }

/* --- Alertas --- */
.alerta-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border: 1px solid var(--borde); border-radius: 8px; margin-bottom: 10px;
}
.alerta-punto { width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; flex-shrink: 0; }
.alerta-punto.alta { background: var(--rojo); }
.alerta-punto.media { background: var(--amarillo); }
.alerta-punto.baja { background: var(--texto-tenue); }
.alerta-texto { flex: 1; font-size: 13px; }
.alerta-fecha { font-size: 11px; color: var(--texto-tenue); margin-top: 2px; }

/* --- Login --- */
.login-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(circle at 12% 12%, rgba(63, 198, 245, 0.20), transparent 48%),
    radial-gradient(circle at 88% 88%, rgba(10, 106, 214, 0.16), transparent 48%),
    var(--bg-sidebar);
}
.login-card {
  background: #fff; border: 1px solid var(--borde); border-radius: 12px;
  padding: 40px 36px; width: 360px; box-shadow: var(--sombra-grande);
}
.login-card .logo-cuadro {
  width: 46px; height: 46px; font-size: 20px; margin-bottom: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-weight: 700;
  background: var(--marca-degradado); color: #fff; box-shadow: var(--marca-halo);
}
.login-card h1 { font-size: 19px; margin: 0 0 4px; letter-spacing: -0.01em; }
.login-card p.subtitulo { color: var(--texto-tenue); font-size: 13px; margin: 0 0 22px; }
.login-error { color: var(--rojo); font-size: 13px; margin: 12px 0 0; }
.login-demo {
  margin-top: 22px; padding: 12px 14px; border-radius: 8px; background: var(--gris-fondo);
  font-size: 12px; color: var(--texto-tenue); line-height: 1.7;
}

/* --- Charts --- */
.chart-wrap { position: relative; height: 260px; }

/* --- Utilidades --- */
.texto-tenue { color: var(--texto-tenue); }
/* Nota breve de "aquí no hay nada", dentro de una sección o una fila de
   tabla. Para una pantalla entera sin datos se usa .estado-vacio. */
.vacio {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--espacio-sm); padding: var(--espacio-xl) var(--espacio-lg);
  text-align: center; color: var(--texto-tenue); font-size: 13px; line-height: 1.6;
}
td.vacio { display: table-cell; }
.fila-titulo { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.fila-titulo h2, .fila-titulo h3 { margin: 0; }
.chips-filtro { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }

/* --- Contenido win ---------------------------------------------------------
   Se pidio «un formato llamativo que no sea tablas». La cifra manda: es lo
   unico que se lee de lejos, y en una tabla un video de 900 mil pesaba igual
   que uno de 100 mil. Se envuelve sola y no lleva scroll horizontal: una
   banda que se arrastra esconde la mitad de los wins en movil. */
.wins-banda {
  display: grid; gap: 12px; margin: 0;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.win-card {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--borde); border-radius: 12px; padding: 14px 15px 12px;
  background: linear-gradient(160deg, var(--verde-fondo) 0%, var(--bg-content) 62%);
  transition: box-shadow var(--transicion), transform var(--transicion),
              border-color var(--transicion);
}
a.win-card:hover {
  box-shadow: var(--sombra-media); transform: translateY(-2px);
  border-color: var(--verde);
}
a.win-card:active { transform: translateY(0); }
.win-cifra {
  font-size: 30px; font-weight: 800; line-height: 1; color: var(--verde);
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.win-etq {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-tenue); margin-top: 3px;
}
/* Dos lineas y corta: los titulos que vinieron de Notion llegan a 200
   caracteres y uno solo empujaba la tarjeta al triple de alto que las demas. */
.win-titulo {
  font-size: 13px; font-weight: 600; line-height: 1.35; margin-top: 10px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.7em;
}
.win-pie {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 10px; font-size: 11.5px; color: var(--texto-tenue);
}
.win-quien { font-weight: 600; color: var(--texto); }
.win-cuando { margin-left: auto; font-variant-numeric: tabular-nums; }

/* --- Ranking de clientes por resultado -------------------------------------
   Sustituye a la tabla del resumen. Una tabla ordena, pero no deja ver de un
   vistazo cuanto separa al primero del quinto; la barra si. */
.rank-clientes { list-style: none; margin: 0; padding: 0; }
.rank-fila + .rank-fila { border-top: 1px solid var(--borde); }
.rank-fila > a {
  display: grid; align-items: center; gap: 12px; padding: 10px 4px;
  grid-template-columns: 28px minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr);
  text-decoration: none; color: inherit; border-radius: 8px;
}
.rank-fila > a:hover { background: var(--bg-hover); }
.rank-pos {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; background: var(--gris-fondo);
  font-size: 12px; font-weight: 700; color: var(--texto-tenue);
}
/* Solo el podio se tine. Con los ocho de color, ninguno destaca. */
.rank-fila:nth-child(1) .rank-pos { background: var(--verde); color: #fff; }
.rank-fila:nth-child(2) .rank-pos,
.rank-fila:nth-child(3) .rank-pos { background: var(--verde-fondo); color: var(--verde); }
/* Sin resultado esta semana no se pinta como podio aunque caiga arriba. */
.rank-sin-dato .rank-pos { background: var(--gris-fondo) !important; color: var(--texto-tenue) !important; }
.rank-quien { min-width: 0; }
.rank-nombre {
  display: block; font-weight: 600; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rank-sub { display: block; font-size: 11.5px; color: var(--texto-tenue); }
.rank-cifra { min-width: 0; }
.rank-num {
  font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--verde);
}
.rank-sin-dato .rank-num { color: var(--texto-tenue); }
.rank-unidad { display: block; font-size: 11.5px; color: var(--texto-tenue); }
.rank-meta { min-width: 0; }
.rank-barra {
  display: block; height: 6px; border-radius: 4px; background: var(--bg-hover);
  overflow: hidden; margin-bottom: 4px;
}
.rank-barra > span { display: block; height: 100%; background: var(--marca-solido); }
.rank-pct { font-size: 11.5px; color: var(--texto-tenue); font-variant-numeric: tabular-nums; }

/* Aviso de puesto sin asignar dentro de la tabla de capacidad. En amarillo
   y no en rojo: no esta roto, falta un dato que solo puede poner una persona. */
.aviso-sin-puesto {
  margin-top: 4px; font-size: 11.5px; line-height: 1.4;
  color: var(--amarillo); max-width: 42ch;
}
.aviso-sin-puesto a { color: var(--amarillo); font-weight: 600; text-decoration: underline; }

/* --- Campo plegable (Campos del tablero) -----------------------------------
   Veinte formularios abiertos a la vez medían 8.753 px: para cambiar el color
   de un campo había que recorrer nueve pantallas, y «Eliminar campo» en rojo
   aparecía veinte veces. Ahora cada campo es una fila y el formulario se abre
   solo en el que se toca.

   Con <details> y no con JavaScript: funciona con el teclado, lo encuentra el
   buscar del navegador y no depende de que el script cargue. */
.campo-plegable {
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: var(--radio); margin-bottom: var(--espacio-sm);
  transition: border-color var(--transicion), box-shadow var(--transicion);
}
.campo-plegable > summary {
  list-style: none; cursor: pointer; padding: 11px var(--espacio-lg);
  border-radius: var(--radio);
}
.campo-plegable > summary::-webkit-details-marker { display: none; }
/* El triángulo se dibuja aquí para poder girarlo al abrir. */
.campo-plegable > summary::before {
  content: ""; float: left; margin: 6px 10px 0 0;
  border: 5px solid transparent; border-left-color: var(--texto-tenue);
  transition: transform var(--transicion);
}
.campo-plegable[open] > summary::before {
  transform: rotate(90deg) translate(2px, 3px);
}
.campo-plegable > summary:hover { background: var(--bg-hover); }
.campo-plegable > summary:focus-visible {
  outline: 2px solid var(--marca-solido); outline-offset: -2px;
}
.campo-plegable > summary:active { background: var(--gris-fondo); }
.campo-plegable[open] {
  border-color: var(--marca); box-shadow: var(--sombra);
}
.campo-plegable[open] > summary { border-bottom: 1px solid var(--borde); border-radius: var(--radio) var(--radio) 0 0; }
.campo-cuerpo { padding: var(--espacio-lg); }

.campo-fila {
  display: flex; align-items: baseline; gap: var(--espacio-md);
  flex-wrap: wrap; min-width: 0;
}
.campo-nombre {
  font-weight: 600; font-size: 14px; display: flex; align-items: center;
  gap: 7px; min-width: 0;
}
.campo-sub { font-size: 12px; color: var(--texto-tenue); min-width: 0; }
.campo-avisos { display: flex; gap: 5px; flex-wrap: wrap; margin-left: auto; }
/* Un campo apagado se lee apagado, pero sin llegar a ilegible: sigue
   habiendo que poder leerlo para volver a encenderlo. */
.campo-plegable.inactivo-campo > summary .campo-nombre { color: var(--texto-tenue); }
/* Crear un campo es más raro que ajustar uno: nace cerrado, pero se distingue
   de la lista para que se encuentre. */
.campo-nuevo { border-style: dashed; }
.campo-nuevo > summary .campo-nombre { color: var(--marca-texto); }
@media (max-width: 640px) {
  .campo-avisos { margin-left: 0; }
  .campo-cuerpo { padding: var(--espacio-md); }
}

/* --- Objetivos táctiles -----------------------------------------------------
   WCAG 2.2 AA (2.5.8) pide 24x24 px de área pulsable. Una casilla nativa mide
   13x13: cuando va dentro de una etiqueta no importa —lo que se toca es la
   etiqueta— pero suelta, sí. Se le da el área sin agrandar el dibujo, que es
   lo que mantiene la densidad de las tablas. */
@media (pointer: coarse) {
  input[type="checkbox"], input[type="radio"] {
    min-width: 24px; min-height: 24px;
  }
  .btn-pequeno, .enlace-quitar, .btn-iconico {
    min-height: 32px;
  }
}

/* --- Anotar seguidores a mano ----------------------------------------------
   Va dentro de la propia cuenta porque es donde se ve el hueco: la cifra pone
   «—» y al lado esta como arreglarlo. Plegado para no meter un formulario por
   cuenta en la tira de cifras. */
.anotar-seg > summary {
  list-style: none; cursor: pointer; font-size: 11.5px; margin-top: 6px;
  color: var(--marca-texto); text-decoration: underline;
}
.anotar-seg > summary::-webkit-details-marker { display: none; }
.anotar-seg > summary:hover { color: var(--texto); }
.anotar-seg > summary:focus-visible {
  outline: 2px solid var(--marca-solido); outline-offset: 2px; border-radius: 4px;
}
.anotar-seg[open] > summary { color: var(--texto); font-weight: 600; }
.anotar-seg form { margin-top: 8px; }
.anotar-seg input { font-size: 13px; }
@media (pointer: coarse) { .anotar-seg > summary { min-height: 24px; } }

/* --- Campos de archivo ------------------------------------------------------
   Un `input[type=file]` trae un ancho minimo propio (boton + nombre) que no
   respeta al contenedor: dentro de un flex con `flex:1` pero sin `min-width:0`
   empuja la fila fuera de la pantalla. Le pasaba a «Foto de perfil»: 414 px de
   fila en un movil de 390. */
input[type="file"] { max-width: 100%; min-width: 0; }
label:has(> input[type="file"]) { min-width: 0; }
/* Para navegadores sin :has, el mismo efecto desde el contenedor. */
.campo-archivo { min-width: 0; }

/* --- Panel de invitacion --------------------------------------------------
   Sale sobre la lista de usuarios con el enlace ya hecho. Se hizo panel y no
   pantalla aparte porque quien invita esta mirando la lista y volver atras
   para seguir invitando al siguiente es el paso que sobra. */
.inv-fondo {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center; padding: 20px;
  background: rgba(15, 15, 15, .45);
}
.inv-caja {
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 12px; padding: 18px 20px; width: 100%; max-width: 560px;
  box-shadow: var(--sombra-grande);
}
/* DESPUES de la regla del display: a igual especificidad gana la ultima, y
   sin esto la capa se queda encima de todo aunque este «oculta». */
.inv-fondo[hidden] { display: none; }
.inv-caja input[readonly] { font-size: 12.5px; }
.inv-aviso { font-size: 12.5px; line-height: 1.4; max-width: 60%; }
.inv-aviso.bien { color: var(--verde); }
.inv-aviso.mal { color: var(--rojo); }

/* --- Copiar el valor de un campo ------------------------------------------
   Se pidio «igual al notion»: el boton vive pegado al valor, no en un menu.
   Dos tamanos: el grande para el formulario y la ficha, el mini para la
   tabla, donde una fila mide 34px y un boton normal la haria crecer. */
.fila-copiar { display: flex; gap: 6px; align-items: flex-start; }
.fila-copiar > input, .fila-copiar > textarea { flex: 1; min-width: 0; }
.fila-copiar > .btn-copiar { flex: none; margin-top: 2px; }

.btn-copiar-mini {
  font: inherit; font-size: 11px; line-height: 1.2; padding: 2px 7px;
  border-radius: 6px; cursor: pointer; vertical-align: middle;
  border: 1px solid var(--borde); background: var(--bg-content);
  color: var(--texto-tenue); margin-left: 6px;
  transition: background var(--transicion), border-color var(--transicion),
              color var(--transicion);
}
.btn-copiar-mini:hover {
  border-color: var(--marca); color: var(--marca-texto); background: var(--azul-fondo);
}
.btn-copiar-mini:active { transform: translateY(1px); }
/* En la tabla el boton solo aparece al pasar por encima o al tabular: con 200
   filas, doscientos botones grises compiten con el dato. En tactil no hay
   hover, asi que ahi se queda siempre visible. */
.celda-desc .btn-copiar-mini, td .btn-copiar-mini { opacity: 0; }
tr:hover .btn-copiar-mini,
.btn-copiar-mini:focus-visible { opacity: 1; }
@media (hover: none) {
  td .btn-copiar-mini, .celda-desc .btn-copiar-mini { opacity: 1; }
}
/* El resultado se dice en el propio boton: un mensaje flotante en la esquina
   no se ve cuando estas mirando la fila de abajo del todo. */
.btn-copiar.copiado, .btn-copiar-mini.copiado {
  background: var(--verde-fondo); border-color: var(--verde);
  color: var(--verde); opacity: 1;
}
.btn-copiar.copia-fallo, .btn-copiar-mini.copia-fallo {
  background: var(--rojo-fondo); border-color: var(--rojo);
  color: var(--rojo); opacity: 1;
}
/* La descripcion en la tabla: dos lineas y corta. Hay copys de 900 caracteres
   y uno solo estiraba la fila hasta empujar la tabla entera. */
/* Ancho minimo para que el nombre no se parta en tres lineas y la
   descripcion no se coma la fila. */
.celda-desc { max-width: 340px; min-width: 200px; position: relative; }
/* Fuera del flujo: si el boton empuja al texto, la fila crece al pasar el
   raton y la tabla entera pega un salto justo cuando vas a pulsar. */
.celda-desc .btn-copiar-mini {
  position: absolute; top: 4px; right: 4px; margin: 0;
  background: var(--bg-content); box-shadow: 0 0 0 3px var(--bg-content);
}
tr:hover .celda-desc .btn-copiar-mini { background: var(--bg-hover); box-shadow: 0 0 0 3px var(--bg-hover); }
.celda-desc .pieza-texto { display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; text-decoration: none; }

/* --- Chip de filtro / pestana ligera -------------------------------------
   Estaba copiado dentro de <style> en tres plantillas (chat, catalogo de
   tareas y panel de tareas) y NO existia aqui. Resultado: las dos pantallas
   que lo usaban sin copiarlo -la bandeja de alertas y el pipeline- pintaban
   botones y enlaces del navegador sin estilo; en el pipeline las dos
   pestanas se leian como una sola frase corrida, "Exito del cliente
   Comercial", y nadie veia que hubiera dos procesos.

   Vale igual para <button> y para <a>: el pipeline navega de verdad (cada
   proceso es su URL) y los filtros solo esconden filas, asi que hacen falta
   los dos. De ahi el text-decoration:none y el font:inherit, que un <a> no
   hereda la tipografia del boton ni al reves.

   Con variables, no con #fff/#475569 fijos como las copias: asi tambien
   funciona en tema oscuro y en alto contraste. */
.chip-rol {
  display: inline-flex; align-items: center; gap: 4px;
  font: inherit; font-size: 13px; line-height: 1.3;
  padding: 6px 14px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--borde); background: var(--bg-content);
  color: var(--texto-tenue); text-decoration: none;
  transition: background var(--transicion), border-color var(--transicion),
              color var(--transicion);
}
.chip-rol:hover {
  border-color: var(--marca); color: var(--marca-texto);
  background: var(--azul-fondo);
}
.chip-rol:active { transform: translateY(1px); }
.chip-rol.activo {
  background: var(--marca-solido); border-color: var(--marca-solido);
  color: #fff; box-shadow: var(--marca-halo);
}
.chip-rol.activo:hover { background: var(--marca-solido); color: #fff; }
.chip-rol[disabled], .chip-rol[aria-disabled="true"] {
  opacity: .5; cursor: not-allowed; box-shadow: none;
}
.chip-rol[disabled]:hover, .chip-rol[aria-disabled="true"]:hover {
  border-color: var(--borde); color: var(--texto-tenue); background: var(--bg-content);
}
.chip-rol .cuenta { opacity: .7; font-size: 12px; }
/* Va DESPUES de la regla de display, no antes: a igual especificidad gana la
   ultima, y sin esto un chip escondido con [hidden] se seguiria viendo. */
.chip-rol[hidden] { display: none; }
/* Un grupo de chips que son pestanas de verdad (cambian de pagina). */
.chip-pestanas { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }

/* ============================================================
   Responsive — móvil y tablet
   ============================================================ */
@media (max-width: 860px) {
  .app-shell { flex-direction: column; }

  .topbar-movil {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 16px; border-bottom: 1px solid var(--borde);
    background: var(--bg-content); position: sticky; top: 0; z-index: 30;
  }

  .fondo-sidebar {
    display: block; position: fixed; inset: 0; background: rgba(15, 15, 15, 0.4);
    opacity: 0; pointer-events: none; transition: opacity var(--transicion);
    z-index: 40;
  }
  .fondo-sidebar.visible { opacity: 1; pointer-events: auto; }

  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 50;
    width: 78vw; max-width: 300px;
    transform: translateX(-100%);
    transition: transform var(--transicion);
    box-shadow: var(--sombra-grande);
  }
  .sidebar.abierto { transform: translateX(0); }
  .sidebar .marca { display: none; }

  .contenido { min-width: 0; width: 100%; }

  .topbar { padding: 14px 18px; }
  .topbar h1 { font-size: 19px; }
  .pagina { padding: 18px 18px 44px; }

  .card { padding: 15px 16px; }

  .form-acciones { flex-wrap: wrap; }

  /* --- Columna de acciones fija ---
     En las tablas anchas los botones viven en la última columna, que en el
     móvil queda fuera de la pantalla: parecían cortados y había que arrastrar
     la tabla a ciegas para llegar a ellos. Se quedan pegados al borde
     derecho, siempre visibles, mientras el resto de columnas se desliza.
     La clase la pone app.js solo en las tablas cuya última columna tiene
     botones, para no fijar por error una columna de datos. */
  table.tabla-acciones th:last-child,
  table.tabla-acciones td:last-child {
    position: sticky; right: 0; z-index: 2;
    background: var(--bg-content);
    box-shadow: -7px 0 9px -7px rgba(0, 0, 0, 0.28);
  }
  table.tabla-acciones thead th:last-child { background: var(--gris-fondo); }
  table.tabla-acciones.tabla-zebra tbody tr.fila-par td:last-child { background: var(--gris-fondo); }
  table.tabla-acciones tbody tr:hover td:last-child { background: var(--bg-hover); }
  /* Las filas que ocupan todo el ancho (edición en línea, estado vacío) no
     tienen columna de acciones que fijar. */
  table.tabla-acciones td[colspan] { position: static; box-shadow: none; }
}

@media (max-width: 540px) {
  html, body { font-size: 14px; }
  .login-card { width: 100%; padding: 26px 22px; }
  .login-wrap { padding: 20px; }
  table.tabla-notion th, table.tabla-notion td { padding: 8px 10px; }
  .form-acciones { flex-direction: column; align-items: stretch; }
  .form-acciones .btn { width: 100%; justify-content: center; }

  /* Las acciones de la cabecera (Descargar PDF, Editar, Desactivar...) se
     reparten el ancho en vez de quedar desordenadas al saltar de línea. */
  .topbar > div:last-child { width: 100%; }
  .topbar > div:last-child > .btn,
  .topbar > div:last-child > form { flex: 1 1 auto; }
  .topbar > div:last-child > form > .btn { width: 100%; justify-content: center; }
  .topbar > div:last-child > .btn { justify-content: center; }

  /* Las pestañas se deslizan en horizontal en vez de apilarse en varias
     filas y empujar el contenido hacia abajo. */
  .pestanas-cliente {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; padding-bottom: 2px;
  }
  .pestanas-cliente::-webkit-scrollbar { display: none; }
  .pestana-cliente { flex-shrink: 0; }

  /* El anillo ocupaba casi todo el ancho útil de la tarjeta. */
  .anillo { width: 128px; height: 128px; }
  .anillo-centro strong { font-size: 24px; }
}

/* --- Pantallas táctiles: objetivos de toque cómodos ---
   Se detecta por el tipo de puntero, no por el ancho: una tablet ancha
   también se toca con el dedo, y un escritorio estrecho no. La referencia de
   44px es la de las guías de Apple y Google. --- */
@media (pointer: coarse) {
  .btn { min-height: 44px; padding: 10px 16px; }
  .btn-pequeno { min-height: 38px; padding: 8px 12px; font-size: 13px; }
  .nav-link { padding: 11px 8px; }
  .salir-link { padding: 9px 8px; }
  .pestana-cliente { min-height: 42px; }
  select, textarea,
  input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="date"], input[type="datetime-local"] {
    min-height: 44px;
  }
  /* En las tablas los pares Editar/Eliminar se separan un poco más para no
     tocar el equivocado. */
  table.tabla-notion .btn-pequeno { margin: 2px 0; }
}

/* --- Calendario en móvil: sin scroll horizontal, celdas compactas con
   puntos de color en vez del texto de cada reunión (igual que las apps de
   calendario nativas); tocar el día lleva a la agenda completa de ese día. --- */
@media (max-width: 640px) {
  .calendario-cabecera { flex-wrap: wrap; justify-content: center; text-align: center; row-gap: 8px; }
  .calendario-cabecera h2 { font-size: 15px; order: -1; flex-basis: 100%; }
  .calendario-grid-wrap { overflow-x: visible; }
  .calendario-grid { grid-template-columns: repeat(7, 1fr); }
  .calendario-diasemana { font-size: 9px; padding: 6px 1px; letter-spacing: 0; }
  .calendario-celda {
    min-height: 44px; padding: 3px 1px; align-items: center; justify-content: flex-start; gap: 3px;
  }
  /* En el dedo, 24px es justo el mínimo y el número es lo único que se
     puede tocar: la celda no lleva enlace. Se agranda hasta llenar la celda. */
  .calendario-numero { width: 32px; height: 32px; }
  /* La casilla mide 13px; lo que se toca es la etiqueta entera, así que es
     ella la que tiene que dar la altura mínima cómoda. */
  .check-linea { min-height: 44px; }
  .calendario-eventos-escritorio { display: none; }
  .calendario-puntos-movil { display: flex; gap: 2px; flex-wrap: wrap; justify-content: center; }
  .calendario-punto { width: 5px; height: 5px; border-radius: 50%; background: var(--azul); flex-shrink: 0; }
  .calendario-punto-interna { background: var(--texto-tenue); }
}

/* --- Calendarios con contenido dentro: agenda en móvil ---
   Los de Contenido y Leads no llevan puntos, llevan fichas con texto. En una
   rejilla de siete columnas dentro de 390px cada celda queda en 39px: la ficha
   se salía de su día y pisaba la columna siguiente, y las semanas vacías
   gastaban cien píxeles cada una. Se apilan en una lista y se enseñan solo los
   días que tienen algo, que es como funcionan las agendas del teléfono. --- */
@media (max-width: 640px) {
  .calendario-agenda { display: block; border: 0; }
  /* La cabecera de días de la semana no significa nada apilada. */
  .calendario-agenda .calendario-diasemana { display: none; }
  /* minmax(0, 1fr) y no 1fr: una columna 1fr no encoge por debajo de su
     contenido, y un título largo en una sola línea estiraba la tarjeta más allá
     de la pantalla y la cortaba por la derecha, sin borde ni puntos. */
  .calendario-agenda .calendario-celda {
    display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: var(--espacio-md);
    align-items: start; min-height: 0; padding: var(--espacio-md) var(--espacio-sm);
    border: 0; border-bottom: 1px solid var(--borde); text-align: left;
  }
  .calendario-agenda .calendario-celda:last-child { border-bottom: 0; }
  /* El día de hoy, marcado en la agenda: es donde se aterriza y tiene que
     reconocerse sin leer la fecha. */
  .calendario-agenda .calendario-celda.hoy {
    background: var(--azul-fondo);
    box-shadow: inset 3px 0 0 var(--marca-solido);
  }
  /* Un día sin nada no aporta una fila: solo se muestran los que tienen algo.
     El :has() es la única forma de saberlo sin tocar la plantilla. */
  .calendario-agenda .calendario-celda:not(:has(.pieza)):not(:has(.dia-leads)) {
    display: none;
  }
  /* El día de la semana lo daba la columna; apilado hay que escribirlo, y
     colgando del propio número para que no se despegue cuando la ficha de al
     lado estira la fila. */
  .calendario-agenda .calendario-numero {
    grid-column: 1; grid-row: 1;
    width: auto; height: auto; justify-self: start; align-self: start;
    display: block; text-align: left;
    font-size: 19px; font-weight: 700; line-height: 1.1;
  }
  .calendario-agenda .calendario-numero::after {
    content: attr(data-dia); display: block; margin-top: 2px;
    font-size: 11px; font-weight: 600; color: var(--texto-tenue);
    text-transform: uppercase; letter-spacing: .04em;
  }
  /* Sin grid-row fijo: si un día tiene tres piezas, cada una toma su propia
     fila de la columna 2 en vez de amontonarse todas en la misma. */
  .calendario-agenda .pieza,
  .calendario-agenda .dia-leads { grid-column: 2; width: 100%; }
  .calendario-agenda .pieza + .pieza { margin-top: var(--espacio-sm); }
  /* Hoy se marca con el color, no con un recuadro que aquí no encaja. */
  .calendario-agenda .calendario-celda.hoy {
    outline: 0; background: var(--azul-fondo); border-radius: 8px;
  }
  .calendario-agenda .calendario-celda.fuera-de-mes { opacity: .55; }
}

/* ============================================================
   Accesibilidad — preferencias por usuario (ver rutas/cuenta.py)
   Se leen de atributos data-* en <html>, fijados desde base.html.
   ============================================================ */

/* --- Tema oscuro (elegido, o "sistema" cuando el SO está en oscuro) --- */
html[data-tema="oscuro"],
html[data-tema="sistema"] {
  /* Neutros con una pizca de azul en vez de gris puro: el gris neutro sobre
     pantalla se ve apagado y sucio, y hace que los acentos parezcan sucios. */
  --bg-sidebar: #1b1e24;
  --bg-content: #16181d;
  --bg-hover: #242832;
  --borde: #2e333d;
  --texto: #e6e8ec;
  --texto-tenue: #99a1ae;
  --gris-fondo: #21252d;

  /* Los acentos de TEXTO se aclaran. Los del tema claro (#2f7a4f, #c4432b,
     #9f6a12) están pensados para fondo blanco: sobre las pastillas oscuras
     se quedaban en 2,5-3:1 y era justo lo que se veía embarrado. */
  --azul: #6cb8f5;
  --azul-fondo: #14273b;
  --verde: #5ddb96;
  --verde-fondo: #12301f;
  --paso-fondo: #a5b4fc;
  --paso-texto: #1e1b4b;
  --amarillo: #f0c261;
  --amarillo-fondo: #362a11;
  --rojo: #ff8d7c;
  --rojo-fondo: #38201d;

  --marca: #3fb4f3;
  --marca-profundo: #86d0fa;
  --marca-halo: 0 4px 14px rgba(30, 155, 236, 0.40);

  /* Las plataformas también: sus fondos del tema claro no se redefinían, así
     que las etiquetas salían como pastillas rosas y rojas brillantes encima
     de la interfaz oscura. */
  --pf-instagram: #f591c6;  --pf-instagram-fondo: #341a2b;
  --pf-tiktok: #e4e8f0;     --pf-tiktok-fondo: #313a4a;
  --pf-youtube: #ff9090;    --pf-youtube-fondo: #351f1f;
  --pf-facebook: #7fb4f0;   --pf-facebook-fondo: #16253c;

  /* Series de las gráficas: los tonos del tema claro son medios y sobre el
     fondo oscuro se apagan (el morado bajaba a 2.92). Mismos matices, más
     claros, para que las líneas se distingan entre sí y del fondo. */
  --serie-1: #38bdd8;
  --serie-2: #a78bfa;
  --serie-3: #34d399;
  --serie-4: #f0a844;
  /* Azul de texto: aquí sí se aclara, porque no es fondo de nada. */
  --marca-texto: #6cb8f7;
  --pf-linkedin: #74bdec;   --pf-linkedin-fondo: #14283a;
}
/* "sistema" hereda el bloque oscuro de arriba; si el equipo está en claro hay
   que devolver TODAS las variables que aquél redefine. Si se añade una nueva
   al tema oscuro, tiene que aparecer también aquí o el tema claro la arrastra. */
@media (prefers-color-scheme: light) {
  html[data-tema="sistema"] {
    --bg-sidebar: #f7f6f3;
    --bg-content: #ffffff;
    --bg-hover: #efefed;
    --borde: #e9e9e7;
    --texto: #37352f;
    --texto-tenue: #6d6c68;
    --gris-fondo: #f1f1ef;

    --azul: #1583de;
    --azul-fondo: #e6f4fd;
    --verde: #2e794e;
    --verde-fondo: #ddf3e4;
    --paso-fondo: #4f46e5;
    --paso-texto: #ffffff;
    --amarillo: #97620a;
    --amarillo-fondo: #fbf0d3;
    --rojo: #bd3c24;
    --rojo-fondo: #fbe4e0;

    --marca-claro: #3fc6f5;
    --marca: #1e9bec;
    --marca-profundo: #0a6ad6;
    --marca-halo: 0 4px 14px rgba(30, 155, 236, 0.28);

    --pf-instagram: #bd3477;  --pf-instagram-fondo: #fbe7f1;
    --pf-tiktok: #1f2937;     --pf-tiktok-fondo: #dfe3ea;
    --pf-youtube: #c92828;    --pf-youtube-fondo: #fbe4e4;
    --pf-facebook: #1257a8;   --pf-facebook-fondo: #e4eefb;
    --serie-1: #0e7490;  --serie-2: #7048c8;
    --serie-3: #0f8f6f;  --serie-4: #b26212;
    --marca-texto: #0f72d8;
    --pf-linkedin: #0a66a3;   --pf-linkedin-fondo: #e2effa;
  }
}
/* Enumerar los tipos dejaba fuera los que no estaban en la lista: url y
   datetime-local seguían saliendo blancos sobre la interfaz oscura. Ahora se
   excluyen los tres que NO deben pintarse (casilla, radio y archivo) y todo
   lo demás queda cubierto, incluidos los tipos que se añadan luego. */
html[data-tema="oscuro"] input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]),
html[data-tema="oscuro"] select, html[data-tema="oscuro"] textarea,
html[data-tema="sistema"] input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]),
html[data-tema="sistema"] select, html[data-tema="sistema"] textarea {
  background: var(--bg-content);
  color: var(--texto);
}
html[data-tema="oscuro"] .login-wrap, html[data-tema="sistema"] .login-wrap { background: var(--bg-sidebar); }
html[data-tema="oscuro"] .login-card, html[data-tema="sistema"] .login-card { background: var(--bg-content); }
html[data-tema="oscuro"] .log, html[data-tema="sistema"] .log,
html[data-tema="oscuro"] #config-textarea, html[data-tema="sistema"] #config-textarea {
  background: var(--gris-fondo);
  color: var(--texto);
}

/* --- Tamaño de texto --- */
html[data-tamano-fuente="grande"] body { font-size: 17px; }
html[data-tamano-fuente="extra_grande"] body { font-size: 19px; }
html[data-tamano-fuente="grande"] .metrica-grande { font-size: 30px; }
html[data-tamano-fuente="extra_grande"] .metrica-grande { font-size: 34px; }

/* --- Alto contraste --- */
html[data-alto-contraste="si"] { --texto-tenue: var(--texto); }
html[data-alto-contraste="si"]:not([data-tema="oscuro"]):not([data-tema="sistema"]) {
  --texto: #000000;
  --borde: #000000;
}
html[data-alto-contraste="si"][data-tema="oscuro"],
html[data-alto-contraste="si"][data-tema="sistema"] {
  --texto: #ffffff;
  --borde: #ffffff;
}
html[data-alto-contraste="si"] .btn { outline: 1.5px solid currentColor; }
html[data-alto-contraste="si"] .tag { outline: 1px solid currentColor; }
html[data-alto-contraste="si"] .nav-link.activo { outline: 1.5px solid var(--azul); }
html[data-alto-contraste="si"] .calendario-evento { outline: 1px solid currentColor; }
html[data-alto-contraste="si"] .calendario-celda.hoy { box-shadow: inset 0 0 0 3px var(--azul); }
html[data-alto-contraste="si"] .calendario-punto { outline: 1px solid var(--texto); width: 6px; height: 6px; }
html[data-alto-contraste="si"] .cliente-card { outline: 1px solid var(--borde); }

/* --- Reducir movimiento --- */
html[data-reducir-movimiento="si"] *,
html[data-reducir-movimiento="si"] *::before,
html[data-reducir-movimiento="si"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}

/* --- Subrayar enlaces --- */
html[data-subrayar-enlaces="si"] a { text-decoration: underline; }
html[data-subrayar-enlaces="si"] .nav-link,
html[data-subrayar-enlaces="si"] .btn,
html[data-subrayar-enlaces="si"] table.tabla-notion tr[onclick] {
  text-decoration: none;
}

/* --- Colapsar / mostrar el sidebar (escritorio) --- */
.btn-colapsar {
  margin-left: auto; background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radio); color: var(--texto-tenue);
  transition: background var(--transicion), color var(--transicion);
}
.btn-colapsar:hover { background: var(--bg-hover); color: var(--texto); }
.btn-colapsar svg { width: 18px; height: 18px; }

.btn-mostrar-sidebar {
  display: none; position: fixed; top: 14px; left: 14px; z-index: 45;
  width: 34px; height: 34px; align-items: center; justify-content: center;
  background: var(--bg-content); border: 1px solid var(--borde); border-radius: var(--radio);
  color: var(--texto); cursor: pointer; box-shadow: var(--sombra);
  transition: background var(--transicion), box-shadow var(--transicion);
}
.btn-mostrar-sidebar:hover { background: var(--bg-hover); box-shadow: var(--sombra-media); }
.btn-mostrar-sidebar svg { width: 20px; height: 20px; }

.app-shell.sidebar-colapsado .sidebar { display: none; }
.app-shell.sidebar-colapsado .btn-mostrar-sidebar { display: flex; }

/* En móvil el sidebar usa la hamburguesa; ocultamos estos controles. */
@media (max-width: 860px) {
  .btn-colapsar,
  .app-shell.sidebar-colapsado .btn-mostrar-sidebar { display: none; }
  .app-shell.sidebar-colapsado .sidebar { display: flex; }
}

/* --- Pestañas de secciones dentro del detalle de cliente ---
   Inspiradas en las tarjetas de cliente (chip de icono, borde suave,
   leve elevación al pasar el mouse) pero como píldoras horizontales. */
.pestanas-cliente {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px;
}
.pestana-cliente {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px 8px 8px; border: 1px solid var(--borde); border-radius: 999px;
  background: var(--bg-content); color: var(--texto-tenue); cursor: pointer;
  font-size: 13px; font-weight: 600; box-shadow: var(--sombra);
  transition: background var(--transicion), color var(--transicion),
              border-color var(--transicion), box-shadow var(--transicion),
              transform var(--transicion);
}
.pestana-cliente:hover { color: var(--texto); box-shadow: var(--sombra-media); transform: translateY(-1px); }
.pestana-cliente .pestana-icono {
  width: 22px; height: 22px; border-radius: 6px; background: var(--gris-fondo);
  color: var(--texto-tenue); display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: background var(--transicion), color var(--transicion);
}
.pestana-cliente .pestana-icono svg { width: 14px; height: 14px; }
.pestana-cliente.activo {
  background: var(--azul-fondo); color: var(--marca-profundo); border-color: var(--azul);
}
.pestana-cliente.activo .pestana-icono { background: var(--marca-degradado); color: #fff; }

/* El deslizamiento horizontal en móvil se declara arriba (media query de 540px),
   PERO la regla base de .pestanas-cliente viene después en el archivo y, a
   igualdad de especificidad, gana la última: flex-wrap volvía a "wrap" y las
   pestañas se apilaban en varias filas empujando el contenido hacia abajo.
   Estar dentro de una media query no da prioridad; solo filtra cuándo aplica.
   Por eso se repite aquí, ya después de la base. */
@media (max-width: 540px) {
  .pestanas-cliente { flex-wrap: nowrap; }
}

/* --- Estado vacío ---
   Una pantalla sin datos no debería ser una frase suelta en medio de la nada:
   se explica qué va a aparecer ahí y se ofrece el camino para llenarla. --- */
/* --- Pestañas de sección ---
   Van justo debajo de las de cliente y sin distinguirlas se leían como una
   segunda lista de clientes. Se agrupan en un solo control segmentado: un
   carril con las opciones dentro, que es el gesto habitual para "estoy
   viendo lo mismo de otra manera". --- */
.pestanas-seccion {
  display: inline-flex; flex-wrap: wrap; gap: 4px; margin-bottom: 20px;
  padding: 4px; border-radius: 12px; background: var(--gris-fondo);
  border: 1px solid var(--borde);
}
.pestana-seccion {
  padding: 7px 14px; border-radius: 9px; border: 0; background: transparent;
  color: var(--texto-tenue); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.pestana-seccion:hover { background: var(--bg-content); color: var(--texto); }
.pestana-seccion.activo {
  background: var(--bg-content); color: var(--marca-texto);
  box-shadow: var(--sombra);
}
html[data-alto-contraste="si"] .pestana-seccion.activo { outline: 1.5px solid var(--azul); }

/* Las vistas a un lado y la acción al otro: separarlas evita que "Importar"
   se lea como una octava vista del Tracker. */
.fila-vistas {
  display: flex; align-items: center; gap: var(--espacio-md);
  flex-wrap: wrap; margin-bottom: 20px;
}
.fila-vistas .pestanas-seccion { margin-bottom: 0; }
.fila-vistas .enlace-importar { margin-left: auto; }
@media (max-width: 640px) {
  .fila-vistas .enlace-importar { margin-left: 0; }
}

@media (max-width: 640px) {
  .pestanas-seccion {
    display: flex; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  }
  .pestanas-seccion::-webkit-scrollbar { display: none; }
  .pestana-seccion { flex-shrink: 0; }
}
@media (pointer: coarse) { .pestana-seccion { min-height: 40px; } }

.panel-cliente { display: none; }
.panel-cliente.activo { display: block; animation: aparecer-panel var(--transicion); }
@keyframes aparecer-panel { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

html[data-alto-contraste="si"] .pestana-cliente { outline: 1px solid var(--borde); }
html[data-alto-contraste="si"] .pestana-cliente.activo { outline: 1.5px solid var(--azul); }

/* --- Filtro de fechas para las gráficas --- */
.filtro-fechas {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin-bottom: 16px;
}
.filtro-fechas label {
  margin: 0; font-size: 12px; font-weight: 600; color: var(--texto-tenue);
  display: flex; flex-direction: column; gap: 4px;
}
.filtro-fechas input[type="date"] { font-size: 13px; }
.filtro-fechas .filtro-presets { display: flex; gap: 6px; flex-wrap: wrap; }

/* ============================================================
   PULIDO VISUAL
   ============================================================ */

/* --- Números tabulares: las cifras se alinean en columnas y no "bailan"
   al actualizarse. Clave en una app llena de métricas. --- */
.metrica-grande, .metrica-delta,
table.tabla-notion td, .barra-progreso + p, .puntaje {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* --- Chips (listas de clientes asignados, etiquetas encadenadas) --- */
.chips-lista { display: flex; flex-wrap: wrap; gap: 5px; }
.chip-enlace { transition: background var(--transicion), color var(--transicion); }
.chip-enlace:hover { background: var(--azul-fondo); color: var(--azul); }

/* --- Estados vacíos con más presencia --- */
/* --- Tablas: cabecera fija en las tablas largas (historial de semanas) --- */
.tabla-wrap.tabla-alta {
  max-height: 62vh; overflow-y: auto;
}
.tabla-wrap.tabla-alta table.tabla-notion th {
  position: sticky; top: 0; z-index: 2;
}
/* Separador sutil bajo la cabecera fija (el border-bottom se pierde al hacer sticky). */
.tabla-wrap.tabla-alta table.tabla-notion th::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--borde);
}
table.tabla-notion tr { transition: background var(--transicion); }

/* --- Barra de progreso: animada y con matiz según el avance --- */
.barra-progreso { height: 9px; }
.barra-progreso > div {
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 999px;
}

/* --- Tarjetas: elevación coherente al pasar el mouse --- */
.card:hover { box-shadow: var(--sombra-media); }

/* --- Barras de desplazamiento discretas --- */
* { scrollbar-width: thin; scrollbar-color: var(--borde) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--borde); border-radius: 999px;
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--texto-tenue); background-clip: content-box; }

/* --- Selección de texto con el azul de la marca --- */
::selection { background: rgba(30, 155, 236, 0.24); }

/* --- Anillo de progreso de la meta semanal --- */
.anillo { position: relative; width: 150px; height: 150px; margin: 4px auto 2px; }
.anillo svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.anillo circle { fill: none; stroke-width: 11; }
.anillo-pista { stroke: var(--gris-fondo); }
.anillo-valor {
  stroke-linecap: round;
  stroke-dasharray: 326.7;
  /* Arranca vacío y se dibuja hasta el valor que trae en su style inline. */
  animation: anillo-dibujar 900ms cubic-bezier(0.2, 0.8, 0.3, 1) forwards;
}
@keyframes anillo-dibujar { from { stroke-dashoffset: 326.7; } }
.anillo-completo .anillo-valor { stroke: var(--verde) !important; }

.anillo-centro {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; pointer-events: none;
}
.anillo-centro strong {
  font-size: 28px; font-weight: 700; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.anillo-centro span { font-size: 12px; color: var(--texto-tenue); font-variant-numeric: tabular-nums; }
.anillo-completo .anillo-centro strong { color: var(--verde); }

/* Celebración al alcanzar la meta: un pulso breve, sin estridencias. */
.anillo-completo::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--verde);
  animation: anillo-celebra 1.8s cubic-bezier(0.2, 0.8, 0.3, 1) 700ms 2;
  opacity: 0;
}
@keyframes anillo-celebra {
  0% { opacity: 0.7; transform: scale(0.94); }
  70% { opacity: 0; transform: scale(1.10); }
  100% { opacity: 0; transform: scale(1.10); }
}

/* --- Barra de carga superior (navegación parcial) --- */
.barra-carga {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  pointer-events: none; z-index: 200; opacity: 0;
  transition: opacity 180ms ease;
}
.barra-carga > i {
  display: block; height: 100%; width: 0;
  background: var(--marca-degradado-ancho);
  box-shadow: 0 0 8px rgba(30, 155, 236, 0.55);
}
/* Avanza rápido hasta 70% y ahí espera: da sensación de progreso sin mentir
   sobre cuánto falta, porque no se conoce el tamaño de la respuesta. */
.barra-carga.cargando { opacity: 1; }
.barra-carga.cargando > i { animation: barra-avanza 1.6s cubic-bezier(0.1, 0.6, 0.3, 1) forwards; }
.barra-carga.listo { opacity: 1; }
.barra-carga.listo > i { width: 100%; transition: width 180ms ease; }
@keyframes barra-avanza { from { width: 0; } to { width: 72%; } }

/* La región que se está reemplazando se atenúa y recibe un barrido de luz
   (skeleton): informa de que algo viene en camino sin mover el layout. */
.region-cargando { position: relative; opacity: 0.5; transition: opacity 140ms ease; }
.region-cargando::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 5;
  background: linear-gradient(100deg,
    transparent 20%,
    rgba(30, 155, 236, 0.10) 50%,
    transparent 80%);
  background-size: 220% 100%;
  animation: barrido 1.1s ease-in-out infinite;
}
@keyframes barrido { from { background-position: 180% 0; } to { background-position: -80% 0; } }

/* --- Avisos flotantes (toasts) --- */
.avisos-flotantes {
  position: fixed; right: 18px; bottom: 18px; z-index: 210;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none; max-width: min(380px, calc(100vw - 36px));
}
.aviso-flotante {
  pointer-events: auto;
  background: var(--bg-content); color: var(--texto);
  border: 1px solid var(--borde); border-left: 3px solid var(--marca);
  border-radius: var(--radio); box-shadow: var(--sombra-grande);
  padding: 10px 14px; font-size: 13px; line-height: 1.45;
  animation: aviso-entra 220ms cubic-bezier(0.2, 0.8, 0.3, 1);
}
.aviso-flotante.tono-ok { border-left-color: var(--verde); }
.aviso-flotante.tono-error { border-left-color: var(--rojo); }
.aviso-flotante.saliendo { animation: aviso-sale 240ms ease forwards; }
@keyframes aviso-entra { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes aviso-sale { to { opacity: 0; transform: translateY(6px) scale(0.98); } }

@media (max-width: 640px) {
  .avisos-flotantes { left: 12px; right: 12px; bottom: 12px; align-items: stretch; max-width: none; }
}

/* Respeta la preferencia de accesibilidad de reducir movimiento: nada de lo
   anterior es informativo por sí mismo, así que se muestra en su estado final
   en vez de animarse. */
html[data-reducir-movimiento="si"] .barra-carga > i,
html[data-reducir-movimiento="si"] .aviso-flotante,
html[data-reducir-movimiento="si"] .region-cargando::after,
html[data-reducir-movimiento="si"] .anillo-completo::after { animation: none; }
html[data-reducir-movimiento="si"] .barra-carga.cargando > i { width: 72%; }
html[data-reducir-movimiento="si"] .anillo-valor { animation: none; }

/* --- Login con más aire y jerarquía --- */
.login-card { width: 380px; padding: 42px 38px; }
.login-demo { border: 1px solid var(--borde); background: transparent; }
.login-demo strong { color: var(--texto); }

/* --- Modo oscuro: las sombras claras no se ven, se refuerzan los bordes --- */
html[data-tema="oscuro"], html[data-tema="sistema"] {
  --sombra: 0 1px 2px rgba(0, 0, 0, 0.45);
  --sombra-media: 0 4px 14px rgba(0, 0, 0, 0.55);
  --sombra-grande: 0 14px 36px rgba(0, 0, 0, 0.6);
}
html[data-tema="oscuro"] ::selection, html[data-tema="sistema"] ::selection {
  background: rgba(35, 131, 226, 0.4);
}
html[data-tema="oscuro"] .login-card, html[data-tema="sistema"] .login-card {
  background: var(--bg-sidebar);
}

/* --- Barra superior fija en escritorio: el título y las acciones siguen
   a la vista al recorrer páginas largas. --- */
@media (min-width: 861px) {
  .topbar {
    position: sticky; top: 0; z-index: 20;
    background: var(--bg-content);
    backdrop-filter: saturate(180%) blur(6px);
  }
}

/* --- Score AM: la cifra acompañada de una barra para leer el nivel
   de un vistazo, sin tener que interpretar el número. --- */
.score-celda { display: flex; align-items: center; gap: 9px; min-width: 116px; }
.score-num { font-weight: 600; min-width: 34px; font-variant-numeric: tabular-nums; }
.barra-mini {
  flex: 1; min-width: 46px; height: 6px; border-radius: 999px;
  background: var(--gris-fondo); overflow: hidden;
}
.barra-mini > i {
  display: block; height: 100%; border-radius: 999px; background: var(--azul);
  transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1);
}
.barra-mini > i.tono-verde { background: var(--verde); }
.barra-mini > i.tono-azul { background: var(--azul); }
.barra-mini > i.tono-amarillo { background: var(--amarillo); }
.barra-mini > i.tono-rojo { background: var(--rojo); }
.barra-mini > i.tono-gris { background: var(--texto-tenue); }

/* Cifra grande de KPI coloreada según la banda alcanzada. */
.metrica-grande.tono-verde { color: var(--verde); }
.metrica-grande.tono-azul { color: var(--azul); }
.metrica-grande.tono-amarillo { color: var(--amarillo); }
.metrica-grande.tono-rojo { color: var(--rojo); }

/* Formulario compacto dentro de una celda (upsell). */
.form-celda {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
.form-celda label { margin: 0; font-size: 12px; font-weight: 500; display: flex; align-items: center; gap: 4px; }
.form-celda input[type="checkbox"] { width: auto; margin: 0; }
.form-celda select, .form-celda input[type="text"] {
  width: auto; font-size: 12px; padding: 4px 8px; margin: 0;
}
.form-celda input[type="text"] { width: 88px; }

/* --- Avisos (confirmación / error), en vez de repetir estilos en línea --- */
.aviso {
  display: flex; align-items: flex-start; gap: 10px;
  border: 1px solid var(--borde); border-left: 3px solid var(--azul);
  background: var(--bg-content); border-radius: 10px;
  padding: 12px 16px; margin-bottom: 18px; font-size: 13px;
  box-shadow: var(--sombra);
}
.aviso-error { border-left-color: var(--rojo); color: var(--rojo); }
.aviso-ok { border-left-color: var(--verde); }
/* Ni error ni confirmación: algo que conviene saber pero no ha fallado. */
.aviso-atencion { border-left-color: var(--amarillo); }

/* --- Estado vacío ---
   Una pantalla sin datos no debería ser una frase suelta en medio de la nada:
   dice qué va a aparecer ahí y ofrece el camino para llenarla. La variante
   "ok" es para cuando vacío es justo lo que se busca (cero alertas), que no
   es lo mismo que faltar datos y no debe leerse en gris de ausencia. */
.estado-vacio { text-align: center; padding: var(--espacio-2xl) var(--espacio-lg); }
.estado-vacio h2 { margin: 0 0 var(--espacio-sm); font-size: 15px; }
.estado-vacio p {
  margin: 0 auto var(--espacio-lg); max-width: 46ch;
  color: var(--texto-tenue); font-size: 13.5px; line-height: 1.55;
}
.estado-vacio p:last-child { margin-bottom: 0; }
.estado-ok { border-color: color-mix(in srgb, var(--verde) 32%, var(--borde)); }
.estado-ok h2 { color: var(--verde); }
.estado-ok h2::before {
  content: ""; display: inline-block; vertical-align: middle;
  width: 15px; height: 8px; margin-right: var(--espacio-sm);
  border-left: 2.5px solid var(--verde); border-bottom: 2.5px solid var(--verde);
  transform: rotate(-45deg) translateY(-2px);
}

/* --- Lista de definición para fichas de estado ---
   Se usaba en Métricas y Configuración sin ninguna regla, así que salía con
   el sangrado por defecto del navegador: la etiqueta a un lado y el valor
   metido hacia dentro, como un documento sin maquetar. */
.detalle { margin: 0; display: grid; gap: var(--espacio-md); }
.detalle dt {
  font-size: 11.5px; font-weight: 600; color: var(--texto-tenue);
  margin: 0 0 2px;
}
.detalle dd { margin: 0; font-size: 13.5px; line-height: 1.5; }
@media (min-width: 720px) {
  /* Con sitio, etiqueta y valor en dos columnas: se leen en pares en vez de
     como una lista larga. */
  .detalle { grid-template-columns: minmax(120px, 34%) 1fr; align-items: baseline; }
  .detalle dt { margin: 0; }
}

/* Contador junto al título de una sección, para no repetirlo en el texto. */
.contador-seccion {
  display: inline-block; margin-left: var(--espacio-sm);
  padding: 1px 8px; border-radius: 999px;
  background: var(--gris-fondo); color: var(--texto-tenue);
  font-size: 12px; font-weight: 600; vertical-align: middle;
}

/* --- Alertas --- */
.alerta-cliente {
  font-weight: 700; color: var(--texto); text-decoration: none;
  margin-right: var(--espacio-xs);
}
a.alerta-cliente:hover { color: var(--marca-texto); text-decoration: underline; }
.alerta-mensaje { color: var(--texto); }
.alerta-atendida { opacity: .55; }

/* --- Celda de identidad en tablas de piezas ---
   Cliente y título juntos. En columnas separadas, un nombre largo partía la
   fila en tres líneas y hundía las publicaciones visibles de quince a nueve. */
/* Acotada: si crece, empuja la columna de acciones fuera del contenedor y el
   botón de eliminar queda cortado. El título trunca con puntos suspensivos y
   el completo sigue en el title. */
.celda-pieza { min-width: 170px; max-width: 250px; }
.pieza-cliente {
  display: block; font-size: 11.5px; font-weight: 600; color: var(--texto-tenue);
  text-decoration: none; margin-bottom: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pieza-cliente:hover { color: var(--marca-texto); text-decoration: underline; }
.pieza-titulo {
  display: block; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pieza-titulo a { color: inherit; text-decoration: none; }
.pieza-titulo a:hover { text-decoration: underline; color: var(--marca-texto); }

/* El desglose es detalle de una fila, no algo que se compare entre filas:
   sigue ahí y sigue legible, pero deja de competir con lo que sí importa. */
.col-detalle {
  font-size: 12.5px; color: var(--texto-tenue);
  padding-left: var(--espacio-sm); padding-right: var(--espacio-sm);
}
th.col-detalle { font-weight: 500; }
/* En pantallas estrechas el desglose es lo primero que sobra: son las cuatro
   columnas menos importantes, y esconderlas deja visible la de acciones en
   vez de dejar el botón de eliminar fuera del borde. El dato no se pierde,
   sigue en la fila de edición. */
@media (max-width: 1400px) {
  .col-detalle { display: none; }
}

/* --- Bloque plegable ---
   <details> nativo: sin JS, accesible con teclado, y recuerda su estado
   mientras dure la página. Para acciones ocasionales que no deben ocupar
   sitio encima de lo que se mira a diario. */
.plegable {
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 10px; box-shadow: var(--sombra); margin-bottom: var(--espacio-md);
}
.plegable > summary {
  padding: var(--espacio-md) var(--espacio-xl);
  font-size: 14px; font-weight: 700; cursor: pointer;
  list-style: none; display: flex; align-items: center; gap: var(--espacio-sm);
  border-radius: 10px;
}
.plegable > summary::-webkit-details-marker { display: none; }
.plegable > summary::before {
  content: ""; width: 7px; height: 7px; flex-shrink: 0;
  border-right: 2px solid var(--texto-tenue); border-bottom: 2px solid var(--texto-tenue);
  transform: rotate(-45deg); transition: transform var(--transicion);
}
.plegable[open] > summary::before { transform: rotate(45deg); }
.plegable > summary:hover { background: var(--gris-fondo); }
.plegable-cuerpo { padding: 0 var(--espacio-xl) var(--espacio-lg); }

/* --- Barra de filtros ---
   Antes cada filtro vivía en su propia tarjeta con título "Filtrar": 110px
   de caja para dos desplegables. Ahora es una fila. */
.barra-filtros {
  display: flex; flex-wrap: wrap; gap: var(--espacio-md);
  align-items: flex-end; margin-bottom: var(--espacio-md);
}
.barra-filtros label {
  margin: 0; font-size: 11.5px; font-weight: 600; color: var(--texto-tenue);
  display: flex; flex-direction: column; gap: var(--espacio-xs); min-width: 170px;
}
.barra-filtros select { font-size: 13px; }

/* ============================================================
   ESTADOS DE INTERACCIÓN
   Había 33 reglas de hover y prácticamente nada más: sin foco visible no se
   puede usar con teclado, sin deshabilitado ni carga se envía dos veces el
   mismo formulario, y sin error de campo el fallo solo se ve arriba del todo.
   ============================================================ */

/* --- Foco ---
   :focus-visible y no :focus, para que el anillo salga al tabular pero no al
   hacer clic con el ratón. */
a:focus-visible, button:focus-visible, select:focus-visible,
textarea:focus-visible, input:focus-visible,
[tabindex]:focus-visible, summary:focus-visible {
  outline: 2px solid var(--marca-texto);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Sobre fondo azul el anillo azul desaparece: ahí va blanco. */
.btn-primario:focus-visible, .pestana-cliente.activo:focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 4px rgba(15, 114, 216, .45);
}

/* --- Activo (mientras se mantiene pulsado) --- */
.btn:active:not(:disabled), .pestana-seccion:active, .pestana-cliente:active {
  transform: translateY(1px);
}

/* --- Deshabilitado ---
   Se cubre también aria-disabled porque un <a> no admite el atributo
   disabled y en la app hay acciones que son enlaces. */
.btn:disabled, .btn[aria-disabled="true"],
button:disabled, input:disabled, select:disabled, textarea:disabled {
  opacity: .5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}
.btn:disabled:hover, .btn[aria-disabled="true"]:hover {
  filter: none;
  transform: none;
}
input:disabled, select:disabled, textarea:disabled { background: var(--gris-fondo); }

/* --- Carga ---
   El botón conserva su ancho para que la fila no dé un salto al enviarse. */
.btn[aria-busy="true"] {
  color: transparent !important;
  pointer-events: none;
  position: relative;
}
.btn[aria-busy="true"]::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  color: #fff;
  animation: girar 620ms linear infinite;
}
.btn:not(.btn-primario):not(.btn-azul)[aria-busy="true"]::after { color: var(--texto); }
@keyframes girar { to { transform: rotate(360deg); } }

/* --- Error de campo --- */
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--rojo);
  background: var(--rojo-fondo);
}
input[aria-invalid="true"]:focus-visible { outline-color: var(--rojo); }
.campo-error {
  display: flex; align-items: flex-start; gap: var(--espacio-xs);
  color: var(--rojo); font-size: 12px; font-weight: 600; margin-top: var(--espacio-xs);
}
.campo-error::before { content: "!";
  flex-shrink: 0; width: 14px; height: 14px; border-radius: 50%;
  background: var(--rojo); color: #fff; font-size: 10px; line-height: 14px;
  text-align: center; font-weight: 700;
}

/* --- Vacío ---
   Se refuerza el que ya existía: antes era una frase suelta y centrada en
   mitad de la nada, sin decir qué va a aparecer ahí. */
@media (prefers-reduced-motion: reduce) {
  .btn[aria-busy="true"]::after { animation-duration: 2s; }
  .btn:active:not(:disabled) { transform: none; }
}

/* --- Código en línea y campos de fórmula --- */
code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.92em; background: var(--gris-fondo); color: var(--texto);
  padding: 1px 5px; border-radius: 4px;
}
textarea.mono, input.mono {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
}

/* --- Respeta la preferencia del sistema de reducir animaciones --- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* --- Cuentas de redes del cliente: una fila por cuenta --- */
.fila-cuenta {
  display: flex; gap: 8px; align-items: center; margin-bottom: 8px;
}
.fila-cuenta select { width: 148px; flex-shrink: 0; margin-top: 0; }
.fila-cuenta input { flex: 1; min-width: 0; margin-top: 0; }
@media (max-width: 540px) {
  .fila-cuenta { flex-wrap: wrap; }
  .fila-cuenta select, .fila-cuenta input { width: 100%; flex: none; }
}

/* --- Calendario de contenido: piezas dentro de cada día --- */
.pieza {
  display: block; margin-top: 4px; padding: 5px 7px;
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 6px; font-size: 11.5px; line-height: 1.35;
  transition: border-color var(--transicion), box-shadow var(--transicion);
}
.pieza:hover { border-color: var(--marca); box-shadow: var(--sombra); }
.pieza-cliente {
  display: block; font-weight: 700; color: var(--marca-profundo);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pieza-titulo {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; color: var(--texto);
}
.pieza-etiquetas { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 3px; }
.pieza-etiquetas .tag { font-size: 10px; padding: 0 5px; }

/* «+N más»: el resumen de un día con demasiadas piezas. Se distingue de una
   pieza de verdad —sin borde de fase y centrado— para que no parezca una. */
.pieza-mas {
  text-align: center; font-weight: 700; color: var(--marca-texto);
  background: var(--bg-sidebar); border-style: dashed;
  border-left-width: 1px;
}

/* Las casillas de un día crecen con su contenido, a diferencia del
   calendario de reuniones, que solo muestra puntos. */
.calendario-celda { min-height: 104px; align-items: stretch; }

/* Campos de tipo lista múltiple en el formulario de contenido. */
.casillas-opciones { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; }
.casilla-opcion {
  display: flex; align-items: center; gap: 6px; font-size: 13px;
  color: var(--texto); font-weight: 500;
}
.casilla-opcion input { width: auto; margin: 0; }
.inactivo-campo { opacity: 0.6; }

/* --- Fase del proceso: destacada en la pieza del calendario --- */
.pieza { border-left-width: 3px; }
.pieza-fase-gris     { border-left-color: var(--texto-tenue); }
.pieza-fase-azul     { border-left-color: var(--azul); }
.pieza-fase-verde    { border-left-color: var(--verde); }
.pieza-fase-amarillo { border-left-color: var(--amarillo); }
.pieza-fase-rojo     { border-left-color: var(--rojo); }

.pieza-fase {
  display: inline-block; margin-top: 3px; padding: 1px 7px;
  border-radius: 999px; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.pieza-fase.tono-gris     { background: var(--gris-fondo);     color: var(--texto-tenue); }
.pieza-fase.tono-azul     { background: var(--azul-fondo);     color: var(--azul); }
.pieza-fase.tono-verde    { background: var(--verde-fondo);    color: var(--verde); }
.pieza-fase.tono-amarillo { background: var(--amarillo-fondo); color: var(--amarillo); }
.pieza-fase.tono-rojo     { background: var(--rojo-fondo);     color: var(--rojo); }
/* Una fase larga («Guion aprobado para Grabacion») partía la pastilla en dos
   líneas y dejaba las tarjetas de alturas distintas: una línea y puntos. */
.pieza-fase { max-width: 100%; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; vertical-align: top; }

/* Un campo de texto, número o fecha elegido para la tarjeta: una línea con su
   nombre delante. El valor entero va en el title. */
.pieza-campo {
  display: block; margin-top: 2px; font-size: 10.5px; line-height: 1.35;
  color: var(--texto-tenue); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.pieza-campo-nombre { font-weight: 600; }

/* --- Calendario de contenido: herramientas de la cabecera --- */
.calendario-herramientas {
  margin-left: auto; display: flex; align-items: flex-end;
  gap: var(--espacio-sm); flex-wrap: wrap;
}
.menu-tarjeta { position: relative; }
.menu-tarjeta > summary { list-style: none; cursor: pointer; user-select: none; }
.menu-tarjeta > summary::-webkit-details-marker { display: none; }
.menu-tarjeta > summary .cuenta {
  margin-left: 6px; padding: 0 6px; border-radius: 999px; font-size: 11px;
  background: var(--azul-fondo); color: var(--marca-texto);
}
.menu-tarjeta[open] > summary { background: var(--bg-hover); }
.menu-tarjeta-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  width: 280px; max-width: calc(100vw - 32px); padding: var(--espacio-md);
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: var(--radio); box-shadow: var(--sombra-grande); text-align: left;
}
.menu-tarjeta-ayuda { margin: 0; font-size: 12.5px; color: var(--texto-tenue); }
.menu-tarjeta-lista {
  display: grid; gap: 6px; margin: var(--espacio-sm) 0;
  max-height: 50vh; overflow-y: auto;
}
.menu-tarjeta-acciones { display: flex; gap: var(--espacio-sm); }
/* Las etiquetas de formulario llevan 14px de margen arriba para separar campos;
   en una lista de casillas eso dejaba cada opción a un dedo de la siguiente. */
.menu-tarjeta-lista .casilla-opcion { margin: 0; padding: 3px 0; }

/* --- Calendario de contenido: un botón por fase --- */
.chips-fase { display: flex; flex-wrap: wrap; gap: 6px; margin: var(--espacio-md) 0 var(--espacio-sm); }
.chips-fase .chip-rol { padding: 4px 11px; font-size: 12.5px; }
.punto-fase {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--texto-tenue);
}
.punto-fase.tono-azul     { background: var(--azul); }
.punto-fase.tono-verde    { background: var(--verde); }
.punto-fase.tono-amarillo { background: var(--amarillo); }
.punto-fase.tono-rojo     { background: var(--rojo); }
/* Sobre el azul del botón encendido un punto azul desaparece, y rodeado de
   blanco se leía como una letra «O». Encendido, el punto es blanco: el estado
   ya lo dice el fondo del botón. */
.chip-rol.activo .punto-fase { background: #fff; }
.calendario-vacio { margin: var(--espacio-sm) 0; }
.calendario-vacio a { font-weight: 600; }

/* En el teléfono los botones van en UNA fila que se desliza: diez botones
   partidos en cuatro filas empujaban el calendario media pantalla abajo.
   Va después de la regla base a propósito: a igual especificidad gana la
   última, y dentro de la media query no hay más prioridad. */
@media (max-width: 640px) {
  .chips-fase {
    flex-wrap: nowrap; overflow-x: auto; padding-bottom: 6px;
    scrollbar-width: thin; -webkit-overflow-scrolling: touch;
  }
  .chips-fase .chip-rol { flex: none; }
  .calendario-herramientas { margin-left: 0; width: 100%; justify-content: center; }
  .menu-tarjeta { width: 100%; }
  .menu-tarjeta > summary { display: block; text-align: center; }
  /* En el teléfono el panel se abre en su sitio: flotando se salía por el
     borde según dónde cayera el botón. */
  .menu-tarjeta-panel {
    position: static; width: auto; max-width: none; margin-top: var(--espacio-sm);
    box-shadow: var(--sombra);
  }
}

/* --- Banda de fase en la ficha de una pieza --- */
.fase-banda {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px; border-radius: 12px; margin-bottom: 18px;
  border: 1px solid var(--borde); background: var(--bg-content);
  border-left: 5px solid var(--texto-tenue);
}
.fase-banda.tono-azul     { border-left-color: var(--azul);     background: var(--azul-fondo); }
.fase-banda.tono-verde    { border-left-color: var(--verde);    background: var(--verde-fondo); }
.fase-banda.tono-amarillo { border-left-color: var(--amarillo); background: var(--amarillo-fondo); }
.fase-banda.tono-rojo     { border-left-color: var(--rojo);     background: var(--rojo-fondo); }
.fase-banda strong { font-size: 18px; }
.fase-etiqueta { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--texto-tenue); }
.fase-punto { width: 10px; height: 10px; border-radius: 50%; background: currentColor; flex-shrink: 0; }

/* --- Ficha de lectura --- */
dl.ficha { display: grid; grid-template-columns: 190px 1fr; gap: 10px 16px; margin: 0; font-size: 13.5px; }
dl.ficha dt { color: var(--texto-tenue); font-weight: 600; }
dl.ficha dd { margin: 0; }
/* `pre-wrap` respeta los saltos pero NO parte una palabra larga: las
   descripciones migradas de Notion acaban en una tira de etiquetas sin
   espacios y se salían 613 px de la pantalla en móvil. Mismo arreglo que en
   `.av-texto`. */
.texto-multilinea { white-space: pre-wrap; overflow-wrap: anywhere; }

/* --- Ficha editable en sitio ------------------------------------------------
   Un dato que se puede cambiar se ve igual que antes; lo delata el puntero, un
   fondo suave al pasar por encima y el anillo de foco al llegar con el
   teclado. No lleva borde de campo: se pidió la ficha «en el formato de como
   antes, no en un formulario». */
.valor-editable {
  cursor: pointer; border-radius: 6px;
  margin-left: -6px; margin-right: -6px; padding: 2px 6px;
  transition: background var(--transicion), box-shadow var(--transicion);
}
.valor-editable:hover { background: var(--bg-hover); }
.valor-editable:focus-visible { outline: 2px solid var(--marca-solido); outline-offset: 1px; }
.valor-editable[hidden] { display: none; }
.valor-bloque { padding: 6px; margin: -6px; }
.valor-vacio { margin: 0; color: var(--texto-tenue); font-style: italic; }
.fase-banda.valor-editable { margin-left: 0; margin-right: 0; padding: 14px 18px; }
.fase-banda.valor-editable:hover { box-shadow: var(--sombra-media); }
.valor-pista {
  margin-left: auto; font-size: 12px; font-weight: 600; color: var(--texto-tenue);
  opacity: 0; transition: opacity var(--transicion);
}
.valor-editable:hover .valor-pista, .valor-editable:focus-visible .valor-pista { opacity: 1; }
/* En pantallas táctiles no hay «pasar por encima»: la pista se ve siempre. */
@media (hover: none) { .valor-pista { opacity: 1; } }

.chip-editable { cursor: pointer; border: 0; font: inherit; }
.chip-editable:hover { filter: brightness(.95); }
.chip-editable[hidden] { display: none; }

.editor-campo {
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
  padding: 8px; margin: 0; border-radius: 8px;
  background: var(--bg-sidebar); border: 1px solid var(--borde);
}
.editor-campo select, .editor-campo input:not([type="checkbox"]), .editor-campo textarea {
  margin-top: 0;
}
.editor-campo textarea { resize: vertical; }
/* El nombre del campo solo hace falta donde no hay nada al lado que lo diga:
   la banda de fase y las etiquetas de «Sin completar». */
.editor-titulo { display: none; font-size: 12px; font-weight: 600; color: var(--texto-tenue); }
.chips-lista .editor-campo, .editor-campo[data-clave="fase"] { flex-basis: 100%; margin: 0 0 12px; }
.chips-lista .editor-titulo, .editor-campo[data-clave="fase"] .editor-titulo { display: block; }
.editor-acciones { display: flex; align-items: center; gap: var(--espacio-sm); flex-wrap: wrap; }
/* Destacado: el botón encendido se ve encendido, sin depender de leer el texto. */
.btn-destacar[aria-pressed="true"] {
  background: var(--azul-fondo); color: var(--marca-texto); border-color: var(--marca);
}
.btn-destacar[aria-busy="true"] { opacity: .6; pointer-events: none; }
.editor-pista { font-size: 11.5px; color: var(--texto-tenue); }
.editor-campo .casillas-opciones { margin-top: 0; }
/* Guardando: se ve que está pasando algo y no se puede pulsar dos veces. */
.editor-campo[aria-busy="true"] { opacity: .6; pointer-events: none; }
.editor-campo[aria-busy="true"]::after {
  content: "Guardando…"; font-size: 12px; color: var(--texto-tenue);
}
.editor-error[hidden] { display: none; }

/* «Guardado»: en la cabecera de la ventana, o flotando en la página entera. */
.aviso-ficha {
  font-size: 12.5px; font-weight: 600; color: var(--verde);
  opacity: 0; transition: opacity var(--transicion);
}
.aviso-ficha.visible { opacity: 1; }
.aviso-ficha.en-ventana { display: block; margin-top: 2px; }
.aviso-ficha:not(.en-ventana) {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 60;
  padding: 8px 14px; border-radius: 9px; background: var(--bg-content);
  border: 1px solid var(--borde); box-shadow: var(--sombra-grande);
}

/* Campos obligatorios en el formulario de nueva pieza. */
.marca-obligatorio { color: var(--rojo); font-weight: 700; }

/* --- Comentarios de una pieza (solo equipo) --- */
.cuenta-comentarios {
  display: inline-block; min-width: 20px; padding: 0 6px; margin-left: 4px;
  border-radius: 999px; background: var(--azul-fondo); color: var(--marca-texto);
  font-size: 12px; font-weight: 700; text-align: center; vertical-align: middle;
}
.comentario { padding: 10px 0; border-top: 1px solid var(--borde); }
.comentario:first-of-type { border-top: 0; padding-top: 0; }
.comentario-cabecera {
  display: flex; align-items: baseline; gap: var(--espacio-sm); flex-wrap: wrap;
  font-size: 13px;
}
.comentario-cabecera time { color: var(--texto-tenue); font-size: 12px; }
.comentario-borrar { margin-left: auto; display: inline; }
.comentario-texto { margin: 4px 0 0; font-size: 13.5px; }
.comentario-nuevo { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--borde); }
.comentario-nuevo textarea { resize: vertical; }
.comentario-nuevo .editor-acciones { margin-top: 8px; }

/* En la tarjeta del calendario, cuántos comentarios tiene. */
.pieza-comentarios {
  display: block; margin-top: 2px; font-size: 10.5px; font-weight: 600;
  color: var(--marca-texto);
}
/* minmax(0, 1fr) y no 1fr: una columna 1fr no encoge por debajo de su
   contenido. Un enlace largo sin espacios (las URLs de Instagram de «Idea /
   referencia») la estiraba a 508 px en una ventana de 348, y al abrir un editor
   la ventana se desplazaba de lado. Y un desplegable mide lo que su opción más
   larga: sin max-width se salía igual. */
dl.ficha { grid-template-columns: 190px minmax(0, 1fr); }
dl.ficha dd { min-width: 0; overflow-wrap: anywhere; }
.editor-campo select, .editor-campo input, .editor-campo textarea { max-width: 100%; }
@media (max-width: 640px) {
  dl.ficha { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  dl.ficha dd { margin-bottom: 10px; }
}

/* --- Opciones de un campo de lista: una fila por opción --- */
.fila-opcion { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.fila-opcion input { flex: 1; min-width: 0; margin-top: 0; }
.fila-opcion select { width: 130px; flex-shrink: 0; margin-top: 0; }
@media (max-width: 540px) {
  .fila-opcion { flex-wrap: wrap; }
  .fila-opcion input, .fila-opcion select { width: 100%; flex: none; }
}

/* --- Ventana emergente (ficha de contenido) --- */
.modal-fondo {
  position: fixed; inset: 0; z-index: 220;
  background: rgba(15, 15, 15, 0.45);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity var(--transicion);
}
.modal-fondo.visible { opacity: 1; pointer-events: auto; }
.modal-caja {
  background: var(--bg-content); border-radius: 14px;
  box-shadow: var(--sombra-grande); border: 1px solid var(--borde);
  width: min(860px, 100%); max-height: 88vh; display: flex; flex-direction: column;
  transform: translateY(10px) scale(0.99); transition: transform var(--transicion);
}
.modal-fondo.visible .modal-caja { transform: none; }
.modal-cabecera {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px 20px; border-bottom: 1px solid var(--borde);
}
.modal-titulo { font-size: 17px; font-weight: 700; margin: 0; }
.modal-sub { font-size: 12.5px; color: var(--texto-tenue); margin-top: 2px; }
.modal-cerrar {
  margin-left: auto; background: none; border: none; cursor: pointer;
  color: var(--texto-tenue); padding: 4px; border-radius: var(--radio);
  display: flex; flex-shrink: 0;
}
.modal-cerrar:hover { background: var(--bg-hover); color: var(--texto); }
.modal-cerrar svg { width: 20px; height: 20px; }
.modal-cuerpo { padding: 18px 20px; overflow-y: auto; }
/* Dentro del popup las tarjetas de la ficha no repiten marco ni sombra. */
.modal-cuerpo .card { border: none; box-shadow: none; padding: 0; margin-bottom: 18px; }
.modal-cuerpo .grid-2 { grid-template-columns: 1fr; gap: 18px; }
.modal-pie {
  display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap;
  padding: 14px 20px; border-top: 1px solid var(--borde);
}
@media (max-width: 640px) {
  .modal-fondo { padding: 0; align-items: flex-end; }
  .modal-caja { max-height: 92vh; border-radius: 14px 14px 0 0; }
}
html[data-reducir-movimiento="si"] .modal-fondo,
html[data-reducir-movimiento="si"] .modal-caja { transition: none; }

/* Punto de color del campo en la ficha, para reconocerlo de un vistazo. */
.punto-campo {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 7px; vertical-align: middle; background: var(--texto-tenue);
}
.punto-campo.tono-azul     { background: var(--azul); }
.punto-campo.tono-verde    { background: var(--verde); }
.punto-campo.tono-amarillo { background: var(--amarillo); }
.punto-campo.tono-rojo     { background: var(--rojo); }

/* --- Calendario de leads: lo que rindió cada día --- */
.dia-leads {
  margin-top: 4px; padding: 5px 7px; border-radius: 6px;
  border: 1px solid var(--borde); border-left: 3px solid var(--texto-tenue);
  background: var(--bg-content); font-size: 11px; line-height: 1.4;
}
.dia-leads-azul  { border-left-color: var(--azul); }
.dia-leads-verde { border-left-color: var(--verde); }
.dia-leads-gris  { border-left-color: var(--texto-tenue); opacity: .75; }
.dia-leads .tag { font-size: 10px; padding: 0 5px; }
.dia-dolor {
  display: block; margin: 3px 0 2px; color: var(--texto-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dia-cifras {
  display: flex; flex-wrap: wrap; gap: 2px 8px; margin: 2px 0 3px;
  font-variant-numeric: tabular-nums;
}

/* Vista previa de una plantilla de correo: texto tal cual saldrá, sin que las
   líneas largas obliguen a desplazar la página. */
.vista-previa {
  margin-top: var(--espacio-md); padding: var(--espacio-lg);
  background: var(--gris-fondo); border: 1px solid var(--borde);
  border-radius: 10px; font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; overflow-wrap: break-word;
}

/* En claro, el día de hoy es un círculo azul oscuro con el número en blanco.
   En oscuro ese azul se aclara y el blanco encima se queda en 2.14 de
   contraste: justo el día que más se mira es el que peor se lee. */
html[data-tema="oscuro"] .calendario-celda.hoy .calendario-numero,
html[data-tema="sistema"] .calendario-celda.hoy .calendario-numero {
  color: var(--bg-content);
}
@media (prefers-color-scheme: light) {
  html[data-tema="sistema"] .calendario-celda.hoy .calendario-numero { color: #fff; }
}

/* La celda que sustituye a las cuatro columnas del desglose se centra sobre
   ellas; alineada a la derecha parecia el valor de "Guardados". */
table.tabla-notion td.col-detalle[colspan] { text-align: center; }

/* --- Barra de contexto del Tracker ---
   Responde a las dos preguntas que hay que tener siempre a la vista —de quién
   son estos números y de qué periodo— en una sola línea. Antes el cliente se
   elegía con un muro de pastillas en escritorio y con un desplegable distinto
   en el móvil, y el periodo se llevaba una tarjeta entera: entre las tres
   cosas, el primer dato quedaba a 523px del borde superior. --- */
.barra-tracker {
  display: flex; align-items: center; gap: var(--espacio-md);
  flex-wrap: wrap;
  margin-bottom: var(--espacio-md);
}
.tracker-cliente {
  display: flex; align-items: center; gap: var(--espacio-sm);
  margin: 0; min-width: 0;
  /* Envuelve por dentro. El filtro del Historial mete cinco controles en este
     mismo hijo flex, y sin esto el padre no los puede partir: la fila medía
     1.154 px y estiraba la página entera en móvil. */
  flex-wrap: wrap;
}
.tracker-cliente label {
  font-size: 12px; font-weight: 600; color: var(--texto-tenue);
  margin: 0; white-space: nowrap;
}
.tracker-cliente select {
  min-width: 190px; max-width: 320px; margin: 0;
  font-weight: 600;
}
/* Los campos de fecha del Historial son estrechos y no necesitan el mínimo de
   un desplegable de nombres. */
.tracker-cliente input[type="date"] { min-width: 0; margin: 0; }

/* El periodo se va al extremo opuesto: es el otro eje del mismo contexto, y
   separarlos evita leerlo como parte del nombre del cliente. */
.tracker-periodo {
  display: flex; align-items: center; gap: 2px;
  margin-left: auto;
  padding: 3px; border-radius: 10px;
  background: var(--gris-fondo); border: 1px solid var(--borde);
}
.tracker-periodo-txt {
  font-size: 13px; font-weight: 600; color: var(--texto);
  padding: 0 var(--espacio-sm); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tracker-flecha {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  color: var(--texto-tenue); text-decoration: none;
  font-size: 18px; line-height: 1;
  transition: background var(--transicion), color var(--transicion);
}
.tracker-flecha:hover { background: var(--bg-content); color: var(--texto); }
@media (pointer: coarse) {
  .tracker-flecha { width: 40px; height: 40px; }
  .tracker-cliente select { min-height: 44px; }
}
@media (max-width: 640px) {
  /* Apilado, el periodo deja de empujarse a la derecha y el desplegable ocupa
     todo el ancho: con nombres largos, cortarlos es peor que ensancharlo. */
  .tracker-periodo { margin-left: 0; }
  .tracker-cliente { flex: 1 1 100%; }
  /* `min-width:0` además de `max-width:none`: sin lo primero un select no baja
     de su contenido y vuelve a desbordar por mucho que se le quite el tope. */
  .tracker-cliente select { flex: 1 1 100%; min-width: 0; max-width: none; }
  .tracker-cliente label { flex: 0 0 100%; }
  .tracker-cliente input[type="date"] { flex: 1 1 120px; }
}

/* Aviso que ocupa el sitio de una gráfica cuando no hay nada medido. Un
   lienzo vacío con eje de 0 a 1 se lee como "todo a cero", que es distinto. */
.grafica-sin-datos {
  margin: 0; padding: var(--espacio-xl) var(--espacio-lg);
  text-align: center; color: var(--texto-tenue); font-size: 13px;
  line-height: 1.5; background: var(--gris-fondo); border-radius: 10px;
}

/* --- Franja del modo demostración ---
   Ámbar y en todas las pantallas: el fallo caro de este modo es confundir un
   dato inventado con uno real, así que no puede pasar desapercibido. --- */
.franja-demo {
  display: flex; align-items: center; gap: var(--espacio-sm);
  flex-wrap: wrap;
  padding: var(--espacio-sm) var(--espacio-xl);
  background: var(--amarillo-fondo); color: var(--amarillo);
  border-bottom: 1px solid var(--borde);
  font-size: 13px;
}
.franja-demo strong { font-weight: 700; }
.franja-demo span { color: var(--texto); }
.franja-demo form { margin-left: auto; }
.franja-demo button {
  border: 1px solid currentColor; background: transparent; color: inherit;
  border-radius: 8px; padding: 4px 12px; font-size: 12px; font-weight: 600;
  cursor: pointer; min-height: 32px;
}
.franja-demo button:hover { background: rgba(0, 0, 0, 0.06); }
@media (max-width: 720px) {
  .franja-demo { padding: var(--espacio-sm) var(--espacio-md); }
  .franja-demo form { margin-left: 0; width: 100%; }
  .franja-demo button { width: 100%; min-height: 40px; }
}

/* --- Hoja mensual de Leads ---
   Es una rejilla de doce columnas editables, así que las celdas van sin
   marco: con un recuadro por cada una la tabla se vuelve ilegible. --- */
.tabla-mensual .celda-mes {
  width: 100%; min-width: 62px; padding: 4px 6px; text-align: right;
  border: 1px solid transparent; background: transparent;
  border-radius: 6px; font-size: 13px; font-variant-numeric: tabular-nums;
}
.tabla-mensual .celda-mes:hover { border-color: var(--borde); }
.tabla-mensual .celda-mes:focus {
  border-color: var(--azul); background: var(--bg-content); outline: 0;
}
.tabla-mensual .fila-grupo td {
  background: var(--gris-fondo); font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--texto-tenue);
}
.enlace-quitar {
  border: 0; background: transparent; color: var(--texto-tenue);
  cursor: pointer; font-size: 15px; line-height: 1; padding: 0 4px;
  min-height: 24px;
}
.enlace-quitar:hover { color: var(--rojo); }
@media (max-width: 720px) {
  .tabla-mensual .celda-mes { min-width: 54px; }
}

/* --- Aviso en ventana ---
   Para lo que hay que leer antes de seguir. Sustituye a mandar al usuario a
   una página de error, que además le hacía perder lo que estaba escribiendo. */
.popup-aviso {
  border: 1px solid var(--borde); border-radius: 14px;
  padding: var(--espacio-xl); max-width: 440px; width: calc(100% - 32px);
  background: var(--bg-content); color: var(--texto);
  box-shadow: var(--sombra-grande);
}
.popup-aviso::backdrop { background: rgba(15, 15, 15, 0.45); }
.popup-aviso h2 { margin: 0 0 var(--espacio-sm); font-size: 16px; }
.popup-aviso p { margin: 0 0 var(--espacio-lg); font-size: 14px; line-height: 1.55; }
.popup-aviso form { margin: 0; display: flex; justify-content: flex-end; }

/* --- Carpeta de clientes inactivos ---
   Las bajas no se borran, pero tampoco tienen por qué competir por la
   atención con los que están en marcha. Se pliegan aparte. --- */
.carpeta-inactivos { margin-top: var(--espacio-2xl); }
.carpeta-inactivos > summary {
  display: flex; align-items: center; gap: var(--espacio-sm);
  padding: var(--espacio-md); cursor: pointer; list-style: none;
  border: 1px solid var(--borde); border-radius: 12px;
  background: var(--gris-fondo); font-weight: 600; font-size: 14px;
  min-height: 48px;
}
.carpeta-inactivos > summary::-webkit-details-marker { display: none; }
.carpeta-inactivos > summary:hover { background: var(--bg-hover); }
.carpeta-inactivos > summary:focus-visible {
  outline: 2px solid var(--marca-texto); outline-offset: 2px;
}
.carpeta-icono { display: inline-flex; color: var(--texto-tenue); }
.carpeta-icono svg { width: 18px; height: 18px; }
/* La flecha dice si está abierta o cerrada sin depender del triángulo nativo,
   que en Safari no se puede quitar ni girar. */
.carpeta-inactivos > summary::after {
  content: "›"; margin-left: auto; font-size: 20px; line-height: 1;
  color: var(--texto-tenue); transition: transform var(--transicion);
}
.carpeta-inactivos[open] > summary::after { transform: rotate(90deg); }
.carpeta-inactivos[open] > summary { border-radius: 12px 12px 0 0; }
.clientes-galeria-apagada {
  padding: var(--espacio-md); border: 1px solid var(--borde); border-top: 0;
  border-radius: 0 0 12px 12px;
}
/* Apagadas, pero legibles: al pasar por encima vuelven a su color entero. */
.clientes-galeria-apagada .cliente-card { opacity: 0.72; }
.clientes-galeria-apagada .cliente-card:hover,
.clientes-galeria-apagada .cliente-card:focus-visible { opacity: 1; }

/* Crédito del autor, al pie de Configuración y Accesibilidad. */
.credito-autor { text-align: center; margin: var(--espacio-2xl) 0 var(--espacio-md); font-size: 12px; color: var(--texto-tenue); }
.credito-autor a { color: var(--marca-texto); text-decoration: none; }
.credito-autor a:hover { text-decoration: underline; }

/* Texto de ayuda debajo de un campo o formulario. */
.ayuda { font-size: 12px; color: var(--texto-tenue); line-height: 1.5; }

/* =========================================================================
   Organigrama y Biblioteca
   ========================================================================= */

/* --- Conmutador de vista (árbol / tabla), en la barra superior --- */
.vista-toggle { display: inline-flex; gap: 2px; background: var(--gris-fondo);
  border-radius: var(--radio); padding: 3px; }
.vista-toggle a {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border-radius: 6px; font-size: 13px; font-weight: 600; color: var(--texto-tenue);
  text-decoration: none; transition: background var(--transicion), color var(--transicion);
}
.vista-toggle a svg { width: 15px; height: 15px; }
.vista-toggle a:hover { color: var(--texto); }
.vista-toggle a.activo { background: var(--bg-content); color: var(--marca-profundo);
  box-shadow: var(--sombra); }

/* --- Botones sólo-icono (editar/eliminar en las tarjetas) --- */
.btn-iconico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: none; border-radius: 7px; cursor: pointer;
  background: var(--gris-fondo); color: var(--texto-tenue);
  transition: background var(--transicion), color var(--transicion);
}
.btn-iconico:hover { background: var(--azul-fondo); color: var(--marca-profundo); }
.btn-iconico svg { width: 15px; height: 15px; }
.btn-iconico-peligro:hover { background: var(--rojo-fondo); color: var(--rojo); }
.btn-iconico form, .biblio-card-acciones form { margin: 0; }

/* --- Organigrama: vista árbol --- */
.org-lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--espacio-lg);
}
.org-nodo {
  display: flex; flex-direction: column; gap: var(--espacio-sm);
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 10px; padding: var(--espacio-md); box-shadow: var(--sombra);
}
.org-cabeza { display: flex; align-items: center; gap: var(--espacio-sm); }
.org-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--marca-degradado); color: #fff; font-weight: 700; font-size: 14px;
}
.org-avatar img { width: 100%; height: 100%; object-fit: cover; }
.org-cabeza-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.org-cabeza-txt strong { font-size: 14px; }
.org-rol { font-size: 11.5px; color: var(--texto-tenue); }
.org-conteo { margin-left: auto; flex-shrink: 0; }
.org-clientes { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.org-vacio { font-size: 12.5px; }
.org-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 10px;
  background: var(--gris-fondo); border-radius: 20px; font-size: 12.5px;
}
.org-chip > a { color: var(--texto); text-decoration: none; font-weight: 500; }
.org-chip > a:hover { color: var(--marca-profundo); text-decoration: underline; }
.org-chip-suelto { padding: 4px 12px; }
.org-chip-suelto:hover { background: var(--azul-fondo); }
.org-chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border: none; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--texto-tenue); font-size: 15px; line-height: 1;
  transition: background var(--transicion), color var(--transicion);
}
.org-chip-x:hover { background: var(--rojo-fondo); color: var(--rojo); }
.org-asignar { display: flex; gap: 6px; margin-top: 2px; }
.org-asignar select { flex: 1; min-width: 0; }
.org-fila-empleado { display: flex; align-items: center; gap: 8px; }
.org-fila-empleado .org-avatar { width: 28px; height: 28px; font-size: 12px; }
.org-sin-asignar { margin-top: var(--espacio-lg); }
.org-sin-asignar h2 { font-size: 15px; margin: 0 0 var(--espacio-sm); }

/* --- Biblioteca --- */
.biblio-acciones-top { display: flex; gap: var(--espacio-sm); }
.miga { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: 13px; margin-bottom: var(--espacio-lg); }
.miga a { color: var(--texto-tenue); text-decoration: none; }
.miga a:hover { color: var(--marca-profundo); text-decoration: underline; }
.miga-sep { color: var(--texto-tenue); }
.miga-actual { color: var(--texto); font-weight: 600; }

.biblio-card { position: relative; }
.biblio-card-main {
  display: flex; flex-direction: column; flex: 1; color: inherit; text-decoration: none;
}
.biblio-portada { height: 118px; overflow: hidden; background: var(--gris-fondo); flex-shrink: 0; }
.biblio-portada img { width: 100%; height: 100%; object-fit: cover; }
.biblio-icono {
  height: 96px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: var(--gris-fondo); color: var(--texto-tenue);
}
.biblio-icono svg { width: 34px; height: 34px; }
.biblio-icono-carpeta { background: var(--amarillo-fondo); color: var(--amarillo); }
.biblio-icono-enlace { background: var(--azul-fondo); color: var(--marca-profundo); }
.biblio-icono-video { background: var(--amarillo-fondo); color: var(--amarillo); }
.biblio-icono-documento { background: var(--gris-fondo); color: var(--texto-tenue); }
.biblio-card-txt { padding: 12px 14px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.biblio-card-txt strong { font-size: 14px; line-height: 1.3; }
.biblio-meta { font-size: 12px; }
.biblio-desc {
  font-size: 12px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.biblio-tipo { align-self: flex-start; margin-top: auto; }
.biblio-card-acciones {
  position: absolute; top: 8px; right: 8px; display: flex; gap: 4px;
  opacity: 0; transition: opacity var(--transicion);
}
.biblio-card:hover .biblio-card-acciones,
.biblio-card:focus-within .biblio-card-acciones { opacity: 1; }
.biblio-card-acciones .btn-iconico {
  background: var(--bg-content); box-shadow: var(--sombra); width: 28px; height: 28px;
}
@media (hover: none) { .biblio-card-acciones { opacity: 1; } }

/* --- Modales con <dialog> (crear/editar en la Biblioteca) --- */
dialog.modal {
  border: 1px solid var(--borde); border-radius: 14px; padding: var(--espacio-xl);
  max-width: 520px; width: calc(100% - 32px);
  background: var(--bg-content); color: var(--texto); box-shadow: var(--sombra-grande);
}
dialog.modal::backdrop { background: rgba(15, 15, 15, 0.45); }
dialog.modal h2 { margin: 0 0 var(--espacio-lg); font-size: 17px; }
dialog.modal label { display: block; margin-bottom: var(--espacio-md); font-size: 13px; font-weight: 600; }
dialog.modal label input, dialog.modal label select { margin-top: 4px; font-weight: 400; }
dialog.modal .grid-2 { margin-bottom: 0; }
.modal-acciones { display: flex; justify-content: flex-end; gap: var(--espacio-sm);
  margin-top: var(--espacio-lg); }

/* =========================================================================
   Organigrama por Account Manager · Checklist · Notificaciones
   ========================================================================= */

/* --- Organigrama: árbol agrupado por AM (como la hoja de referencia) --- */
.org-grupos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: var(--espacio-lg); align-items: start;
}
.org-grupo { border: 1px solid var(--borde); border-radius: 10px; overflow: hidden;
  box-shadow: var(--sombra); background: var(--bg-content); }
.org-grupo-cabeza { display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  color: #fff; font-size: 15px; }
.org-grupo-cabeza .org-avatar { background: rgba(255, 255, 255, 0.28); color: #fff; }
.org-grupo-conteo { margin-left: auto; font-size: 12px; font-weight: 600;
  background: rgba(255, 255, 255, 0.22); padding: 2px 9px; border-radius: 20px; }
.org-grupo-cabeza-vacia { background: var(--gris-fondo); color: var(--texto); }
.org-grupo-cabeza-vacia .org-grupo-conteo { background: var(--bg-content); color: var(--texto-tenue); }
.org-tabla-grupo { width: 100%; }
.org-grupo-vacio { padding: 14px; margin: 0; font-size: 13px; }

.org-asignar-mini { display: inline-flex; margin: 0; }
.org-asignar-mini select { font-size: 12px; padding: 4px 8px; min-height: 0;
  color: var(--texto-tenue); background: var(--gris-fondo); border-style: dashed; }
/* Cuando ya hay alguien asignado, el "+" se guarda y aparece al pasar el cursor,
   para que la fila se lea limpia. En táctil se muestra siempre. */
.org-asignar-oculta { visibility: hidden; }
tr:hover .org-asignar-oculta { visibility: visible; }
@media (hover: none) { .org-asignar-oculta { visibility: visible; } }

/* --- Checklist diario --- */
.checklist-lista { display: flex; flex-direction: column; gap: 6px; max-width: 560px; }
.checklist-item { display: flex; align-items: center; gap: 12px; padding: 11px 14px;
  border-radius: 8px; cursor: pointer; border: 1px solid var(--borde);
  transition: background var(--transicion), border-color var(--transicion); }
.checklist-item:hover { border-color: var(--azul); }
.checklist-item input { width: 18px; height: 18px; flex-shrink: 0; cursor: pointer; }
.checklist-item:has(input:checked) { background: var(--verde-fondo); border-color: var(--verde); }
.checklist-nombre { font-size: 14px; }

/* --- Notificaciones --- */
.notif-lista { display: flex; flex-direction: column; gap: 8px; }
.notif-item { display: flex; gap: 12px; padding: 14px 16px; background: var(--bg-content);
  border: 1px solid var(--borde); border-radius: 10px; }
.notif-no-leida { border-left: 3px solid var(--azul); }
.notif-punto { width: 8px; height: 8px; border-radius: 50%; background: transparent;
  margin-top: 6px; flex-shrink: 0; }
.notif-no-leida .notif-punto { background: var(--azul); }
.notif-cuerpo { flex: 1; min-width: 0; }
.notif-cabeza { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.notif-fecha { font-size: 12px; white-space: nowrap; }
.notif-texto { margin: 6px 0 0; font-size: 13px; white-space: pre-line; color: var(--texto); }
.notif-acciones { display: flex; gap: 8px; margin-top: 10px; }
.notif-acciones form { margin: 0; }

/* --- Biblioteca: espacio en disco --- */
.biblio-disco { display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  background: var(--bg-content); border: 1px solid var(--borde); border-radius: 10px;
  margin-bottom: var(--espacio-lg); }
.biblio-disco-icono { width: 22px; height: 22px; color: var(--texto-tenue); flex-shrink: 0; }
.biblio-disco-cuerpo { flex: 1; min-width: 0; }
.biblio-disco-txt { display: flex; justify-content: space-between; gap: 12px;
  font-size: 13px; margin-bottom: 6px; flex-wrap: wrap; }
.biblio-disco-barra { height: 8px; background: var(--gris-fondo); border-radius: 20px; overflow: hidden; }
.biblio-disco-barra span { display: block; height: 100%; background: var(--marca-degradado-boton);
  border-radius: 20px; }
.biblio-disco-lleno .biblio-disco-barra span { background: var(--rojo); }

/* --- Roles: emite/recibe notificaciones --- */
.rol-notif { display: flex; align-items: center; gap: 16px; padding: 12px 0;
  border-bottom: 1px solid var(--borde); }
.rol-notif:last-child { border-bottom: none; }
.rol-notif-txt { flex: 1; min-width: 0; }
.rol-notif-check { display: flex; align-items: center; gap: 6px; font-size: 13px;
  font-weight: 600; white-space: nowrap; margin: 0; cursor: pointer; }
.rol-notif-check input { width: auto; }

/* --- Camino de etapas del cliente ---------------------------------------- */
/* La idea es que se lea de un vistazo en qué punto está el cliente: lo hecho
   se apaga, lo actual resalta y lo que queda se ve en gris. */
.etapas-camino { list-style:none; margin:0; padding:0; }
.etapa-fila { display:flex; gap:14px; padding:0 0 22px; position:relative; }
.etapa-fila:not(:last-child)::before {
  content:""; position:absolute; left:17px; top:36px; bottom:2px;
  width:2px; background:var(--borde);
}
.etapa-marca {
  flex:0 0 36px; width:36px; height:36px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:14px; color:#fff; background:var(--texto-tenue);
  position:relative; z-index:1;
}
.etapa-marca svg { width:18px; height:18px; }
.etapa-cuerpo { flex:1; min-width:0; }
.etapa-cabecera { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:2px; }
.etapa-cabecera strong { font-size:15px; }
.etapa-meta { font-size:13px; color:var(--texto-tenue); margin-bottom:6px; }
.etapa-meta strong { color:var(--texto); }
.etapa-barra { height:8px; border-radius:99px; background:var(--fondo-suave); overflow:hidden; }
.etapa-barra span { display:block; height:100%; border-radius:99px; transition:width .4s ease; }
.etapa-pasos { margin-top:10px; }
.etapa-pasos ul { margin:4px 0 0; padding-left:18px; font-size:13px; }
.etapa-pasos li { margin:3px 0; }
.etapa-futura { opacity:.55; }
.etapa-actual .etapa-cabecera strong { font-size:16px; }
.etapa-hecha .etapa-barra span { opacity:.75; }

.etapa-color-azul     { background:#1e9bec; }
.etapa-color-verde    { background:#16a34a; }
.etapa-color-amarillo { background:#d97706; }
.etapa-color-rojo     { background:#dc2626; }
.etapa-color-gris     { background:#6b7280; }

.etapa-editor {
  border:1px solid var(--borde); border-radius:var(--radio);
  padding:12px 14px; margin-bottom:12px;
}

/* --- Onboarding del cliente --------------------------------------------- */
.onb-lista { list-style: none; margin: 12px 0 0; padding: 0; }
.onb-item {
  display: flex; align-items: flex-start; gap: 10px; flex-wrap: wrap;
  padding: 9px 0; border-top: 1px solid var(--borde);
}
.onb-item:first-child { border-top: 0; }
.onb-form { flex: 1; min-width: 0; margin: 0; }
.onb-check {
  display: flex; align-items: flex-start; gap: 10px; margin: 0;
  font-weight: 500; cursor: pointer; line-height: 1.45;
}
.onb-check input { width: auto; margin: 2px 0 0; flex: none; cursor: pointer; }
.onb-texto { min-width: 0; }
/* Un paso hecho se atenúa y se tacha: la vista de un vistazo es "qué falta". */
.onb-hecho .onb-texto { text-decoration: line-through; color: var(--texto-tenue); }
.onb-firma { font-size: 12px; white-space: nowrap; padding-top: 2px; }
@media (max-width: 640px) {
  .onb-firma { padding-left: 26px; }
}

/* --- Enlace directo a la pieza, en el Histórico de Ganadores ---
   Va en su propia columna y no dentro del título: al ordenar por vistas, lo
   que se quiere es saltar al vídeo que las consiguió, y un enlace escondido
   dentro de un texto largo no se ve. --- */
.enlace-pieza {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  color: var(--texto-tenue);
  transition: background var(--transicion), color var(--transicion);
}
.enlace-pieza svg { width: 15px; height: 15px; }
.enlace-pieza:hover { background: var(--azul-fondo); color: var(--marca-profundo); }
@media (pointer: coarse) { .enlace-pieza { width: 40px; height: 40px; } }

/* Texto que solo leen los lectores de pantalla. */
.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- El logo real de la agencia ---
   Sustituye a la inicial dibujada. Se queda con la caja y el radio del
   recuadro anterior para no mover nada de su alrededor, pero sin el degradado
   ni el color de fondo: el logo ya trae los suyos. --- */
.logo-cuadro.logo-img {
  /* El logo ya trae su propio círculo y su degradado: hay que quitarle los del
     recuadro que sustituye, incluido el halo, que alrededor de un PNG con
     transparencia se ve como una mancha. */
  background: none;
  box-shadow: none;
  color: inherit;
  object-fit: contain;
  padding: 0;
  display: block;
}
/* Y un poco más grande que la inicial: donde había una letra ahora hay una
   flecha y dos letras, y a 24px no se distinguía. */
.sidebar .marca .logo-cuadro.logo-img,
.marca-movil .logo-cuadro.logo-img { width: 28px; height: 28px; }
.login-card .logo-cuadro.logo-img { width: 56px; height: 56px; }

/* --- Tareas --- */
/* Una tarea cerrada sigue estando, pero deja de pedir atención. */
.tabla-notion tr.fila-hecha td { opacity: 0.55; }
.tabla-notion tr.fila-hecha .pieza-titulo { text-decoration: line-through; }
/* «Iniciar» y «Terminar», uno al lado del otro: cada botón es su propio
   formulario, y sin esto caían en dos filas y doblaban el alto de la tabla. */
.acciones-tarea {
  display: flex; gap: 6px; align-items: center; flex-wrap: nowrap;
  white-space: nowrap;
}
.acciones-tarea form { margin: 0; }

/* --- Chat con el cliente ---
   Globos a lado y lado: quien mira se ve siempre a la derecha, que es la
   convención de cualquier mensajería y ahorra tener que leer el nombre. --- */
.chat-hilo {
  display: flex; flex-direction: column; gap: 10px;
  overflow-y: auto; padding: 4px 2px;
  background: var(--gris-fondo); border: 1px solid var(--borde);
  border-radius: 10px; padding: 14px;
}
.chat-linea { display: flex; }
.chat-linea.chat-mio { justify-content: flex-end; }
.chat-globo {
  max-width: 74%; padding: 9px 13px; border-radius: 12px;
  background: var(--bg-content); border: 1px solid var(--borde);
  box-shadow: var(--sombra);
}
.chat-mio .chat-globo {
  background: var(--azul-fondo); border-color: var(--azul);
}
.chat-quien {
  font-size: 11px; font-weight: 700; color: var(--texto-tenue);
  margin-bottom: 3px;
}
.chat-cuerpo { font-size: 14px; line-height: 1.5; white-space: pre-wrap;
  overflow-wrap: anywhere; }
.chat-cuando { font-size: 11px; color: var(--texto-tenue); margin-top: 4px; }
.chat-escribir {
  display: flex; gap: 8px; align-items: flex-end; margin-top: 12px;
}
.chat-escribir textarea { flex: 1; margin: 0; resize: vertical; }
.chat-escribir button { flex-shrink: 0; }
@media (max-width: 560px) {
  .chat-globo { max-width: 88%; }
  .chat-escribir { flex-direction: column; align-items: stretch; }
}

/* El rol de quien escribe, al lado de su nombre: sirve para saber a quién se
   le está hablando sin tener que preguntar quién es cada uno. */
.chat-rol {
  font-weight: 500; color: var(--texto-tenue); margin-left: 6px;
  text-transform: none; letter-spacing: 0;
}
.chat-rol::before { content: "· "; }

/* --- Burbuja de chat ---
   Fija en la esquina, por encima de todo pero por debajo de los diálogos. En
   el móvil la ventanita ocupa casi toda la pantalla: en 360px de ancho, un
   panel de 360 se sale. --- */
/* El hueco que ocupa la burbuja, en una variable: la barra pegajosa y el pie
   de la pagina lo usan para no meter texto debajo. */
:root { --hueco-burbuja: 90px; }
.burbuja { position: fixed; right: 20px; bottom: 20px; z-index: 60; }
/* Se aparta al bajar para no tapar lo que hay debajo. Solo en móvil: en
   escritorio sobra sitio y esconderla molestaría más que ayudar. */
@media (max-width: 640px) {
  .burbuja {
    transition: transform var(--transicion), opacity var(--transicion);
  }
  .burbuja.apartada {
    transform: translateY(calc(100% + 24px)); opacity: 0;
    pointer-events: none;
  }
  /* Abierta no se aparta nunca: estarías escribiendo y desaparecería. */
  .burbuja.abierta.apartada {
    transform: none; opacity: 1; pointer-events: auto;
  }
}
@media (prefers-reduced-motion: reduce) {
  .burbuja { transition: none; }
}
.burbuja-boton {
  position: relative;
  width: 54px; height: 54px; border-radius: 50%;
  border: 0; cursor: pointer;
  background: var(--marca-degradado); color: #fff;
  box-shadow: var(--sombra-grande);
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--transicion), box-shadow var(--transicion);
}
.burbuja-boton svg { width: 24px; height: 24px; }
.burbuja-boton:hover { transform: translateY(-2px); }
.burbuja-chapa {
  position: absolute; top: -2px; right: -2px;
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 10px; background: var(--rojo); color: #fff;
  font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--bg-content);
}
.burbuja-panel {
  position: absolute; right: 0; bottom: 66px;
  width: 360px; max-height: min(70vh, 560px);
  display: flex; flex-direction: column;
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 12px; box-shadow: var(--sombra-grande);
  overflow: hidden;
}
.burbuja-panel[hidden] { display: none; }
.burbuja-cab {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid var(--borde);
  background: var(--bg-sidebar);
}
.burbuja-cerrar {
  border: 0; background: none; cursor: pointer; font-size: 15px;
  color: var(--texto-tenue); padding: 2px 6px; border-radius: 6px;
}
.burbuja-cerrar:hover { background: var(--bg-hover); color: var(--texto); }
.burbuja-cuerpo { overflow-y: auto; padding: 12px; }
.burbuja-vacia {
  margin: 0; padding: 18px 6px; text-align: center;
  color: var(--texto-tenue); font-size: 13px; line-height: 1.5;
}

.burbuja-lista { list-style: none; margin: 0; padding: 0; }
.burbuja-lista li + li { border-top: 1px solid var(--borde); }
.burbuja-conv {
  width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
  padding: 10px 8px; border-radius: 8px;
  display: flex; flex-direction: column; gap: 3px;
}
.burbuja-conv:hover { background: var(--bg-hover); }
.burbuja-conv-nombre {
  font-size: 14px; font-weight: 600; color: var(--texto);
  display: flex; align-items: center; gap: 6px;
}
.burbuja-conv-ultimo {
  font-size: 12px; color: var(--texto-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Un punto y no un texto: en una fila estrecha, "esperando respuesta" se
   comería el nombre del cliente. */
.burbuja-punto {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--amarillo); flex-shrink: 0;
}

.burbuja-hilo-cab {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 10px; font-size: 14px;
}
.burbuja-volver {
  border: 0; background: none; cursor: pointer; padding: 2px 4px;
  color: var(--azul); font-size: 13px; border-radius: 6px;
}
.burbuja-volver:hover { background: var(--azul-fondo); }
.burbuja-mensajes { max-height: 300px; }
.burbuja-escribir { display: flex; gap: 6px; align-items: flex-end; margin-top: 10px; }
.burbuja-escribir textarea { flex: 1; margin: 0; resize: none; font-size: 13px; }

@media (max-width: 520px) {
  .burbuja { right: 14px; bottom: 14px; }
  .burbuja-panel {
    position: fixed; right: 10px; left: 10px; bottom: 78px;
    width: auto; max-height: 70vh;
  }
}
@media print { .burbuja { display: none; } }

/* El selector para empezar una conversación: va arriba del todo de la
   burbuja, separado de la lista por una línea. */
.burbuja-nueva {
  display: block; margin: 0 0 10px; padding-bottom: 10px;
  border-bottom: 1px solid var(--borde);
}
.burbuja-nueva select { margin: 0; width: 100%; font-size: 13px; }

/* Paginación. Nació duplicada en tres plantillas (publicaciones, registro de
   errores y la tabla de contenido); vive aquí desde que el calendario de Notion
   obligó a paginar también el contenido. */
.barra-paginas {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 12px 2px 4px; font-size: 13px;
}
.paginas, .paginas-lista, .paginas-log { display: flex; gap: 4px; flex-wrap: wrap; }
.pag-btn {
  display: inline-block; min-width: 32px; text-align: center; padding: 5px 9px;
  border: 1px solid var(--borde); border-radius: 7px; background: #fff;
  color: #475569; text-decoration: none; font-size: 13px; font-weight: 600;
}
.pag-btn:hover { border-color: var(--marca); color: var(--marca-texto); }
.pag-btn.activo {
  background: var(--marca-solido); border-color: var(--marca-solido); color: #fff;
}
.pag-hueco { padding: 5px 2px; color: #94a3b8; }

/* La descripción de una pieza es el copy entero del post: se guarda completa y
   se recorta AL PINTARLA, para que una fila no crezca media pantalla. El texto
   completo va en el title, y en la ficha se ve entero. */
.pieza-texto {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; text-decoration: underline; max-width: 520px;
}

/* --- Pipeline del cliente ------------------------------------------------
   La tarjeta que sustituye a la lista vertical de etapas. Los pasos van en
   horizontal porque lo que se quiere ver es el RECORRIDO, y en vertical hay
   que hacer scroll para saber por dónde va. */
.pipe-tarjeta {
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 12px; padding: 16px 18px; margin: 0 0 14px;
}
.pipe-cabecera {
  display: flex; gap: 22px; flex-wrap: wrap; align-items: flex-start;
  justify-content: space-between; padding-bottom: 14px;
  border-bottom: 1px solid var(--borde);
}
.pipe-quien { display: flex; gap: 12px; align-items: center; min-width: 260px; flex: 1 1 260px; }
.pipe-foto {
  width: 46px; height: 46px; border-radius: 50%; object-fit: cover;
  flex: 0 0 46px;
}
.pipe-inicial {
  display: flex; align-items: center; justify-content: center;
  background: var(--marca-solido); color: #fff; font-weight: 700; font-size: 19px;
}
.pipe-nombre { font-size: 16px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.pipe-nombre a { color: inherit; text-decoration: none; }
.pipe-nombre a:hover { color: var(--marca-texto); }
.pipe-sub { font-size: 12px; color: var(--texto-tenue); margin-top: 2px; }
.pipe-etq {
  font-size: 11px; color: var(--texto-tenue); text-transform: uppercase;
  letter-spacing: .04em; margin-bottom: 4px;
}
.pipe-cumplimiento { min-width: 180px; flex: 0 1 200px; }
.pipe-pct { font-size: 26px; font-weight: 700; line-height: 1.1; }
.pipe-barra {
  height: 7px; background: var(--bg-hover); border-radius: 4px;
  overflow: hidden; margin-top: 6px;
}
.pipe-barra span { display: block; height: 100%; background: var(--verde); }
.pipe-hitos { min-width: 230px; flex: 0 1 300px; }
.pipe-hito { display: flex; align-items: center; gap: 7px; font-size: 12.5px; padding: 2px 0; }
.pipe-hito-que {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pipe-hito-cuando { color: var(--texto-tenue); white-space: nowrap; }
.pipe-punto { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 7px; }
.pipe-punto.pipe-reunion { background: var(--azul); }
.pipe-punto.pipe-contenido { background: var(--verde); }
.pipe-vacio { font-size: 12.5px; color: var(--texto-tenue); }

/* Los pasos. Se desbordan en horizontal en pantallas estrechas en vez de
   apilarse: apilados se pierde la idea de "camino". */
.pipe-pasos {
  display: flex; gap: 0; list-style: none; margin: 16px 0 0; padding: 0;
  overflow-x: auto;
}
.pipe-paso {
  flex: 1 1 0; min-width: 104px; text-align: center; position: relative;
  padding: 0 4px;
}
/* La línea que une los pasos. Va detrás del número, de ahí el z-index. */
.pipe-paso::before {
  content: ""; position: absolute; top: 13px; left: -50%; width: 100%;
  height: 2px; background: var(--borde);
}
.pipe-paso:first-child::before { display: none; }
.pipe-paso.hecha::before, .pipe-paso.actual::before { background: var(--verde); }
.pipe-num {
  position: relative; z-index: 1; display: inline-flex; align-items: center;
  justify-content: center; width: 27px; height: 27px; border-radius: 50%;
  background: var(--bg-hover); color: var(--texto-tenue);
  font-size: 12.5px; font-weight: 700; border: 2px solid var(--bg-content);
}
.pipe-num svg { width: 14px; height: 14px; }
.pipe-paso.hecha .pipe-num { background: var(--verde); color: #fff; }
.pipe-paso.actual .pipe-num { background: var(--marca-solido); color: #fff; }
.pipe-paso-nombre {
  display: block; font-size: 11.5px; margin-top: 6px; line-height: 1.25;
  color: var(--texto);
}
.pipe-paso-pct { display: block; font-size: 13px; font-weight: 700; margin-top: 2px; }
.pipe-paso.hecha .pipe-paso-pct { color: var(--verde); }
.pipe-paso.actual .pipe-paso-pct { color: var(--marca-texto); }
.pipe-paso.futura .pipe-paso-pct { color: var(--texto-tenue); }
/* La etapa que no se mide con una barra: no lleva cifra, asi que tampoco
   tamano de cifra. */
.pipe-paso-auto { font-size: 10.5px; font-weight: 600; color: var(--texto-tenue); }
.pipe-retraso {
  display: block; font-size: 10.5px; color: #dc2626; font-weight: 600; margin-top: 2px;
}
/* La etiqueta de cada proceso dentro de la tarjeta. Solo sale cuando hay mas
   de uno: con uno solo, el titulo del cumplimiento ya dice cual es. */
.pipe-proceso {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 18px 0 -2px; padding-top: 12px;
  border-top: 1px solid var(--borde);
}
.pipe-proceso:first-of-type { border-top: 0; padding-top: 0; margin-top: 14px; }
.pipe-proceso-nombre {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--texto-tenue);
}
.pipe-proceso-pct { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* El vacio del recorrido. Antes salian dos mensajes en la misma tarjeta
   diciendo lo mismo -«Sin etapas definidas» arriba y una frase larga abajo- y
   ninguno llevaba a ningun sitio. Ahora es uno solo y con el boton dentro. */
.pipe-vacio-camino {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 20px 16px 6px; text-align: center;
}
.pipe-vacio-camino p {
  margin: 0; font-size: 13px; color: var(--texto-tenue); max-width: 46ch; line-height: 1.5;
}

/* --- La tira: el recorrido en una linea, para la tarjeta de la galeria ---
   No cabe el recorrido con nombres, asi que se deja lo unico que se pregunta
   de un golpe de vista: en que etapa va y cuanto lleva. Los puntos son los
   mismos pasos, sin texto. */
.pipe-tira { margin-top: 10px; }
.pipe-tira-cabeza {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; margin-bottom: 5px;
}
.pipe-tira-etapa {
  color: var(--texto-tenue); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; min-width: 0;
}
.pipe-tira-pct { font-weight: 700; font-size: 12.5px; flex: none; font-variant-numeric: tabular-nums; }
.pipe-tira-puntos {
  display: flex; gap: 3px; list-style: none; margin: 0; padding: 0;
}
.pipe-tira-punto {
  flex: 1 1 0; height: 5px; border-radius: 3px; background: var(--bg-hover);
}
.pipe-tira-punto.hecha { background: var(--verde); }
/* La actual va a rayas y no en solido: en solido se confunde con una
   superada y la tarjeta miente sobre por donde va el cliente. */
.pipe-tira-punto.actual {
  background: repeating-linear-gradient(90deg, var(--marca-solido) 0 4px,
              transparent 4px 7px), var(--bg-hover);
}

.pipe-sin-etapas { font-size: 12.5px; color: var(--texto-tenue); margin: 14px 0 0; }

/* --- Meta de seguidores por red social -----------------------------------
   Se puede poner a una red o a varias: cada cuenta lleva su casilla y la
   vacia significa «esta red no entra en la meta». Se maqueta como una rejilla
   de tres columnas -nombre, meta, resultado- para que las cifras queden
   alineadas y se pueda comparar de un vistazo, que es para lo que se mira. */
.meta-redes {
  border: 1px solid var(--borde); border-radius: 8px;
  padding: var(--espacio-md); margin-bottom: var(--espacio-md);
  background: var(--bg-sidebar);
}
.meta-redes-titulo {
  font-size: 12px; font-weight: 600; color: var(--texto);
  margin-bottom: 2px;
}
.meta-red {
  display: grid; grid-template-columns: 1fr 96px auto;
  align-items: center; gap: var(--espacio-sm);
  padding: 3px 0; margin: 0;
}
.meta-red + .meta-red { border-top: 1px solid var(--borde); }
.meta-red-nombre {
  font-size: 12.5px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.meta-red-nombre .texto-tenue { font-size: 11.5px; }
.meta-red input { margin: 0; text-align: right; }
.meta-red-real {
  font-size: 11.5px; color: var(--texto-tenue);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* En movil la fila de tres columnas no cabe: el nombre pasa arriba y la meta
   y el resultado se reparten debajo. */
@media (max-width: 560px) {
  .meta-red { grid-template-columns: 1fr auto; }
  .meta-red-nombre { grid-column: 1 / -1; }
}

/* La casilla de totales del cliente destaca sobre el detalle por cuenta: es
   el numero que se busca primero. */
.tira-dato.tira-total { background: var(--bg-sidebar); }

/* El porcentaje del proceso necesitaba decir QUE promedia: se leia como si
   fuera lo que falta para la ultima etapa. */
.pipe-nota {
  font-size: 11px; color: var(--texto-tenue); line-height: 1.35;
  margin-top: 4px; max-width: 26ch;
}

/* Un campo de texto que contiene una direccion web se pulsa y abre, como en
   Notion. Se subraya para que se distinga de un campo normal: sin eso nadie
   sabe que se puede pulsar. La URL puede ser larguisima (una carpeta de Drive
   pasa de 70 caracteres), asi que parte por donde sea antes que salirse. */
.enlace-campo {
  color: var(--azul); text-decoration: underline;
  overflow-wrap: anywhere; word-break: break-word;
}
.enlace-campo:hover { text-decoration-thickness: 2px; }
.enlace-campo:focus-visible {
  outline: 2px solid var(--azul); outline-offset: 2px; border-radius: 3px;
}

/* --- Escala de la gráfica de seguidores -----------------------------------
   El grupo va separado de los presets de fecha: son dos decisiones distintas
   sobre la misma gráfica y juntas parecían una sola fila de seis botones. */
.filtro-fechas .filtro-escala {
  margin-left: auto;
  border-left: 1px solid var(--borde);
  padding-left: var(--espacio-md);
}
.filtro-escala .btn.activo {
  background: var(--azul); color: #fff; border-color: var(--azul);
}
.filtro-escala .btn.activo:hover { background: var(--azul); }
@media (max-width: 640px) {
  /* En móvil no cabe a la derecha: baja a su propia línea y se queda sin la
     raya, que ahí ya no separa nada. */
  .filtro-fechas .filtro-escala {
    margin-left: 0; border-left: 0; padding-left: 0;
  }
}

/* --- Buscador global -------------------------------------------------------
   La lupa vive en la barra de arriba para que esté siempre a mano: antes solo
   había buscador dentro de Clientes, así que para encontrar una pieza había
   que saber de antemano en qué sección estaba. */
.topbar-derecha {
  display: flex; align-items: center; gap: var(--espacio-md);
  flex-wrap: wrap; justify-content: flex-end;
}
.buscador-global {
  display: flex; align-items: center; gap: 6px;
  background: var(--bg-content); border: 1px solid var(--borde);
  border-radius: 999px; padding: 0 10px;
  transition: border-color var(--transicion), box-shadow var(--transicion);
}
.buscador-global svg {
  width: 15px; height: 15px; color: var(--texto-tenue); flex: none;
}
.buscador-global input {
  border: 0; background: transparent; margin: 0; padding: 7px 0;
  width: 190px; min-width: 0; font-size: 13px;
}
.buscador-global input:focus { outline: none; box-shadow: none; }
/* El foco se pinta en la cápsula entera, no en el campo: si no, salía un
   recuadro cuadrado dentro de un borde redondeado. */
.buscador-global:focus-within {
  border-color: var(--azul); box-shadow: 0 0 0 3px var(--azul-fondo);
}
@media (max-width: 900px) {
  /* En pantallas estrechas la caja se lleva la fila entera del título. Se
     queda solo la lupa, que sigue llevando a la pantalla de buscar. */
  .buscador-global input { width: 120px; }
}
@media (max-width: 560px) {
  .topbar-derecha { width: 100%; justify-content: flex-start; }
  .buscador-global { flex: 1 1 auto; }
  .buscador-global input { width: auto; flex: 1 1 auto; }
}

.busca-bloques { display: grid; gap: var(--espacio-lg); }
.busca-lista { list-style: none; margin: var(--espacio-md) 0 0; padding: 0; }
.busca-lista li + li { border-top: 1px solid var(--borde); }
.busca-lista a {
  display: flex; align-items: baseline; gap: var(--espacio-md);
  padding: 8px 6px; border-radius: 6px; color: inherit; text-decoration: none;
  transition: background var(--transicion);
}
.busca-lista a:hover { background: var(--bg-sidebar); }
.busca-lista a:focus-visible { outline: 2px solid var(--azul); outline-offset: -2px; }
.busca-texto {
  font-weight: 500; min-width: 0; overflow-wrap: anywhere;
  /* Los titulos de publicaciones son parrafos enteros traidos de la red y
     ocupaban tres lineas cada uno. Se recortan a dos: lo que hace falta para
     reconocer el resultado, no para leerlo entero. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.busca-detalle {
  font-size: 12px; color: var(--texto-tenue); margin-left: auto;
  white-space: nowrap; flex: none;
}
@media (max-width: 560px) {
  /* El detalle debajo, no a la derecha: en móvil empujaba el título. */
  .busca-lista a { flex-direction: column; gap: 2px; }
  .busca-detalle { margin-left: 0; white-space: normal; }
}

/* --- Tracker: formulario de la semana (v99) ---------------------------------
   Rehecho porque «tiene que ser más accesible y bonito a la vista». Medido
   antes: campos de meta de 29 px en el teléfono, diez filas de desglose vacías
   siempre abiertas y «Guardar» a 1.576 px sin nada que lo acompañara.
   Cada paso es una fila de rejilla con las mismas cuatro columnas que su
   cabecera, así las cifras quedan en columna; en el teléfono se apilan con su
   rótulo encima. */
.tracker-hoja { padding-bottom: 0; }
.tracker-encabezado { margin-bottom: var(--espacio-lg); }
.card h2.tracker-titulo { font-size: 16px; margin: 0 0 var(--espacio-xs); }
.tracker-intro { margin: 0; }

.tracker-grupo + .tracker-grupo { margin-top: var(--espacio-2xl); }
.tracker-fila {
  display: grid; align-items: center;
  /* El sitio que sobra se lo lleva la barra de cumplimiento, no el hueco
     entre el nombre y sus cifras: a 1440 px el ojo cruzaba 580 px de nada
     para llegar del paso a su resultado. */
  grid-template-columns: minmax(200px, 340px) 150px 150px minmax(150px, 1fr);
  column-gap: var(--espacio-lg);
}
.tracker-cumpl .barra-mini { max-width: 260px; }
/* El desglose va 14 px hacia dentro (12 de sangría + 2 de raya): su primera
   columna es 14 px más estrecha para que sus campos caigan justo debajo de
   los del paso. */
.tracker-desglose .tracker-fila { grid-template-columns: minmax(186px, 326px) 150px 150px minmax(150px, 1fr); }
.tracker-cabecera {
  padding-bottom: var(--espacio-sm); border-bottom: 1px solid var(--borde);
  align-items: end;
}
.card h3.tracker-grupo-titulo { margin: 0; font-size: 13px; letter-spacing: 0.02em; }
.tracker-col {
  font-size: 12px; font-weight: 600; color: var(--texto-tenue); text-align: right;
}
.tracker-col-cumpl { text-align: left; }

.tracker-paso { border-bottom: 1px solid var(--borde); padding: var(--espacio-md) 0; }
.tracker-nombre { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tracker-etiqueta { font-size: 14px; font-weight: 600; color: var(--texto); }
.tracker-ayuda { font-size: 12px; color: var(--texto-tenue); }

.tracker-cifra { min-width: 0; display: flex; flex-direction: column; align-items: stretch; }
/* El rótulo de cada cifra solo hace falta cuando no hay cabecera encima. */
.tracker-rotulo { display: none; font-size: 12px; font-weight: 600; color: var(--texto-tenue); margin-bottom: 4px; }
.campo-num { position: relative; }
.tracker-form .campo-num input {
  text-align: right; font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  height: 36px; padding: 6px 10px;
}
.tracker-form .es-dinero .campo-num input { padding-left: 24px; }
.campo-num-moneda {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  font-size: 14px; color: var(--texto-tenue); pointer-events: none;
}
.tracker-form input[aria-invalid="true"] { border-color: var(--rojo); }
.tracker-error { font-size: 12px; color: var(--rojo); margin-top: 4px; text-align: right; }
/* Un total que sale de sumar las redes: se lee como cifra, no como campo
   apagado, que parecería roto. */
.tracker-suma, .tracker-fijo {
  display: block; text-align: right; font-weight: 600; font-size: 14px;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  padding: 8px 11px; line-height: 20px;
}
.tracker-suma { border-radius: var(--radio); background: var(--gris-fondo); }
/* `hidden` pierde contra cualquier `display` de una clase: sin esto salían a
   la vez el campo y la suma. */
.tracker-form [hidden] { display: none !important; }

.tracker-cumpl { display: flex; align-items: center; gap: 9px; min-width: 0; }
.tracker-cumpl .score-num { min-width: 40px; }
.tracker-cumpl .barra-mini { flex: 1; }
.tracker-sin-meta { font-size: 13px; color: var(--texto-tenue); }

/* Desglose por red: debajo de su paso, con una raya a la izquierda que lo
   cuelga de él, y sin fondo gris (antes parecía otra tabla). */
.tracker-desglose {
  margin: var(--espacio-sm) 0 0; padding: var(--espacio-xs) 0 var(--espacio-xs) var(--espacio-md);
  border-left: 2px solid var(--borde);
}
.tracker-desglose-titulo { font-size: 12px; font-weight: 600; color: var(--texto-tenue); margin: 0 0 var(--espacio-xs); }
.tracker-red { padding: var(--espacio-xs) 0; }
.tracker-red-nombre { font-size: 13px; color: var(--texto); }
.tracker-red .campo-num input { height: 32px; font-size: 13px; }
.tracker-otras { margin-top: var(--espacio-xs); }
.tracker-otras > summary {
  cursor: pointer; font-size: 13px; color: var(--marca-texto); padding: 6px 0;
  width: fit-content; min-height: 32px; display: flex; align-items: center; gap: 4px;
}
.tracker-otras > summary:hover { text-decoration: underline; }

.tracker-notas { margin-top: var(--espacio-xl); }
.tracker-notas textarea { font-weight: 400; }
/* Guardar va pegado abajo mientras se baja por la hoja. A la izquierda y con
   hueco a la derecha: en esa esquina vive la burbuja del chat y lo tapaba. */
.tracker-acciones {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: var(--espacio-md); flex-wrap: wrap;
  margin: var(--espacio-lg) calc(-1 * var(--espacio-xl)) 0;
  padding: var(--espacio-md) var(--hueco-burbuja) var(--espacio-md) var(--espacio-xl);
  background: var(--bg-content); border-top: 1px solid var(--borde);
  border-radius: 0 0 10px 10px;
}
.tracker-estado { font-size: 13px; color: var(--texto-tenue); order: 2; }
.tracker-estado.pendiente { color: var(--amarillo); font-weight: 600; }
.tracker-acciones .btn { order: 1; }

@media (max-width: 900px) {
  .tracker-fila, .tracker-desglose .tracker-fila {
    grid-template-columns: minmax(0, 1fr) 128px 128px 112px; column-gap: var(--espacio-md);
  }
}
@media (max-width: 640px) {
  .tracker-cabecera .tracker-col { display: none; }
  .tracker-fila {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    row-gap: var(--espacio-sm); column-gap: var(--espacio-md);
  }
  .tracker-cabecera { grid-template-columns: 1fr; }
  .tracker-nombre, .tracker-paso > .tracker-fila > .tracker-cumpl { grid-column: 1 / -1; }
  .tracker-rotulo { display: block; }
  .tracker-red .tracker-rotulo { display: none; }
  /* En el desglose, la red y sus dos campos en una línea: con el nombre
     encima cada red eran dos filas y la hoja pasaba de 3.200 px. */
  /* Con `.tracker-desglose` delante: la regla de 900 px lleva dos clases y,
     con una sola, ganaba ella y las redes salían con las columnas de tableta. */
  .tracker-desglose .tracker-red { grid-template-columns: 72px minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--espacio-sm); }
  .tracker-red .tracker-red-nombre { font-weight: 600; font-size: 13px; }
  .tracker-red > .tracker-cumpl { display: none; }
  /* «Sin meta» en cada paso es una línea entera de nada en el teléfono. */
  .tracker-paso > .tracker-fila > .tracker-cumpl:has(> .tracker-sin-meta) { display: none; }
  .tracker-form .campo-num input { height: 44px; font-size: 16px; }
  .tracker-red .campo-num input { height: 40px; font-size: 16px; }
  .tracker-acciones { margin-left: calc(-1 * var(--espacio-lg)); margin-right: calc(-1 * var(--espacio-lg));
                      padding-left: var(--espacio-lg); }
}

/* --- Panel del cliente: lo ganado por red y cuentas sin cortar (v99) ------ */
/* El nombre de la cuenta ya no se corta con «…»: la red arriba y el usuario
   debajo, partiéndose si hace falta. Se cortaban justo Instagram y Facebook,
   que son los usuarios largos. */
.tira-etiqueta { white-space: normal; overflow: visible; text-overflow: clip; }
.tira-usuario { display: block; overflow-wrap: anywhere; font-weight: 400; }
/* El reparto por red de una semana, debajo de su cifra. */
.reparto-redes {
  display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 2px;
  font-size: 11.5px; font-weight: 400; color: var(--texto-tenue);
}
.reparto-redes > span { white-space: nowrap; }

/* Comentarios con el cliente (v100): la respuesta del equipo va colgada de su
   comentario, con sangría y raya, para que se lea como conversación. */
.comentario-hilo + .comentario-hilo { margin-top: var(--espacio-sm); }
.comentario-respuesta { margin-left: var(--espacio-xl); padding-left: var(--espacio-md);
                        border-left: 2px solid var(--borde); }
.comentario-responder { margin: 4px 0 var(--espacio-sm) var(--espacio-xl); }
.comentario-responder > summary { cursor: pointer; font-size: 13px; color: var(--marca-texto);
                                  width: fit-content; min-height: 32px; display: flex; align-items: center; }
.comentario-responder > summary:hover { text-decoration: underline; }
@media (max-width: 640px) {
  .comentario-respuesta, .comentario-responder { margin-left: var(--espacio-md); }
}

/* El recorrido en tres pasos de las tarjetas de cliente (23/09/2026).
   Se pidió ver «paso anterior - paso actual - paso siguiente con botones
   llamativos»: el del medio manda (color y tamaño) y los de los lados quedan
   apagados, para que de un vistazo se sepa qué toca ahora. */
/* El recorrido dentro de la tarjeta de cliente (23/09/2026).
   Prefijo `paso3-` y no `pipe-paso-`: ese nombre ya era del pipeline completo
   de la ficha (`.pipe-pasos`), y como estas reglas van DESPUÉS en el archivo le
   estaban cambiando el aspecto sin que nadie lo pidiera. A igual especificidad
   gana la última, así que dos componentes no pueden compartir nombre. */
.paso3 { display: flex; flex-direction: column; gap: 5px; margin-top: 10px; min-width: 0; }
.paso3-ahora { display: flex; align-items: center; gap: 8px; padding: 6px 10px;
               border-radius: 8px; background: var(--paso-fondo); color: var(--paso-texto); }
.paso3-nombre { font-size: 13px; font-weight: 650; line-height: 1.25; min-width: 0; }
.paso3-pct { margin-left: auto; font-size: 12px; font-weight: 700;
             font-variant-numeric: tabular-nums; opacity: .92; }
.paso3-medida { display: flex; align-items: center; gap: 8px; }
.paso3-barra { flex: 1 1 auto; height: 4px; border-radius: 3px; background: var(--borde);
               overflow: hidden; }
.paso3-barra > span { display: block; height: 100%; background: var(--paso-fondo); }
.paso3-cifra { font-size: 11.5px; color: var(--texto-tenue); flex: none;
               font-variant-numeric: tabular-nums; }
/* Los dos lados se reparten el ancho según lo que ocupan: con «es la primera»
   a un lado, el nombre largo del otro aprovecha el hueco en vez de cortarse a
   la mitad exacta. */
.paso3-lados { display: flex; gap: 6px; justify-content: space-between; align-items: stretch; }
/* Las etapas de los lados son una pista, no un dato: una línea, y si no cabe se
   corta con puntos suspensivos (el nombre entero está en el `title`). */
/* Los lados eran texto gris de 11 px y se perdían. Ahora son etiquetas con
   fondo y borde: se ven, y siguen sin competir con el paso de ahora porque no
   llevan color de marca. */
.paso3-lado { flex: 0 1 auto; min-width: 0; font-size: 11.5px; color: var(--texto);
              background: var(--gris-fondo); border: 1px solid var(--borde);
              border-radius: 6px; padding: 3px 7px; display: inline-flex;
              align-items: center; white-space: nowrap; overflow: hidden;
              text-overflow: ellipsis; }
.paso3-despues { text-align: right; }
.paso3-eti { font-size: 13px; line-height: 1; color: var(--texto-tenue); margin: 0 4px;
             flex: none; }
.paso3-vacio { margin: 10px 0 0; font-size: 12px; color: var(--texto-tenue); }
/* En el tablero no hay píldora: el porcentaje va suelto, alineado con la
   cifra, y hace de titular de la tarjeta. */
.paso3-pct-suelto { align-self: flex-start; font-size: 15px; font-weight: 700;
                    color: var(--paso-fondo); font-variant-numeric: tabular-nums; }

/* Tablero de clientes por etapa (25/09/2026). Una columna por paso del
   pipeline; dentro, las mismas tarjetas que en la galería. El desplazamiento
   es del TABLERO, no de la página: así la cabecera y el buscador se quedan
   quietos mientras se recorre el recorrido de izquierda a derecha. */
/* Índice de etapas: hace de mapa del tablero y de atajo. Se queda arriba al
   bajar por la página porque es también el «dónde estoy». */
.tablero-indice {
  display: flex; gap: 6px; overflow-x: auto; padding: 8px 2px;
  position: sticky; top: 0; z-index: 3; background: var(--bg-content);
  border-bottom: 1px solid var(--borde); margin-bottom: 8px;
}
.tablero-salto {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px; border: 1px solid var(--borde);
  background: var(--bg-content); color: var(--texto); cursor: pointer;
  font-size: 12.5px; white-space: nowrap;
}
.tablero-salto:hover { border-color: var(--azul); color: var(--azul); }
.tablero-salto:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }
.tablero-salto.sin-nadie { color: var(--texto-tenue); }
/* En AZUL de marca y no en el índigo del paso: el índigo dice «esta es la
   etapa de este cliente» dentro de una tarjeta, y aquí lo que se marca es
   «estás mirando esta columna», que es navegación. Dos cosas distintas, dos
   colores distintos. */
.tablero-salto.aqui { background: var(--marca-solido); color: #fff;
                      border-color: transparent; font-weight: 600; }
.tablero-salto-n { font-variant-numeric: tabular-nums; opacity: .8; }

.tablero-etapas {
  display: flex; gap: 14px; align-items: flex-start;
  overflow-x: auto; padding: 4px 2px 14px;
  scroll-snap-type: x proximity;
  /* Se puede agarrar el fondo y moverlo de lado; el cursor lo anuncia. */
  cursor: grab;
  /* La barra se ve siempre: es la pista de que hay más columnas a la derecha. */
  scrollbar-width: thin; scrollbar-color: var(--borde) transparent;
}
.tablero-etapas.agarrando { cursor: grabbing; scroll-snap-type: none; }
.tablero-etapas::-webkit-scrollbar { height: 10px; }
.tablero-etapas::-webkit-scrollbar-track { background: transparent; }
.tablero-etapas::-webkit-scrollbar-thumb {
  background: var(--borde); border-radius: 999px; border: 2px solid var(--bg-content);
}
.tablero-etapas::-webkit-scrollbar-thumb:hover { background: var(--texto-tenue); }
.tablero-columna {
  /* Altura mínima para que una columna vacía SIGA siendo un destino donde
     soltar: con la altura de su contenido, una columna sin nadie medía 100 px
     y arrastrar una tarjeta a su altura la dejaba caer fuera. */
  flex: 0 0 300px; min-height: 340px; scroll-snap-align: start;
  background: var(--bg-sidebar); border: 1px solid var(--borde);
  border-radius: 12px; padding: 10px;
}
.tablero-columna.vacia { opacity: .72; }
.tablero-cabecera {
  display: flex; align-items: center; gap: 8px; margin: -10px -10px 10px;
  padding: 10px; border-radius: 12px 12px 0 0;
  /* Se queda arriba al bajar por la página, y con fondo propio: sin él, el
     nombre de la etapa se leía encima de la tarjeta que iba pasando. */
  position: sticky; top: 0; z-index: 2; background: var(--bg-sidebar);
  border-bottom: 1px solid var(--borde);
}
.tablero-titulo { font-size: 13.5px; font-weight: 700; line-height: 1.2; }
/* La pila ocupa lo que queda de la columna: así todo el hueco vacío de debajo
   de la última tarjeta también acepta que se suelte ahí. */
.tablero-pila { display: flex; flex-direction: column; gap: 12px; min-height: 260px; }
/* La tarjeta ya no vive en una rejilla: dentro de la columna ocupa el ancho. */
.tablero-pila .cliente-card { width: 100%; }
.tablero-vacia { margin: 6px 2px; font-size: 12px; color: var(--texto-tenue); }
/* Arrastrar una tarjeta a otra columna. La que se lleva se ve a medias y la
   columna que recibe se marca: sin eso no se sabe dónde se va a soltar. */
/* `pan-y`: el desplazamiento vertical se lo queda el navegador (es suyo) y el
   gesto horizontal es el que mueve la tarjeta. Con `none` se perdia el scroll
   de la pagina al pasar el dedo por encima de una tarjeta. */
.tablero-pila .cliente-card[data-cliente] { cursor: grab; touch-action: pan-y; }
.tablero-pila .cliente-card.arrastrando { opacity: .6; cursor: grabbing;
  position: relative; z-index: 5; box-shadow: var(--sombra-grande); }
.tablero-columna.destino { outline: 2px dashed var(--azul); outline-offset: 2px; }
.tablero-columna.destino .tablero-cabecera { color: var(--azul); }
@media (max-width: 820px) {
  /* En el móvil la columna se estrecha para que se intuya la siguiente: si
     ocupa la pantalla entera, nadie descubre que hay más a la derecha. */
  .tablero-columna { flex-basis: 84vw; }
}

/* Etiquetas que se marcan (configuración de avisos, 23/09/2026).
   El aspecto va en el `span` y no en el `label`: `:has()` no lo soporta todavía
   todo el mundo, y `input:checked + span` funciona en cualquier navegador. La
   casilla se queda en el DOM (no `display:none`) para que siga llegándole el
   foco del teclado. */
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip { display: inline-flex; position: relative; cursor: pointer; }
.chip input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }
.chip > span { display: inline-block; padding: 3px 9px; border-radius: 999px;
               border: 1px solid var(--borde); background: var(--bg-content);
               font-size: 12px; line-height: 1.4; color: var(--texto-tenue);
               transition: background .12s ease, color .12s ease, border-color .12s ease; }
.chip:hover > span { border-color: var(--azul); color: var(--texto); }
.chip input:focus-visible + span { outline: 2px solid var(--azul); outline-offset: 2px; }
.chip input:checked + span { background: var(--marca-solido); border-color: transparent;
                             color: #fff; font-weight: 600; }
.chip input:checked:hover + span { filter: brightness(1.08); }
.chip input:active + span { transform: scale(.97); }
.chip input:disabled + span { opacity: .5; cursor: not-allowed; }
/* Sin nada elegido la celda se quedaría vacía y no se entendería: lo dice la
   plantilla con palabras, no un `::after` que dependa de `:has()`. */
.chips-nadie { align-self: center; font-size: 11.5px; color: var(--texto-tenue);
               font-style: italic; }
.chips-mas { display: inline-block; }
.chips-mas > summary { display: inline-block; cursor: pointer; padding: 3px 9px;
                       border-radius: 999px; border: 1px dashed var(--borde);
                       font-size: 12px; color: var(--azul); list-style: none; }
.chips-mas > summary::-webkit-details-marker { display: none; }
.chips-mas > summary:hover { border-color: var(--azul); background: var(--azul-fondo); }
.chips-mas > summary:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }
.chips-mas[open] > summary { color: var(--texto-tenue); }
.chips-mas[open] > .chips { margin-top: 6px; }

/* En el móvil la tabla de avisos se desplazaba en horizontal y las columnas de
   Roles y Personas quedaban FUERA de la pantalla: el control existía pero no se
   podía usar. Aquí cada fila pasa a ser un bloque con su rótulo. */
@media (max-width: 820px) {
  .tabla-avisos thead { display: none; }
  .tabla-avisos, .tabla-avisos tbody, .tabla-avisos tr, .tabla-avisos td { display: block; width: 100%; }
  .tabla-avisos tr { border: 1px solid var(--borde); border-radius: 10px; padding: 8px 10px;
                     margin-bottom: 10px; }
  .tabla-avisos td { border: 0; padding: 6px 0; }
  .tabla-avisos td[data-col]:not(.celda-pieza)::before {
    content: attr(data-col); display: block; font-size: 10.5px; text-transform: uppercase;
    letter-spacing: .04em; color: var(--texto-tenue); margin-bottom: 4px; }
}
/* La tarjeta entera es un enlace: al pasar por encima, el paso de ahora
   responde también, para que se vea que se pulsa. En reposo va en índigo y al
   pasar por encima pasa al azul de marca —el mismo de los botones—, que es el
   color con el que esta aplicación dice «esto se pulsa». Se pone el color a
   mano y no un `filter`: en tema oscuro la píldora es clara con letra oscura,
   y aclararla no se notaba. */
.cliente-card:hover .paso3-ahora, .cliente-card:focus-within .paso3-ahora {
  background: var(--marca-solido); color: #fff;
}
.cliente-card:hover .paso3-barra > span,
.cliente-card:focus-within .paso3-barra > span { background: var(--marca-solido); }
.cliente-card:hover .paso3-lado { border-color: var(--texto-tenue); }

/* Carpetas de la pestaña Clientes (Downsell y las que cree el equipo). */
.carpeta-clientes > summary { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* El botón que abre la ventana de «Nueva carpeta». Discreto: es algo que se
   hace una vez cada mucho, no una acción principal de la pantalla. */
.carpeta-nueva-boton { display: inline-flex; align-items: center; gap: 6px; margin: 4px 0 8px; }
.carpeta-nueva-boton svg { width: 16px; height: 16px; }
.carpeta-nueva input[type="text"] { max-width: 340px; }

/* Comentarios con foto y con gente etiquetada (23/09/2026). */
.comentario-foto { display: inline-block; margin-top: 8px; }
.comentario-foto img { max-width: 260px; max-height: 260px; border-radius: 10px;
                       border: 1px solid var(--borde); display: block; }
.comentario-acciones { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.comentario-adjuntar { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; }
.comentario-adjuntar input[type="file"] { max-width: 210px; font-size: 12px; }
.comentario-etiquetar { flex: 1; min-width: 180px; }
.mencion { background: var(--azul-fondo); color: var(--azul); border-radius: 5px;
           padding: 0 4px; font-weight: 600; }

/* Grupos de Mensajes. */
.grupo-nuevo { margin: 10px 8px 4px; }
.grupo-nuevo > summary { cursor: pointer; font-size: 13.5px; color: var(--azul); }
.grupo-nuevo form { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.grupo-gente { display: flex; flex-direction: column; gap: 4px; max-height: 190px;
               overflow: auto; border: 1px solid var(--borde); border-radius: 8px; padding: 8px; }

/* Foto, descripción y datos de un grupo de Mensajes (23/09/2026). Los colores
   salen de los tokens para que el tema oscuro no deje un cuadro blanco. */
.grupo-avatar, .avatar-chat { width: 46px; height: 46px; border-radius: 50%;
                object-fit: cover; flex: none; border: 1px solid var(--borde); }
.grupo-avatar.mini, .avatar-chat { width: 28px; height: 28px; }
.grupo-avatar.sin-foto, .avatar-chat.sin-foto {
                         display: inline-flex; align-items: center; justify-content: center;
                         background: var(--azul-fondo); color: var(--marca-texto);
                         font-size: 15px; font-weight: 700; letter-spacing: .5px; }
.grupo-avatar.mini.sin-foto, .avatar-chat.sin-foto { font-size: 11px; }
/* Dentro de la fila elegida el fondo es sólido: con `--azul-fondo` las
   iniciales desaparecían sobre el azul. */
.cl-item.activo .grupo-avatar.sin-foto,
.cl-item.activo .avatar-chat.sin-foto { background: rgba(255, 255, 255, .24); color: #fff; }
.grupo-cab { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
             margin-bottom: 10px; }
.grupo-desc { margin: 2px 0 0; font-size: 13.5px; color: var(--texto-tenue); }
.grupo-editar { margin: 0 0 12px; }
.grupo-editar > summary { cursor: pointer; font-size: 13.5px; color: var(--azul); }
.grupo-editar form { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 0;
                     max-width: 420px; }
