/* ═══════════════════════════════════════════════════════════════════════════════════════════
   ESTE ARCHIVO SE SIRVE TAL CUAL AL NAVEGADOR. NO PASA POR NINGUN BUNDLER.
   ═══════════════════════════════════════════════════════════════════════════════════════════

   Fuente: cuatro constantes concatenadas EN ESTE ORDEN (la cascada de CSS importa: lo que viene
   despues gana en un empate de especificidad):

     1. ESTILOS_PANEL   (functions/_lib/panel-chrome.js)          el chrome del panel, compartido
     2. ESTILOS_LEADZ    (functions/_lib/leadz-vistas.js)          el CRM: pipeline, ficha, inbox...
     3. CSS_TELEFONIA    (functions/_lib/leadz-telefono-ui.js)     el modal de marcar y el softphone
     4. CSS_ALERTA_CITA  (functions/_lib/vista-leadz-alerta-cita.js) el modal de videollamada

   Las cuatro se HORNEABAN inline en el <head> de cada HTML que emitia el cascaron (cascaronLeadz,
   leadz-vistas.js), nunca se cacheaban, y sumaban mas de 100 KB de los 397 KB de un cascaron
   vacio. Ahora viven aqui, servidas con `?v=<hash>` y cache-control immutable (public/_headers).
   Las cuatro constantes de origen se QUEDAN exportadas como texto (las sigue usando este mismo
   archivo generado y el harness de rasterizado, scripts/leadz-render-harness.mjs, que escribe
   HTML a disco para abrirlo sin servidor); lo que cambio es que el cascaron ya no las hornea, sino
   que emite `<link rel="stylesheet">` apuntando aqui.

   `extraCss` de cada vista (el CSS chico y propio de una sola pantalla) sigue inline en un
   `<style>` despues de este `<link>`: no vale la pena versionarlo aparte, y sigue cambiando con
   cada vista.

   Este archivo es EL TEXTO YA EVALUADO de las cuatro constantes, no una copia escrita a mano:
   se genero importando los cuatro modulos de origen y concatenando los valores reales.

   SIN DATOS, SIN SECRETOS: /leadz/* vive fuera de /app/*, o sea fuera de Cloudflare Access.
   Cualquiera con la URL puede leer este archivo. Es CSS, nada de un lead.

   ⚠️ VERSION_LEADZ_CSS (functions/_lib/leadz-estaticos.js) ES CACHE-BUSTING, NO ADORNO. Si editas
   cualquiera de las cuatro constantes de origen y no regeneras este archivo (y subes esa
   constante), el navegador del asesor se queda con el estilo viejo cacheado un año (immutable).
   El selftest (scripts/leadz-estaticos-selftest.mjs) compara el hash de este archivo contra la
   constante y se pone en ROJO si no coinciden.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

  :root {
    --border: rgba(10, 10, 10, .10);
    --r-chip: 6px; --r-control: 8px; --r-input: 10px; --r-btn: 10px; --r-card: 12px; --r-pill: 999px;
    --shadow-sm: 0 0 0 1px rgba(10,10,10,.04), 0 1px 2px rgba(10,10,10,.06);
    --bg: #FFFFFF; --surface: #FFFFFF; --surface-2: #F9FAFB;
    --text: #0A0A0A; --text-muted: #737373; --accent: #0A0A0A;
    --danger: #B91C1C;
  }
  [data-ds-theme="dark"] {
    --border: rgba(255,255,255,.10);
    --bg: #0A0A0A; --surface: #161616; --surface-2: #1c1c1c;
    --text: #FFFFFF; --text-muted: #A3A3A3; --accent: #FFFFFF;
    --shadow-sm: 0 0 0 1px rgba(255,255,255,.05), 0 1px 2px rgba(0,0,0,.4);
    --danger: #F87171;
  }
  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  body { background: var(--bg); color: var(--text); font-family: 'Inter', system-ui, -apple-system, sans-serif; -webkit-font-smoothing: antialiased; }
  .wrap { max-width: 1280px; margin: 0 auto; padding: 28px 24px 64px; }
  .topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; gap: 16px; flex-wrap: wrap; }
  .zback { font-size: 13px; font-weight: 500; color: var(--text-muted); text-decoration: none; }
  .zback:hover { color: var(--text); }
  .ztools { display: flex; align-items: center; gap: 10px; }
  #zg-theme { width: 36px; height: 36px; border-radius: var(--r-control); border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  #zg-theme svg { width: 16px; height: 16px; }
  #zg-theme .zg-sun { display: none; }
  [data-ds-theme="dark"] #zg-theme .zg-moon { display: none; }
  [data-ds-theme="dark"] #zg-theme .zg-sun { display: block; }
  .eyebrow-keep { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--text-muted); }
  h1 { margin: 6px 0 24px; font-size: 28px; font-weight: 600; letter-spacing: -0.02em; }
  h2 { margin: 0 0 14px; font-size: 15px; font-weight: 600; }
  .muted { color: var(--text-muted); }
  .mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12px; }

  .zcard { border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-sm); padding: 18px; }
  .zsection { margin-top: 20px; }

  label { display: block; font-size: 12px; font-weight: 500; margin: 14px 0 6px; }
  label:first-of-type { margin-top: 0; }
  .zinput, .zta, select.zinput { width: 100%; border-radius: var(--r-input); border: 1px solid var(--border); background: var(--surface); color: var(--text); padding: 9px 12px; font-size: 13.5px; font-family: inherit; }
  .zinput { height: 38px; }
  .zta { resize: vertical; line-height: 1.6; }
  .zinput:focus, .zta:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
  .zhint { font-size: 11.5px; color: var(--text-muted); margin-top: 5px; }

  /* gap y no un margen en el glifo: .zbtn es inline-flex, y en flex el espacio entre dos
     hijos -el que uno escribe como " " en ICONS.wa + espacio + Enviar- COLAPSA. El boton salia con el
     glifo pegado a la palabra. Se vio rasterizando; en el HTML el espacio esta y parece correcto.
     Va aqui, en el componente, y no en .lz-glifo: los contenedores que ya traen su propio gap
     (.lz-do, 8px) lo sumarian a un margen y separarian de mas. */
  .zbtn { height: 38px; padding: 0 16px; border-radius: var(--r-btn); border: 1px solid var(--border); background: var(--surface); color: var(--text); font-size: 13px; font-weight: 500; font-family: inherit; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 7px; }
  .zbtn:hover { background: var(--surface-2); }
  .zbtn--pri { background: var(--accent); color: var(--bg); border-color: var(--accent); }
  .zbtn[disabled] { opacity: .45; cursor: not-allowed; }
  .zrow { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 18px; }

  table { width: 100%; border-collapse: collapse; margin-top: 8px; }
  th { text-align: left; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); font-weight: 500; padding: 8px 10px; border-bottom: 1px solid var(--border); }
  td { padding: 10px; border-bottom: 1px solid var(--border); font-size: 13px; vertical-align: top; }
  td a { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--border); }
  td a:hover { border-bottom-color: var(--accent); }

  .badge { display: inline-block; padding: 2px 8px; border-radius: var(--r-pill); border: 1px solid var(--border); font-size: 11px; font-family: 'JetBrains Mono', ui-monospace, monospace; }
  .badge--on { background: var(--accent); color: var(--bg); border-color: var(--accent); }
  .badge--mal { color: var(--danger); border-color: currentColor; }

  .zaviso { border: 1px solid var(--border); border-radius: var(--r-card); padding: 12px 14px; font-size: 13px; margin-bottom: 20px; background: var(--surface-2); }
  .zalert { border: 1px solid var(--danger); color: var(--danger); border-radius: var(--r-card); padding: 12px 14px; font-size: 13px; margin-bottom: 20px; }
  .zfoot { margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 14px; color: var(--text); }
  .zfoot svg { width: 78px; height: 19px; }

  /* 'hidden' GANA SIEMPRE, y esto es un arreglo de raiz, no una preferencia de estilo.
     El atributo 'hidden' del navegador vale 'display:none', pero con especificidad de elemento:
     CUALQUIER regla de clase que declare su propio 'display' le gana y el elemento se ve igual.
     Eso ya salio en produccion: '.lz-comp-cita { display:flex }' dejaba la barra de cita del
     compositor visible y vacia, con su X, sobre cada conversacion.
     Hasta hoy cada sitio se defendia solo ('.lz-modal[hidden]', '.lz-sf__panel[hidden]',
     '.lz-selbar[hidden]'), lo que significa que la proxima clase con 'display' propio vuelve a
     tener el mismo bug y nadie se entera hasta verlo en pantalla. Una regla global lo cierra para
     todos, incluidos los que aun no existen.
     Va con '!important' a proposito: sin el empata en especificidad con cualquier selector de
     clase y decide el orden en la hoja, que es justo la clase de fragilidad que esto viene a
     eliminar. Si alguna vez hace falta un elemento visible ESTANDO 'hidden', no existe tal cosa:
     lo que hace falta es otro atributo. */
  [hidden] { display:none !important; }

  /* Encabezado de sección: título a la izquierda y su acción a la derecha. Vivía solo en el CSS
     del mailer, así que en las pantallas de LeadZ el botón se caía debajo del título. */
  .zcab { display:flex; align-items:baseline; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-bottom:6px; }
  .lz-yo { padding:8px 8px 12px; border-bottom:1px solid var(--border); margin-bottom:10px; }
  .lz-yo__n { font-size:12.5px; font-weight:500; line-height:1.3; }
  .lz-yo__r { font-size:11px; color:var(--muted); margin-top:1px; }
  .zcab h2 { margin:0; }
  /* ═══════════════════════════════════════════════════════════════════════════════════════════
     EL ENLACE DE TEXTO. La regla que faltaba desde el Inbox original (commit 15134c6).
     ═══════════════════════════════════════════════════════════════════════════════════════════

     QUE PASABA. Setenta y cinco anclas de las vistas de LeadZ no llevan class, y aqui no habia
     NINGUNA regla global de a. Salian en el azul por omision del navegador: fuera del Design
     System -que es monocromatico- e ilegible en el tema oscuro.

     LA DECISION, Y NO ES ESTETICA. El enlace de texto va SUBRAYADO SIEMPRE, no solo al pasar el
     cursor. En un sistema monocromatico el color no puede senalar nada, asi que el subrayado es la
     unica afordancia que queda. Quitarlo en reposo deja un enlace indistinguible del texto que lo
     rodea, que es PEOR que el azul: el azul al menos avisaba.

     LO QUE NO LLEVA SUBRAYADO ES EL CROMO -pestanas, chips, botones, el menu lateral-, porque su
     forma ya dice que se puede apretar. Eso no hace falta excluirlo a mano: esas piezas ya tienen
     su regla con text-decoration:none y un selector de clase, que gana a este por especificidad
     (.lz-snav a y .zbtn son 0-1-1 y 0-1-0 contra el 0-0-1 de aqui). Por eso esta regla va tan
     arriba y con el selector mas flojo posible: para ser la que pierde siempre que alguien haya
     decidido otra cosa a proposito.

     UNA REGLA Y NO SETENTA Y CINCO PARCHES. El problema de origen fue justamente que no habia
     regla: parchear ancla por ancla arregla las de hoy y se olvida en la numero 76.

     currentColor y no un token fijo: dentro de una burbuja de WhatsApp saliente el texto es
     claro sobre fondo oscuro, y un color fijo la volveria ilegible. Heredar es lo unico que
     funciona en las dos direcciones. */
  /* ═══════════════════════════════════════════════════════════════════════════════════════════
     EL GLIFO. La regla base que faltaba, hermana de la regla de a de aqui abajo.
     ═══════════════════════════════════════════════════════════════════════════════════════════

     Los SVG de ICON (leadz-vistas.js) no traen medidas ni color propios. Hasta hoy eso lo resolvian
     NUEVE reglas de contenedor, una por sitio; el decimo sitio -un ICONS.wa dentro de un .zbtn, en
     el boton Enviar del toque de Enfoque- no tenia la suya, y el glifo salia a tamano por omision y
     relleno negro: un blob de ~700 px tapando media pantalla, en produccion.

     ESPECIFICIDAD 0-1-0 Y A PROPOSITO. Tiene que PERDER contra las nueve reglas de contenedor, que
     son 0-1-1 (.lz-do svg) o mas: el sidebar sigue con sus 17 px, el FAB con sus 20, el
     reproductor con su relleno solido. Esta regla no decide como se ve un glifo donde alguien ya
     lo decidio; decide que pasa donde NADIE lo decidio, que es justo el caso que fallaba.

     1em y currentColor en vez de medidas fijas: asi el glifo hereda el tamano y el color del
     texto que lo acompana, que es lo que uno quiere dentro de un boton. El vertical-align
     compensa la linea base para que no empuje el texto hacia arriba. */
  .lz-glifo { width:1em; height:1em; flex:none; stroke:currentColor; fill:none;
    stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; vertical-align:-.15em; }

  a { color:inherit; text-decoration:underline; text-underline-offset:2px;
      text-decoration-thickness:1px; text-decoration-color:color-mix(in srgb, currentColor 45%, transparent); }
  a:hover { text-decoration-color:currentColor; }
  a:focus-visible { outline:1px solid currentColor; outline-offset:2px; border-radius:2px; }

  /* Layout app: sidebar fijo a la izquierda + contenido a todo el ancho (estilo Kommo) */
  .lz-app { display:flex; align-items:stretch; min-height:100vh; }
  /* z-index:2, no 'auto': en las pantallas 'pleno' (Inbox, ficha) '.lz-main--pleno' tambien es
     'position:relative', y sin esto su contenido se pintaria ENCIMA de lo que se le escapa a la
     columna hacia la derecha (el panel del softphone que sale de '.lz-side-foot', ver
     CSS_TELEFONIA en leadz-telefono-ui.js), invisible detras de la lista o del hilo. */
  .lz-side { flex:0 0 214px; width:214px; border-right:1px solid var(--border); background:var(--surface); display:flex; flex-direction:column; padding:20px 14px; position:sticky; top:0; height:100vh; box-sizing:border-box; z-index:2; }
  .lz-side-top { padding:2px 8px 20px; }
  .lz-brand { font-size:22px; font-weight:700; letter-spacing:-.02em; margin-top:5px; line-height:1; }
  .lz-snav { display:flex; flex-direction:column; gap:2px; }
  .lz-snav a { display:flex; align-items:center; gap:10px; padding:9px 11px; border-radius:var(--r-btn); font-size:13.5px; color:var(--text-muted); text-decoration:none; }
  .lz-snav a svg { width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:1.7; flex:0 0 auto; }
  .lz-snav a:hover { background:var(--surface-2); color:var(--text); }
  .lz-snav a.on { background:var(--accent); color:var(--bg); font-weight:600; }
  /* El contador del menú: inversión, nunca color. En el renglón normal es negro sobre el fondo;
     en el renglón activo (que ya está invertido) se invierte al revés, o se perdería contra su
     propio fondo. Cuando no hay pendientes el elemento NO EXISTE: un cero colgando del menú es
     ruido permanente que enseña a ignorar el contador. */
  /* EL CONTADOR, uno solo para la bandeja y para el menú, porque cuentan LO MISMO: conversaciones
     SIN RESPONDER. Antes la bandeja usaba una píldora rellena, que es el lenguaje de "no leído" de
     WhatsApp, y por eso desconcertaba: no bajaba al leer, solo al contestar. Con hairline y sin
     relleno ya no promete lo que no cumple, y "currentColor" lo deja legible igual sobre el
     renglón normal que sobre el renglón activo, que va invertido. */
  .lz-cnt { min-width:18px; height:18px; padding:0 5px; box-sizing:border-box; flex:0 0 auto;
    display:inline-flex; align-items:center; justify-content:center; border-radius:var(--r-pill);
    border:1px solid currentColor; font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:10.5px; line-height:1; }
  .lz-snav .lz-cnt { margin-left:auto; }
  .lz-side-foot { margin-top:auto; display:flex; flex-direction:column; gap:6px; padding-top:12px; border-top:1px solid var(--border); }
  .lz-main { flex:1; min-width:0; padding:26px 30px 60px; box-sizing:border-box; }

  /* La regla estrecha que vivia aqui -".lz-main p a", ".zhint a", ".muted a", con color propio y un
     border-bottom que se encendia al pasar el cursor- SE RETIRO, y las dos mitades importan:

       · COBERTURA. Solo alcanzaba a los enlaces dentro de prosa de ".lz-main". Las otras sesenta y
         pico anclas sin clase del CRM seguian en el azul del navegador. Parchear por selector
         arregla las de hoy y se olvida en la siguiente.

       · DECISION. Decidia subrayado SOLO AL PASAR EL CURSOR. La regla de arriba decide lo
         contrario y es la que manda: en un sistema monocromatico el subrayado es la unica
         afordancia que queda, y quitarlo en reposo deja el enlace indistinguible del texto.

     Y no podian convivir: "border-bottom" y "text-decoration" son dos mecanismos distintos, asi
     que juntas pintaban dos rayas. */
  /* Modo pleno (Inbox): el scroll lo hacen las columnas de adentro, no la página.
     100dvh y no 100vh porque en Safari móvil 100vh incluye la barra de direcciones y el
     compositor queda tapado; se deja 100vh de respaldo para navegadores sin dvh. */
  .lz-pleno, .lz-pleno body { height:100%; overflow:hidden; }
  .lz-main--pleno { padding:0; height:100vh; height:100dvh; overflow:hidden; position:relative; display:flex; }
  .lz-toast { position:absolute; top:14px; left:50%; transform:translateX(-50%); z-index:40; max-width:min(560px,92%); }
  .lz-toast .zaviso, .lz-toast .zalert { margin:0; box-shadow:0 8px 28px rgba(0,0,0,.18); background:var(--surface); }
  /* Segunda columna: el índice de una sección con varias pantallas (hoy, Reportes). */
  .lz-sub { flex:0 0 208px; width:208px; border-right:1px solid var(--border); background:var(--bg); padding:22px 12px; position:sticky; top:0; height:100vh; box-sizing:border-box; overflow-y:auto; }
  .lz-sub h3 { margin:0 0 12px; padding:0 9px; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-muted); font-weight:500; }
  .lz-sub a { display:block; padding:9px 10px; border-radius:var(--r-btn); font-size:13px; color:var(--text-muted); text-decoration:none; line-height:1.35; }
  .lz-sub a:hover { background:var(--surface-2); color:var(--text); }
  .lz-sub a.on { background:var(--surface-2); color:var(--text); font-weight:600; }
  .lz-sub a small { display:block; font-size:11px; font-weight:400; color:var(--text-muted); margin-top:1px; }
  .lz-sub a.on small { color:var(--text-muted); }
  @media (max-width:820px){
    .lz-app { flex-direction:column; }
    .lz-side { position:static; height:auto; width:auto; flex:none; flex-direction:row; align-items:center; gap:12px; padding:10px 16px; overflow-x:auto; }
    .lz-side-top { padding:0; white-space:nowrap; }
    .lz-side-top .eyebrow-keep { display:none; }
    .lz-brand { font-size:17px; margin:0; }
    .lz-snav { flex-direction:row; gap:2px; }
    .lz-side-foot { margin:0 0 0 auto; flex-direction:row; align-items:center; border-top:0; padding-top:0; }
    .lz-main { padding:18px 16px 48px; }
    .lz-sub { position:static; height:auto; width:auto; flex:none; border-right:0; border-bottom:1px solid var(--border); padding:10px 12px; display:flex; gap:6px; overflow-x:auto; align-items:center; }
    .lz-sub h3 { margin:0; padding:0 6px 0 0; white-space:nowrap; }
    .lz-sub a { white-space:nowrap; padding:7px 10px; }
    .lz-sub a small { display:none; }
  }

  .znav { display:flex; gap:4px; border-bottom:1px solid var(--border); margin:0 0 24px; flex-wrap:wrap; }
  .znav a { padding:9px 14px; font-size:13.5px; color:var(--text-muted); text-decoration:none; border-bottom:2px solid transparent; margin-bottom:-1px; }
  .znav a:hover { color:var(--text); }
  .znav a.on { color:var(--text); font-weight:600; border-bottom-color:var(--accent); }

  .lz-metrics { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:22px; }
  @media (max-width:720px){ .lz-metrics { grid-template-columns:repeat(2,1fr); } }
  .lz-stat { border:1px solid var(--border); border-radius:var(--r-card); background:var(--surface); box-shadow:var(--shadow-sm); padding:14px 16px; }
  .lz-stat b { display:block; font-size:24px; font-weight:700; letter-spacing:-.02em; }
  .lz-stat span { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-muted); }

  .lz-board { display:flex; gap:12px; overflow-x:auto; padding-bottom:10px; }
  .lz-col { flex:0 0 262px; background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r-card); padding:10px; }
  .lz-col > h3 { margin:2px 4px 10px; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted); display:flex; justify-content:space-between; align-items:center; }
  .lz-col > h3 .c { color:var(--text); }
  .lz-lead { background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:10px 11px; margin-bottom:8px; box-shadow:var(--shadow-sm); }
  .lz-lead .nm { font-weight:600; font-size:13.5px; color:var(--text); text-decoration:none; }
  .lz-lead .nm:hover { text-decoration:underline; }
  .lz-lead .mt { font-size:11.5px; color:var(--text-muted); margin-top:2px; }
  .lz-lead .rowq { display:flex; align-items:center; gap:6px; margin-top:9px; }
  .lz-ico { width:30px; height:30px; border-radius:8px; border:1px solid var(--border); background:var(--surface); color:var(--text); display:inline-flex; align-items:center; justify-content:center; text-decoration:none; }
  .lz-ico:hover { background:var(--surface-2); }
  .lz-ico svg { width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:1.6; }
  /* El asesor en la tarjeta es TEXTO, no un select: cambiar de owner ahora es cosa de la ficha
     únicamente (perfilado.B). */
  .lz-lead .asesor { font-size:11.5px; color:var(--text-muted); margin-top:6px; }
  .lz-lead .lz-perfil-toggle-f { margin-top:8px; }
  .lz-count { font-family:'JetBrains Mono',monospace; font-size:10.5px; color:var(--text-muted); border:1px solid var(--border); border-radius:var(--r-pill); padding:1px 7px; }
  .lz-lead[draggable="true"] { cursor:grab; }
  .lz-lead.dragging { opacity:.4; }
  .lz-col.dragover { border-color:var(--accent); background:var(--surface); }
  .lz-lead .meta2 { display:flex; align-items:center; gap:7px; flex-wrap:wrap; margin-top:7px; }
  .lz-src { font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.05em; text-transform:uppercase; border:1px solid var(--border); border-radius:var(--r-chip); padding:1px 6px; color:var(--text-muted); white-space:nowrap; }
  .lz-owner { font-size:11px; color:var(--text); white-space:nowrap; }
  .lz-date { font-family:'JetBrains Mono',monospace; font-size:10px; color:var(--text-muted); margin-left:auto; }
  .lz-notask { font-size:10.5px; color:var(--text-muted); }

  /* Estados terminales: zonas para arrastrar y marcar Ganado / Perdido (estilo ActiveCampaign) */
  .lz-dz-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:18px; }
  .lz-dz { border:1px dashed var(--border); border-radius:var(--r-card); padding:13px 16px; text-align:center; color:var(--text-muted); transition:border-color .12s, background .12s; }
  .lz-dz b { display:block; font-size:13px; color:var(--text); font-weight:600; }
  .lz-dz span { font-size:11.5px; }
  .lz-dz.dzover { border-style:solid; }
  .lz-dz--won.dzover { border-color:#16a34a; background:rgba(22,163,74,.09); color:#16a34a; }
  .lz-dz--won.dzover b { color:#16a34a; }
  .lz-dz--lost.dzover { border-color:#dc2626; background:rgba(220,38,38,.09); color:#dc2626; }
  .lz-dz--lost.dzover b { color:#dc2626; }
  /* MODALES — una sola definición para toda la app, y UNA sola convención para abrirlos:
     el atributo "hidden". Todo modal nace con hidden en el HTML y el JS lo quita.
     Por qué está escrito aquí y no en el CSS de cada pantalla: había DOS definiciones de
     .lz-modal (esta y una en el CSS del pipeline) con la misma especificidad. La que se
     emitía después ganaba, y como el cascarón pone el CSS de la pantalla al final, el
     pipeline volvía visible por defecto un modal que el resto de la app daba por cerrado.
     El modal de "marcar perdido" quedaba tapando el tablero sin lead seleccionado (24 ago).
     Si algún día hace falta un estilo propio de modal en una pantalla, va con OTRO nombre
     de clase — nunca redefiniendo .lz-modal. */
  .lz-modal { position:fixed; inset:0; background:rgba(0,0,0,.45); display:flex; align-items:center; justify-content:center; z-index:9000; padding:20px; }
  .lz-modal[hidden] { display:none; }
  .lz-modal .box, .lz-modal__box { background:var(--surface); color:var(--text); border:1px solid var(--border); border-radius:var(--r-card); padding:20px 22px; width:min(420px,94vw); box-shadow:0 24px 48px rgba(0,0,0,.28); }
  .lz-modal .box h3, .lz-modal__box h3 { margin:0 0 12px; font-size:16px; }
  .lz-modal__box p { font-size:13px; line-height:1.55; margin:0 0 10px; }
  .lz-modal__acc { display:flex; gap:8px; justify-content:flex-end; margin-top:16px; }

  /* Modo enfoque */
  .lz-focus { max-width:600px; margin:0 auto; }
  .lz-focus .prog { text-align:center; font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-muted); margin-bottom:14px; }
  .lz-focus .who { font-size:26px; font-weight:600; letter-spacing:-.02em; }
  .lz-focus .sub { color:var(--text-muted); font-size:13.5px; margin-top:2px; }
  .lz-do { display:flex; gap:10px; margin:20px 0; }
  .lz-do a { flex:1; height:52px; border-radius:var(--r-btn); border:1px solid var(--accent); background:var(--accent); color:var(--bg); font-weight:600; font-size:15px; display:inline-flex; align-items:center; justify-content:center; gap:8px; text-decoration:none; }
  .lz-do a.ghost { background:var(--surface); color:var(--text); border-color:var(--border); }
  .lz-do svg { width:18px; height:18px; stroke:currentColor; fill:none; stroke-width:1.7; }
  .lz-actions { display:grid; grid-template-columns:repeat(2,1fr); gap:8px; }
  .lz-out { height:44px; border-radius:var(--r-btn); border:1px solid var(--border); background:var(--surface); color:var(--text); font-size:14px; font-weight:500; font-family:inherit; cursor:pointer; }
  .lz-out:hover { background:var(--surface-2); border-color:var(--accent); }
  .lz-out--stop { }
  .lz-extra { margin-top:12px; display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  .lz-skip { text-align:center; margin-top:16px; }

  .lz-time { list-style:none; padding:0; margin:8px 0 0; }
  .lz-time li { border-left:1px solid var(--border); padding:0 0 14px 14px; position:relative; }
  .lz-time li::before { content:""; position:absolute; left:-4px; top:4px; width:7px; height:7px; border-radius:50%; background:var(--text-muted); }
  .lz-time .t { font-size:13px; }
  .lz-time .d { font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--text-muted); }
  .lz-chip { display:inline-block; font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.05em; text-transform:uppercase; padding:2px 7px; border:1px solid var(--border); border-radius:var(--r-pill); color:var(--text-muted); }
  .lz-two { display:grid; grid-template-columns:1.4fr 1fr; gap:18px; align-items:start; }
  @media (max-width:860px){ .lz-two { grid-template-columns:1fr; } }
  .lz-blk { margin-bottom:18px; }
  .lz-blk h2 .lz-count { margin-left:8px; }
  .lz-inline { display:flex; gap:8px; align-items:flex-end; flex-wrap:wrap; }
  .lz-inline > * { margin:0; }
  .zgrid { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
  @media (max-width:720px){ .zgrid { grid-template-columns:1fr; } }

  /* ==== La burbuja de WhatsApp ========================================================
     Compartida entre el Inbox y la ficha del lead, porque burbuja() (vista-leadz-inbox.js) es
     UNA sola plantilla y la usan las dos pantallas. Vivía privada en el CSS del Inbox y la
     conversación de la ficha salía sin estilo: markup compartido, CSS compartido. */
  .lz-ibx-dia { align-self:center; margin:14px 0 10px; flex:0 0 auto; }
  .lz-ibx-dia span { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-muted); background:var(--bg); border:1px solid var(--border); border-radius:var(--r-pill); padding:3px 11px; }
  /* flex:0 0 auto es obligatorio: con un espaciador en flex:1 arriba (el que pega los hilos
     cortos abajo), las burbujas se aplastarían en cuanto el hilo desborde el alto del feed. */
  .lz-bb { position:relative; flex:0 0 auto; max-width:min(560px,78%); padding:8px 12px; border-radius:14px; font-size:13.5px; line-height:1.45; word-wrap:break-word; overflow-wrap:anywhere; }
  .lz-bb-tx { white-space:pre-wrap; }
  .lz-bb-mt { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.03em; margin-top:4px; text-align:right; opacity:.7; }
  .lz-bb--in { align-self:flex-start; background:var(--surface); border:1px solid var(--border); border-bottom-left-radius:4px; }
  .lz-bb--out { align-self:flex-end; background:var(--accent); color:var(--bg); border-bottom-right-radius:4px; }
  .lz-bb--out .lz-bb-rc { opacity:.55; }
  .lz-bb--out .lz-bb-rc.on { opacity:1; }
  /* El microfono del recibo "escuchada". Va pegado a las palomitas y a su misma altura: el recibo
     es UNA cosa que se lee de un golpe, no un icono y unas palomitas que se miran por separado.
     El tamano sale de la caja del recibo (en em sobre el 9px de .lz-bb-mt), no de un numero
     suelto, que es lo que hace que siga cuadrando si algun dia cambia esa tipografia. */
  .lz-bb-rc { display:inline-flex; align-items:center; gap:3px; }
  .lz-bb-rc .lz-glifo { width:1.15em; height:1.15em; stroke-width:2.2; }
  .lz-bb--err { align-self:flex-end; background:var(--surface); color:var(--danger); border:1px solid var(--danger); }
  /* La burbuja de SISTEMA (un aviso de Meta: hoy solo "cambió de número"). No la escribió el lead
     ni la empresa, asi que no va ni a la izquierda ni a la derecha: se centra, como el separador
     de dia, que es el precedente que ya existe para "esto paso y no lo dijo nadie". Toma prestados
     sus mismos tokens -el mono chico, el borde hairline, el pill- para que se lean como la misma
     familia y no como una burbuja descolorida. */
  /* ⚠️ display:block Y LA HORA EN LINEA, no un flex con align-items:baseline. Con el flex, en
     cuanto el texto ocupaba dos renglones la hora se quedaba clavada en la linea base del PRIMERO,
     flotando a media burbuja y leyendose como parte de la frase. Se vio rasterizando; ninguna
     asercion lo alcanzaba. En el flujo normal la hora va donde va: detras de lo ultimo que se lee.
     El radio de 13px y no pill: con dos renglones, un pill se convierte en un ovalo. */
  .lz-bb--sis { align-self:center; max-width:min(560px,92%); display:block; padding:6px 14px; background:var(--bg); border:1px solid var(--border); border-radius:13px; text-align:center; }
  /* ⚠️ Y overflow-wrap:normal, QUE ANULA EL "anywhere" DE .lz-bb. Heredado, partia el telefono
     a media linea ("+1 (902) 877-" / "5090"), y el telefono es justo el dato de este aviso. Los dos
     numeros van ademas en nowrap (ver burbuja() en vista-leadz-hilo.js), porque el salto despues
     del guion es la regla normal del navegador y overflow-wrap no lo impide. */
  .lz-bb-sis-tx { font-size:11.5px; line-height:1.45; color:var(--text-muted); overflow-wrap:normal; word-break:normal; hyphens:none; }
  .lz-bb-sis-n { white-space:nowrap; }
  .lz-bb-sis-h { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.03em; color:var(--text-muted); opacity:.7; margin-left:7px; white-space:nowrap; }
  .lz-bb--err .lz-bb-mt { opacity:1; }
  /* El motivo del fallo, dentro de la burbuja. Va en ESTILOS_LEADZ y no en el CSS del Inbox por lo
     mismo que el resto de .lz-bb: burbuja() es UNA función, y la ficha del lead pinta el mismo
     hilo. overflow-wrap porque un mensaje de Meta trae identificadores largos sin espacios. */
  .lz-bb-err { margin-top:6px; padding-top:6px; border-top:1px solid currentColor; font-size:11.5px;
    line-height:1.45; opacity:.85; overflow-wrap:anywhere; }
  /* Más tenue y en cursiva porque NO es un motivo: es la constancia de que no lo hubo. Si se viera
     igual que un motivo real, la distinción que esta línea existe para hacer se perdería. */
  .lz-bb-err--sin { font-style:italic; opacity:.55; }
  .lz-bb.nueva { animation:lzEntra .18s ease-out; }
  @keyframes lzEntra { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }

  /* ---- Citar (lote 2 de la pista conversacional) --------------------------------------------
     Patrón para lo que sigue (reaccionar, adjuntos, la burbuja de transcripción): un botón de
     acción sobre la burbuja es un hijo más de ".lz-bb-acc", nunca un contenedor aparte. Y toda
     acción tiene DOS caminos: uno JS (bonito, aquí puebla el compositor) y uno de <form> real que
     funciona solo (aquí, un <details> por burbuja). ".lz-feed-js" es la bandera que pone el JS del
     Inbox (JS_INBOX) cuando SÍ hay a dónde mandar la cita bonita: sin ella (como en la ficha del
     lead, que no trae ese JS) gana el <details>, que manda por la misma puerta de siempre. */
  .lz-bb-acc { display:none; position:absolute; top:-10px; gap:3px; z-index:1; }
  .lz-feed-js .lz-bb-acc { display:flex; opacity:0; transition:opacity .12s; }
  .lz-bb--in .lz-bb-acc { left:8px; }
  .lz-bb--out .lz-bb-acc { right:8px; }
  .lz-bb:hover .lz-bb-acc, .lz-bb:focus-within .lz-bb-acc { opacity:1; }
  .lz-bb-act { width:22px; height:22px; padding:0; border-radius:50%; border:1px solid var(--border);
    background:var(--surface); color:var(--text-muted); display:inline-flex; align-items:center;
    justify-content:center; cursor:pointer; box-shadow:var(--shadow-sm); }
  .lz-bb-act:hover { color:var(--text); border-color:var(--text-muted); }
  .lz-bb-act svg { width:12px; height:12px; stroke:currentColor; fill:none; }

  .lz-bb-cita { display:block; margin:0 0 6px; padding:5px 8px; border-left:2px solid currentColor;
    border-radius:6px; background:color-mix(in srgb, currentColor 12%, transparent); font-size:11.5px;
    line-height:1.35; opacity:.85; text-decoration:none; color:inherit; cursor:pointer; }
  .lz-bb-cita:hover { opacity:1; }
  /* Sin match en el mapa de citadosPorWaId: no hay a dónde saltar, así que no es un enlace. */
  .lz-bb-cita--sin { font-style:italic; opacity:.6; cursor:default; }
  /* El destello del salto al original. Gris y no verde/azul: monocromático (ZR-05), y además así
     no se confunde con ".nueva" (burbuja recién llegada), que es un aviso distinto. */
  .lz-bb--flash { animation:lzFlash 1.1s ease-out; }
  @keyframes lzFlash { 0% { box-shadow:0 0 0 2px var(--text) inset; } 100% { box-shadow:0 0 0 2px transparent inset; } }

  /* El <details> sin JS. Vive SIEMPRE en el HTML; ".lz-feed-js" lo apaga donde el botón de arriba
     ya hace el mismo trabajo mejor. Sin esa clase (la ficha del lead) es la única forma de citar. */
  .lz-bb-rf { margin-top:6px; }
  .lz-feed-js .lz-bb-rf { display:none; }
  .lz-bb-rf > summary { cursor:pointer; font-size:11px; opacity:.6; list-style:none; }
  .lz-bb-rf > summary::-webkit-details-marker { display:none; }
  .lz-bb-rf > summary:hover, .lz-bb-rf[open] > summary { opacity:1; }
  .lz-bb-rf-in { display:flex; gap:6px; margin-top:6px; }
  .lz-bb-rf-in input[name="texto"] { flex:1; min-width:0; height:28px; font-size:12px; }
  .lz-bb-rf-in .zbtn { height:28px; padding:0 10px; font-size:11.5px; }
  .lz-bb-rf-in select[name="emoji"] { flex:1; min-width:0; height:28px; font-size:16px; }

  /* ---- Reaccionar (lote 3 de la pista conversacional) ---------------------------------------
     ⚠️ FRONTERA DE EMOJIS: esta burbuja (.lz-ibx-feed en el Inbox, .lz-wa2-feed en la ficha del
     lead) es el ÚNICO lugar del CRM donde un emoji es CONTENIDO, no chrome. Fuera de la ventana
     de conversación manda el design system: SVG, nunca emoji. No copies ".lz-bb-act--rx" ni
     ".lz-bb-rx-c" a otra pantalla sin releer esto.
     Seis botones fijos (no configurables) conviven con "Responder" dentro del MISMO ".lz-bb-acc":
     un contenedor de acciones sobre la burbuja, no dos. */
  .lz-bb-act--rx { font-size:13px; line-height:1; }
  /* Las reacciones YA puestas, agrupadas por emoji: como en WhatsApp, la pastilla se MONTA sobre
     la burbuja, medio encimada en la esquina inferior, del lado que le toca segun la direccion
     (".lz-bb--in" izquierda, ".lz-bb--out" derecha, mismo patron que ".lz-bb-acc" arriba). No es
     un renglon aparte debajo del mensaje -por eso "position:absolute" y no el viejo
     "margin-top:4px"-, asi que sale del flujo y hay que devolverle el espacio a mano: ver la
     regla ".lz-bb:has(.lz-bb-rx)" de abajo.
     "pointer-events:none" porque la pastilla es solo lectura (las seis acciones de reaccionar
     viven en ".lz-bb-acc", aparte); sin esto, en la esquina de una foto o de la tarjeta de
     documento la pastilla se interponia al hacer clic justo donde queda encimada.
     Como mucho hay dos autores por conversación (el lead y el número de la empresa, ver
     reaccionesPorWaId), así que el número solo aparece cuando los dos coincidieron. */
  .lz-bb-rx { position:absolute; bottom:-7px; display:flex; gap:4px; z-index:1; pointer-events:none; }
  .lz-bb--in .lz-bb-rx { left:6px; }
  .lz-bb--out .lz-bb-rx { right:6px; }
  /* Al salir del flujo, la pastilla ya no empuja nada: sin esto encimaria la hora y el recibo
     (".lz-bb-mt") en cuanto la burbuja fuera corta, tapando justo lo que no debe. Sube el
     padding de abajo SOLO cuando hay reacciones (nunca cuando no las hay) y agrega un poco de
     margen fuera de la burbuja para que la mitad de la pastilla que cuelga del borde no se
     encime con la burbuja siguiente (el feed las separa con "gap:3px", que solo no alcanza).
     Gana por especificidad sobre ".lz-bb--md", ".lz-bb--stk" y compania -dos selectores contra
     uno- sin importar el orden en la hoja, asi que aplica igual a texto, imagen, sticker, audio
     y documento sin repetir la regla por tipo de burbuja. */
  .lz-bb:has(.lz-bb-rx) { padding-bottom:20px; margin-bottom:9px; }
  .lz-bb-rx-c { display:inline-flex; align-items:center; gap:2px; font-size:13px; line-height:1;
    background:var(--bg); border:1px solid var(--border); border-radius:var(--r-pill); padding:2px 6px;
    box-shadow:var(--shadow-sm); }
  .lz-bb--out .lz-bb-rx-c { background:color-mix(in srgb, var(--bg) 85%, transparent); }
  .lz-bb-rx-c b { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; font-weight:500; opacity:.75; }
  /* El <details> sin JS de reaccionar. Comparte ".lz-bb-rf" con el de responder (mismo apagado
     por ".lz-feed-js"; ver arriba) y suma ".lz-bb-rxf" solo por si necesita un ajuste propio. */
  .lz-bb-rxf { margin-top:2px; }

  /* ---- El archivo que manda el lead, dentro de la burbuja ----------------------------------
     ⚠️ Va AQUÍ y no en el CSS del Inbox, por lo mismo que .lz-bb: burbuja() es UNA función y la
     usan el Inbox Y la ficha del lead. Markup compartido, CSS compartido. Esto ya nos mordió una
     vez con esta misma función y la conversación de la ficha salió sin estilo en producción. */
  .lz-bb--md { padding:5px 5px 6px; max-width:min(360px,72%); }
  .lz-bb--md .lz-bb-mt { padding:0 6px; }
  /* color/text-decoration explícitos: la foto y el sticker van dentro de un <a> (abren el
     original) y sin esto el navegador les pinta su subrayado azul de liga encima del archivo. */
  .lz-bb-md { display:block; border-radius:10px; overflow:hidden; color:inherit; text-decoration:none; }
  .lz-bb-md--img img, .lz-bb-md--stk img { display:block; width:100%; height:auto; }
  /* line-height:0 en los que solo llevan imagen: sin esto el <a> deja el hueco de una línea de
     texto debajo del archivo, con su subrayado. En la tarjeta del documento NO va, que ahí sí hay
     texto y se colapsa a cero de alto (el nombre del archivo desaparece: pasó, se vio en oscuro). */
  /* width:fit-content: el <a> se ajusta a la foto ya escalada. Sin esto el ancla se estiraba a
     todo el ancho de la burbuja (que la fija el pie de foto) y dejaba una franja gris al lado del
     retrato, que es justo lo que se quería quitar. */
  .lz-bb-md--img { line-height:0; background:var(--surface-2); width:fit-content; max-width:100%; }
  .lz-bb-md--stk { line-height:0; }
  /* "contain" y no "cover", y "width:auto" a propósito. Aquí la foto entrante muy seguido ES un
     documento: una identificación, un comprobante, la captura de un estado de cuenta. "cover"
     recorta justo lo que hay que leer. WhatsApp puede permitírselo porque es un chat; LeadZ es la
     herramienta donde esa foto es el contenido. Y con "width:100%" un retrato quedaba centrado
     dentro de una caja del ancho de la burbuja, con franjas vacías a los lados: "width:auto" deja
     que la burbuja tome el ancho real de la foto ya escalada a los 340px de alto. */
  .lz-bb-md--img img { width:auto; max-width:100%; max-height:340px; object-fit:contain; }
  .lz-bb-md--vid, .lz-bb-md--gif { width:100%; max-height:340px; background:#000; }
  /* El reproductor nativo necesita ancho REAL: por debajo de ~280 px Chrome colapsa la barra de
     avance a una rayita y la nota de voz deja de poder adelantarse, que es justo lo que uno hace
     con la nota de voz de un lead. Pero "min-width:284px" a secas es un ancho que NO se encoge, y
     en una columna angosta el reproductor empujaba el hilo entero fuera de la pantalla (el mismo
     aprendizaje que el grid del Inbox, aquí dentro de la burbuja). "min(284px,100%)" pide los 284
     cuando los hay y cede cuando no. */
  .lz-bb-md--aud { width:100%; min-width:min(284px,100%); height:40px; }
  /* Los controles de <audio> y <video> los pinta el navegador, y por defecto los pinta CLAROS: en
     tema oscuro la nota de voz quedaba como una barra blanca en medio de un feed negro, que es
     exactamente el tipo de cosa que el DS monocromático no admite. color-scheme es la única
     palanca que hay sobre ese chrome nativo, y va acotada a estos elementos: aplicarla a la raíz
     cambiaría de golpe selects, scrollbars y date inputs de todas las pantallas. */
  [data-ds-theme="dark"] .lz-bb-md--aud,
  [data-ds-theme="dark"] .lz-bb-md--vid,
  [data-ds-theme="dark"] .lz-bb-md--gif { color-scheme:dark; }
  .lz-bb--md:has(.lz-bb-md--doc) { max-width:min(340px,84%); }
  /* La del audio lleva ancho DEFINIDO, no solo tope, y llega al 100% cuando hace falta:
     · Definido, porque un porcentaje se mide contra el bloque contenedor y una burbuja que se
       ajusta a su contenido no tiene ancho contra el cual medir: el min(284px,100%) de adentro se
       resolvía a cero y el reproductor se encogía a nada.
     · 100% y no 84%, porque el 84% de una columna angosta deja el reproductor por debajo de los
       ~280px que necesita, que es el problema que se quería evitar. En pantalla ancha el tope de
       340px manda igual que antes; el 100% solo entra cuando la columna ya no da para más. */
  .lz-bb--md:has(.lz-bb-md--aud) { width:min(340px,100%); max-width:100%; }

  /* ---- EL REPRODUCTOR DE LA NOTA DE VOZ (lote 5-B) ------------------------------------------
     Lo de arriba (".lz-bb-md--aud") sigue siendo el <audio> NATIVO y sigue siendo la base: sin
     JavaScript es lo unico que hay en la burbuja y tiene que seguir sirviendo. Esto de aqui es la
     mejora que JS_HILO enciende marcando la caja con ".lz-au--js" (ver montaAu): hasta que esa
     clase no esta, el reproductor bonito NO SE VE y el nativo si. Un script que no corre, o que
     corre y truena, deja la pildora del navegador en pantalla en vez de una burbuja muda.

     NI UN COLOR FIJO, y no es una formalidad: la misma nota de voz se pinta sobre burbuja normal
     y sobre burbuja INVERTIDA (".lz-bb--out" pone background:accent y color:bg), en claro y en
     oscuro. Son cuatro combinaciones. Todo lo que se dibuja aqui sale de "currentColor" -que
     dentro de ".lz-bb--out" YA es el color invertido- o de un color-mix sobre el, asi que las
     cuatro salen bien con UNA sola regla y ninguna se queda sin revisar por descuido. Por lo
     mismo el foco va en currentColor y no en var(--accent), que es el patron del resto del CRM:
     dentro de la burbuja saliente el acento ES el fondo, y el anillo desapareceria justo ahi. */
  /* display:flex y no el display:block que hereda de ".lz-bb-md": el markup del reproductor
     viene indentado, y entre el <audio> y la caja de controles quedan nodos de texto en blanco
     que en un bloque generan renglones de verdad. Medido: la burbuja salia 98px mas alta de la
     cuenta, con un hueco negro encima del reproductor. En un contenedor flex esos nodos no
     cuentan, asi que el arreglo no depende de como se indente el HTML. */
  .lz-au { display:flex; flex-direction:column; position:relative; overflow:visible; }
  .lz-au-ui { display:none; }
  .lz-au--js > .lz-bb-md--aud { display:none; }
  .lz-au--js > .lz-au-ui { display:flex; align-items:center; gap:8px; height:40px; padding:0 3px; }

  .lz-au-pp { flex:none; width:30px; height:30px; padding:0; cursor:pointer; color:inherit;
    display:inline-flex; align-items:center; justify-content:center; border-radius:var(--r-pill);
    background:color-mix(in srgb, currentColor 12%, transparent);
    border:1px solid color-mix(in srgb, currentColor 20%, transparent); }
  .lz-au-pp:hover { background:color-mix(in srgb, currentColor 22%, transparent); }
  .lz-au-pp svg { width:13px; height:13px; display:block; fill:currentColor; stroke:none; }
  /* Los dos iconos viven en el mismo boton y se turnan. Van con el selector COMPLETO
     (".lz-au-pp svg") porque esa es la regla que les da display:block: una clase suelta pierde
     por especificidad y salen los dos a la vez, con el play y la pausa uno al lado del otro.
     Pasó, se vio, y por eso esta escrito asi. */
  .lz-au-pp .lz-au-i--pausa { display:none; }
  .lz-au--son .lz-au-pp .lz-au-i--play { display:none; }
  .lz-au--son .lz-au-pp .lz-au-i--pausa { display:block; }

  /* La onda: DOS caras encimadas con la misma forma. La de abajo es la pista completa, apagada;
     la de arriba es la misma onda a plena opacidad, recortada por clip-path hasta el avance. Asi
     moverse cuesta UNA propiedad custom por cuadro (--lz-au-p) en vez de repintar 40 barras, y el
     "ya escuchado" se lee de un vistazo como en WhatsApp sin copiarle un solo color. */
  .lz-au-onda { position:relative; flex:1; min-width:0; height:26px; cursor:pointer;
    border-radius:3px; touch-action:none; }
  .lz-au-cara { position:absolute; inset:0; display:flex; align-items:center; gap:2px; }
  .lz-au-cara--base { opacity:.3; }
  .lz-au-cara--hecho { opacity:1; clip-path:inset(0 calc(100% - var(--lz-au-p, 0%)) 0 0); }
  .lz-au-cara i { flex:1 1 0; min-width:1px; height:10%; background:currentColor; border-radius:1px; }

  /* ⚠️ SIN PICOS NO HAY ONDA, Y NO SE INVENTA UNA. Mientras la caja siga en ".lz-au--lisa" -antes
     de decodificar, o porque el navegador no supo decodificar este Ogg/Opus- las barras se
     esconden y queda una barra de progreso LISA. Una onda derivada del id del mensaje se veria
     exactamente igual de bien y seria mentira: le dibujaria al asesor una forma que no
     corresponde a lo que se dijo. Lisa es honesto; inventada, no. */
  .lz-au--lisa .lz-au-cara i { display:none; }
  .lz-au--lisa .lz-au-cara::before { content:''; position:absolute; left:0; right:0; top:50%;
    height:3px; margin-top:-1.5px; background:currentColor; border-radius:2px; }

  .lz-au-t { flex:none; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px;
    letter-spacing:.02em; opacity:.72; min-width:31px; text-align:right;
    font-variant-numeric:tabular-nums; }
  /* El multiplicador: 1x, 1.5x, 2x. Es de lo mas usado de WhatsApp para oir una nota larga, y es
     un GESTO, no piel. Se ve apagado en 1x (el estado en el que no hay nada que decir) y encendido
     en cuanto deja de ser normal, que es cuando importa saberlo. */
  .lz-au-vel { flex:none; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px;
    letter-spacing:.04em; padding:2px 6px; cursor:pointer; color:inherit; opacity:.55;
    background:transparent; border-radius:var(--r-pill);
    border:1px solid color-mix(in srgb, currentColor 30%, transparent); }
  .lz-au-vel:hover { opacity:1; }
  .lz-au-vel[data-v="1.5"], .lz-au-vel[data-v="2"] { opacity:1;
    background:color-mix(in srgb, currentColor 12%, transparent); }
  /* Teclado: el boton y el multiplicador son <button> de verdad (espacio y enter salen gratis) y
     la onda es un role="slider" con tabindex, asi que los tres reciben foco. Y el foco SE VE: un
     anillo de 1px en currentColor, que es el ancho de foco del design system. */
  .lz-au-pp:focus-visible, .lz-au-vel:focus-visible, .lz-au-onda:focus-visible {
    outline:1px solid currentColor; outline-offset:2px; }

  /* ---- La transcripción de la nota de voz (lote 6b), debajo del reproductor de audio --------
     Mismo borde-arriba fino que ".lz-bb-err" (misma familia: "aviso dentro de la burbuja"), pero
     nunca en --danger: sin transcripción la nota de voz sigue sirviendo igual, así que esto es
     información de más, no un error. Los CUATRO estados se ven distinto A PROPÓSITO (invariante
     5 puesto en pantalla): "pendiente" y "sin_motor" van en cursiva porque ninguno de los dos es
     un error, y aun así se leen distinto entre sí porque dicen cosas distintas.
     EL LADRILLO ERA ESTO, no el recorte de abajo: ".lz-bb-tx" (la caja de la burbuja, dos letras
     de diferencia con ".lz-bb-tr-tx" de aquí abajo y por eso costó dos rondas verlo) pone
     "white-space:pre-wrap" para respetar los saltos de línea que sí escribió el lead. Esta caja
     vive dentro de esa burbuja y white-space se hereda: sin cortar la herencia aquí, el resumen
     y el propio bloque plegable heredaban ese "pre-wrap", y entonces la indentación y los saltos
     de línea del template literal que arma este bloque (puro espacio en blanco insignificante
     del código fuente) dejaban de colapsar y pasaban a ser renglones en blanco de verdad en
     pantalla, uno arriba del texto y otro abajo. Medido en Chrome: quitando SOLO el line-clamp
     de aquí abajo el hueco seguía igual de grande; quitando esta herencia con "white-space:normal",
     el hueco se fue por completo. */
  .lz-bb-tr { margin-top:6px; padding-top:6px; border-top:1px solid currentColor; font-size:11.5px;
    line-height:1.45; opacity:.75; white-space:normal; }
  .lz-bb-tr--pendiente, .lz-bb-tr--sinmotor { font-style:italic; opacity:.6; }
  .lz-bb-tr--fallo { opacity:.85; }
  /* El <details> de "lista": plegado por default, como pide el punto 1 del lote. Mismo patrón
     visual que ".lz-bb-rf" (el <details> sin JS de responder), sin compartir la clase porque ese
     otro se apaga con ".lz-feed-js" y este SIEMPRE se ve, con o sin JavaScript. */
  .lz-bb-tr--lista > summary { cursor:pointer; list-style:none; opacity:.85; }
  .lz-bb-tr--lista > summary::-webkit-details-marker { display:none; }
  .lz-bb-tr--lista > summary:hover, .lz-bb-tr--lista[open] > summary { opacity:1; }
  .lz-bb-tr--baja > summary { opacity:1; }
  /* El texto transcrito, en la MISMA tipografía que un mensaje normal (13.5px/1.45, ver ".lz-bb"
     arriba) y no en el 11.5px de ".lz-bb-tr": WhatsApp Web transcribe con la letra del mensaje,
     no con la de un aviso. "pre-line" y no "pre-wrap" (A5): colapsa espacios/tabs de más pero
     conserva un salto de línea SI el motor lo puso de verdad; "pre-wrap" convertía cualquier
     espacio repetido en aire visual, que es justo lo que hacía ver el bloque tosco.
     El recorte a 6 líneas es el tope real (line-clamp), independiente de si el servidor decidió
     ofrecer o no el "ver más" (ver UMBRAL_VER_MAS_TR en vista-leadz-hilo.js): aunque ese umbral
     se equivoque, esto nunca deja crecer el bloque sin límite. La burbuja de audio ya trae ancho
     FIJO (".lz-bb--md:has(.lz-bb-md--aud)" arriba), así que el texto envuelve dentro de ese ancho
     y nunca la ensancha, por largo que sea. */
  .lz-bb-tr-tx { margin-top:5px; font-size:13.5px; line-height:1.45; white-space:pre-line;
    overflow-wrap:anywhere; opacity:.95; display:-webkit-box; -webkit-box-orient:vertical;
    -webkit-line-clamp:6; line-clamp:6; overflow:hidden; }
  /* El checkbox vive en el DOM (justo antes del texto) para que el combinador "~" lo alcance,
     pero nunca se ve: la caja visible es la etiqueta de abajo, ".lz-bb-tr-mas". */
  .lz-bb-tr-mck { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0);
    white-space:nowrap; }
  .lz-bb-tr-mas { display:inline-block; margin-top:4px; font-size:11px; text-decoration:underline;
    opacity:.65; cursor:pointer; }
  .lz-bb-tr-mas:hover { opacity:1; }
  /* Marcado el checkbox, se quita el tope (mismo texto, ya completo) y la propia etiqueta
     desaparece: no hay "ver menos" a propósito, tal como el <details> que lo envuelve no ofrece
     "ver menos" del bloque entero, solo abrirlo o dejarlo cerrado. */
  .lz-bb-tr-mck:checked ~ .lz-bb-tr-tx { -webkit-line-clamp:unset; line-clamp:unset; overflow:visible; }
  .lz-bb-tr-mck:checked ~ .lz-bb-tr-mas { display:none; }
  .lz-bb-tr-warn { margin-top:4px; font-style:italic; opacity:.7; }

  /* El sticker se pega sobre el fondo del feed, sin caja: una burbuja blanca alrededor de un PNG
     recortado se lee como un error de maquetación, no como un sticker. */
  .lz-bb--stk { background:none; border:0; padding:0; max-width:132px; }
  .lz-bb--stk .lz-bb-mt { padding:0; }
  .lz-bb-md--stk img { max-height:132px; object-fit:contain; }

  .lz-bb-md--doc { display:flex; align-items:center; gap:9px; padding:9px 11px; border-radius:10px;
    border:1px solid var(--border); background:var(--surface-2); color:inherit; text-decoration:none; }
  .lz-bb-md--doc:hover { border-color:var(--text-muted); }
  .lz-bb-md--doc svg { width:19px; height:19px; flex:none; stroke:currentColor; fill:none; stroke-width:1.6; opacity:.75; }
  .lz-bb-doc-t { min-width:0; display:block; }
  .lz-bb-doc-t b { display:block; font-size:12.5px; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-bb-doc-t i { display:block; font-style:normal; font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:9.5px; letter-spacing:.03em; opacity:.65; margin-top:2px; text-transform:uppercase; }

  /* Llegó el mensaje, no llegó el archivo. La fila conserva su media_id, así que es reintentable:
     un marcador discreto, no --danger, que está reservado para lo que de verdad falló.
     SON DOS ESTADOS Y SE VEN DISTINTO A PROPÓSITO (invariante 5 en pantalla): "descargando" es
     un trámite en curso y respira; "no disponible" es un final, y se queda quieto. La misma caja
     para los dos porque son el mismo hueco, y ninguno de los dos es un error de verdad: ver el
     bloque de 'enCurso' en vista-leadz-hilo.js para saber por qué esa diferencia es una
     heurística por reloj y no un dato. */
  .lz-bb-md--no, .lz-bb-md--bajando { padding:9px 11px; border:1px dashed var(--border); border-radius:10px;
    font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; letter-spacing:.04em;
    text-transform:uppercase; color:var(--text-muted); }
  .lz-bb-md--bajando { animation:lzBajando 1.6s ease-in-out infinite; }
  @keyframes lzBajando { 0%,100% { opacity:1; } 50% { opacity:.45; } }
  /* El latido es la ÚNICA señal de que algo sigue pasando, así que apagarlo no puede dejar el
     estado indistinguible del otro: sin movimiento, el borde continuo lo separa del punteado de
     "no disponible". */
  @media (prefers-reduced-motion: reduce) {
    .lz-bb-md--bajando { animation:none; border-style:solid; }
  }

  /* ---- A3: la tarjeta de documento y el marcador de "no disponible", dentro de una burbuja
     SALIENTE ----------------------------------------------------------------------------------
     .lz-bb--out invierte la paleta (background:accent, color:bg), pero .lz-bb-md--doc y
     .lz-bb-md--no traen su PROPIO fondo/borde/color pensados contra la página (surface-2,
     border, text-muted), no contra el accent. Sin este bloque la tarjeta salía con texto blanco
     (heredado de .lz-bb--out) sobre --surface-2, que es clara: ilegible. Mismo patrón que
     ".lz-bb--out .lz-bb-rx-c" arriba, color-mix sobre var(--bg) -que dentro de .lz-bb--out YA es
     el color del texto- para que la tarjeta quede en el mismo tono que la burbuja en los dos
     temas, sin un solo color fijo. */
  .lz-bb--out .lz-bb-md--doc { background:color-mix(in srgb, var(--bg) 15%, transparent);
    border-color:color-mix(in srgb, var(--bg) 25%, transparent); }
  .lz-bb--out .lz-bb-md--doc:hover { border-color:color-mix(in srgb, var(--bg) 45%, transparent); }
  .lz-bb--out .lz-bb-md--bajando, .lz-bb--out .lz-bb-md--no { color:color-mix(in srgb, var(--bg) 65%, transparent);
    border-color:color-mix(in srgb, var(--bg) 35%, transparent); }
  /* El pie de la foto: es texto del lead, va debajo del archivo y dentro de la misma burbuja. */
  .lz-bb-pie { padding:6px 6px 0; white-space:pre-wrap; }
  /* LA FICHA DE CONTACTO dentro de la burbuja. Misma familia visual que la plantilla: el chip
     ".lz-wa-tpl" dice de qué TIPO es este mensaje y debajo va el contenido. El borde se hereda
     de currentColor para que la tarjeta se vea igual en la burbuja blanca y en la invertida, sin
     un solo color fijo (ZR-05), igual que hace ".lz-bb-md--doc". */
  .lz-bb-fc-c { margin-top:6px; padding:8px 10px; border:1px solid currentColor; border-radius:var(--r-card, 12px);
    background:color-mix(in srgb, currentColor 6%, transparent); }
  .lz-bb-fc-c + .lz-bb-fc-c { margin-top:5px; }
  .lz-bb-fc-c b { display:block; font-size:13px; }
  .lz-bb-fc-l { font-size:12px; opacity:.8; margin-top:2px; }
  .lz-bb-fc-l .mono { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:11.5px; }
  .lz-bb-fc-u { word-break:break-all; }
  /* LA UBICACIÓN, misma familia que la ficha de contacto: chip arriba, tarjeta con borde heredado
     de currentColor para que se vea igual en la burbuja blanca y en la invertida, sin un color
     fijo (ZR-05). */
  .lz-bb-ub-c { margin-top:6px; padding:8px 10px; border:1px solid currentColor; border-radius:var(--r-card, 12px);
    background:color-mix(in srgb, currentColor 6%, transparent); }
  .lz-bb-ub-c b { display:block; font-size:13px; }
  .lz-bb-ub-l { font-size:12px; opacity:.8; margin-top:2px; }
  .lz-bb-ub-l .mono { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:11.5px; }
  /* El enlace al mapa es la ÚNICA acción de esta burbuja, así que se ve como acción y no como
     texto subrayado suelto: hairline, misma altura de chip que el resto del hilo. */
  .lz-bb-ub-a { display:inline-block; margin-top:7px; padding:4px 9px; border-radius:var(--r-btn, 10px);
    border:1px solid currentColor; font-size:12px; text-decoration:none; color:inherit; opacity:.85; }
  .lz-bb-ub-a:hover { opacity:1; }
  .lz-bb-ub-a:focus-visible { outline:1px solid currentColor; outline-offset:2px; }

  /* EL MENSAJE QUE NO SE PUEDE MOSTRAR. Reusa el marcador punteado de "no disponible" y le añade
     la explicación debajo, en texto normal: el asesor tiene que poder leer qué hacer, y un bloque
     entero en mayúsculas monoespaciadas no se lee. Nunca --danger: no es un error del sistema, es
     un mensaje que hay que ir a ver a otro lado (ZR-05). */
  .lz-bb-nv-t { font-size:12.5px; line-height:1.45; margin-top:7px; opacity:.85; }
  .lz-bb-nv-m { font-size:11.5px; line-height:1.4; margin-top:6px; padding:6px 8px; opacity:.8;
    border:1px solid currentColor; border-radius:8px;
    background:color-mix(in srgb, currentColor 5%, transparent); }
  .lz-wa-tpl { display:inline-block; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:8.5px; letter-spacing:.06em; text-transform:uppercase; padding:1px 5px; border-radius:var(--r-chip); border:1px solid currentColor; opacity:.6; margin-right:6px; vertical-align:middle; }
  /* EL DISTINTIVO DE COEXISTENCIA: un saliente que salió del celular de Andrés, no de LeadZ. Vive
     en ".lz-bb-mt" junto a la hora, misma familia visual que ".lz-wa-tpl" -borde de currentColor,
     opacidad baja, mono chica, mayúsculas- para que sea información, no una alerta (ZR-05: nunca
     un color fijo). "currentColor" hereda el color YA invertido de ".lz-bb--out" (background:accent,
     color:bg), así que se lee igual en la burbuja saliente y en los dos temas sin declarar un solo
     valor de color. */
  .lz-bb-tel { display:inline-block; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:8px; letter-spacing:.05em; text-transform:uppercase; padding:0 4px; border-radius:var(--r-chip); border:1px solid color-mix(in srgb, currentColor 55%, transparent); opacity:.75; margin:0 2px; vertical-align:middle; }
  .lz-pill { display:inline-block; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.08em; text-transform:uppercase; padding:2px 8px; border-radius:var(--r-pill); border:1px solid var(--border); color:var(--text-muted); white-space:nowrap; }
  .lz-pill--on { background:var(--accent); color:var(--bg); border-color:var(--accent); }
  /* Los últimos diez minutos de la ventana. La urgencia se marca por PESO, no por color: --danger
     está reservado a errores reales (ZR-05) y una ventana por cerrarse es información. El peso
     extra sobre la píldora ya invertida es todo lo que hace falta para que salte a la vista. */
  .lz-ventana--ya { font-weight:600; letter-spacing:.1em; }

  /* ==== Cajas desplegables (.lz-acc) ==================================================
     Comprimir no es esconder: una caja CERRADA sigue diciendo lo esencial en un renglón.
     El resumen va DENTRO del <summary> a propósito — en un <details> cerrado el navegador no
     pinta nada que esté fuera de él, así que un resumen hermano jamás se vería. Ese es el
     detalle del que depende todo el patrón; si algún día alguien lo mueve, deja de funcionar. */
  .lz-acc { border-bottom:1px solid var(--border); }
  .lz-acc:last-child { border-bottom:0; }
  .lz-acc > summary { list-style:none; cursor:pointer; display:block; padding:10px 13px; }
  .lz-acc > summary::-webkit-details-marker { display:none; }
  .lz-acc > summary:hover { background:var(--surface-2); }
  .lz-acc > summary:focus-visible { outline:none; box-shadow:inset 0 0 0 1px var(--accent); }
  .lz-acc-hd { display:flex; align-items:center; gap:8px; }
  .lz-acc-t { flex:1; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); font-weight:500; }
  .lz-acc[open] .lz-acc-t { color:var(--text); }
  .lz-acc-n { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; color:var(--text-muted); border:1px solid var(--border); border-radius:var(--r-pill); padding:1px 7px; white-space:nowrap; }
  .lz-acc-cv { width:13px; height:13px; stroke:var(--text-muted); fill:none; stroke-width:2; transition:transform .15s; flex:0 0 auto; }
  .lz-acc[open] .lz-acc-cv { transform:rotate(90deg); }
  .lz-acc-peek { font-size:11.5px; color:var(--text-muted); margin:4px 0 0 21px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .lz-acc[open] .lz-acc-peek { display:none; }
  .lz-acc-body { padding:2px 13px 16px; }
  .lz-acc-body label:first-child { margin-top:0; }

  /* ==== Pestañas de un panel (Datos · Marketing · Actividad) ==== */
  .lz-ptabs { flex:0 0 auto; display:flex; border-bottom:1px solid var(--border); }
  .lz-ptabs button { flex:1; height:40px; border:0; background:transparent; color:var(--text-muted); font-family:inherit; font-size:12.5px; font-weight:500; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; display:inline-flex; align-items:center; justify-content:center; gap:5px; }
  .lz-ptabs button:hover { color:var(--text); }
  .lz-ptabs button.on { color:var(--text); font-weight:600; border-bottom-color:var(--accent); }
  .lz-ptabs .n { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; color:var(--text-muted); }
  .lz-ptabs button.on .n { color:var(--text); }
  /* El scroll vive en el PANEL, no en la página: es lo que evita que una pantalla crezca de alto
     sin límite cuando el lead trae cientos de renglones de historia. */
  .lz-pane { display:none; flex:1; min-height:0; overflow-y:auto; }
  .lz-pane.on { display:block; }

  /* ==== Flotante + cajón lateral ======================================================
     El botón es el mismo .back-to-top del sitio público (44 px, hairline, la curva
     cubic-bezier(.16,1,.3,1), hover que invierte a negro y sube 2 px). Se copia en vez de
     importarse porque el CSS del sitio es de Astro y los paneles no lo cargan.
     Va en bottom:92px y no en 32px porque abajo a la derecha está el botón de enviar del chat;
     es el mismo ajuste que hacen las landings de VSL para no encimarse con el FAB de WhatsApp. */
  .lz-fab { position:fixed; bottom:92px; right:28px; z-index:50; width:44px; height:44px; display:grid; place-items:center;
    border-radius:var(--r-pill); border:1px solid var(--border); background:var(--surface); color:var(--text); cursor:pointer;
    transition:all .4s cubic-bezier(.16,1,.3,1); box-shadow:0 4px 12px rgba(0,0,0,.08); }
  .lz-fab:hover { background:var(--accent); color:var(--bg); border-color:var(--accent); transform:translateY(-2px); box-shadow:0 8px 24px rgba(0,0,0,.15); }
  .lz-fab svg { width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:2; }
  .lz-fab-n { position:absolute; top:-3px; right:-3px; min-width:17px; height:17px; padding:0 4px; border-radius:var(--r-pill);
    background:var(--accent); color:var(--bg); border:1px solid var(--bg); font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:9.5px; display:grid; place-items:center; }
  .lz-fab:hover .lz-fab-n { background:var(--bg); color:var(--accent); border-color:var(--accent); }
  .lz-velo { position:fixed; inset:0; background:rgba(0,0,0,.28); opacity:0; pointer-events:none; transition:opacity .3s; z-index:55; }
  .lz-velo.on { opacity:1; pointer-events:auto; }
  .lz-cajon { position:fixed; top:0; right:0; bottom:0; width:392px; max-width:92vw; z-index:60;
    background:var(--surface); border-left:1px solid var(--border); box-shadow:-12px 0 40px rgba(0,0,0,.16);
    transform:translateX(100%); transition:transform .4s cubic-bezier(.16,1,.3,1), width .3s cubic-bezier(.16,1,.3,1);
    display:flex; flex-direction:column; }
  .lz-cajon.on { transform:translateX(0); }
  .lz-cajon.ancho { width:660px; }
  .lz-cajon-h { flex:0 0 auto; display:flex; align-items:center; gap:9px; padding:14px 16px; border-bottom:1px solid var(--border); }
  .lz-cajon-h b { flex:1; font-size:14px; }
  .lz-cajon-h svg { width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.8; }
  .lz-cajon-top { flex:0 0 auto; padding:11px 16px; border-bottom:1px solid var(--border); }
  .lz-cajon-list { flex:1; min-height:0; overflow-y:auto; padding:4px 16px 24px; }

  /* Selector de plantillas. Vive aqui y no en el CSS de una vista porque el MARKUP es compartido
     entre la ficha del lead y el Inbox: cuando los estilos se quedaron privados de una vista (el
     caso de .lz-bb), la otra pinto el bloque sin formato durante semanas sin que nadie lo notara. */
  .lz-tpl { display:block; margin-top:9px; }
  .lz-tpl-bar { display:grid; grid-template-columns:1fr 132px; gap:7px; margin-bottom:7px; }
  .lz-tpl-bar .zinput { height:32px; font-size:12px; }
  .lz-tpl-lista { max-height:238px; overflow-y:auto; border:1px solid var(--border); border-radius:12px; padding:5px; background:var(--surface); }
  .lz-tpl-gr { margin:5px 6px 3px; font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
  .lz-tpl-op { display:grid; grid-template-columns:16px 1fr; gap:4px 8px; align-items:start;
    padding:7px 8px; border-radius:9px; cursor:pointer; }
  .lz-tpl-op:hover { background:var(--ink-50, rgba(0,0,0,.035)); }
  .lz-tpl-op input { margin:2px 0 0; }
  .lz-tpl-op:has(input:checked) { background:var(--ink-50, rgba(0,0,0,.05)); box-shadow:inset 0 0 0 1px var(--border); }
  .lz-tpl-tx { font-size:12.5px; line-height:1.42; white-space:pre-wrap; }
  .lz-tpl-m { grid-column:2; font-size:10.5px; color:var(--muted); font-family:var(--mono, ui-monospace, monospace); word-break:break-all; }
  .lz-tpl-falta { grid-column:2; font-size:11px; color:var(--muted); }
  .lz-tpl-op.is-off { cursor:not-allowed; opacity:.62; }
  .lz-tpl-op.is-off .lz-tpl-tx { color:var(--muted); }
  .lz-tpl-here { margin-top:6px; border-top:1px solid var(--border); padding-top:5px; }
  .lz-tpl-here > summary { cursor:pointer; font-size:11.5px; color:var(--muted); padding:4px 6px; list-style:none; }
  .lz-tpl-here > summary::-webkit-details-marker { display:none; }
  .lz-tpl-here > summary::before { content:'▸ '; }
  .lz-tpl-here[open] > summary::before { content:'▾ '; }
  .lz-tpl-nada { margin:10px 8px; font-size:12px; color:var(--muted); }
  .lz-tpl-pie { display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-top:8px; }
  .lz-tpl-pie .lz-nada { flex:1; min-width:140px; }

  /* ---- El editor de plantillas (/app/leadz-plantilla) --------------------------------
     ⚠️ ESTE CSS VIVE AQUÍ Y NO EN LA VISTA, y no es una preferencia de organización: la burbuja
     '.lz-bb' se compartió entre el Inbox y la ficha con su CSS privado, y la conversación de la
     ficha salió SIN ESTILO en producción. Markup compartido, CSS compartido. El editor reusa
     '.lz-bb' para su previa, así que su CSS tiene que estar donde está el de la burbuja: aquí,
     en lo que el cascarón emite en TODAS las vistas, no en el 'extraCss' de una sola. */

  .lz-pl { max-width: 1180px; }
  .lz-pl-h { display:flex; gap:16px; align-items:flex-start; flex-wrap:wrap; padding:15px 17px; border-bottom:1px solid var(--border); }
  .lz-pl-id { flex:1; min-width:240px; }
  .lz-pl-nom { font-size:15px; font-weight:600; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .lz-pl-tec { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:11px; color:var(--text-muted); margin-top:5px; display:flex; align-items:center; gap:6px; }
  .lz-pl-chips { display:flex; gap:6px; margin-top:9px; flex-wrap:wrap; }
  .lz-pl-ic { width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:1.8; flex:none; }

  /* El contador de cupo. Diez casillas, una por edición del mes: se lee de un vistazo y no hay que
     interpretar un porcentaje. Con el cupo agotado usa --danger, que es un bloqueo real y el único
     uso del color que permite ZR-05. */
  .lz-cupo { border:1px solid var(--border); border-radius:var(--r-control); padding:11px 13px; background:var(--surface-2); min-width:266px; }
  .lz-cupo-t { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); margin-bottom:8px; }
  .lz-cupo-b { display:flex; gap:3px; margin-bottom:9px; }
  .lz-cupo-b span { flex:1; height:6px; border-radius:2px; border:1px solid var(--border); background:transparent; }
  .lz-cupo-b span.usa { background:var(--accent); border-color:var(--accent); }
  .lz-cupo-b span.hoy { background:repeating-linear-gradient(45deg,var(--accent),var(--accent) 2px,transparent 2px,transparent 4px); border-color:var(--accent); }
  .lz-cupo-l { font-size:11.5px; color:var(--text-muted); line-height:1.55; display:flex; gap:6px; align-items:flex-start; }
  .lz-cupo-l + .lz-cupo-l { margin-top:5px; }
  .lz-cupo-l b { color:var(--text); font-weight:500; }
  .lz-cupo--stop { border-color:var(--danger); }
  .lz-cupo--stop .lz-cupo-b span.usa { background:var(--danger); border-color:var(--danger); }
  /* El rojo va en el renglón QUE BLOQUEA, no en todo el bloque: con el cupo mensual agotado, el
     renglón de las 24 h suele decir que ese candado ya se liberó, y pintarlo de rojo lo convierte
     en una segunda mala noticia que no es cierta. */
  .lz-cupo-l--stop b { color:var(--danger); }
  .lz-cupo-fuente { font-size:10.5px; color:var(--text-muted); margin-top:8px; padding-top:7px; border-top:1px solid var(--border); line-height:1.5; }

  /* Los tres niveles de cambio, con su costo escrito, para que nadie gaste su edición del día en
     corregir un alias que ni siquiera existe en Meta. */
  .lz-niv { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin:14px 0 0; }
  @media (max-width:900px) { .lz-niv { grid-template-columns:1fr; } }
  .lz-niv > div { border:1px solid var(--border); border-radius:var(--r-card); background:var(--surface); padding:13px 14px; }
  .lz-niv-h { display:flex; align-items:center; gap:8px; margin-bottom:7px; }
  .lz-niv-h b { font-size:12.5px; font-weight:600; }
  .lz-niv p { margin:0; font-size:11.5px; color:var(--text-muted); line-height:1.6; }
  .lz-niv .costo { margin-top:9px; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; }
  .lz-niv .costo--libre { color:var(--text-muted); }
  .lz-niv .costo--cupo { color:var(--text); }
  .lz-niv .costo--no { color:var(--danger); }

  /* El editor: cuerpo a la izquierda, previa siempre a la vista a la derecha. */
  .lz-ed { display:grid; grid-template-columns:1fr 316px; }
  @media (max-width:980px) { .lz-ed { grid-template-columns:1fr; } }
  .lz-ed-l { padding:16px 17px; border-right:1px solid var(--border); min-width:0; }
  @media (max-width:980px) { .lz-ed-l { border-right:0; border-bottom:1px solid var(--border); } }
  .lz-ed-r { padding:16px 17px; background:var(--surface-2); border-radius:0 var(--r-card) var(--r-card) 0; }
  @media (max-width:980px) { .lz-ed-r { border-radius:0 0 var(--r-card) var(--r-card); } }
  .lz-ed-c { margin-bottom:15px; }
  .lz-ed-c > label { display:block; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-muted); margin-bottom:6px; }
  .lz-ed-c .cont { float:right; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; color:var(--text-muted); text-transform:none; letter-spacing:0; }
  .lz-ed-c .cont.pasa { color:var(--danger); }
  /* Un campo bloqueado por Meta tiene que VERSE bloqueado, o alguien teclea encima y da guardar
     esperando que pase algo. Se apaga el fondo y se quita el cursor de texto. */
  .lz-ed input[readonly], .lz-ed input:disabled, .lz-ed select:disabled {
    color:var(--text-muted); font-family:'JetBrains Mono',ui-monospace,monospace; font-size:12px;
    background:transparent; border-style:dashed; cursor:not-allowed; opacity:1; -webkit-text-fill-color:var(--text-muted); }
  .lz-ed textarea { min-height:120px; line-height:1.65; }

  /* Las fichas de campos: insertar sin tener que acordarse de cómo se escribe cada token. */
  .lz-tk { display:flex; gap:5px; flex-wrap:wrap; margin-top:8px; align-items:center; }
  .lz-tk .lbl { font-size:11px; color:var(--text-muted); margin-right:2px; }
  .lz-tk button { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; padding:3px 8px; border-radius:var(--r-chip); border:1px solid var(--border); background:transparent; color:var(--text-muted); cursor:pointer; }
  .lz-tk button:hover { border-color:var(--accent); color:var(--text); }

  .lz-pl-av { border:1px solid var(--border); border-left-width:2px; border-radius:var(--r-control); padding:10px 12px; font-size:12px; line-height:1.6; color:var(--text-muted); display:flex; gap:9px; align-items:flex-start; margin-bottom:14px; background:var(--surface-2); }
  .lz-pl-av b { color:var(--text); font-weight:500; }
  .lz-pl-av--ok { border-left-color:var(--accent); }
  .lz-pl-av--stop { border-left-color:var(--danger); }
  .lz-pl-av--stop b { color:var(--danger); }
  /* La acción del aviso es HERMANA del texto, no un <span> dentro de él: anidada, 'margin-left:auto'
     no aplica y el botón se cuela entre las palabras del párrafo. */
  .lz-pl-av .der { margin-left:auto; flex:none; align-self:center; }
  .lz-pl-av ul { margin:5px 0 0; padding-left:16px; }

  /* El diff de variables: lo que se va tachado, lo que llega en inversión. */
  .lz-dif { display:flex; gap:6px; flex-wrap:wrap; margin-top:8px; }
  .lz-dif span { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10px; padding:3px 8px; border-radius:var(--r-chip); border:1px solid var(--border); color:var(--text-muted); }
  .lz-dif .fuera { color:var(--danger); border-color:var(--danger); text-decoration:line-through; }
  .lz-dif .nueva { background:var(--accent); color:var(--bg); border-color:var(--accent); }

  .lz-pv-t { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); margin-bottom:10px; display:flex; justify-content:space-between; gap:8px; align-items:center; }
  /* La previa reusa la burbuja del Inbox (.lz-bb), pero entrante y a todo el ancho de la columna. */
  .lz-ed-r .lz-bb { max-width:100%; background:var(--surface); border:1px solid var(--border); }
  .lz-ed-r .lz-bb .hueco { border-bottom:1px solid var(--danger); color:var(--danger); }
  .lz-pv-bt { display:flex; flex-direction:column; gap:4px; margin-top:7px; }
  .lz-pv-bt span { text-align:center; font-size:12px; padding:6px; border-top:1px solid var(--border); color:var(--text-muted); }
  .lz-pv-m { margin-top:13px; font-size:11.5px; color:var(--text-muted); line-height:1.7; }
  .lz-pv-m div { display:flex; justify-content:space-between; gap:10px; padding:4px 0; border-bottom:1px solid var(--border); }
  .lz-pv-m div:last-child { border-bottom:0; }
  .lz-pv-m b { color:var(--text); font-weight:500; }

  .lz-pl-pie { padding:13px 17px; border-top:1px solid var(--border); display:flex; gap:9px; align-items:center; flex-wrap:wrap; }
  .lz-pl-pie .razon { font-size:11.5px; color:var(--text-muted); flex:1; min-width:220px; line-height:1.5; }

  /* La comparación "qué se está enviando" mientras Meta revisa. */
  .lz-vs { display:grid; grid-template-columns:1fr 1fr; gap:0; }
  @media (max-width:760px) { .lz-vs { grid-template-columns:1fr; } }
  .lz-vs > div { padding:14px 16px; }
  .lz-vs > div:first-child { border-right:1px solid var(--border); }
  @media (max-width:760px) { .lz-vs > div:first-child { border-right:0; border-bottom:1px solid var(--border); } }
  .lz-vs .lbl { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); margin-bottom:9px; display:flex; align-items:center; gap:7px; }
  .lz-vs p { margin:0; font-size:13px; line-height:1.65; }

  .lz-bot { display:flex; flex-direction:column; gap:8px; }
  .lz-bot-f { display:flex; gap:7px; align-items:center; flex-wrap:wrap; border:1px solid var(--border); border-radius:var(--r-control); padding:8px 10px; background:var(--surface-2); }
  .lz-bot-f select, .lz-bot-f input { height:30px; font-size:12px; }
  .lz-bot-f .tx { flex:0 0 160px; }
  .lz-bot-f .ur { flex:1; min-width:150px; }
  .lz-hist { font-size:11.5px; color:var(--text-muted); line-height:1.7; }
  .lz-hist li { margin-bottom:2px; }

  /* El toggle "Perfilado" (leads.perfilado, migración 0093). Vive en la tarjeta del tablero Y en
     la ficha — el CSS va aquí, una sola vez, para que no le pase lo que a la burbuja del Inbox:
     dos copias del mismo widget que se desincronizan a la primera semana. Monocromático, sin
     color de acento: apagado = borde hairline, encendido = tinta (var(--accent)). */
  .lz-perfil-toggle { display:inline-flex; align-items:center; gap:7px; cursor:pointer; user-select:none; }
  .lz-perfil-toggle input[type="checkbox"] { position:absolute; opacity:0; width:1px; height:1px; }
  .lz-perfil-toggle .tr { position:relative; width:34px; height:20px; border-radius:999px; background:var(--surface-2); border:1px solid var(--border); transition:background .15s ease; flex:0 0 auto; box-sizing:border-box; }
  .lz-perfil-toggle .tr::after { content:''; position:absolute; top:1px; left:1px; width:16px; height:16px; border-radius:50%; background:var(--bg); box-shadow:0 1px 2px rgba(0,0,0,.25); transition:transform .15s ease; }
  .lz-perfil-toggle input:checked + .tr { background:var(--accent); border-color:var(--accent); }
  .lz-perfil-toggle input:checked + .tr::after { transform:translateX(14px); }
  .lz-perfil-toggle input:focus-visible + .tr { outline:1px solid var(--accent); outline-offset:2px; }
  .lz-perfil-toggle .tx { font-size:12px; color:var(--text-muted); }
  .lz-perfil-toggle input:checked ~ .tx { color:var(--text); font-weight:500; }

  /* --- Modal de "¿con qué número marco?" ---------------------------------------------------- */
  .lz-tel-back { position:fixed; inset:0; background:rgba(10,10,10,.45); z-index:400;
    display:flex; align-items:center; justify-content:center; padding:20px; }
  [data-ds-theme="dark"] .lz-tel-back { background:rgba(0,0,0,.65); }
  .lz-tel-modal { background:var(--surface); color:var(--text); border:1px solid var(--border);
    border-radius:var(--r-card); box-shadow:0 24px 60px rgba(10,10,10,.22); width:100%; max-width:420px;
    padding:24px; text-align:center; }
  .lz-tel-modal h3 { margin:0 0 4px; font-size:15px; font-weight:600; }
  .lz-tel-num { font-family:'JetBrains Mono', ui-monospace, monospace; font-size:20px; letter-spacing:-.01em; margin:6px 0 2px; }
  .lz-tel-modal .lz-tel-sub { font-size:12.5px; color:var(--text-muted); margin:10px 0 16px; }
  .lz-tel-objs { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 4px; }
  .lz-tel-obj { flex:1 1 auto; padding:7px 10px; border-radius:10px; font-size:12.5px; font-weight:500;
    border:1px solid var(--border); background:var(--surface); color:var(--text); cursor:pointer; }
  .lz-tel-obj:hover { border-color:var(--text-muted); }
  .lz-tel-obj--on { background:var(--text); color:var(--surface); border-color:var(--text); }
  .lz-tel-aviso { position:fixed; top:16px; right:16px; z-index:10000; max-width:340px;
    padding:10px 14px; border-radius:10px; font-size:13px; line-height:1.35;
    background:var(--surface); color:var(--text); border:1px solid var(--border);
    box-shadow:0 8px 24px rgba(0,0,0,.12); }
  .lz-tel-aviso--ok { border-color:var(--text-muted); }
  /* El softphone no arranco: el aviso ofrece el tel: como salida, pero lo dice, no lo silencia. */
  .lz-tel-aviso--sf { max-width:300px; }
  .lz-tel-aviso--sf .lz-tel-aviso-row { display:flex; gap:8px; margin-top:8px; }
  .lz-tel-aviso--sf a, .lz-tel-aviso--sf button { font-size:12px; font-weight:500; border-radius:8px;
    padding:6px 9px; border:1px solid var(--border); background:var(--surface); color:var(--text);
    cursor:pointer; text-decoration:none; }
  .lz-tel-aviso--sf a:hover, .lz-tel-aviso--sf button:hover { border-color:var(--text-muted); }
  .lz-tel-hueco { margin:8px 0 0; font-size:12px; line-height:1.45; color:var(--text-muted); }
  .lz-tel-inter { margin:4px 0 0; font-size:12px; line-height:1.4; color:var(--text-muted); }
  .lz-tel-ops { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  .lz-tel-op { border:1px solid var(--border); border-radius:var(--r-btn); background:var(--surface);
    color:var(--text); font-family:inherit; padding:14px 10px; cursor:pointer; text-align:center; }
  .lz-tel-op:hover:not([disabled]) { border-color:var(--accent); }
  .lz-tel-op--pri { background:var(--accent); color:var(--bg); border-color:var(--accent); }
  .lz-tel-op[disabled] { opacity:.4; cursor:not-allowed; }
  .lz-tel-op b { display:block; font-size:13.5px; font-weight:600; }
  .lz-tel-op span { display:block; font-family:'JetBrains Mono', ui-monospace, monospace;
    font-size:11px; margin-top:5px; opacity:.75; }
  .lz-tel-cancel { margin-top:14px; background:none; border:none; color:var(--text-muted);
    font-family:inherit; font-size:12.5px; cursor:pointer; }
  .lz-tel-cancel:hover { color:var(--text); }

  /* --- "¿Cómo quedó?" (Cadencias v2, §1.6): el modal al colgar una saliente establecida --------
     Reusa '.lz-tel-back'/'.lz-tel-modal' (mismo velo, mismo lenguaje visual) pero SIN '.lz-tel-cancel':
     este modal no tiene botón de cerrar/cancelar a propósito, ver el comentario del JS. */
  .lz-quedo { text-align:left; }
  .lz-quedo h3 { text-align:center; }
  .lz-quedo .lz-tel-sub { text-align:center; }
  .lz-quedo-raiz { display:flex; flex-direction:column; gap:8px; margin-top:6px; }
  .lz-quedo-op { border:1px solid var(--border); border-radius:var(--r-btn); background:var(--surface);
    color:var(--text); font-family:inherit; font-size:13.5px; text-align:left; padding:12px 14px; cursor:pointer; }
  .lz-quedo-op:hover { border-color:var(--accent); }
  .lz-quedo-panel[hidden] { display:none; }
  .lz-quedo-panel .zinput { width:100%; box-sizing:border-box; margin-top:2px; }
  .lz-quedo-atras { display:block; margin:0 0 12px; background:none; border:none; color:var(--text-muted);
    font-family:inherit; font-size:12.5px; cursor:pointer; padding:0; }
  .lz-quedo-atras:hover { color:var(--text); }
  .lz-quedo-presets { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
  .lz-quedo-preset, .lz-quedo-preset-e { border:1px solid var(--border); border-radius:var(--r-pill);
    background:none; color:var(--text); font-family:inherit; font-size:11.5px; padding:5px 11px; cursor:pointer; }
  .lz-quedo-preset:hover, .lz-quedo-preset-e:hover { border-color:var(--accent); }
  .lz-quedo-espera { margin-top:16px; padding-top:14px; border-top:1px solid var(--border); }
  .lz-quedo-toggle-espera { background:none; border:none; color:var(--text-muted); font-family:inherit;
    font-size:12.5px; text-decoration:underline; cursor:pointer; padding:0; }
  .lz-quedo-toggle-espera:hover { color:var(--text); }
  .lz-quedo-espera-c[hidden] { display:none; }
  .lz-quedo-espera-c { margin-top:10px; }
  .lz-quedo-nutri { display:flex; gap:6px; margin-top:10px; align-items:center; }
  .lz-quedo-nutri .zinput { margin-top:0; }
  .lz-quedo-nutri-bt { flex:0 0 auto; border:1px solid var(--border); border-radius:var(--r-btn); background:none;
    color:var(--text); font-family:inherit; font-size:11.5px; padding:7px 10px; cursor:pointer; white-space:nowrap; }
  .lz-quedo-nutri-bt:hover { border-color:var(--accent); }

  /* El botón de llamar de las listas reusa .lz-ico, que nació para <a>: un <button> trae su
     propio fondo, borde y tipografía del navegador y sin esto se vería distinto en cada fila. */
  button.lz-ico { padding:0; font-family:inherit; cursor:pointer; }

  /* --- Softphone: el disparador -------------------------------------------------------------
     Dos vidas para la MISMA pieza, segun donde la monte el JS (ver montarPastilla en este mismo
     archivo): si existe la columna izquierda (barraLateral, leadz-vistas.js) se cuelga de
     '.lz-side-foot' y se vuelve un renglon mas del menu; si no hay columna, o la pantalla es
     angosta, se queda flotando. Por eso la regla de abajo ya NO es 'bottom:18px': ahi vivia
     encima del compositor, que es justo lo que este lote vino a destapar. Arriba a la derecha no
     tapa nada de lo que el asesor esta usando. */
  .lz-sf { position:fixed; top:14px; right:14px; z-index:390; font-size:13px; }
  /* La llamada EN CURSO no se toca: este lote reubica el disparador y su panel, no la experiencia
     de llamada. Mismas coordenadas de siempre, con mas especificidad que la regla de arriba
     (selector por id) para que le gane sin depender del orden en la hoja. */
  #lz-sf-curso.lz-sf { position:fixed; top:auto; right:18px; bottom:18px; z-index:390; }
  .lz-sf__pill { display:flex; align-items:center; gap:8px; height:38px; padding:0 14px;
    border:1px solid var(--border); border-radius:var(--r-pill); background:var(--surface);
    color:var(--text); box-shadow:var(--shadow-sm); cursor:pointer; font-family:inherit; font-size:12.5px; }
  /* El icono y la chip de estado nacen apagados: son el lenguaje de la nav (ver mas abajo), y la
     pastilla flotante de siempre no los necesita. */
  .lz-sf__ico { display:none; }
  .lz-sf__stchip { display:none; }
  .lz-sf__dot { width:7px; height:7px; border-radius:50%; background:var(--text-muted); flex:none; }
  .lz-sf--on .lz-sf__dot { background:#16a34a; }
  .lz-sf--dnd .lz-sf__dot { background:var(--danger); }
  /* GRIS DICE "ESPERA", ROJO DICE "ESTO NO SE ARREGLA SOLO". El punto gris de "Conectando…" es
     una promesa: que en un momento va a estar. Cuando el proveedor ya contestó que no, sostener
     el gris es mentirle al asesor, que se queda esperando algo que no va a pasar. */
  /* "Está en otra pestaña" NO es un error: es el estado normal de la segunda pestaña de un CRM,
     que es como se usa un CRM. Punto hueco, no rojo — el rojo promete un problema que no existe. */
  .lz-sf--otra .lz-sf__dot { background:none; box-shadow:inset 0 0 0 1.5px var(--text-muted); }
  .lz-sf__otra { margin-top:10px; width:100%; border-color:var(--border); color:var(--text); }
  .lz-sf__otra[hidden] { display:none; }
  /* La franja va PEGADA a las pestañas y separada del cuerpo por su hairline: se lee como parte
     del chasis del teléfono, no como un mensaje flotando dentro del contenido. Fondo de superficie
     secundaria, igual que la barra de pestañas, para que las dos se lean como una sola pieza. */
  .lz-sf__franja { border-top:1px solid var(--border); background:var(--surface-2);
    padding:10px 12px; display:flex; flex-direction:column; gap:7px; }
  .lz-sf__franja[hidden] { display:none; }
  .lz-sf__franja-txt { font-size:11.5px; line-height:1.45; color:var(--text-muted); }
  .lz-sf__franja .lz-sf__otra { margin-top:0; }
  .lz-sf__otra--pri { border-color:var(--text); }
  /* Deshabilitado se LEE deshabilitado. Un botón que parece apretable y no hace nada se lee como
     que la app está rota; aquí no lo está, sólo hay una llamada en curso del otro lado. */
  .lz-sf__otra:disabled { opacity:.5; cursor:default; border-color:var(--border); }
  .lz-sf--err .lz-sf__dot { background:var(--danger); }
  .lz-sf--err .lz-sf__pill { border-color:var(--danger); }
  /* El aviso de fallo es un panel chico y aparte: el teléfono no llegó a existir, así que no hay
     teclado ni recientes que enseñar. Solo qué pasó, qué sí funciona, y cómo reintentar. */
  .lz-sf__err { padding:14px; }
  .lz-sf__err h4 { margin:0 0 6px; font-size:13px; font-weight:600; }
  .lz-sf__err p { margin:0 0 8px; font-size:12px; line-height:1.5; color:var(--text-muted); }
  .lz-sf__err .lz-sf__det { font-family:'JetBrains Mono', ui-monospace, monospace; font-size:10.5px;
    word-break:break-all; opacity:.7; }
  /* El panel es una VENTANA CENTRADA sobre el contenido, no un dropdown pegado al disparador: se
     encimaba con la lista de conversaciones, y el pie de la columna es demasiado angosto para que
     tome el protagonismo ahí. Sigue viviendo donde siempre (dentro de '.lz-sf', junto a la
     pastilla): este mismo archivo lo encuentra por 'd.querySelector(...)' en media docena de
     funciones (montaTabs, pideRecientes, montaTeclado...), y moverlo a otro padre las dejaría
     buscando en el lugar equivocado. Se centra con 'position:fixed' + transform, que no depende
     de qué tan arriba en el árbol esté su contenedor.
     z-index:401, uno más que '.lz-tel-back' (400, su velo, ver esa regla más arriba): el velo
     tiene que quedar DEBAJO del panel aunque los dos vivan dentro de la columna, cuyo propio
     z-index:2 (ver '.lz-side' en leadz-vistas.js) ya confina a los dos al mismo nivel local frente
     al resto de la página. */
  .lz-sf__panel { position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:401;
    width:320px; max-width:calc(100vw - 32px); max-height:calc(100vh - 32px); overflow:auto;
    border:1px solid var(--border); border-radius:var(--r-card); background:var(--surface);
    box-shadow:0 24px 60px rgba(10,10,10,.22); }
  .lz-sf__panel[hidden] { display:none; }
  /* --- El disparador COMO ITEM DEL MENU ------------------------------------------------------
     Solo aplica cuando el JS de verdad lo colgo de '.lz-side-foot' (existe columna) Y hay ancho
     para que la columna no este colapsada. Selector por ancestro, no una clase aparte: si algun
     dia la columna deja de existir en una pantalla, esta regla nunca se activa sola y el widget
     se queda flotando, que es el fallback seguro.
     El mismo tratamiento que '.lz-snav a' (leadz-vistas.js): icono de 17px, mismo padding, mismo
     hover, y la fila activa se invierte igual que '.lz-snav a.on' (ZR-05: enfasis por inversion,
     nunca por color). */
  @media (min-width:900px){
    .lz-side-foot .lz-sf { position:relative; top:auto; right:auto; bottom:auto; z-index:1; width:100%; }
    .lz-side-foot .lz-sf__pill { width:100%; box-sizing:border-box; height:auto; padding:9px 11px;
      border:0; border-radius:var(--r-btn); background:none; box-shadow:none; color:var(--text-muted);
      font-family:inherit; font-size:13.5px; }
    .lz-side-foot .lz-sf__pill:hover { background:var(--surface-2); color:var(--text); }
    .lz-side-foot .lz-sf--on .lz-sf__pill { background:var(--accent); color:var(--bg); font-weight:600; }
    .lz-side-foot .lz-sf__ico { display:block; width:17px; height:17px; stroke:currentColor; fill:none;
      stroke-width:1.7; flex:0 0 auto; }
    /* El punto de color se apaga: en la columna el estado se dice como YA lo dice el menu para el
       contador de conversaciones ('.lz-cnt', importado de leadz-vistas.js junto con este mismo
       cascaron), inversion y hairline, nunca color inventado. Registrado y sin pendientes no
       pinta chip, igual que '.lz-cnt' en cero: un chip permanente enseña a ignorarlo. */
    .lz-side-foot .lz-sf__dot { display:none; }
    .lz-side-foot .lz-sf__txt { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis;
      white-space:nowrap; text-align:left; }
    .lz-side-foot .lz-sf__stchip { display:inline-flex; margin-left:auto; }
    /* El panel YA NO sale pegado a la columna: es la ventana centrada de '.lz-sf__panel' de más
       arriba, la misma en modo columna que en modo flotante. Sin regla propia aquí a propósito. */
  }
  /* ⚠️ "align-items:center" con "justify-content:space-between" NO reserva alto cuando la etiqueta
     envuelve a dos líneas: el renglón crecía hacia arriba y se encimaba con el bloque de abajo, y
     el margin-top del siguiente no alcanzaba. Se arregla de raíz: la etiqueta puede encoger
     (min-width:0) y envolver, y el control no se deforma (flex:none). Nada de subir márgenes. */
  .lz-sf__row { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:12px; }
  .lz-sf__row:first-child { margin-top:0; }
  .lz-sf__row > .lz-sf__lbl { flex:1 1 auto; min-width:0; line-height:1.35; }
  .lz-sf__row > .lz-sf__sw { flex:0 0 auto; }
  .lz-sf__nota { font-size:11px; color:var(--text-muted); line-height:1.5; margin:6px 0 8px; }

  /* ---- El flotante como TELÉFONO: tres pestañas abajo ---------------------------------------- */
  .lz-fon { display:flex; flex-direction:column; }
  .lz-fon__cuerpo { padding:14px; min-height:270px; max-height:min(62vh, 420px); overflow:auto; }
  .lz-fon__tabs { display:flex; border-top:1px solid var(--border); background:var(--surface-2); }
  .lz-fon__tab { flex:1 1 0; height:40px; border:0; background:none; color:var(--text-muted);
    font-family:inherit; font-size:11.5px; cursor:pointer; position:relative; }
  /* La pestaña activa se marca por PESO y una línea, no por color: el DS es monocromático. */
  .lz-fon__tab.on { color:var(--text); font-weight:600; box-shadow:inset 0 2px 0 var(--accent); }
  .lz-fon__tab:focus-visible { outline:2px solid var(--accent); outline-offset:-2px; }
  .lz-fon__pd { display:inline-flex; align-items:center; justify-content:center; min-width:16px; height:16px;
    margin-left:5px; padding:0 4px; box-sizing:border-box; border-radius:var(--r-pill);
    border:1px solid currentColor; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:9.5px; }

  /* ---- Teclado ------------------------------------------------------------------------------- */
  .lz-tec__num { width:100%; box-sizing:border-box; height:42px; border:0; border-bottom:1px solid var(--border);
    background:none; color:var(--text); text-align:center; font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:19px; letter-spacing:.02em; }
  .lz-tec__num:focus { outline:none; border-bottom-color:var(--accent); }
  .lz-tec__quien { min-height:16px; text-align:center; font-size:11.5px; color:var(--text-muted); margin-top:6px; }
  /* "justify-items:center" + ancho fijo: con celdas de 1fr los botones salían OVALADOS, porque
     border-radius:50% sobre un rectángulo da una elipse. Un teclado con teclas ovaladas se ve
     como un error de CSS, no como un teléfono. */
  .lz-tec__rej { display:grid; grid-template-columns:repeat(3, 1fr); justify-items:center; gap:9px; margin-top:10px; }
  .lz-tec__t { width:58px; height:58px; border-radius:50%; border:1px solid var(--border); background:var(--surface-2);
    color:var(--text); cursor:pointer; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px; }
  .lz-tec__t b { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:17px; font-weight:500; line-height:1; }
  .lz-tec__t i { font-size:7.5px; letter-spacing:.12em; color:var(--text-muted); font-style:normal; line-height:1; }
  .lz-tec__t:active { background:var(--accent); color:var(--bg); border-color:var(--accent); }
  .lz-tec__t:active i { color:var(--bg); }
  .lz-tec__pie { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; margin-top:12px; }
  .lz-tec__hueco { display:block; }
  /* Verde sólo aquí y en colgar: es lo único que nadie lee antes de apretar. */
  .lz-tec__call { width:52px; height:52px; border-radius:50%; border:0; background:#0f7b3f; color:#fff;
    cursor:pointer; display:flex; align-items:center; justify-content:center; justify-self:center; }
  .lz-tec__call svg { width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
  .lz-tec__del { justify-self:end; width:38px; height:38px; border-radius:50%; border:0; background:none;
    color:var(--text-muted); font-size:16px; cursor:pointer; }

  /* ---- Recientes ----------------------------------------------------------------------------- */
  .lz-rec__filtros { display:flex; gap:6px; margin-bottom:10px; }
  .lz-rec__f { height:26px; padding:0 11px; border-radius:var(--r-pill); border:1px solid var(--border);
    background:none; color:var(--text-muted); font-family:inherit; font-size:11px; cursor:pointer; }
  .lz-rec__f.on { background:var(--accent); border-color:var(--accent); color:var(--bg); }
  .lz-rec__it { display:flex; align-items:center; gap:9px; padding:8px 0; border-bottom:1px solid var(--border);
    text-decoration:none; color:var(--text); }
  .lz-rec__av { width:30px; height:30px; flex:0 0 auto; border-radius:50%; display:flex; align-items:center;
    justify-content:center; color:#fff; font-size:11px; font-weight:600; }
  .lz-rec__txt { flex:1 1 auto; min-width:0; }
  .lz-rec__nom { display:block; font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* Una fila vieja sin número no se pinta en blanco: se dice qué pasó, en tenue. */
  .lz-rec__nom--vacio { color:var(--text-muted); font-style:italic; }
  .lz-rec__meta { display:flex; align-items:center; gap:4px; font-size:10.5px; color:var(--text-muted); margin-top:1px; }
  .lz-rec__meta svg { width:11px; height:11px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
  /* La perdida se distingue de un vistazo: es a lo que se entra. Por PESO, no por color. */
  .lz-rec__it--mal .lz-rec__nom { font-weight:600; }
  .lz-rec__it--mal .lz-rec__meta { color:var(--danger); }
  .lz-rec__call { width:30px; height:30px; flex:0 0 auto; border-radius:50%; border:1px solid var(--border);
    background:none; color:var(--text); cursor:pointer; display:flex; align-items:center; justify-content:center; }
  .lz-rec__call svg { width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:1.7; }
  .lz-rec__nada, .lz-rec__cargando { font-size:12px; color:var(--text-muted); padding:18px 0; text-align:center; }
  .lz-rec__todas { display:block; margin-top:12px; font-size:11.5px; color:var(--text-muted); text-align:center; }
  .lz-sf__lbl { font-size:12px; color:var(--text-muted); }
  .lz-sf__sw { position:relative; width:38px; height:21px; border-radius:var(--r-pill); border:1px solid var(--border);
    background:var(--surface-2); cursor:pointer; flex:none; padding:0; }
  .lz-sf__sw::after { content:''; position:absolute; top:2px; left:2px; width:15px; height:15px; border-radius:50%;
    background:var(--text-muted); transition:transform .14s, background .14s; }
  .lz-sf__sw[aria-checked="true"] { background:var(--accent); border-color:var(--accent); }
  .lz-sf__sw[aria-checked="true"]::after { transform:translateX(17px); background:var(--bg); }
  .lz-sf__panel select { width:100%; margin-top:5px; height:32px; font-size:12px; }
  .lz-sf__est { font-size:11.5px; color:var(--text-muted); line-height:1.45; margin-top:12px;
    border-top:1px solid var(--border); padding-top:10px; }

  /* --- Softphone: llamada entrante y llamada en curso --------------------------------------- */
  .lz-sf__quien { font-size:13.5px; font-weight:600; margin-top:2px; }
  .lz-sf__acc { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:18px; }
  .lz-sf__ring { animation:lz-sf-ring 1.1s ease-in-out infinite; }
  @keyframes lz-sf-ring { 0%,100% { opacity:1; } 50% { opacity:.45; } }
  .lz-sf__curso { display:flex; align-items:center; gap:10px; height:38px; padding:0 8px 0 14px;
    border:1px solid var(--accent); border-radius:var(--r-pill); background:var(--accent); color:var(--bg);
    box-shadow:var(--shadow-sm); }
  .lz-sf__t { font-family:'JetBrains Mono', ui-monospace, monospace; font-size:12px; }
  .lz-sf__mini { height:28px; padding:0 10px; border-radius:var(--r-pill); border:1px solid currentColor;
    background:none; color:inherit; font-family:inherit; font-size:11.5px; cursor:pointer; }
  .lz-sf__mini--col { background:var(--danger); border-color:var(--danger); color:#fff; }
  /* El aviso de "esta pestaña no va a sonar". Va tenue: es una advertencia sobre el canal, no
     sobre la llamada, y no puede competir con los botones de contestar. */
  /* ---- La tarjeta de llamada entrante --------------------------------------------------------
     Clases PROPIAS: .lz-tel-back / .lz-tel-modal las comparte el modal de identidad del botón de
     marcar, y redefinirlas ahí lo rediseñaría de paso. Todo con tokens del DS, para que las dos
     variantes de tema salgan solas. */
  .lz-llam-back { position:fixed; inset:0; z-index:10000; display:flex; align-items:center; justify-content:center;
    background:rgba(10,10,10,.45); backdrop-filter:blur(2px); }
  .lz-llam { width:min(360px, calc(100vw - 32px)); box-sizing:border-box; background:var(--surface);
    border:1px solid var(--border); border-radius:var(--r-card); box-shadow:var(--shadow-lg, 0 24px 48px rgba(0,0,0,.24));
    padding:26px 22px 20px; text-align:center; color:var(--text); }
  /* El avatar: grande, circular, con las iniciales. El anillo pulsa mientras timbra, que es lo que
     hace que se lea como "está sonando" sin necesidad de una etiqueta que lo diga. */
  .lz-llam__av { width:72px; height:72px; margin:0 auto 14px; border-radius:50%; display:flex;
    align-items:center; justify-content:center; color:#fff; font-size:24px; font-weight:600;
    letter-spacing:.02em; background:var(--accent); position:relative; }
  .lz-llam__av::after { content:''; position:absolute; inset:-6px; border-radius:50%;
    border:2px solid var(--accent); opacity:.35; animation:lz-llam-pulso 1.6s ease-out infinite; }
  @keyframes lz-llam-pulso { 0% { transform:scale(1); opacity:.45; } 100% { transform:scale(1.18); opacity:0; } }
  .lz-llam__nom { font-size:19px; font-weight:600; letter-spacing:-.01em; line-height:1.25; }
  .lz-llam__nom a { color:inherit; text-decoration:none; border-bottom:1px solid transparent; }
  .lz-llam__nom a:hover { border-bottom-color:var(--accent); }
  .lz-llam__emp:empty, .lz-llam__linea:empty { display:none; }
  .lz-llam__emp { font-size:13px; color:var(--text-muted); margin-top:2px; }
  .lz-llam__num { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:12.5px;
    color:var(--text-muted); margin-top:8px; }
  .lz-llam__linea { font-size:11px; color:var(--text-muted); margin-top:4px; text-transform:uppercase; letter-spacing:.06em; }
  /* El bloque de contexto tiene ALTURA MÍNIMA aunque esté vacío: es lo que evita que la tarjeta
     salte cuando responde el fetch, justo cuando el dedo va hacia Contestar. */
  .lz-llam__ctx { min-height:74px; margin:14px 0 4px; text-align:left; display:flex;
    flex-direction:column; gap:5px; }
  .lz-llam__dato { font-size:12.5px; line-height:1.45; color:var(--text); }
  .lz-llam__dato--muted { color:var(--text-muted); }
  .lz-llam__dato--fuerte { font-weight:600; }
  /* Las alertas se marcan por inversión, no por color: --danger es para errores y "lead de otro
     asesor" no es un error, es un aviso. */
  .lz-llam__alerta { font-size:11px; text-transform:uppercase; letter-spacing:.06em;
    background:var(--accent); color:var(--bg); border-radius:var(--r-pill); padding:3px 9px; align-self:flex-start; }
  .lz-llam__mas summary { font-size:11.5px; color:var(--text-muted); cursor:pointer; }
  .lz-llam__mas div { font-size:11.5px; color:var(--text-muted); line-height:1.6; margin-top:4px; }
  /* Esqueleto, no spinner: un spinner dice "espera", un esqueleto dice "aquí va a haber algo" y
     además ya ocupa el sitio. */
  .lz-llam__sk { height:13px; border-radius:var(--r-btn); background:var(--surface-2); }
  .lz-llam__sk--corto { width:60%; }
  .lz-llam__crear { display:inline-block; margin:6px 0 2px; font-size:12px; color:var(--text-muted); }
  .lz-llam__acc { display:flex; gap:12px; justify-content:center; margin-top:16px; }
  .lz-llam__bt { flex:1 1 0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:6px;
    padding:12px 8px; border-radius:var(--r-card); border:1px solid var(--border); background:var(--surface-2);
    color:var(--text); font-family:inherit; font-size:12px; cursor:pointer; }
  .lz-llam__bt svg { width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.7;
    stroke-linecap:round; stroke-linejoin:round; }
  /* Verde y rojo son la ÚNICA excepción cromática del DS aquí, y se gana: contestar y colgar son
     universales, y en un teléfono nadie lee las etiquetas antes de apretar. */
  .lz-llam__bt--si { background:#0f7b3f; border-color:#0f7b3f; color:#fff; }
  .lz-llam__bt--no { background:var(--danger); border-color:var(--danger); color:#fff; }
  .lz-llam__bt:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

  /* ---- Panel de llamada en curso -------------------------------------------------------------
     Conserva avatar, nombre y contexto MIENTRAS dura la llamada: el contexto sirve durante, no
     sólo antes. Y se minimiza a la pastilla de siempre, porque una llamada de veinte minutos no
     puede tapar la pantalla en la que el asesor está tomando notas. */
  .lz-curso { width:min(340px, calc(100vw - 32px)); box-sizing:border-box; background:var(--surface);
    border:1px solid var(--border); border-radius:var(--r-card); box-shadow:var(--shadow-md, 0 12px 28px rgba(0,0,0,.18));
    padding:12px 14px 12px; color:var(--text); }
  .lz-curso__top { display:flex; align-items:center; gap:10px; }
  .lz-curso__av { width:36px; height:36px; flex:0 0 auto; border-radius:50%; display:flex; align-items:center;
    justify-content:center; background:var(--accent); color:#fff; font-size:13px; font-weight:600; }
  .lz-curso__quien { flex:1 1 auto; min-width:0; }
  .lz-curso__nom { font-size:13.5px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .lz-curso__num { font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10.5px; color:var(--text-muted); }
  .lz-curso__min { flex:0 0 auto; width:24px; height:24px; border-radius:var(--r-btn); border:1px solid var(--border);
    background:none; color:var(--text-muted); cursor:pointer; line-height:1; }
  .lz-curso__ctx { margin:10px 0 0; display:flex; flex-direction:column; gap:4px; }
  .lz-curso__ctx:empty { display:none; }
  /* El alta durante la llamada: plegada, para que no empuje los botones fuera de la vista. Quien
     la abre ya decidió capturar; quien no, ni la ve. */
  /* El "+" de crear lead vive junto al de volver a llamar, en gris: la acción verde de esa fila
     es llamar. Mismo tamaño para que la fila no se deforme cuando aparece o desaparece. */
  .lz-rec__nuevo { flex:0 0 auto; width:30px; height:30px; border-radius:50%; border:1px solid var(--border);
    background:none; color:var(--text-muted); cursor:pointer; display:flex; align-items:center; justify-content:center; }
  .lz-rec__nuevo svg { width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; }
  .lz-rec__nuevo:hover { color:var(--text); border-color:var(--text); }
  .lz-rec__alta { padding:0 4px 10px; }
  .lz-curso__alta { margin-top:10px; }
  .lz-curso__alta summary { cursor:pointer; font-size:12px; color:var(--text-muted); }
  .lz-curso__alta-c { display:flex; flex-direction:column; gap:6px; margin-top:8px; }
  .lz-curso__alta-c .zinput { height:30px; font-size:12.5px; }
  .lz-curso__alta-msg { font-size:11.5px; color:var(--text-muted); line-height:1.4; }
  .lz-curso__acc { display:flex; gap:6px; margin-top:11px; flex-wrap:wrap; }
  .lz-curso__acc .lz-sf__mini { border-color:var(--border); color:var(--text); text-decoration:none;
    display:inline-flex; align-items:center; }
  .lz-curso__dtmf { display:grid; grid-template-columns:repeat(3, 1fr); gap:5px; margin-top:10px; }
  .lz-curso__tecla { height:30px; border-radius:var(--r-btn); border:1px solid var(--border);
    background:var(--surface-2); color:var(--text); font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:13px; cursor:pointer; }
  /* Minimizada: la misma pastilla de siempre, para volver con un clic. */
  .lz-curso__pill { height:38px; padding:0 16px; border-radius:var(--r-pill); border:1px solid var(--accent);
    background:var(--accent); color:var(--bg); font-family:'JetBrains Mono',ui-monospace,monospace;
    font-size:12px; cursor:pointer; box-shadow:var(--shadow-sm); }

  .lz-sf__mudo:empty { display:none; }
  .lz-sf__mudo { margin-top:8px; font-size:11px; color:var(--text-muted); line-height:1.45; }
  /* La barra cuando la llamada NO salió. Fondo del panel y borde hairline, no relleno: es un
     estado que se lee, no una alarma. El texto ya dice lo que hay que hacer. */
  .lz-sf__curso--mal { background:var(--surface); color:var(--text); border-color:var(--border); height:auto;
    padding:8px 10px 8px 14px; flex-wrap:wrap; max-width:420px; }
  .lz-sf__curso--mal .lz-sf__mini--col { background:none; border-color:var(--border); color:var(--text-muted); }
  .lz-sf__num { height:28px; font-size:12px; flex:1 1 auto; min-width:0; }
  .lz-sf__mini--diag { border-color:var(--border); color:var(--text); }
  .lz-sf__diag { margin-top:12px; padding-top:12px; border-top:1px solid var(--border); }

  .lz-avc-back { position:fixed; inset:0; z-index:10050; display:flex; align-items:center; justify-content:center;
    padding:20px; background:rgba(10,10,10,.45); }
  [data-ds-theme="dark"] .lz-avc-back { background:rgba(0,0,0,.65); }
  .lz-avc { width:min(380px, calc(100vw - 32px)); box-sizing:border-box; background:var(--surface); color:var(--text);
    border:1px solid var(--border); border-radius:var(--r-card); box-shadow:0 24px 60px rgba(10,10,10,.22);
    padding:26px 24px; text-align:center; }
  .lz-avc__av { width:64px; height:64px; margin:0 auto 14px; border-radius:50%; position:relative;
    display:flex; align-items:center; justify-content:center; background:var(--surface-2); font-size:20px; font-weight:600; }
  .lz-avc__av::after { content:''; position:absolute; inset:-6px; border-radius:50%;
    border:2px solid var(--accent); opacity:.35; animation:lz-avc-pulso 1.6s ease-out infinite; }
  @keyframes lz-avc-pulso { 0% { transform:scale(1); opacity:.45; } 100% { transform:scale(1.18); opacity:0; } }
  .lz-avc__tit { font-size:18px; font-weight:600; letter-spacing:-.01em; line-height:1.3; }
  .lz-avc__emp { font-size:13px; color:var(--text-muted); margin-top:2px; }
  .lz-avc__sub { font-size:12.5px; color:var(--text-muted); margin-top:8px; }
  .lz-avc__mudo, .lz-avc__sinliga { font-size:12px; line-height:1.5; margin-top:12px; padding:9px 11px;
    border:1px solid var(--border); border-radius:var(--r-btn); background:var(--surface-2); color:var(--text); }
  .lz-avc__acc { display:flex; flex-direction:column; gap:10px; margin-top:18px; }
  .lz-avc__bt { display:block; width:100%; box-sizing:border-box; border-radius:var(--r-btn); padding:11px 14px;
    font-family:inherit; font-size:13.5px; font-weight:600; text-align:center; text-decoration:none; cursor:pointer;
    border:1px solid var(--border); }
  .lz-avc__bt--pri { background:var(--accent); color:var(--bg); border-color:var(--accent); }
  .lz-avc__bt--sec { background:var(--surface); color:var(--text); font-weight:500; }
  .lz-avc__bt--sec:hover { border-color:var(--text-muted); }
  .lz-avc__bt:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

  /* El aviso de 3 minutos: '.zaviso' (panel-chrome.js) pone la tarjeta base; esto solo la saca
     flotante a una esquina y la vuelve un renglon con boton de cerrar. No tapa nada, se ignora. */
  .lz-avc-previo { position:fixed; right:16px; bottom:16px; z-index:9000; max-width:320px;
    box-shadow:0 8px 24px rgba(10,10,10,.16); display:flex; align-items:flex-start; gap:10px; }
  .lz-avc-previo__txt { flex:1 1 auto; line-height:1.45; }
  .lz-avc-previo__liga { flex:none; margin-top:2px; text-decoration:none; }
  .lz-avc-previo__cerrar { flex:none; border:none; background:none; color:var(--text-muted); font-size:16px;
    line-height:1; cursor:pointer; padding:2px 4px; margin:-2px -4px 0 0; }
  .lz-avc-previo__cerrar:hover { color:var(--text); }
