/* ═══════════════════════════════════════════════════════════════════════════════════════════
   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 {
    /* tipografia y densidad: una sola familia, y --sp para que una vista pueda compactar sin tocar valores */
    --font: 'Inter', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif; --sp: 1;
    /* Sin monoespaciada (Alex, 15-oct, ola 9, PCB9A-16): cifras, horas, teléfonos, correos y cabeceras de tabla
       van en la sans con numerales tabulares. --mono se queda como nombre para no tocar cien selectores, pero
       vale la sans: un solo punto de cambio. La mono de verdad (--mono-code) queda solo para código, IDs y JSON
       crudo (code, pre, samp, .lz-code). Para volver a la mono de la versión 1.4 del DS: --mono: var(--mono-code). */
    --mono-code: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --mono: var(--font); --muted: var(--text-muted);
    /* radios: chips y controles chicos, campos, botones, tarjetas, pildora solo para contadores */
    --r-chip: 999px; --r-control: 8px; --r-input: 8px; --r-btn: 999px; --r-card: 12px; --r-pill: 999px;
    /* ALTO DE CONTROL (Alex, 15-oct: «revisa que todo esté alineado verticalmente»). Campo, select, campo compuesto
       y botón miden lo mismo para compartir alto y eje en una fila. Antes el campo medía 38 y la píldora 36, y en
       las filas con flex-end el botón quedaba más bajo que el campo (7 px en Ajustes · Campos). El par chico es
       para filas densas (tablas, cabeceras de tarjeta): .zbtn--sm va con .zinput--sm, nunca uno chico junto a uno
       normal. Regla en DESIGN.md · Alineación vertical. */
    --h-control: 38px; --h-control-sm: 30px;
    /* neutros SIN tinte: blanco y negro con toques de color (Alex, 13-oct). El tinte azul de la
       primera versión Cobalto hacía que el oscuro se viera azulado en vez de negro, como era el tema original. */
    /* El fondo baja a 97 % y el borde a 88 % para que la tarjeta blanca se despegue del fondo (Alex,
       13-oct: «falta diferenciación entre tarjetas y fondo» en claro). */
    --bg: #f4f4f4; --surface: #fafafa; --surface-2: #ededed; --surface-3: #e4e4e4;
    --border: rgba(0,0,0,.07); --line-2: rgba(0,0,0,.12);
    /* limite de CONTROL (campo, select, interruptor, chip discontinuo): --border mide 1.3:1 y un
       control necesita 3:1 contra la superficie y contra el fondo (WCAG 1.4.11). --border queda
       para hairlines que separan, nunca para delimitar algo que se aprieta o se escribe. */
    /* .42 da 3.0:1 sobre --surface (PCB9A-05, ola 9): a .14 medía 1.38:1 y el campo no se distinguía. */
    --border-control: rgba(0,0,0,.42);
    /* campo: fondo propio que contrasta con la tarjeta (Alex, 13-oct: «se están perdiendo»). Con «quieto» la
       tarjeta es #fafafa, así que el campo sube a blanco y su línea a 3:1 (PCB9A-05, ola 9); en oscuro el campo
       es más negro que la tarjeta. */
    --field: #ffffff; --field-line: rgba(0,0,0,.42);
    /* texto en tres niveles; los tres pasan 4.5:1 sobre fondo y superficie */
    --text: #2a2a2a; --text-2: #5a5a5a; --text-muted: #646464;
    /* acento (gris desde «quieto»): relleno del primario y de lo seleccionado; -soft es el chip claro, -text la tinta del enlace */
    --accent: #dcdcdc; --accent-hover: #d2d2d2; --accent-soft: #ededed;
    --accent-text: #3f3f3f; --ink-on-accent: #2a2a2a;
    /* Para los controles nativos (checkbox, radio, progress): el navegador pinta la palomita en blanco,
       así que el acento del control tiene que sostener blanco encima. En claro es el mismo acento. */
    --accent-control: #5a5a5a;
    /* FOCO: sigue al acento, como antes de la ola 9. PCB9A-01 lo había sacado a #646464 con anillo de 2 px
       (1d1eb33) y Alex lo descartó el 15-oct («no lo quiero»). El token se queda para que el foco tenga un
       solo punto de cambio: volver al gris de apoyo es cambiar esta línea y las de --ring abajo
       (registro en docs/leadz/auditoria/ola9-correcciones.md). */
    --focus: var(--accent);
    /* HOVER DE ENLACE: texto, no relleno (PCB9B-01, ola 9). --accent-hover es el hover del RELLENO del primario
       (#d2d2d2) y como color de texto dejaba el enlace a 1.45:1. El enlace en hover sube a la tinta principal. */
    --link-hover: var(--text);
    /* Selección y estado activo (nav, pestañas, filtros, chips de banda): NEUTROS. Alex, 13-oct:
       «blanco y negro con toques de color, se volvió demasiado colorido». El acento queda para la
       acción primaria, los contadores de aviso, los enlaces y el foco; el color semántico, para el
       punto del chip, nunca para su fondo. */
    --sel-bg: var(--surface-2); --sel-text: var(--text); --sel-line: var(--line-2);
    /* Chip o pestaña de filtro SELECCIONADO: un solo lenguaje en Tareas, Agenda, Pipeline y DS
       (PCB-74, Ola 7). Tinta sobre texto invertido, 3:1 contra lo que lo rodea en los dos temas. */
    --chip-on-bg: var(--text); --chip-on-text: var(--bg);
    /* burbuja saliente del hilo: un gris más que la entrante (blanca con borde) para distinguirlas */
    --bb-out: #e9e9e9;
    /* HILO DE WHATSAPP · tema de color del hilo (Alex, 13-oct): tres paletas elegibles en Ajustes ·
       Apariencia (retirado el 14-oct a pedido de Alex: un solo hilo; quedan las variables).
       «gris» es la de siempre; «pizarra» va oscura con un azul de pizarra (la referencia de
       Telegram, alineada a nuestros neutros); «cobalto» es la más azul, sobre el acento. Las
       seis variables son las UNICAS que lee el hilo: fondo, entrante y su línea, saliente y su
       texto, y la tinta del recibo leído. */
    --hilo-bg: var(--surface-2); --hilo-in: var(--surface); --hilo-in-line: var(--border);
    --hilo-out: var(--bb-out); --hilo-out-text: var(--text); --hilo-meta: var(--text-muted); --hilo-meta-on: var(--accent-text);
    /* semanticos aparte del acento: el color significa estado, nunca decoracion */
    /* --ok va en matiz 172 (verde azulado) y --wa en 150: eran el mismo verde (dE OKLab .03) y a
       tamano de icono no se distinguian. Ahora dE >= .08 en los dos temas. */
    --ok: oklch(50% 0.12 172); --ok-soft: oklch(94% 0.04 172); --ok-text: oklch(40% 0.10 172);
    --warn: oklch(62% 0.15 70); --warn-soft: oklch(95% 0.06 80); --warn-text: oklch(46% 0.11 70);
    --bad: oklch(53% 0.19 25); --bad-soft: oklch(95% 0.04 25); --bad-text: oklch(46% 0.17 25); --danger: var(--bad-text);
    --info: var(--accent);
    /* verde del canal WhatsApp, para distinguir el canal sin usar el verde de exito */
    --wa: oklch(54% 0.16 150); --ink-on-wa: #fff;
    /* color por etapa del embudo: del gris (nuevo) al ambar (cierre); ganado y perdido reusan lo semantico */
    --st-l: 50%; --st-c: 0.14;
    --st1: oklch(58% 0.03 262); --st2: oklch(var(--st-l) var(--st-c) 236); --st3: oklch(var(--st-l) 0.12 200);
    --st4: oklch(var(--st-l) 0.14 300); --st5: oklch(62% 0.14 70); --st-won: var(--ok); --st-lost: var(--bad);
    /* elevacion con desplazamiento vertical real; en oscuro la da la luminancia de la superficie */
    --shadow-sm: none;
    --shadow-md: 0 10px 28px -14px rgba(0,0,0,.18), 0 0 0 1px rgba(0,0,0,.05);
    /* marca: el simbolo y el wordmark NO leen --accent (la accion) para que el logo no parezca el
       boton primario; valor fijo, igual en los dos temas, con tinta blanca (6.2:1) */
    --brand: oklch(50% 0.19 262); --ink-on-brand: #fff;
    /* anillo de foco: UNA sola linea de 1.5 px en --focus (el acento), que respira (Alex, 13-oct: «no quiero
       doble linea en ningun lado»). --ring-soft es el punto bajo de la respiracion; --ring-inset es para
       contenedores con overflow que recortan el anillo exterior (acordeones, pestanas). Un campo con borde no
       suma anillo: su propio borde pasa a --focus y respira (lzBreathBorder). */
    --ring: 0 0 0 1.5px var(--focus);
    /* El valle del anillo que respira queda en 70 % (ACB-305, Ola 5). */
    --ring-soft: 0 0 0 1.5px color-mix(in oklch, var(--focus) 70%, transparent);
    --ring-inset: inset 0 0 0 1.5px var(--focus);
    --accent-breath: color-mix(in oklch, var(--focus) 70%, transparent);
    /* el anillo nace desde cero y crece (tanda A, 13-oct) */
    --ring-0: 0 0 0 0 var(--focus);
    /* escala tipografica (DESIGN.md): ningun tamano de texto fuera de estos siete */
    --fs-1: 12px; --fs-2: 13px; --fs-3: 14px; --fs-4: 15.5px; --fs-5: 18px; --fs-6: 22px; --fs-7: 28px;
    /* movimiento: dos duraciones y una curva; las animaciones largas respetan reduced-motion */
    --dur-1: 120ms; --dur-2: 200ms; --dur-3: 320ms; --ease-out: cubic-bezier(.2, 0, 0, 1);
    /* capas: una escala, no numeros sueltos */
    --z-sticky: 5; --z-drawer: 30; --z-dropdown: 40; --z-fab: 50; --z-modal: 100; --z-sf: 390; --z-toast: 9500;
    /* Capas que vivían como literales (9000, 9100) en las vistas (PCB-166, Ola 7): el modal de pantalla
       completa y la llamada en curso cuando hay una hoja abierta encima de todo. */
    --z-hoja: 9000; --z-softphone-curso: 9100;
    --z-base: 1; --z-cajon-velo: 55; --z-cajon: 60; --z-sf-velo: 400;
    /* la pantalla de cobro o suspensión tapa todo, incluida la barra de agentation en desarrollo */
    --z-bloqueo: 10001;
    /* hairline de modales y hojas, ademas de la sombra */
    /* .08 sobre un azul casi negro, regla de la casa (Alex); la ola 9 lo encontró en .06 (PCB9A-14) */
    --hairline: rgba(16,24,40,.08);
    color-scheme: light;
    /* tokens que nacieron con «quieto» */
    --pri-bg: #dcdcdc; --pri-bg-hover: #d2d2d2;
    /* Borde del primario gris (PCB9A-07, ola 9, Alex: «sí, borde de 1 px»): el relleno #dcdcdc mide 1.25:1 contra
       el fondo y se leía como desactivado. Al 55 % de la tinta da 3.3:1 contra --bg; el gris se queda. */
    --pri-line: color-mix(in oklch, var(--text) 55%, transparent);
    /* Muestras del selector de tema en Ajustes: el fondo real de cada tema, fijo aunque cambie el tema activo. */
    --muestra-claro: #f4f4f4; --muestra-oscuro: #161616;
    /* Módulo interno: un paso entre la tarjeta (--surface) y su borde, para que lo que vive DENTRO de una tarjeta se lea como
       pieza aparte sin otra sombra (Alex, 15-oct: «los módulos internos deberían tener un color ligeramente diferente»). */
    --surface-anidada: #f3f3f3;
    /* Velo de los modales a pantalla casi completa (el selector de plantillas D, Alex 15-oct): negro translúcido con
       desenfoque; detrás se adivina la conversación sin distraer. */
    --velo: rgba(10,10,10,.46); --velo-blur: 14px;
  }
  [data-ds-theme="dark"] {
    color-scheme: dark;
    /* negro de verdad, como el tema original (#0A0A0A / #161616 / #1c1c1c), sin tinte azul */
    --bg: #161616; --surface: #1d1d1d; --surface-2: #242424; --surface-3: #2c2c2c;
    --border: rgba(255,255,255,.08); --line-2: rgba(255,255,255,.13);
    --border-control: rgba(255,255,255,.34);
    --field: #141414; --field-line: rgba(255,255,255,.34);
    --text: #e6e6e6; --text-2: #b0b0b0; --text-muted: #989898;
    --accent: #3a3a3a; --accent-hover: #444444; --accent-soft: #242424;
    --accent-text: #cfcfcf; --ink-on-accent: #e6e6e6;
    /* Casillas, radios e interruptores encendidos en oscuro: el gris secundario #b0b0b0, que se ve sobre el fondo.
       (Con Cobalto era un azul que sostenía la palomita blanca; con «quieto» es gris, PCB9B-26, ola 9.) */
    --accent-control: #b0b0b0;
    /* Foco en oscuro: el acento del tema, como en claro (PCB9A-01 revertido). Se declara aquí también para que
       un bloque con data-ds-theme="dark" anidado lo resuelva en su tema. */
    --focus: var(--accent);
    --link-hover: var(--text);
    --sel-bg: var(--surface-3); --sel-text: var(--text); --sel-line: var(--line-2);
    --chip-on-bg: var(--text); --chip-on-text: var(--bg);
    --bb-out: #262626;
    --hilo-bg: var(--bg); --hilo-in: var(--surface); --hilo-in-line: var(--border);
    /* --hilo-meta en oscuro va en --text-2 y no en --text-muted: sobre la burbuja saliente medía 4.21:1 (Ola 4). */
    --hilo-out: var(--bb-out); --hilo-out-text: var(--text); --hilo-meta: var(--text-2); --hilo-meta-on: var(--accent-text);
    --ok: oklch(74% 0.12 178); --ok-soft: oklch(26% 0.04 178); --ok-text: var(--ok);
    --warn: oklch(78% 0.14 75); --warn-soft: oklch(28% 0.06 75); --warn-text: var(--warn);
    --bad: oklch(72% 0.16 25); --bad-soft: oklch(27% 0.06 25); --bad-text: var(--bad);
    --wa: oklch(74% 0.16 146); --ink-on-wa: oklch(16% 0.06 150);
    --st-l: 72%;
    --st1: oklch(66% 0.03 262); --st2: oklch(var(--st-l) 0.13 236); --st3: oklch(var(--st-l) 0.11 200);
    --st4: oklch(var(--st-l) 0.12 300); --st5: oklch(78% 0.12 75);
    --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --shadow-md: 0 12px 28px -14px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.05);
    --hairline: rgba(255,255,255,.08);
    /* tokens que nacieron con «quieto» */
    --pri-bg: #3a3a3a; --pri-bg-hover: #444444; --pri-line: color-mix(in oklch, var(--text) 55%, transparent);
    --surface-anidada: #222222;
    --velo: rgba(0,0,0,.58);
  }

  html { scrollbar-color: var(--line-2) transparent; accent-color: var(--accent-control); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  /* Foco de respaldo para todo lo que no trae regla propia (boton de tema, summary, casillas, la
     pildora del telefono, "Entrar con Google"): el mismo anillo del sistema. :where() lo deja en
     especificidad 0 para que cualquier regla de componente gane sin pelear. */
  :where(a, button, summary, select, input[type=checkbox], input[type=radio], [tabindex]):focus-visible { outline: none; box-shadow: var(--ring); }
  /* WebKit no pinta box-shadow sobre un checkbox o radio nativo (F1-01, medido: 0 px cambiados en Safari contra 160 en
     Chromium): esos dos llevan contorno propio. Y los controles nativos son clicables: cursor de mano (F1-20). */
  input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: none; }
  input[type="checkbox"], input[type="radio"], .zswitch { cursor: pointer; }
  @media (hover: hover) { .zinput:hover:not(:disabled):not(:focus-visible) { border-color: var(--text-muted); } }
  /* Animación del anillo: crece de 0 a su medida en 160 ms. Vive en :focus-visible, así el foco por
     ratón no la dispara. Reduced-motion la corta por la regla global de abajo. */
  @keyframes lzRing { from { box-shadow: var(--ring-0); } }
  /* Respiración: el anillo baja al 85 % y vuelve, cada 1.8 s, mientras el foco esté ahí. */
  @keyframes lzBreath { to { box-shadow: var(--ring-soft); } }
  @keyframes lzBreathBorder { to { border-color: var(--accent-breath); } }
  :focus-visible { animation: lzRing var(--dur-2) var(--ease-out), lzBreath 1.8s ease-in-out var(--dur-2) infinite alternate; }
  /* Pulsación: el botón baja 1 px y se encoge un 2 % mientras se aprieta. */
  .zbtn { transition: background var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out); }
  .zbtn:active { transform: translateY(1px) scale(.98); }
  /* Estado "Guardando": lo pone el cascarón al enviar un formulario con primario; el glifo gira. */
  .zbtn.is-saving { pointer-events: none; opacity: .85; }
  .zbtn.is-saving::before { content: ""; width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: lzSpin .7s linear infinite; flex: none; }
  @keyframes lzSpin { to { transform: rotate(360deg); } }
  /* Windows (forced-colors) borra las sombras, y el foco vive en box-shadow: aqui se le da contorno real. */
  @media (forced-colors: active) { :focus-visible { outline: 2px solid CanvasText !important; outline-offset: 2px; } }
  /* Y el estado elegido, que en el tema vive en el relleno, se pierde con él (PCB9A-10, ola 9): la etapa actual del
     stepper y todo segmentado con aria-pressed llevan borde de 2 px en Highlight, una vez para todo el producto. */
  /* !important solo aquí: en colores forzados el borde ES el estado, y los segmentados de cada vista (.lz-tl-seg button,
     .lz-ibx-tabs) le ganaban por especificidad con su border:0 (verificador de la ola 9). */
  @media (forced-colors: active) { .lz-step.on, .lz-step[aria-current], .lz-step:has([aria-current]), [aria-pressed="true"], [aria-selected="true"][role="tab"], [aria-current]:not([aria-current="false"]) { border: 2px solid Highlight !important; } }
  ::placeholder { color: var(--text-muted); opacity: 1; }
  /* sin zoom de doble toque en controles, modales y velos */
  a, button, summary, label, select, [role=button], .lz-modal, .lz-velo, .lz-cajon { touch-action: manipulation; }
  ::selection { background: color-mix(in oklch, var(--accent) 28%, transparent); }
  /* 3 · Transición entre páginas (View Transitions entre documentos): la raíz se funde en 200 ms y
     el nombre del lead viaja de la tarjeta del tablero al título de la ficha (view-transition-name
     por lead, puesto en línea). Reduced-motion la apaga. */
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur-2); animation-timing-function: var(--ease-out); }
  @media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }
  /* 4 · Esqueleto de carga: bloques grises con brillo que recorre; sustituye al spinner mientras
     llega una lista o un hilo. Dos medidas: renglón (.lz-skel) y bloque (.lz-skel--b). */
  .lz-skel { display: block; height: 12px; border-radius: 6px; background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%); background-size: 200% 100%; animation: lzSkel 1.4s ease-in-out infinite; }
  .lz-skel--b { height: 64px; border-radius: var(--r-card); }
  .lz-skel--t { height: 16px; width: 40%; }
  .lz-skel--c { width: 36px; height: 36px; border-radius: 50%; }
  .lz-skel-fila { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
  .lz-skel-fila > div { flex: 1; display: grid; gap: 8px; }
  @keyframes lzSkel { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
  * { box-sizing: border-box; }
  /* Los controles heredan la fuente: sin esto un botón sin clase sale a 13.33 px del navegador. */
  button, input, select, textarea { font-family: inherit; font-size: inherit; }
  html, body { margin: 0; padding: 0; }
  body { background: var(--bg); color: var(--text); font-family: var(--font); font-variant-numeric: tabular-nums; font-size: 13.5px; line-height: 1.45; caret-color: var(--accent); -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; }
  @media (hover:hover) { .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-control); 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: var(--font); font-size: 12px; font-weight: 500; letter-spacing: .03em; color: var(--text-muted); }
  h1 { margin: 6px 0 24px; font-size: var(--fs-6); font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; }
  /* titulo de pagina canonico: h1 de 22 px dentro de .zcab (con su zona de acciones a la derecha), o .lz-h1 suelto */
  .zcab h1, .lz-h1 { margin: 0; font-size: var(--fs-6); font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; }
  h2 { margin: 0 0 14px; font-size: var(--fs-4); font-weight: 600; }
  .muted { color: var(--text-muted); }
  .mono { font-family: var(--mono); font-size: 12px; font-variant-numeric: tabular-nums; }
  code, pre, samp, .lz-code { font-family: var(--mono-code); }

  .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; }
  /* Los campos llevan un tinte apenas perceptible (feedback de Alex, 13-oct) para distinguirse del
     papel; al enfocar vuelven al blanco de la superficie. */
  .zinput, .zta, select.zinput { width: 100%; border-radius: var(--r-input); border: 1px solid var(--field-line); background: var(--field); color: var(--text); padding: 9px 12px; font-size: 13.5px; font-family: inherit; }
  .zinput, .zfield { height: var(--h-control); }
  .zfield { box-sizing: border-box; }
  /* Par chico del campo: mismo alto que .zbtn--sm, para la fila densa que lleva botón chico. */
  .zinput.zinput--sm { height: var(--h-control-sm); padding-top: 0; padding-bottom: 0; padding-left: 10px; font-size: var(--fs-2); }
  select.zinput.zinput--sm { padding-right: 28px; background-position: right 8px center; background-size: 14px 14px; }
  /* El select con apariencia propia: con fondo propio Safari pintaba su flecha nativa pegada al
     borde y sin aire interno (feedback de Alex, 13-oct). Chevron de Lucide (chevron-down) como
     imagen de fondo, en un gris que pasa 3:1 sobre el campo en los dos temas, y 32 px de padding
     derecho para que el texto no se le monte. Las reglas de arriba usan background-color, no
     background, para no borrar la imagen en foco ni en disabled. */
  select.zinput { appearance: none; -webkit-appearance: none; padding-top: 0; padding-bottom: 0; padding-right: 32px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23737a8c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; background-size: 16px 16px; text-overflow: ellipsis; }
  select.zinput[multiple], select.zinput[size] { background-image: none; padding-right: 12px; height: auto; }
  /* En oscuro el gris del chevron sube para seguir pasando 3:1 sobre el campo. */
  [data-ds-theme="dark"] select.zinput { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa0ae' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
  .zta { resize: vertical; line-height: 1.6; }
  .zinput:focus, .zta:focus { outline: none; border-color: var(--focus); box-shadow: none; animation: lzBreathBorder 1.8s ease-in-out infinite alternate; }
  /* campo compuesto (contenedor con borde + input sin borde): el anillo va en el contenedor */
  .zfield:focus-within { border-color: var(--focus); box-shadow: none; animation: lzBreathBorder 1.8s ease-in-out infinite alternate; }
  .zfield input, .zfield textarea { outline: none; box-shadow: none; border: 0; background: transparent; }
  .zfield input:focus-visible, .zfield textarea:focus-visible { animation: none; box-shadow: none; }
  .zinput::placeholder, .zta::placeholder, .zfield input::placeholder, .zfield textarea::placeholder { color: var(--text-muted); opacity: 1; }
  .zinput[disabled], .zta[disabled] { background-color: var(--surface-2); color: var(--text-muted); cursor: not-allowed; }
  /* La ayuda corre a lo ancho de su contenedor y nunca se recorta (feedback de Alex, 13-oct). */
  .zhint { font-size: var(--fs-1); color: var(--text-muted); margin-top: 5px; max-width: none; white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.5; }
  /* parrafos de ayuda: renglones de 150 caracteres no se leen; 75 es el techo */
  /* Texto de ayuda en LISTA (regla de Alex): un renglon por pregunta, palabra clave en negrita al
     inicio y una hairline entre renglones. Sin vinetas. <div class="zayuda"><div><b>Que cuenta</b> ...</div>...</div> */
  .zayuda { display: grid; font-size: var(--fs-2); line-height: 1.45; color: var(--text-2); }
  .zayuda > * { padding: 6px 0; border-top: 1px solid var(--border); }
  .zayuda > :first-child { padding-top: 0; border-top: 0; }
  .zayuda > :last-child { padding-bottom: 0; }
  .zayuda b { font-weight: 600; color: var(--text); margin-right: 4px; }
  /* region de tabla con scroll horizontal: foco por teclado, nombre y sombra de borde cuando hay mas contenido */
  /* position:relative: el scroller es el bloque contenedor de lo que va en absoluto dentro (el texto de lector .lz-sr);
     sin esto la página entera medía 612 px a 390 en Reportes (F1-08). */
  .lz-scroll-x { position: relative; overflow-x: auto; max-width: 100%; background:
    linear-gradient(to right, var(--surface) 30%, transparent) left / 24px 100% no-repeat local,
    linear-gradient(to left, var(--surface) 30%, transparent) right / 24px 100% no-repeat local,
    linear-gradient(to right, color-mix(in oklch, var(--text) 14%, transparent), transparent) left / 10px 100% no-repeat scroll,
    linear-gradient(to left, color-mix(in oklch, var(--text) 14%, transparent), transparent) right / 10px 100% no-repeat scroll; }
  .lz-scroll-x:focus-visible { outline: none; box-shadow: var(--ring-inset); }

  /* 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: var(--h-control); padding: 0 16px; border-radius: var(--r-btn); border: 1px solid var(--border-control); 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; }
  /* El color va explícito en hover porque a:hover (color de enlace, 0,1,1) le ganaba a .zbtn--pri (0,1,0)
     y el primario de Tareas quedaba gris con texto azul al pasar el puntero (Alex, 14-oct). */
  /* El hover solo responde en lo habilitado (F1-04: 36 botones deshabilitados reaccionaban como si pudieran actuar). */
  @media (hover: hover) { .zbtn:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--surface-2); color: var(--text); } }
  .zbtn[disabled]:active, .zbtn[aria-disabled="true"]:active { transform: none; }
  .zbtn:active { background: var(--surface-3); }
  /* Primario base en tinta (Alex, 13-oct); el bloque de «quieto» más abajo lo pasa al relleno gris con borde
     --pri-line, que es lo que se ve (PCB9B-26, ola 9). */
  .zbtn--pri { background: var(--text); color: var(--bg); border-color: var(--text); }
  /* Hover del primario: la tinta se atenúa un 10 %, no baja a --text-2 (78 % en oscuro), que leía como deshabilitado. */
  @media (hover: hover) { .zbtn--pri:hover:not([disabled]):not([aria-disabled="true"]) { background: color-mix(in oklch, var(--text) 90%, var(--bg)); border-color: color-mix(in oklch, var(--text) 90%, var(--bg)); color: var(--bg); } }
  /* El color del primario no depende del estado: en táctil no hay @media (hover:hover) y a:hover lo volvía azul sobre gris (F1-03). */
  @media (hover:hover) { a.zbtn--pri, a.zbtn--pri:hover, a.zbtn--pri:active { color: var(--bg); } }
  .zbtn--pri:active { background: color-mix(in oklch, var(--text) 82%, var(--bg)); border-color: color-mix(in oklch, var(--text) 82%, var(--bg)); color: var(--bg); }
  /* Todo botón lleva su glifo (Alex, 14-oct noche): 16 px, sin encoger, el trazo lo pone .lz-glifo. */
  .zbtn .lz-glifo { width: 16px; height: 16px; flex: none; }
  .zbtn--sm .lz-glifo { width: 14px; height: 14px; }
  .zbtn:focus-visible { outline: none; box-shadow: var(--ring); border-color: var(--accent); }
  .zbtn[disabled] { opacity: .45; cursor: not-allowed; }
  /* Tres niveles de botón (PCB-93): primario macizo, secundario con borde, ghost sin borde para lo
     terciario. El destructivo se distingue por el tono de error y nunca por ser rojo macizo. */
  /* Tooltip visible al pasar o enfocar (feedback de Alex, 13-oct): el title nativo tarda y no se ve en
     touch. Va en data-tip, sin JS, y no sustituye al aria-label. */
  .lz-tip { position: relative; }
  .lz-tip::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%) translateY(2px); background: var(--text); color: var(--bg); font-size: var(--fs-1); font-weight: 500; line-height: 1; padding: 6px 8px; border-radius: var(--r-chip); white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out); z-index: var(--z-dropdown); }
  /* 300 ms de retardo al pasar (PCB-107, Ola 8): el globo no salta al cruzar el puntero; con foco sale
     al instante. Esc lo cierra (SCRIPT_TITULOS pone data-tip-cerrado) hasta que el foco cambie. */
  .lz-tip::after { transition-delay: 0s; }
  @media (hover: hover) { .lz-tip:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); transition-delay: 300ms; } }
  .lz-tip[data-tip-cerrado]::after { opacity: 0 !important; }
  .lz-tip:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }
  @media (prefers-reduced-motion: reduce) { .lz-tip::after { transition: none; } }
  /* Lado del globo (Alex, 15-oct): data-tip-lado="abajo|izquierda|derecha" en el control; arriba por omisión. Es CSS,
     así que no se voltea solo: el lado se elige al pintar el control según el borde que tenga cerca. El flotante de
     SCRIPT_TITULOS lee el mismo atributo y sí se voltea cuando no cabe. */
  .lz-tip[data-tip-lado="abajo"]::after { bottom: auto; top: calc(100% + 6px); transform: translateX(-50%) translateY(-2px); }
  .lz-tip:is([data-tip-lado="izquierda"], [data-tip-lado="derecha"])::after { bottom: auto; top: 50%; }
  .lz-tip[data-tip-lado="izquierda"]::after { left: auto; right: calc(100% + 6px); transform: translateY(-50%) translateX(2px); }
  .lz-tip[data-tip-lado="derecha"]::after { left: calc(100% + 6px); transform: translateY(-50%) translateX(-2px); }
  @media (hover: hover) {
    .lz-tip[data-tip-lado="abajo"]:hover::after { transform: translateX(-50%) translateY(0); }
    .lz-tip:is([data-tip-lado="izquierda"], [data-tip-lado="derecha"]):hover::after { transform: translateY(-50%); }
  }
  .lz-tip[data-tip-lado="abajo"]:focus-visible::after { transform: translateX(-50%) translateY(0); }
  .lz-tip:is([data-tip-lado="izquierda"], [data-tip-lado="derecha"]):focus-visible::after { transform: translateY(-50%); }
  /* El globo flotante de SCRIPT_TITULOS: uno solo para toda la página, fijo y por encima de todo, con la misma
     tinta invertida que .lz-tip. No se recorta en contenedores con overflow y no roba el puntero. */
  .lz-tooltip { position: fixed; left: 0; top: 0; z-index: var(--z-toast); max-width: 260px; padding: 5px 8px; border-radius: 6px; background: var(--text); color: var(--bg); font-size: var(--fs-1); line-height: 1.3; font-weight: 500; box-shadow: var(--shadow-sm); pointer-events: none; opacity: 0; transform: translateY(2px); transition: opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out); white-space: normal; }
  .lz-tooltip.on { opacity: 1; transform: none; }
  .lz-tooltip--abajo { transform: translateY(-2px); }
  .lz-tooltip--abajo.on { transform: none; }
  .lz-tooltip--izquierda { transform: translateX(2px); }
  .lz-tooltip--derecha { transform: translateX(-2px); }
  .lz-tooltip--izquierda.on, .lz-tooltip--derecha.on { transform: none; }
  @media (prefers-reduced-motion: reduce) { .lz-tooltip { transition: none; } }
  /* Formulario en una fila: todo en un eje (align-items:center), con la etiqueta a la izquierda de su campo.
     Solo cuando la etiqueta va ENCIMA de su campo (label que envuelve el campo) la fila se alinea abajo:
     centrar contra una caja que incluye la etiqueta bajaría el botón. Con los dos controles al mismo
     --h-control, alinear abajo es alinear el eje. La etiqueta no lleva margen, que es lo que desalineaba
     el botón. */
  .zinline { display: flex; gap: 8px 10px; align-items: center; flex-wrap: wrap; }
  .zinline:has(> label > :is(.zinput, .zfield, select), > div > label > :is(.zinput, .zfield, select), > div > label + :is(.zinput, .zfield, select)) { align-items: flex-end; }
  .zinline label { margin: 0; display: grid; gap: 6px; }
  .zinline label .zinput { margin: 0; }
  .zbtn--ghost { background:transparent; border-color:transparent; color:var(--text-2); }
  @media (hover: hover) { .zbtn--ghost:hover:not([disabled]):not([aria-disabled="true"]) { background:var(--surface-2); color:var(--text); } }
  .zbtn--danger { color:var(--bad-text); border-color:var(--bad); background:var(--surface); }
  @media (hover: hover) { .zbtn--danger:hover:not([disabled]):not([aria-disabled="true"]) { background:var(--bad-soft); border-color:var(--bad-soft); } }
  .zbtn--sm { height:var(--h-control-sm); padding:0 12px; font-size:var(--fs-2); }
  /* En tactil el objetivo es de 44 px y los campos de 16 px: por debajo de 16 Safari de iPhone hace
     zoom al enfocar y el asesor pierde la pantalla. */
  @media (pointer: coarse) {
    .zbtn, .zbtn--sm { min-height: 44px; }
    .zinput, .zta, select.zinput, input[type=search], input[type=text], input[type=email], input[type=tel], input[type=datetime-local] { font-size: 16px; }
    :root { --h-control: 44px; --h-control-sm: 44px; }
    .zinput.zinput--sm { font-size: 16px; }
    #zg-theme { width: 44px; height: 44px; }
  }
  /* Interruptor: booleano de efecto inmediato (PCB-1435). Lleva role=switch y etiqueta visible. */
  .zswitch { appearance:none; -webkit-appearance:none; width:34px; height:20px; border-radius:var(--r-pill); background:var(--surface-3); border:1px solid var(--border-control); position:relative; cursor:pointer; vertical-align:middle; margin:0; }
  .zswitch::after { content:""; position:absolute; top:2px; left:2px; width:14px; height:14px; border-radius:50%; background:var(--surface); box-shadow:0 0 0 1px var(--border-control); transition:transform var(--dur-1) var(--ease-out); }
  .zswitch { transition:background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out); }
  .zswitch:active::after { width:18px; }
  .zswitch:checked { background:var(--accent); border-color:var(--accent); }
  @media (hover: hover) { .zswitch:hover:not(:disabled) { border-color: var(--text-muted); } }
  .zswitch:checked::after { transform:translateX(14px); background:var(--ink-on-accent); box-shadow:none; }
  .zswitch:focus-visible { outline:none; box-shadow:var(--ring); }
  select.zinput:focus-visible { box-shadow: none; }
  /* Reduced motion, global: ninguna animacion infinita (pulsos del telefono y de la alerta de cita,
     anillo de llamada) ni transicion larga sobrevive a la preferencia del sistema. Lo que informaba
     con el pulso lo sigue diciendo el texto y el borde estatico de cada componente. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
  }
  /* Quien pide más contraste al sistema (PCB-244, Ola 7): bordes al tono de control, texto
     atenuado al secundario y líneas de campo y control más firmes que en el modo normal (PCB9A-06,
     ola 9: igualarlas a --border-control las dejaba IGUAL o más débiles). El foco no se toca: sigue al
     acento por decisión de Alex. forced-colors se atiende aparte con los colores del sistema. */
  @media (prefers-contrast: more) {
    :root { --border-control: rgba(0,0,0,.55); --field-line: rgba(0,0,0,.55); --border: var(--border-control); --hairline: rgba(16,24,40,.2); --text-muted: var(--text-2); --line-2: var(--border-control); }
    [data-ds-theme="dark"] { --border-control: rgba(255,255,255,.45); --field-line: rgba(255,255,255,.45); --hairline: rgba(255,255,255,.2); }
  }
  .zrow { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 18px; }

  /* Bordes SEPARADOS con espaciado 0 (Alex, 15-oct: «en algunas tablas se ve como doble línea o más remarcada, debe ser
     estable y continua»): con border-collapse:collapse Safari pinta el borde de cada celda por su cuenta y bajo la primera
     columna la línea salía más brillante (medido en WebKit: 63 contra 47 en Por devolver, Ganados, Perdidos y Lista). Con
     separate cada celda lleva solo su border-bottom y la línea es una. Ninguna tabla del panel dibuja border-top en sus
     celdas, así que no aparecen dobles. */
  table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 8px; }
  /* Tabla global (decisión de Alex, 13-oct, «hairline»): cabecera mono en mayúscula sobre una línea
     firme, filas separadas solo por hairline horizontal, celdas centradas en vertical, cifras
     tabulares y a la derecha con .n, «sin dato» apagado y en mono con .lz-nd. Sin cebra ni fondos. */
  th { text-align: left; font-family: var(--mono); font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); font-weight: 600; padding: 0 10px; height: 36px; border-bottom: 1px solid var(--border); vertical-align: middle; white-space: nowrap; }
  td { padding: 8px 10px; border-bottom: 1px solid var(--border); font-size: var(--fs-3); vertical-align: middle; font-variant-numeric: tabular-nums; }
  th.n, td.n { text-align: right; }
  .lz-nd { color: var(--text-muted); font-family: var(--mono); font-size: var(--fs-2); }
  tr.lz-total td, tfoot td { border-top: 1px solid var(--line-2); border-bottom: 0; font-weight: 600; }
  /* Con bordes separados, la fila de arriba del total no dibuja su hairline: si no, se juntaban dos líneas. */
  tr:has(+ tr.lz-total) > td, table:has(> tfoot) > tbody > tr:last-child > td { border-bottom: 0; }
  /* La última fila no lleva separador: el borde de la tarjeta ya cierra la tabla (feedback de Alex, 13-oct). */
  tbody tr:last-child td { border-bottom: 0; }
  caption { text-align: left; font-size: var(--fs-2); color: var(--text-muted); padding: 0 0 6px; }
  td a { color: var(--accent-text); text-decoration: none; }
  @media (hover:hover) { td a:hover { text-decoration:none; color:var(--link-hover); } }

  .badge { display: inline-block; padding: 2px 8px; border-radius: var(--r-pill); border: 1px solid var(--border); font-size: var(--fs-1); font-weight: 500; font-family: var(--font); }
  .badge--on { background: var(--sel-bg); color: var(--sel-text); border-color: transparent; font-weight: 600; }
  .badge--mal { background: var(--bad-soft); color: var(--bad-text); border-color: transparent; }

  .zaviso { border: 1px solid var(--border); border-radius: var(--r-card); padding: 12px 14px; font-size: 13px; margin-bottom: 20px; background: var(--surface-2); }
  /* La sesion simulada de desarrollo se ve siempre: ambar, sin cierre, encima de todo aviso. */
  .zaviso--dev { background: var(--warn-soft); color: var(--warn-text); border-color: color-mix(in oklch, var(--warn) 35%, var(--border)); font-weight: 500; }
  .zalert { border: 1px solid var(--bad); background: var(--bad-soft); color: var(--bad-text); 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 { flex: 0 0 auto; }
  /* El lockup del pie: medida por regla base (el canario de glifos no acepta un svg sin ella). */
  .zlogo { height: 20px; width: auto; display: block; }


  /* QUIETO ES EL DS (Alex, 14-oct-2026: «quieto por omisión»): lo que nació como variante es ahora la base. Botones sin
     alto contraste (primario Gris elevado), controles y contadores en gris, enlaces con peso, aviso de desarrollo
     neutro. Historia y medidas en docs/leadz/DIRECCION-QUIETA.md. */
  .zbtn { background: var(--surface-2); border-color: var(--border-control); }
  @media (hover:hover) { .zbtn:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--surface-3); } }
  .zbtn--pri { background: var(--pri-bg); border-color: var(--pri-line); color: var(--text); font-weight: 500; }
  @media (hover:hover) { .zbtn--pri:hover:not([disabled]):not([aria-disabled="true"]) { background: var(--pri-bg-hover); border-color: var(--pri-line); color: var(--text); } }
  .zbtn--pri:active { background: var(--pri-bg-hover); border-color: var(--pri-line); color: var(--text); }
  .zbtn--pri:is([disabled], [aria-disabled="true"]) { border-color: transparent; }
  @media (hover:hover) { a.zbtn--pri, a.zbtn--pri:hover { color: var(--text); } }
  .zswitch:checked { background: var(--accent-control); border-color: var(--accent-control); }
  .lz-check input:checked { background: var(--accent-control); border-color: var(--accent-control); }
  .lz-cv .lz-cnt, .lz-ibx[data-avisos="on"] #lz-av-b { background: var(--surface-3); color: var(--text); }
  .lz-cx-barra i { background: var(--text-2); }
  .zbtn--ghost { background: transparent; border-color: transparent; }
  /* Barra superior (15-oct, Alex: «línea más sutil y rellenito sutil»): línea --line-2 y relleno --surface. Los botones de
     icono lo llevan en su regla base (ESTILOS_LEADZ, leadz-vistas.js); «Nuevo lead» aquí. Regla en DESIGN.md · Cascarón. */
  .lz-top__nuevo { background: var(--surface); color: var(--text); border-color: var(--line-2); font-weight: 500; }
  @media (hover:hover) { .lz-top__nuevo:hover:not([disabled]) { background: var(--surface-2); border-color: var(--line-2); color: var(--text); } }
  .lz-top__n { background: var(--text-2); color: var(--bg); }
  .lz-yo__dev { background: var(--surface-3); color: var(--text-2); }
  a:not(.zbtn):not(.lz-snav a):not(.lz-top__marca) { font-weight: 500; }
  .zaviso--dev { background: var(--surface-2); color: var(--text-2); border-color: var(--border); }
  body { line-height: 1.5; }
  h1, h2, h3 { font-weight: 500; letter-spacing: -.012em; }
  .zcard { padding: 22px; box-shadow: none; }
  .zbtn { font-weight: 450; }
  .zbtn--pri { font-weight: 500; }
  .lz-eyebrow, .eyebrow-keep { font-weight: 500; letter-spacing: .04em; color: var(--text-muted); }

  /* MÓDULO INTERNO (15-oct): lo que vive dentro de una tarjeta (fila editable, sub-bloque, tarjeta anidada) va en
     --surface-anidada con hairline, nunca en el mismo --surface de la tarjeta ni con sombra propia. Los campos de adentro
     conservan su fondo de campo. Regla en DESIGN.md · Superficies. */
  .lz-modulo, .zcard .zcard { background: var(--surface-anidada); border: 1px solid var(--hairline); border-radius: var(--r-control); box-shadow: none; }

  /* '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. */
  /* align-items:center y no baseline (15-oct, Alineación vertical): con baseline el botón de la derecha se colgaba
     de la línea base del título y quedaba fuera de eje con los campos de su misma zona de acciones. */
  .zcab { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-bottom:6px; }
  /* Con acciones al lado, el h2 pierde su margen: el inferior de 14 px lo subía 7 px sobre el eje de sus controles.
     Sin acciones conserva el margen, que es el aire entre el título y lo que sigue. :root para ganarle a
     «:root .lz-blk h2» de leadz-quieto.js. */
  :root .zcab:has(> :not(h1, h2, h3)) > :is(h2, h3) { margin-block:0; }
  /* El bloque de usuario: avatar de iniciales en accent-soft, nombre y rol. */
  .lz-yo { display:flex; align-items:center; gap:10px; padding:0 6px; }
  .lz-yo__av { width:30px; height:30px; flex:0 0 auto; border-radius:50%; background:var(--sel-bg); color:var(--sel-text); display:grid; place-items:center; font-size:11.5px; font-weight:700; }
  .lz-yo__n { font-size:13px; font-weight:600; line-height:1.2; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-yo__r { font-size:11.5px; color:var(--text-muted); margin-top:1px; }
  /* Identidad de desarrollo (Ola 4): en las pantallas plenas el toast de 522×64 tapaba el nombre del
     chat; en escritorio queda este chip junto a la persona y en móvil el toast se ancla abajo. */
  .lz-yo__dev { display:inline-flex; align-items:center; height:16px; margin-left:auto; padding:0 6px; border-radius:var(--r-pill); background:var(--warn-soft); color:var(--warn-text); font-size:var(--fs-1); font-weight:600; letter-spacing:.04em; }
  .lz-yo__dev--soporte { background:var(--accent-soft); color:var(--accent-text); }
  @media (max-width:820px) { .lz-toast:has(.zaviso--dev) { top:auto; bottom:calc(var(--lz-bar, 60px) + 8px + env(safe-area-inset-bottom)); left:8px; right:8px; transform:none; max-width:none; } .lz-toast .zaviso--dev { font-size:var(--fs-1); padding:6px 10px; } }
  .zcab h2 { margin:0; }
  /* EL ENLACE DE TEXTO (Cobalto). Color de acento, sin subrayado en reposo; el subrayado aparece
     solo al pasar el cursor, con separacion de 3px. Antes iba subrayado siempre porque el sistema
     era monocromatico y el subrayado era la unica afordancia; con un acento con significado el
     color ya dice "se puede apretar" y el subrayado permanente solo mete ruido (regla de Alex).
     Sigue siendo la regla mas floja (0-0-1) para perder contra cualquier clase de cromo. Dentro de
     una burbuja saliente el texto es claro sobre cobalto: ahi el enlace hereda el color. */
  /* ═══════════════════════════════════════════════════════════════════════════════════════════
     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.75; stroke-linecap:round; stroke-linejoin:round; vertical-align:-.15em; }

  a { color:var(--accent-text); text-decoration:none; }
  /* Solo con puntero que de verdad flota: en táctil el hover se queda pegado tras el toque (F1-03, F1-22). */
  @media (hover:hover) { a:hover { text-decoration:none; color:var(--link-hover); } }
  /* En la burbuja saliente el enlace hereda el color del texto: la burbuja ya es acento suave y un
     segundo tono de acento encima leería como ruido. */
  .lz-bb--out a { color:inherit; }
  a:focus-visible { outline:none; box-shadow:var(--ring); border-radius:3px; }

  /* ---- La barra superior (14-oct, versión 2 refinada de barra-4): marca, el hueco de la llamada en
     curso (lo llena telefonia.js cuando hay una), Nuevo lead, el hub (⌘K), avisos y la persona con
     el tema y Salir en su menú. La columna queda solo para navegar y arranca contraída. --lz-top es
     su alto y todo lo pegajoso (columna, subcolumna, pestañas, pantallas plenas) se mide contra él. */
  :root { --lz-top:52px; }
  .lz-top { position:sticky; top:0; z-index:calc(var(--z-drawer) + 1); display:flex; align-items:center; gap:10px; height:var(--lz-top); padding:0 14px; box-sizing:border-box; background:var(--surface); border-bottom:1px solid var(--border); }
  .lz-top__marca { display:flex; align-items:center; gap:10px; flex:0 0 auto; min-width:0; min-height:24px; color:var(--text); text-decoration:none; border-radius:var(--r-control); }
  /* El logo alinea su borde izquierdo con los iconos de la columna (x=23, medido el 14-oct; antes quedaba en 14 y se veía
     corrido: feedback de Alex por agentation). En teléfono no hay columna y la barra conserva su aire de 12. */
  @media (min-width:821px) { .lz-top__marca { padding-left:9px; } }
  .lz-top__marca svg { display:block; }
  .lz-top__marca:focus-visible { outline:none; box-shadow:var(--ring); }
  @media (hover:hover) { .lz-top__marca:hover { text-decoration:none; color:var(--text); } }
  .lz-top__inst { font-size:13px; color:var(--text-2); white-space:nowrap; padding-left:10px; border-left:1px solid var(--hairline); }
  .lz-top__llamada { flex:1 1 auto; min-width:0; display:flex; justify-content:center; }
  .lz-top__der { margin-left:auto; display:flex; align-items:center; gap:8px; flex:0 0 auto; }
  .lz-top__ico { position:relative; display:inline-grid; place-items:center; width:36px; height:36px; padding:0; border:1px solid var(--line-2); border-radius:var(--r-control); background:var(--surface); color:var(--text); cursor:pointer; }
  .lz-top__ico svg { width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round; }
  @media (hover:hover) { .lz-top__ico:hover { background:var(--surface-2); } }
  .lz-top__ico:focus-visible { outline:none; box-shadow:var(--ring); }
  .lz-top__ico[aria-expanded="true"] { background:var(--sel-bg); color:var(--sel-text); border-color:transparent; }
  .lz-top__n { position:absolute; top:-6px; right:-6px; min-width:17px; height:17px; padding:0 4px; box-sizing:border-box; border-radius:var(--r-pill); background:var(--text); color:var(--bg); font-size:10.5px; font-weight:600; line-height:17px; text-align:center; font-variant-numeric:tabular-nums; }
  .lz-top__nuevo { height:36px; padding:0 12px; }
  .lz-top__nuevo .lz-glifo { width:16px; height:16px; }
  @media (max-width:1023px) { .lz-top__nuevo { width:36px; padding:0; justify-content:center; } .lz-top__nuevo span { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; } }
  /* Menús colgados de la barra (details): uno abierto a la vez, Esc y clic fuera cierran (script en barraSuperior). */
  .lz-menu { position:relative; }
  .lz-menu > summary { list-style:none; cursor:pointer; }
  .lz-menu > summary::-webkit-details-marker { display:none; }
  .lz-menu__p { position:absolute; top:calc(100% + 6px); right:0; z-index:var(--z-dropdown); min-width:232px; padding:6px; box-sizing:border-box; border:1px solid var(--hairline); border-radius:var(--r-card); background:var(--surface); box-shadow:var(--shadow-md); }
  .lz-menu__cab { padding:8px 10px 10px; margin-bottom:6px; border-bottom:1px solid var(--hairline); min-width:0; }
  .lz-menu__cab b { display:block; font-size:13px; }
  .lz-menu__cab small { display:block; color:var(--text-muted); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-menu__it { display:flex; align-items:center; gap:10px; width:100%; min-height:36px; padding:0 10px; box-sizing:border-box; border:0; border-radius:var(--r-control); background:transparent; color:var(--text); font:inherit; font-size:13px; text-align:left; text-decoration:none; cursor:pointer; }
  .lz-menu__it svg { width:16px; height:16px; flex:0 0 auto; stroke:currentColor; fill:none; stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round; color:var(--text-muted); }
  @media (hover:hover) { .lz-menu__it:hover { background:var(--surface-2); color:var(--text); text-decoration:none; } }
  .lz-menu__it:focus-visible { outline:none; box-shadow:var(--ring); }
  /* La persona: avatar con nombre y rol desde 1100; debajo solo el avatar y el chip DEV. */
  .lz-top__yo > summary { display:flex; align-items:center; gap:8px; height:36px; padding:0 8px 0 3px; box-sizing:border-box; border:1px solid var(--line-2); border-radius:var(--r-pill); background:var(--surface); }
  .lz-top__yo > summary .lz-yo__av { width:28px; height:28px; font-size:11px; }
  .lz-top__yo > summary .lz-glifo { width:14px; height:14px; color:var(--text-muted); }
  .lz-top__yo-t { display:none; line-height:1.1; font-size:12.5px; font-weight:600; }
  .lz-top__yo-t small { display:block; color:var(--text-muted); font-size:11px; font-weight:400; }
  @media (min-width:1100px) { .lz-top__yo-t { display:block; } }
  .lz-top__yo > summary:focus-visible { outline:none; box-shadow:var(--ring); }
  @media (hover:hover) { .lz-top__yo > summary:hover { background:var(--surface-2); } }
  .lz-top__yo[open] > summary { background:var(--sel-bg); border-color:transparent; }
  .lz-top .lz-yo__dev { margin:0; }
  /* El tema es un botón de icono en la barra (Alex, 14-oct noche: «esto debe estar visible en la barra»; antes vivía
     en el menú de la persona). Mismo id de siempre: scriptTema lo engancha y alterna luna y sol. */
  .lz-top__tema#zg-theme { width:36px; height:36px; border-radius:var(--r-control); border:1px solid var(--line-2); background:var(--surface); color:var(--text); display:inline-grid; place-items:center; }
  .lz-top__tema#zg-theme svg { width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round; }
  @media (pointer:coarse) { .lz-top__tema#zg-theme { width:44px; height:44px; } }
  @media (max-width:820px) {
    :root { --lz-top:48px; }
    .lz-top { padding:0 12px; padding-top:env(safe-area-inset-top); height:calc(var(--lz-top) + env(safe-area-inset-top)); gap:8px; }
    .lz-top__inst, .lz-top__llamada { display:none; }
    .lz-menu__p { position:fixed; left:8px; right:8px; top:calc(var(--lz-top) + env(safe-area-inset-top) + 4px); min-width:0; }
  }
  @media (pointer:coarse) { .lz-top__ico, .lz-top__nuevo, .lz-top__yo > summary { min-height:44px; height:44px; } .lz-top__ico { width:44px; } .lz-menu__it { min-height:44px; } .lz-top__marca { min-height:44px; } }
  /* A 390 con objetivos de 44 la barra medía 430 px (medido 14-oct en WebKit y Chromium): el resumen de la persona
     pierde el chevrón y el chip DEV, que pasa a la cabecera del menú, y el hueco baja a 6. */
  .lz-menu__chips { display:none; gap:6px; margin-top:6px; }
  /* Selector de nivel en el menú de la persona: tres renglones con radio; el que supera el tope se atenúa. */
  .lz-menu__niveles { display:block; padding:6px 0 6px; margin-bottom:6px; border-bottom:1px solid var(--hairline); }
  .lz-menu__rot { display:block; padding:4px 10px 6px; font-size:11px; color:var(--text-muted); }
  .lz-menu__nivel { display:flex; align-items:center; gap:10px; min-height:36px; padding:4px 10px; border-radius:var(--r-control); cursor:pointer; }
  .lz-menu__nivel input { margin:0; flex:none; accent-color:var(--accent-control); }
  .lz-menu__nivel span { display:grid; line-height:1.2; }
  .lz-menu__nivel b { font-size:13px; font-weight:500; }
  .lz-menu__nivel small { font-size:11.5px; color:var(--text-muted); }
  .lz-menu__nivel.is-off { opacity:.5; cursor:not-allowed; }
  @media (hover:hover) { .lz-menu__nivel:not(.is-off):hover { background:var(--surface-2); } }
  .lz-menu__nivel:has(input:focus-visible) { box-shadow:var(--ring); outline:none; }
  @media (pointer:coarse) { .lz-menu__nivel { min-height:44px; } }
  @media (max-width:600px) { .lz-top__der { gap:6px; } .lz-top__yo > summary { padding:0 3px; gap:0; min-width:44px; justify-content:center; } .lz-top__yo > summary .lz-glifo, .lz-top__yo > summary .lz-yo__dev { display:none; } .lz-menu__chips { display:flex; } }
  @media (pointer:coarse) and (max-width:1023px) { .lz-top__nuevo { width:44px; } }
  /* Layout app: la barra arriba, la columna a la izquierda y el contenido a todo el ancho */
  .lz-app { display:flex; align-items:stretch; min-height:calc(100vh - var(--lz-top)); min-height:calc(100dvh - var(--lz-top)); }
  /* 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 232px; width:232px; border-right:1px solid var(--border); background:var(--surface); display:flex; flex-direction:column; padding:18px 12px 14px; position:sticky; top:var(--lz-top); height:calc(100vh - var(--lz-top)); height:calc(100dvh - var(--lz-top)); box-sizing:border-box; z-index:var(--z-sticky); }
  /* El simbolo es simboloLeadz() (shared.js), la Z subrayada del wordmark: el subrayado en --brand, no el acento de
     accion, para que la marca no se lea como el boton primario. */
  .lz-brand { font-size:15px; font-weight:700; letter-spacing:-.01em; line-height:1.15; color:var(--text); }
  .lz-brand__inst { display:block; font-size:11.5px; color:var(--text-muted); line-height:1.2; }
  /* 4 px entre renglones de navegación (Alex, 15-oct: «debe haber más espaciado entre los elementos»): con 2 px el activo y
     el de hover se tocaban y se leían como un solo bloque. */
  .lz-snav { display:flex; flex-direction:column; gap:4px; }
  .lz-snav a { display:flex; align-items:center; gap:10px; min-height:36px; padding:0 10px; border-radius:var(--r-control); font-size:13.5px; font-weight:500; color:var(--text-2); text-decoration:none; }
  .lz-snav a svg { width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.75; flex:0 0 auto; color:var(--text-muted); }
  @media (hover:hover) { .lz-snav a:hover { background:var(--surface-2); color:var(--text); text-decoration:none; } }
  .lz-snav a:active { background:var(--surface-3); }
  /* El activo lleva dos señales (PCB-1938): fondo y peso. La barra de 3 px se quitó a pedido de
     Alex (13-oct); el peso 600 y el glifo en acento siguen siendo la segunda señal. */
  .lz-snav a.on { background:var(--sel-bg); color:var(--sel-text); font-weight:600; }
  .lz-snav a.on svg { color:var(--sel-text); }
  .lz-snav a:focus-visible { outline:none; box-shadow:var(--ring); }
  .lz-mas { display:none; }
  .lz-mas-hoja, .lz-mas-velo { display:none; }
  /* 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. */
  /* Cobalto (reemplaza lo anterior): el contador va relleno de acento con tinta de acento, porque
     sobre el renglon activo (accent-soft) un relleno de acento sigue leyendose. "Por devolver" va en
     aviso con tinta oscura: espera a una persona, y el color distingue la bandeja sin leer el numero. */
  .lz-cnt { min-width:20px; height:20px; padding:0 6px; box-sizing:border-box; flex:0 0 auto;
    display:inline-flex; align-items:center; justify-content:center; border-radius:var(--r-pill);
    background:var(--text); color:var(--bg); border:0; font-family:var(--font);
    font-size:11.5px; font-weight:600; line-height:1; font-variant-numeric:tabular-nums; }
  /* Blanco y negro con toques (Alex, 13-oct): el contador va en tinta, no en acento ni en ámbar;
     el ámbar sobre fondo claro no lucía. «Por devolver» se distingue por su icono, no por el color. */
  .lz-snav #lz-nav-ll .lz-cnt, .lz-cnt--warn { background:var(--text); color:var(--bg); }
  .lz-snav .lz-cnt { margin-left:auto; }
  .lz-side-foot { margin-top:auto; display:flex; flex-direction:column; gap:10px; padding-top:12px; border-top:1px solid var(--border); }
  .lz-main { flex:1; min-width:0; padding:24px 28px 60px; box-sizing:border-box; }
  /* «quieto»: más aire alrededor del contenido y en la columna; la barra no cambia de alto. */
  :root .lz-main { padding:32px 36px 72px; }
  :root .lz-main--pleno { padding:0; }
  @media (min-width:821px) { :root .lz-side { padding-top:22px; } }
  :root .lz-snav a { min-height:38px; }
  :root .lz-top { border-bottom-color:var(--border); }
  @media (max-width:820px) { :root .lz-main { padding:20px 16px 72px; } :root .lz-main--pleno { padding:0; } }
  .lz-main:focus { outline:none; }
  /* Salto al contenido (Ola 4): con la barra lateral hacían falta 17 Tab hasta el primer control. */
  .lz-salto { position:absolute; left:8px; top:8px; z-index:calc(var(--z-modal) + 2); padding:8px 12px; border-radius:var(--r-control); background:var(--surface); color:var(--accent-text); border:1px solid var(--hairline); box-shadow:var(--shadow-md); font-weight:600; transform:translateY(-200%); }
  .lz-salto:focus-visible { transform:none; outline:none; box-shadow:var(--ring); }
  /* Selección múltiple: casilla por fila y barra flotante al pie de la tarjeta que aparece solo
     con algo marcado. Vive aquí porque la usan la lista del pipeline y Tareas. */
  .zchk { width:34px; text-align:center; }
  .zchk input { width:18px; height:18px; margin:0; }
  @media (pointer:coarse) { .zchk { width:48px; } .zchk input { width:24px; height:24px; } }
  /* En móvil la barra de selección se apoya sobre la barra inferior, no debajo (F1-10: «Borrar» quedaba tapado). */
  .lz-selbar { position:sticky; bottom:0; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap;
    gap:12px; margin:10px -14px -14px; padding:10px 14px; background:var(--surface);
    border-top:1px solid var(--border); box-shadow:var(--shadow-md); border-radius:0 0 var(--r-card) var(--r-card); font-size:var(--fs-3); }
  .lz-selbar[hidden] { display:none; }
  .lz-selbar__acc { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .lz-selbar__acc .zinput { width:auto; height:var(--h-control); } /* al alto de sus botones: Alineación vertical */
  /* En móvil la barra de selección va FIJA sobre la barra inferior (F1-10): con sticky no podía subir porque su caja
     contenedora (la tarjeta) empieza justo encima y «Borrar» quedaba bajo las pestañas. La tarjeta deja sitio abajo
     mientras la barra esté visible, para que la última fila siga alcanzable. */
  @media (max-width:820px) {
    .lz-selbar { position:fixed; left:0; right:0; bottom:calc(var(--lz-bar, 60px) + env(safe-area-inset-bottom)); z-index:var(--z-drawer); margin:0; border-radius:0; border-top:1px solid var(--border); box-shadow:var(--shadow-md); max-height:45vh; overflow:auto; }
    .lz-tabla-card:has(.lz-selbar:not([hidden])) { padding-bottom:220px; }
  }
  /* El botón de tema vive junto al logo (Alex, 13-oct): sin borde ni fondo, 30 px, a la derecha. */
  /* 30 px visual, 44 de área de toque en táctil (PCB-1424, Ola 8): el borde invisible crece sin mover el icono. */
  /* WhatsApp SIEMPRE verde (Alex, 14-oct): el glifo va en --wa donde esté; un botón de texto con el
     glifo es verde sólido con tinta --ink-on-wa; un botón de icono lo lleva en verde sobre nada. */
  /* El verde va en el glifo con !important porque cada pantalla tiñe sus .lz-ico con más
     especificidad (.lz-ibx .lz-ico, .lz-fx .lz-ico): sin eso el verde perdía en el Inbox. */
  .lz-glifo--wa { color:var(--wa) !important; }
  /* El verde sólido es para el botón que ESCRIBE o ABRE WhatsApp. El disparador «Enviarle el
     cuestionario» de la tira de calificación lleva el glifo pero es un botón secundario: pintarlo
     de verde ponía tres rellenos fuertes en una tarjeta (PCB-93, Ola 7). Ahí el glifo va en --wa
     sobre el botón neutro. */
  @media (hover:hover) { .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar), .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar):hover { background:var(--wa); border-color:var(--wa); color:var(--ink-on-wa); } }
  .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar) .lz-glifo--wa { color:var(--ink-on-wa) !important; }
  @media (hover:hover) { .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar):hover { filter:brightness(1.06); } }
  /* Todo mensaje va en burbuja (Alex, 14-oct): el grupo del lead también lleva su caja. */
  .lz-hl-g--in .lz-hl-b { padding:10px 14px; background:var(--hilo-in); border:1px solid var(--hilo-in-line); border-radius:var(--r-card); border-top-left-radius:4px; }
  /* Contraer el menú (Alex, 13-oct). Botón al pie con el glifo de panel; en el modo mini la barra
     mide 64 px, solo iconos con su nombre en title, el símbolo en vez del lockup, el contador como
     punto y la persona reducida a su avatar. Solo en escritorio: en el teléfono la barra ya es
     otra cosa (abajo, fija). */
  .lz-side-tg { display:flex; align-items:center; gap:10px; width:100%; min-height:34px; padding:0 10px; border:0; border-radius:var(--r-control); background:transparent; color:var(--text-muted); font:inherit; font-size:12.5px; cursor:pointer; text-align:left; }
  @media (hover:hover) { .lz-side-tg:hover { background:var(--surface-2); color:var(--text); } }
  .lz-side-tg .lz-glifo { width:16px; height:16px; }
  .lz-side-tg__o { display:none; }
  @media (min-width:821px) {
    html[data-side="mini"] .lz-side { flex-basis:64px; width:64px; padding:18px 8px 14px; }
    html[data-side="mini"] .lz-snav a { justify-content:center; padding:0; width:48px; height:40px; margin:0 auto; position:relative; }
    html[data-side="mini"] .lz-snav a > span:not(.lz-cnt) { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
    html[data-side="mini"] .lz-snav a svg { width:18px; height:18px; }
    /* Con el menú contraído el rótulo vuelve como globo al enfocar o pasar el puntero (PCB-1047, Ola 8). */
    html[data-side="mini"] .lz-snav a:focus-visible > span:not(.lz-cnt), html[data-side="mini"] .lz-snav a:hover > span:not(.lz-cnt) { position:absolute; left:calc(100% + 8px); top:50%; transform:translateY(-50%); width:auto; height:auto; clip:auto; overflow:visible; white-space:nowrap; background:var(--text); color:var(--bg); padding:4px 8px; border-radius:6px; font-size:var(--fs-1); z-index:var(--z-dropdown); pointer-events:none; }
    /* En mini el contador es un punto de 8 px; su aria-label (puesto en barraLateral) sigue diciendo el número. */
    html[data-side="mini"] .lz-snav .lz-cnt { position:absolute; top:4px; right:6px; margin:0; min-width:8px; height:8px; padding:0; border-radius:50%; font-size:0; }
    html[data-side="mini"] .lz-side-tg { justify-content:center; padding:0; width:48px; margin:0 auto; }
    html[data-side="mini"] .lz-side-tg span { display:none; }
    html[data-side="mini"] .lz-side-tg__c { display:none; }
    html[data-side="mini"] .lz-side-tg__o { display:block; }
    /* La pastilla del softphone (la monta telefonia.js en el pie) queda en su icono y su punto. */
    html[data-side="mini"] .lz-side-foot .lz-sf__pill { width:48px; height:40px; padding:0; justify-content:center; margin:0 auto; }
    html[data-side="mini"] .lz-side-foot .lz-sf__txt, html[data-side="mini"] .lz-side-foot .lz-sf__stchip { display:none; }
    /* El teléfono centrado y el punto de estado en su esquina, como el botón flotante de ≤ 820 (15-oct). */
    html[data-side="mini"] .lz-side-foot .lz-sf__pill { position:relative; }
    html[data-side="mini"] .lz-side-foot .lz-sf__ico { width:18px; height:18px; }
    html[data-side="mini"] .lz-side-foot .lz-sf__dot { position:absolute; top:6px; left:calc(50% + 5px); box-shadow:0 0 0 2px var(--surface); }
    html[data-side="mini"] .lz-side-foot .lz-sf--on .lz-sf__dot { box-shadow:0 0 0 2px var(--surface); }
  }
  .lz-h1 { margin:0; display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
  /* El chip del título respira (feedback de Alex): aire propio además del gap, y nunca pegado al texto. */
  .lz-h1 .lz-count { margin-left:6px; }
  .zcab:has(.lz-h1) { margin-bottom:18px; padding-top:4px; }
  .lz-h1__ic { width:28px; height:28px; border-radius:var(--r-control); background:var(--sel-bg); color:var(--sel-text); display:inline-grid; place-items:center; flex:none; }
  .lz-h1__ic .lz-glifo, .lz-h1__ic svg { width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.75; }

  /* 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, que es lo que decide hoy la regla
         global de a (Cobalto): color de acento y subrayado solo en hover.

     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:calc(100vh - var(--lz-top)); height:calc(100dvh - var(--lz-top)); overflow:hidden; position:relative; display:flex; }
  /* Fijo abajo y no absoluto arriba (PCB-361, Ola 5): con la página desplazada el toast de «Deshacer»
     quedaba a y=-794, fuera de pantalla. Entra con lzEntra y sale con .lz-toast--fuera. */
  .lz-toast { position:fixed; top:auto; bottom:calc(24px + env(safe-area-inset-bottom)); left:50%; transform:translateX(-50%); z-index:var(--z-toast); max-width:min(560px,92%); display:flex; align-items:flex-start; gap:6px; animation:lzEntra var(--dur-2) var(--ease-out); transition:opacity var(--dur-2) var(--ease-out); }
  .lz-toast--fuera { opacity:0; }
  /* El contenedor nunca atrapa toques: solo sus hijos (PCB-1426). */
  .lz-toast { pointer-events:none; }
  .lz-toast > * { pointer-events:auto; }
  @media (max-width:820px) { .lz-toast { bottom:calc(var(--lz-bar, 60px) + 10px + env(safe-area-inset-bottom)); left:8px; right:8px; transform:none; max-width:none; } .lz-side-tg { display:none; } }
  /* Entre 721 y 820 la barra lateral es la barra inferior fija: su z-index:2 de escritorio la dejaba
     bajo las celdas pegajosas de la tabla de Tareas y los toques caían en la tabla (PCB-1025, Ola 7). */
  @media (max-width:820px) { .lz-side { z-index:var(--z-drawer); } }
  /* Al soltar una tarjeta en otra columna, la columna avisa dónde cayó (ACB-8, Ola 5). */
  .lz-col.lz-col--flash { animation:lzFlash .7s ease-out; }
  .lz-toast > div { flex:1 1 auto; min-width:0; }
  .lz-toast__undo { flex:none; align-self:center; }
  .lz-toast__kbd { margin-left:6px; font-family:inherit; font-size:var(--fs-1); color:var(--text-muted); border:1px solid var(--hairline); border-radius:4px; padding:0 4px; line-height:1.4; }
  .lz-toast__x { flex:0 0 auto; width:32px; height:32px; border:0; border-radius:var(--r-control); background:var(--surface); color:var(--text-2); font:inherit; font-size:var(--fs-4); line-height:1; cursor:pointer; box-shadow:var(--shadow-md); }
  @media (hover:hover) { .lz-toast__x:hover { color:var(--text); } }
  .lz-toast .zaviso, .lz-toast .zalert { margin:0; border:1px solid var(--hairline); border-radius:var(--r-card); box-shadow:var(--shadow-md); background:var(--surface); color:var(--text); }
  .lz-toast .zalert { background:var(--bad-soft); color:var(--bad-text); }
  /* Segunda columna: el índice de una sección con varias pantallas (Reportes, Ajustes). La
     jerarquía la hacen el peso y el color, no el tamaño (PCB-89): título en negrita a 18 px,
     etiqueta de grupo en versalitas apagadas con hairline arriba, ítems en 500 con su glifo, y el
     activo con fondo MÁS barra de 3 px (PCB-1938). El punto a la derecha solo aparece cuando hay
     algo por resolver, y el contador solo cuando es un conteo real: cuando todas las filas llevan
     señal, ninguna la lleva. */
  .lz-sub { flex:0 0 220px; width:220px; border-right:1px solid var(--border); background:var(--bg); padding:22px 12px; position:sticky; top:var(--lz-top); height:calc(100vh - var(--lz-top)); height:calc(100dvh - var(--lz-top)); box-sizing:border-box; overflow-y:auto; }
  .lz-sub h3 { margin:0 0 4px; padding:0 10px; font-size:var(--fs-5); letter-spacing:-.01em; color:var(--text); font-weight:700; }
  .lz-sub__sum { padding:0 10px; margin:0 0 12px; font-size:var(--fs-2); color:var(--text-muted); }
  .lz-sub__g { display:flex; align-items:center; gap:8px; margin:8px 0 0; padding:12px 10px 4px; border-top:1px solid var(--border); font-size:var(--fs-1); letter-spacing:.05em; text-transform:uppercase; font-weight:600; color:var(--text-muted); }
  .lz-sub__g:first-of-type, .lz-sub h3 + .lz-sub__g, .lz-sub__sum + .lz-sub__g { border-top:0; margin-top:0; padding-top:4px; }
  .lz-sub a + a { margin-top:4px; } /* mismo aire que .lz-snav: renglones que no se tocan */
  .lz-sub a { display:flex; align-items:center; gap:9px; padding:7px 10px; border-radius:var(--r-control); font-size:var(--fs-3); font-weight:500; color:var(--text-2); text-decoration:none; line-height:1.35; }
  .lz-sub a .lz-glifo { width:15px; height:15px; stroke-width:1.75; color:var(--text-muted); }
  @media (hover:hover) { .lz-sub a:hover { background:var(--surface-2); color:var(--text); text-decoration:none; } }
  .lz-sub a.on { background:var(--sel-bg); color:var(--sel-text); font-weight:600; }
  .lz-sub a.on .lz-glifo { color:var(--sel-text); }
  /* El foco de teclado tiene que verse también sobre el activo: su box-shadow de barra ganaba al
     anillo global por especificidad (PCB-171). */
  .lz-sub a:focus-visible { outline:none; box-shadow:var(--ring-inset); }
  .lz-sub a.on:focus-visible { box-shadow:var(--ring-inset); }
  .lz-sub a small { display:block; font-size:var(--fs-1); font-weight:400; color:var(--text-muted); margin-top:1px; }
  .lz-sub a.on small { color:var(--sel-text); }
  .lz-sub a .lz-count, .lz-sub a .lz-pto { margin-left:auto; }
  .lz-sub a .lz-count { height:18px; padding:0 6px; }
  .lz-pto { width:8px; height:8px; border-radius:50%; background:var(--warn); flex:none; display:inline-block; }
  .lz-pto--ok { background:var(--ok); }
  @media (forced-colors:active) { .lz-pto { forced-color-adjust:none; background:Highlight; } }
  .lz-count--warn { background:var(--warn-soft); color:var(--warn-text); border-color:color-mix(in oklch, var(--warn-text) 35%, transparent); }
  /* El primer renglón de un índice con grupos (Estado en Ajustes) pesa como entrada principal. */
  .lz-sub a.lz-sub__top { font-weight:600; color:var(--text); margin-bottom:6px; }
  /* Pestañas de ancla de una sección larga: pegadas arriba mientras se baja, en una sola fila con
     scroll horizontal (PCB-494: nunca envueltas en dos filas) y la activa siguiendo a la tarjeta visible. */
  .lz-tabs { position:sticky; top:var(--lz-top); z-index:var(--z-sticky); display:flex; gap:2px; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; margin:-6px 0 18px; padding:6px 0 0; background:var(--bg); border-bottom:1px solid var(--border); -webkit-mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
  .lz-tabs::-webkit-scrollbar { display:none; }
  .lz-tabs a { display:inline-flex; align-items:center; min-height:36px; padding:0 12px; font-size:var(--fs-3); font-weight:500; color:var(--text-2); border-bottom:2px solid transparent; margin-bottom:-1px; text-decoration:none; white-space:nowrap; }
  @media (hover:hover) { .lz-tabs a:hover { color:var(--text); text-decoration:none; } }
  .lz-tabs a.on { color:var(--text); border-bottom-color:var(--text); font-weight:600; }
  @media (pointer:coarse) { .lz-tabs a { min-height:44px; } }
  .zcard.lz-blk[id] { scroll-margin-top:56px; }
  .lz-tabs .lz-count { margin-left:8px; }
  /* Hoja lateral: formulario o detalle que se abre sobre la pantalla sin sacar a nadie de ella.
     420 px, hairline translucida ademas de la sombra (regla de modales y hojas), velo detras y
     cierre con Esc y con el velo. Cerrada va con [hidden]; la regla global ya la oculta. */
  .lz-veil { position:fixed; inset:0; z-index:var(--z-modal); background:color-mix(in oklch, var(--text) 28%, transparent); cursor:default; }
  [data-ds-theme="dark"] .lz-veil { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-sheet { position:fixed; top:0; right:0; bottom:0; z-index:calc(var(--z-modal) + 1); width:min(420px,100vw); display:flex; flex-direction:column; gap:14px; padding:22px 24px; overflow-y:auto; overscroll-behavior:contain; background:var(--surface); color:var(--text); border-left:1px solid var(--hairline); box-shadow:var(--shadow-md); }
  .lz-sheet .zcab { margin:0; flex-wrap:nowrap; align-items:center; }
  .lz-sheet__h2 { margin:0; font-size:var(--fs-5); font-weight:600; }
  .lz-sheet__h3 { margin:0; font-size:var(--fs-4); font-weight:600; }
  .lz-sheet__x { width:32px; padding:0; justify-content:center; background:transparent; border-color:transparent; color:var(--text-2); }
  .lz-sheet__form { display:grid; gap:14px; }
  .lz-sheet__sec { display:grid; gap:10px; padding-top:16px; border-top:1px solid var(--border); }
  .lz-sheet__tabla { overflow-x:auto; }
  .lz-sheet__pie { display:grid; gap:8px; justify-items:start; }
  .lz-campo { display:grid; gap:6px; align-content:start; min-width:0; }
  .lz-campo > label { margin:0; font-size:var(--fs-2); font-weight:500; color:var(--text-2); }
  .lz-campo .zinput { width:100%; }
  .lz-grid3 { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; }
  /* Franja: dos horas por renglon (inicio y fin), una etiqueta fija a la izquierda. */
  .lz-franja { display:grid; grid-template-columns:56px minmax(0,1fr) auto minmax(0,1fr); align-items:center; gap:8px; }
  .lz-franja__k { font-size:var(--fs-2); color:var(--text-muted); }
  /* Dias: siete casillas que se ven como fichas. La casilla real queda debajo (teclado y lector
     de pantalla la siguen usando) y la ficha marcada se llena con el color de texto. */
  .lz-dias { display:flex; gap:4px; flex-wrap:wrap; }
  .lz-dia { position:relative; display:inline-grid; margin:0; cursor:pointer; }
  @media (hover:hover) { .lz-dia:hover, .lz-check:hover { background:var(--surface-2); border-radius:var(--r-chip); } }
  .lz-dia input { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer; }
  .lz-dia > span:not(.lz-sr) { width:34px; height:34px; border-radius:var(--r-control); border:1px solid var(--border-control); display:grid; place-items:center; font-size:var(--fs-2); font-weight:600; color:var(--text-2); background:var(--surface); }
  .lz-dia input:checked + span { background:var(--text); color:var(--bg); border-color:var(--text); }
  .lz-dia input:focus-visible + span { outline:2px solid var(--focus); outline-offset:2px; }
  .lz-avanzado { border-top:1px solid var(--border); padding-top:10px; }
  .lz-avanzado summary { cursor:pointer; font-size:var(--fs-2); font-weight:500; color:var(--text-2); margin-bottom:10px; }
  .lz-avanzado[open] > .lz-campo { margin-bottom:10px; }
  /* Lista de cadencias: cabecera mono y una fila por cadencia (nombre y subtitulo, ritmo en
     palabras, canal, inscritos, acciones). */
  .lz-cad { display:grid; grid-template-columns:minmax(0,1.4fr) minmax(0,1.2fr) 120px 90px 170px; gap:14px; align-items:center; padding:12px 0; border-top:1px solid var(--border); }
  .lz-cad__hd { border-top:0; padding:0 0 8px; font-family:var(--mono); font-size:var(--fs-1); letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); font-weight:600; }
  .lz-cad__hd + .lz-cad { border-top:1px solid var(--border); }
  .lz-cad b { font-weight:600; }
  .lz-cad__sub { display:block; margin-top:1px; font-size:var(--fs-2); color:var(--text-muted); }
  .lz-cad__regla { font-size:var(--fs-2); color:var(--text-2); }
  .lz-cad__n { font-variant-numeric:tabular-nums; font-size:var(--fs-2); color:var(--text-2); }
  .lz-cad__acc { display:flex; gap:6px; justify-content:flex-end; }
  .lz-cad__acc form { margin:0; }
  .lz-chip--wa svg { color:var(--wa); }
  @media (max-width:860px) {
    .lz-cad { grid-template-columns:1fr auto; row-gap:6px; }
    .lz-cad__hd { display:none; }
    .lz-cad__regla { grid-column:1 / -1; grid-row:2; }
    .lz-cad__acc { grid-column:2; grid-row:1; }
  }
  /* Tira de acciones: tarjetas hermanas que no necesitan ser una tabla. */
  .lz-strip { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:0; }
  .lz-pend { display:grid; gap:8px; align-content:start; padding:4px 16px; border-left:1px solid var(--border); }
  .lz-pend:first-child { border-left:0; padding-left:0; }
  .lz-pend b { font-size:var(--fs-4); font-weight:600; }
  .lz-pend p { margin:0; font-size:var(--fs-2); }
  /* La ayuda larga va plegada y en lista (regla de la casa: ayuda en renglones con negrita, no en párrafos). */
  /* Sin borde propio: ya vive dentro de una tarjeta y dos fronteras seguidas leen como caja en caja (PCB-100). */
  .lz-ayuda { border-radius:var(--r-card); background:var(--surface-2); margin:0 0 14px; }
  /* Notas al pie de una tabla de reporte: se leen como lista (un renglón por nota, hairline entre
     renglones, a todo lo ancho), nunca como párrafos sueltos (regla de Alex: ayuda en lista). */
  .lz-blk table + p.muted, .lz-blk .lz-scroll-x + p.muted { margin-top:12px !important; }
  .lz-blk p.muted + p.muted { border-top:1px solid var(--border); padding-top:8px; margin-top:8px !important; }
  .lz-ayuda summary { cursor:pointer; padding:10px 14px; min-height:40px; font-weight:600; font-size:var(--fs-2); color:var(--text-2); list-style:none; display:flex; align-items:center; gap:8px; }
  @media (pointer:coarse) { .lz-ayuda summary { min-height:44px; } }
  .lz-ayuda summary::-webkit-details-marker { display:none; }
  .lz-ayuda summary::after { content:""; width:7px; height:7px; border-right:1.75px solid var(--text-muted); border-bottom:1.75px solid var(--text-muted); transform:rotate(45deg); margin-left:auto; transition:transform var(--dur-1) var(--ease-out); }
  .lz-ayuda[open] summary::after { transform:rotate(-135deg); }
  .lz-ayuda .zayuda { padding:0 14px 12px; max-width:none; }
  /* ---- Estrecho (<= 820): barra superior delgada (marca, usuario, tema) y navegacion INFERIOR de
     cinco destinos con "Mas" (la del pulgar). Doce destinos en una tira horizontal arriba mostraban
     dos y medio, sin senal de que habia mas, en la zona dificil del pulgar. Todo lo fijo abajo suma
     el safe-area del iPhone (la meta lleva viewport-fit=cover). --lz-bar es el alto de la barra. */
  @media (max-width:820px){
    :root { --lz-bar:60px; }
    .lz-app { flex-direction:column; }
    .lz-side { position:static; height:0; width:auto; flex:none; padding:0; border:0; overflow:visible; }
    .lz-side-foot { display:contents; }
    .lz-main { padding:18px 16px calc(var(--lz-bar) + 24px + env(safe-area-inset-bottom)); }
    .lz-snav { position:fixed; left:0; right:0; bottom:0; z-index:var(--z-drawer); display:grid; grid-template-columns:repeat(5,1fr); gap:0; background:var(--surface); border-top:1px solid var(--hairline); box-shadow:var(--shadow-md); padding:0 4px env(safe-area-inset-bottom); }
    /* LA BARRA (15-oct, Alex: «la barra de tablet es horrenda»). Cinco celdas iguales; el activo y «Más» abierto
       llevan la MISMA señal: una píldora --sel-bg detrás del glifo (radio píldora, 28 px de alto) y el rótulo en 600.
       Antes el activo pintaba la celda entera en radio de control y el hover de «Más» en radio de chip: dos formas
       para lo mismo. El contador y el punto de «Más» se cuelgan de la esquina del glifo con un aro --surface. */
    .lz-snav a, .lz-mas { flex-direction:column; align-items:center; justify-content:center; gap:4px; min-height:var(--lz-bar); padding:6px 2px; border-radius:var(--r-control); background:none; font-size:var(--fs-1); text-align:center; position:relative; touch-action:manipulation; }
    .lz-snav a span:not(.lz-cnt), .lz-mas span { line-height:1.1; }
    .lz-snav a svg, .lz-mas svg { width:20px; height:20px; padding:4px 16px; box-sizing:content-box; border-radius:var(--r-pill); color:inherit; transition:background-color var(--dur-1) var(--ease-out); }
    .lz-snav a.on, .lz-snav[data-mas="1"] .lz-mas { background:none; color:var(--sel-text); font-weight:600; }
    .lz-snav a.on svg, .lz-snav[data-mas="1"] .lz-mas svg { background:var(--sel-bg); color:var(--sel-text); }
    @media (hover:hover) {
      .lz-snav a:hover, .lz-mas:hover { background:none; color:var(--text); }
      .lz-snav a:hover svg, .lz-mas:hover svg { background:var(--surface-2); }
      .lz-snav a.on:hover svg, .lz-snav[data-mas="1"] .lz-mas:hover svg { background:var(--sel-bg); }
    }
    .lz-snav a:active, .lz-mas:active { background:none; }
    .lz-snav a:active svg, .lz-mas:active svg { background:var(--surface-3); }
    .lz-snav a:focus-visible, .lz-mas:focus-visible { outline:none; box-shadow:var(--ring); }
    /* --focus es un gris suave: con teclado la celda también enciende la píldora, como el hover */
    .lz-snav a:not(.on):focus-visible svg, .lz-snav:not([data-mas="1"]) .lz-mas:focus-visible svg { background:var(--surface-2); }
    /* contador como insignia en la esquina del glifo */
    .lz-snav .lz-cnt { position:absolute; top:3px; left:calc(50% + 6px); margin:0; box-shadow:0 0 0 2px var(--surface); }
    /* destinos secundarios: nunca en la barra; «Más» los enseña en su hoja (.lz-mas-hoja, la arma hub.js) */
    .lz-snav a.lz-n-sec { display:none; }
    .lz-snav:not([data-mas="1"]):has(.lz-n-sec .lz-cnt) .lz-mas::after { content:""; position:absolute; top:7px; left:calc(50% + 9px); width:8px; height:8px; border-radius:50%; background:var(--warn); box-shadow:0 0 0 2px var(--surface); }
    .lz-snav[data-mas="1"] { z-index:calc(var(--z-sf) + 2); }
    .lz-mas { display:flex; border:0; color:var(--text-2); font:inherit; font-size:var(--fs-1); font-weight:500; cursor:pointer; }
    /* LA HOJA DE «MÁS» (15-oct). Antes los secundarios salían en filas de cinco a todo el ancho, con huecos y sin
       título. Ahora es una hoja que flota 8 px sobre la barra: título y cerrar, rejilla de 4 columnas (3 en
       teléfono), hairline translúcido y sombra, velo detrás. Esc, clic fuera y «Cerrar» la cierran; el foco entra al
       primer destino, queda atrapado dentro y vuelve a «Más» (hub.js). La barra queda encima del velo. */
    .lz-mas-velo { display:block; position:fixed; inset:0; z-index:calc(var(--z-sf) + 1); background:color-mix(in oklch, var(--text) 32%, transparent); opacity:0; transition:opacity var(--dur-2) var(--ease-out); touch-action:manipulation; }
    [data-ds-theme="dark"] .lz-mas-velo { background:color-mix(in oklch, var(--bg) 70%, transparent); }
    .lz-mas-hoja { display:block; position:fixed; left:8px; right:8px; bottom:calc(var(--lz-bar) + 8px + env(safe-area-inset-bottom)); z-index:calc(var(--z-sf) + 2); width:auto; max-width:560px; margin:0 auto; box-sizing:border-box; max-height:calc(100dvh - var(--lz-bar) - var(--lz-top, 48px) - 24px); overflow-y:auto; overscroll-behavior:contain; padding:6px 10px 10px; background:var(--surface); color:var(--text); border:1px solid var(--hairline); border-radius:var(--r-card); box-shadow:var(--shadow-md); opacity:0; transform:translateY(8px); transition:opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out); }
    .lz-mas-velo.on, .lz-mas-hoja.on { opacity:1; transform:none; }
    .lz-mas-hoja__cab { display:flex; align-items:center; justify-content:space-between; gap:8px; min-height:44px; padding:0 0 0 6px; }
    .lz-mas-hoja__cab h2 { margin:0; font-size:var(--fs-3); font-weight:600; line-height:1.2; color:var(--text); }
    .lz-mas-hoja__x { display:inline-flex; align-items:center; justify-content:center; width:40px; height:40px; padding:0; border:0; border-radius:var(--r-pill); background:none; color:var(--text-2); cursor:pointer; touch-action:manipulation; }
    .lz-mas-hoja__x svg { width:18px; height:18px; }
    @media (hover:hover) { .lz-mas-hoja__x:hover { background:var(--surface-2); color:var(--text); } }
    .lz-mas-hoja__x:active { background:var(--surface-3); }
    .lz-mas-hoja__x:focus-visible { outline:none; box-shadow:var(--ring); }
    .lz-mas-hoja__g { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:4px; }
    .lz-mas-hoja__g a { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; min-height:76px; padding:10px 4px; box-sizing:border-box; border-radius:var(--r-control); color:var(--text-2); font-size:var(--fs-2); font-weight:500; line-height:1.2; text-align:center; text-decoration:none; position:relative; touch-action:manipulation; overflow-wrap:anywhere; }
    .lz-mas-hoja__g a svg { width:22px; height:22px; flex:none; color:var(--text-muted); }
    @media (hover:hover) { .lz-mas-hoja__g a:hover { background:var(--surface-2); color:var(--text); text-decoration:none; } }
    .lz-mas-hoja__g a:active { background:var(--surface-3); }
    .lz-mas-hoja__g a.on { background:var(--sel-bg); color:var(--sel-text); font-weight:600; }
    .lz-mas-hoja__g a.on svg { color:var(--sel-text); }
    .lz-mas-hoja__g a:focus-visible { outline:none; box-shadow:var(--ring); }
    .lz-mas-hoja__g a:not(.on):focus-visible { background:var(--surface-2); color:var(--text); }
    .lz-mas-hoja__g .lz-cnt { position:absolute; top:6px; left:calc(50% + 6px); margin:0; box-shadow:0 0 0 2px var(--surface); }
    @media (max-width:560px) { .lz-mas-hoja__g { grid-template-columns:repeat(3, minmax(0,1fr)); } }
    @media (pointer:coarse) { .lz-mas-hoja__x { width:44px; height:44px; } }
    html.lz-mas-abierta { overflow:hidden; }
    .lz-sub { position:relative; 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:10px 12px; min-height:40px; }
    .lz-sub a small { display:none; }
    .lz-sub__g { display:none; }
    .lz-sub__sum { display:none; }
    .lz-sub a { flex:none; }
    .lz-sub { -webkit-mask-image:linear-gradient(90deg, transparent, #000 16px, #000 calc(100% - 28px), transparent); mask-image:linear-gradient(90deg, transparent, #000 16px, #000 calc(100% - 28px), transparent); scrollbar-width:none; }
    /* Las pantallas "pleno" (inbox, ficha) ataban el alto a la ventana con overflow:hidden y las
       columnas de adentro hacian el scroll. En el telefono las columnas se apilan y no scrollea
       nada: la pagina tiene que volver a scrollear (se llegaba a 6 de 15 conversaciones). */
    html.lz-pleno, html.lz-pleno body { height:auto; overflow:visible; }
    .lz-main--pleno { height:auto; min-height:100dvh; overflow:visible; display:block; padding:0 0 calc(var(--lz-bar) + env(safe-area-inset-bottom)); }
    /* Fijo abajo también aquí (PCB-1426, Ola 7): con top y bottom a la vez el toast medía 374×766 y se
       quedaba con todos los toques durante seis segundos. */
    .lz-toast { position:fixed; top:auto; }
  }
  /* La ficha (.lz-fx) apila sus columnas desde 900, antes de que la barra colapse */
  @media (max-width:900px){
    html.lz-pleno:has(.lz-fx), html.lz-pleno:has(.lz-fx) body { height:auto; overflow:visible; }
    html:has(.lz-fx) .lz-main--pleno { height:auto; min-height:100dvh; overflow:visible; display:block; }
  }
  /* Tactil: objetivos de 44 y sin hover pegado */
  @media (pointer:coarse) {
    .lz-sub a { min-height:44px; display:flex; align-items:center; }
    .lz-toast__x { width:44px; height:44px; }
  }

  /* PESTANAS: una sola pieza para Agenda, Reglas y Correo. Seleccion = accent-soft + accent-text +
     peso 600, el mismo lenguaje que la navegacion y los filtros activos. */
  .znav { display:flex; gap:4px; margin:0 0 24px; flex-wrap:wrap; }
  .znav a { display:inline-flex; align-items:center; min-height:36px; padding:0 14px; font-size:var(--fs-3); font-weight:500; color:var(--text-2); text-decoration:none; border-radius:var(--r-control); }
  @media (hover:hover) { .znav a:hover { background:var(--surface-2); color:var(--text); text-decoration:none; } }
  .znav a.on { background:var(--sel-bg); color:var(--sel-text); font-weight:600; }
  .znav a:focus-visible { outline:none; box-shadow:var(--ring); }
  @media (pointer:coarse) { .znav a { min-height:44px; } }

  /* CIFRAS EN CAJAS (Alex, 15-oct: «en cajas, en vez de que el texto esté flotando»; reemplaza la tira en bloque del
     13-oct). Una caja por cifra en el tono de módulo interno, rótulo arriba, número grande y nota abajo. Las mismas reglas
     para .lz-metrics (Pipeline), .lz-kpis (Llamadas, Reglas, Agenda, Correo) y .lz-cifras (reportes, en leadz-moleculas). */
  .lz-metrics { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,180px),1fr)); gap:12px; margin-bottom:16px; }
  .lz-stat { display:flex; flex-direction:column; gap:4px; min-width:0; padding:14px 16px; background:var(--surface-anidada); border:1px solid var(--border); border-radius:var(--r-control); }
  .lz-stat b { order:1; display:block; font-size:var(--fs-6); font-weight:600; letter-spacing:-.02em; line-height:1.15; font-variant-numeric:tabular-nums; color:var(--text); overflow-wrap:anywhere; }
  .lz-stat span { order:0; font-size:var(--fs-2); font-weight:400; letter-spacing:0; text-transform:none; color:var(--text-2); }

  /* Tablero: columnas sin caja (la caja gris + borde de color arriba competia con las tarjetas).
     El color de etapa llega como --st y vive solo en el punto y el contador. */
  .lz-board { display:flex; gap:12px; overflow-x:auto; padding-bottom:12px; align-items:flex-start; }
  .lz-col { flex:1 0 208px; min-width:208px; display:grid; gap:8px; align-content:start; padding:4px; border:2px solid transparent; border-radius:var(--r-card); transition:background .12s, border-color .12s; }
  .lz-col > h3 { margin:0; padding:6px 4px 4px; font-size:var(--fs-2); font-weight:600; color:var(--text); display:flex; align-items:center; gap:8px; }
  .lz-etapa-dot { width:8px; height:8px; border-radius:50%; flex:none; background:var(--st, var(--st1)); }
  /* Contador tintado con el color de la etapa; en claro el texto se oscurece para pasar contraste. */
  .lz-col > h3 .c { margin-left:auto; padding:1px 8px; border-radius:var(--r-pill); font-size:11.5px; font-weight:500; background:var(--surface-2); color:var(--text-2); }
  .lz-col.dragover { border:2px dashed var(--accent); background:var(--accent-soft); }
  /* Ayudas de pantalla compartidas por las vistas de consulta: texto solo para lector de pantalla,
     y el estado vacío del DS (icono en círculo, título, dos oraciones, un botón) hecho producto. */
  .lz-vh { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
  .lz-vac { display:grid; justify-items:center; gap:0; padding:32px 20px; text-align:center; }
  .lz-vac--c { padding:24px 16px; }
  .lz-vac__i { display:inline-flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:50%; background:var(--surface-2); color:var(--text-2); font-size:20px; margin-bottom:16px; }
  .lz-vac__i { width:72px; height:72px; }
  .lz-vac__i svg { width:40px; height:40px; stroke-width:1.75; }
  .lz-vac--c .lz-vac__i { width:44px; height:44px; }
  .lz-vac--c .lz-vac__i svg { width:20px; height:20px; stroke-width:1.75; }
  .lz-vac__t { max-width:100%; font-size:var(--fs-4); font-weight:600; line-height:1.3; }
  /* VACÍO CON ICONO (Alex, 15-oct: «que se dibuje el icono, que tenga borde sutil y esté tirando ondas modo sonar muy
     sutil, a todos los que tengan icono»). El círculo lleva un borde de 1 px en --line-2; cada trazo del glifo se dibuja
     una vez en escalera de 90 ms (iconoTrazable en leadz-vacio.js); y dos ondas del mismo gris salen del borde, crecen a
     1.4 veces y se apagan, cada 3.6 s y desfasadas. Muy tenue a propósito: la onda dice «aquí llegará algo», no llama.
     El título y el texto van por encima de la onda. Con prefers-reduced-motion no hay ondas y el icono sale completo. Vale también para la fila de Conversaciones (.lz-cv-vacio__i). */
  .lz-vac__i, .lz-cv-vacio__i { position:relative; box-shadow:inset 0 0 0 1px var(--line-2); }
  .lz-vac__i::before, .lz-vac__i::after, .lz-cv-vacio__i::before, .lz-cv-vacio__i::after { content:""; position:absolute; inset:0; border-radius:50%; border:1px solid var(--line-2); opacity:0; pointer-events:none; animation:lzSonar 3.6s cubic-bezier(.2,0,0,1) 1.1s infinite; }
  .lz-vac__i::after, .lz-cv-vacio__i::after { animation-delay:2.9s; }
  @keyframes lzSonar { 0% { transform:scale(1); opacity:.9; } 80%, 100% { transform:scale(1.4); opacity:0; } }
  .lz-vac__i svg [pathLength], .lz-cv-vacio__i svg [pathLength] { stroke-dasharray:1; animation:lzTraza 720ms cubic-bezier(.2,0,0,1) calc(120ms + var(--i, 0) * 90ms) both; }
  @keyframes lzTraza { from { stroke-dashoffset:1; } }
  /* La regla global acorta las animaciones a 0.001 ms, pero el retraso de las ondas sigue contando: sin esto quedan dos
     animaciones vivas casi 3 s en modo reducido, invisibles pero corriendo. */
  @media (prefers-reduced-motion: reduce) { .lz-vac__i::before, .lz-vac__i::after, .lz-cv-vacio__i::before, .lz-cv-vacio__i::after { animation:none; } }
  .lz-vac__t, .lz-vac__x, .lz-vac > .zbtn { position:relative; z-index:1; }
  /* Ritmo del vacío (15-oct, «ahora el espaciado»): icono, 16; título, 8; texto, 20; botón. Escala de 4. */
  .lz-vac__x { margin:8px 0 20px; font-size:var(--fs-3); line-height:1.5; color:var(--text-2); text-wrap:balance; }

  /* Tarjeta de lead */
  .lz-lead { display:grid; gap:8px; position:relative; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-card); padding:12px; box-shadow:var(--shadow-sm); transition:box-shadow var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }
  .lz-lead:hover, .lz-lead:focus-within { border-color:var(--line-2); box-shadow:var(--shadow-md); transform:translateY(-2px); }
  /* Las acciones de la tarjeta se revelan al pasar o al enfocar (PCB-1493 en táctil: siempre visibles). */
  .lz-lead .rowq .lz-ico { opacity:0; transform:translateY(2px); transition:opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out); }
  .lz-lead:hover .rowq .lz-ico, .lz-lead:focus-within .rowq .lz-ico { opacity:1; transform:none; }
  @media (hover:none), (pointer:coarse) { .lz-lead .rowq .lz-ico { opacity:1; transform:none; } }
  .lz-lead .nm { font-weight:600; font-size:var(--fs-3); line-height:1.25; color:var(--text); text-decoration:none; }
  @media (hover:hover) { .lz-lead .nm:hover { text-decoration:none; color:var(--link-hover); } }
  .lz-lead .mt { font-size:var(--fs-2); color:var(--text-2); margin-top:1px; }
  .lz-chips { display:flex; flex-wrap:wrap; gap:6px; }
  /* Chips de estado: fondo tintado + texto del mismo tono, 22 px, siempre con punto o icono. */
  .lz-chip { display:inline-flex; align-items:center; gap:5px; height:22px; padding:0 8px; border-radius:var(--r-pill); border:1px solid transparent; background:var(--surface-2); color:var(--text-2); font-size:11.5px; font-weight:500; letter-spacing:0; text-transform:none; white-space:nowrap; }
  .lz-chip i { width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; }
  .lz-chip svg { width:12px; height:12px; flex:none; }
  /* El chip es neutro (fondo --surface-2, texto --text-2) y el color semántico vive solo en su
     punto: blanco y negro con toques de color (Alex, 13-oct). El texto sigue diciendo el estado. */
  .lz-chip--alta i, .lz-chip--cita i, .lz-chip--ok i { background:var(--ok); }
  .lz-chip--viable i { background:var(--accent); }
  .lz-chip--nutrir i, .lz-chip--aviso i { background:var(--warn); }
  .lz-chip--bad i { background:var(--bad); }
  .lz-chip--st i { background:var(--st, var(--st1)); }
  .lz-chip--alta, .lz-chip--cita, .lz-chip--ok, .lz-chip--viable, .lz-chip--nutrir, .lz-chip--aviso, .lz-chip--bad, .lz-chip--st { color:var(--text); }
  /* Fila de valor y origen: cifra a la izquierda, apoyo a la derecha. */
  .lz-lead .meta2 { display:flex; align-items:baseline; justify-content:space-between; gap:8px; flex-wrap:wrap; }
  .lz-src { font-size:11.5px; color:var(--text-muted); text-align:right; margin-left:auto; }
  .lz-date { font-size:11.5px; color:var(--text-muted); margin-left:auto; }
  .lz-notask { font-size:11.5px; color:var(--text-muted); }
  /* Pie: hairline, acciones de 26 px, pendientes y asesor a la derecha. */
  /* El siguiente paso dentro de la tarjeta: caja gris con glifo del canal, título y cuándo, y la
     acción a la derecha. Vencido va en ámbar. Es lo que se lee primero (variante 3, 13-oct). */
  .lz-sig { display:grid; gap:6px; padding:8px 9px; border-radius:var(--r-control); background:var(--surface-2); font-size:var(--fs-2); color:var(--text); min-width:0; }
  .lz-sig__h { display:flex; align-items:flex-start; gap:7px; min-width:0; }
  .lz-sig__h .lz-glifo { width:14px; height:14px; color:var(--text-2); margin-top:2px; }
  .lz-sig__h b { font-weight:600; line-height:1.3; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  .lz-sig__f { display:flex; align-items:center; justify-content:space-between; gap:8px; min-width:0; }
  .lz-sig__f small { font-size:var(--fs-1); color:var(--text-2); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-sig .zbtn { height:26px; padding:0 10px; font-size:var(--fs-1); flex:none; }
  /* Vencido, en sutil (Alex, 13-oct): fondo neutro con un lavado de ámbar al 35 % y una hairline
     ámbar a la izquierda; el ámbar pleno queda solo en el «venció …». */
  .lz-sig--late { background:color-mix(in oklch, var(--warn-soft) 35%, var(--surface-2)); color:var(--text); }
  .lz-sig--late .lz-glifo { color:var(--text-2); }
  .lz-sig--late .lz-sig__f small { color:var(--warn-text); font-weight:500; }
  .lz-lead .rowq { display:flex; align-items:center; gap:6px; border-top:1px solid var(--border); padding-top:8px; margin-top:2px; }
  /* Segunda fila: el interruptor Perfilado a la izquierda y el dueño a la derecha, con nombre. */
  .lz-lead .rowq2 { display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
  .lz-asesor { display:inline-flex; align-items:center; gap:6px; margin-left:auto; min-width:0; }
  .lz-asesor__n { font-size:var(--fs-1); color:var(--text-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:84px; }
  .lz-lead .lz-mover { margin-left:0; }
  .lz-ico { width:30px; height:30px; border-radius:var(--r-control); border:1px solid var(--border); background:var(--surface); color:var(--text); display:inline-flex; align-items:center; justify-content:center; text-decoration:none; }
  @media (hover:hover) { .lz-ico:hover { background:var(--surface-2); text-decoration:none; } }
  .lz-ico svg { width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:1.75; }
  .lz-lead .lz-ico { width:26px; height:26px; border-color:transparent; background:transparent; color:var(--text-2); }
  @media (hover:hover) { .lz-lead .lz-ico:hover { background:var(--surface-2); border-color:var(--border); color:var(--text); } }
  .lz-lead .lz-ico svg { width:14px; height:14px; }
  .lz-lead .lz-ico[title="WhatsApp"] { color:var(--wa); }
  .lz-lead .lz-count { border:0; padding:0; margin-left:auto; font-size:var(--fs-1); color:var(--text-2); }
  .lz-lead .lz-notask { margin-left:auto; }
  .lz-av { width:24px; height:24px; flex:none; border-radius:50%; display:grid; place-items:center; font-size:var(--fs-1); font-weight:600; background:var(--surface-3); color:var(--text-2); }
  .lz-av--none { background:transparent; border:1.5px dashed var(--border-control); }
  .lz-lead .lz-perfil-toggle-f { margin:0; }
  .lz-count { font-size:11.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; }
  /* Física del arrastre: la tarjeta levantada se inclina 2 grados y crece un 2 %; la que acaba de
     caer aterriza con un rebote corto (lzLand). La imagen de arrastre nativa la pone el navegador. */
  .lz-lead.dragging { transform:rotate(2deg) scale(1.02); box-shadow:var(--shadow-md); }
  @keyframes lzLand { 0% { transform:translateY(-6px) scale(1.02); } 60% { transform:translateY(1px) scale(1); } 100% { transform:none; } }
  .lz-lead.landed { animation:lzLand var(--dur-3) var(--ease-out); }
  .lz-col.dragover { outline:2px solid var(--accent); outline-offset:-2px; }
  .lz-owner { font-size:11.5px; color:var(--text); white-space:nowrap; }

  /* Zonas de soltar: una linea (icono, conteo, instruccion). Al arrastrar encima, acento. */
  .lz-dz-row { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:16px; }
  /* Línea fina y fondo apenas perceptible (feedback de Alex, 13-oct): la zona se insinúa, no compite con las tarjetas. */
  .lz-dz { display:flex; align-items:center; gap:10px; border:1px dashed var(--border-control); background:color-mix(in oklch, var(--surface-2) 55%, transparent); border-radius:var(--r-card); padding:10px 14px; color:var(--text-2); font-size:var(--fs-2); transition:border-color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out); }
  .lz-dz__tactil { display:none; }
  .lz-dz__tactil .lz-glifo { width:14px; height:14px; }
  .lz-dz b { font-size:var(--fs-2); color:var(--text); font-weight:600; white-space:nowrap; }
  .lz-dz__ic { width:22px; height:22px; border-radius:50%; flex:none; display:grid; place-items:center; }
  .lz-dz__ic .lz-glifo { width:12px; height:12px; }
  .lz-dz--won .lz-dz__ic { background:var(--ok-soft); color:var(--ok-text); }
  .lz-dz--lost .lz-dz__ic { background:var(--bad-soft); color:var(--bad-text); }
  .lz-dz.dzover { border-color:var(--accent); background:var(--accent-soft); }
  /* 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:color-mix(in oklch, var(--text) 45%, transparent); display:flex; align-items:center; justify-content:center; z-index:var(--z-hoja); padding:20px; opacity:1; transition:opacity var(--dur-2) var(--ease-out), display var(--dur-2) allow-discrete; }
  /* Entrada y salida con un solo lenguaje (ACB-68, Ola 5): el velo funde y la caja sube un poco y
     crece desde 96 %; la hoja móvil del calendario entra desde abajo. Con display allow-discrete y
     @starting-style el [hidden] sigue mandando y nada queda a medias si el navegador no lo soporta. */
  .lz-modal .box, .lz-modal__box { transition:transform var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out); }
  @starting-style { .lz-modal:not([hidden]) { opacity:0; } .lz-modal:not([hidden]) .box, .lz-modal:not([hidden]) .lz-modal__box { opacity:0; transform:translateY(6px) scale(.96); } }
  :root { interpolate-size:allow-keywords; }
  .lz-acc::details-content, .lz-acordeon::details-content, details.lz-pop::details-content { block-size:0; overflow:clip; transition:block-size var(--dur-2) var(--ease-out), content-visibility var(--dur-2) allow-discrete; }
  .lz-acc[open]::details-content, .lz-acordeon[open]::details-content, details.lz-pop[open]::details-content { block-size:auto; }
  [data-ds-theme="dark"] .lz-modal { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-modal[hidden] { display:none; opacity:0; }
  /* Hairline translucido ademas de la sombra: la caja se separa del velo en los dos temas. */
  .lz-modal .box, .lz-modal__box { background:var(--surface); color:var(--text); border:1px solid var(--hairline); border-radius:var(--r-card); padding:24px; width:min(440px,94vw); box-shadow:var(--shadow-md); }
  .lz-modal .box h3, .lz-modal__box h3 { margin:0 0 12px; font-size:16px; font-weight:600; }
  .lz-modal__box p { font-size:13.5px; line-height:1.5; margin:0 0 10px; }
  .lz-modal__acc { display:flex; gap:8px; justify-content:flex-end; margin-top:20px; }
  .lz-modal { touch-action:manipulation; }
  .lz-modal__nota { font-size:var(--fs-2); margin:-6px 0 12px; }
  /* «Mover a…»: una hoja de opciones de ancho de dedo; en el teléfono sube desde abajo. */
  .lz-mover__lista { display:grid; gap:6px; }
  .lz-mover__op { justify-content:flex-start; width:100%; }
  .lz-mover__op .lz-etapa-dot { background:var(--st, var(--st1)); }
  .lz-mover__act { display:none; color:var(--text-muted); font-weight:400; }
  .lz-mover__op.es-actual .lz-mover__act { display:inline; }
  .lz-mover__op[disabled] { opacity:1; color:var(--text-muted); background:var(--surface-2); }

  /* Modo enfoque */
  .lz-focus { max-width:600px; margin:0 auto; }
  .lz-focus .prog { text-align:center; font-family:var(--font); font-size:var(--fs-1); 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.75; }
  .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; }
  @media (hover:hover) { .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:var(--font); font-size:var(--fs-1); 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; } }
  /* ==== Reportes (Cobalto) ==========================================================
     UNA definición para todos los reportes y para la agenda: antes cada vista traía su copia de
     .lz-tabla y .lz-kpi con --muted y --card, y a la quinta copia ya no coincidían. */
  .lz-blk { margin-bottom:16px; }
  .zcard.lz-blk { padding:16px 18px; overflow-x:auto; }
  .lz-blk h2 { margin:0 0 12px; font-size:14px; font-weight:600; letter-spacing:-.01em; display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
  .lz-blk h2 .lz-count, .lz-rep-h h2 .lz-count, .lz-rep-h h1 .lz-count { margin-left:0; border:0; padding:0; font-size:12px; font-weight:400; color:var(--text-muted); }
  .lz-rep-h { align-items:baseline; gap:12px; margin-bottom:16px; }
  .lz-rep-h h1, .lz-rep-h h2 { font-size:22px; font-weight:600; letter-spacing:-.02em; display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
  /* Filtros: label arriba, controles de 34 px; el foco de cada campo lo pone .zinput. */
  form.lz-filtros { display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end; margin:0 0 16px; }
  form.lz-filtros label { display:block; font-size:12px; font-weight:500; color:var(--text-2); margin:0 0 4px; }
  form.lz-filtros .zinput { height:34px; font-size:13px; padding:0 10px; }
  form.lz-filtros select.zinput { padding-right:32px; }
  .lz-filtros__acc { display:flex; gap:8px; align-items:center; min-height:34px; }
  .lz-filtros__acc .zbtn { height:34px; }
  /* "Limpiar" es ghost: sin contorno hasta el hover, para que "Ver" sea la única acción con peso. */
  .lz-filtros__acc a.zbtn { background:transparent; border-color:transparent; color:var(--text-2); }
  @media (hover:hover) { .lz-filtros__acc a.zbtn:hover { background:var(--surface-2); color:var(--text); } }
  form.lz-filtros label.lz-check, .lz-check { display:inline-flex; align-items:center; gap:8px; margin:0 8px 0 0; min-height:24px; font-size:13px; font-weight:400; color:var(--text-2); white-space:nowrap; cursor:pointer; }
  .lz-check input { appearance:none; -webkit-appearance:none; width:16px; height:16px; margin:0; border:1.5px solid var(--text-muted); border-radius:4px; background:var(--surface); display:inline-grid; place-content:center; cursor:pointer; flex:0 0 auto; }
  .lz-check input:checked { background:var(--accent); border-color:var(--accent); }
  .lz-check input:checked::after { content:""; width:4px; height:8px; border:solid var(--ink-on-accent); border-width:0 2px 2px 0; transform:rotate(45deg) translate(-1px,-1px); }
  .lz-check input:focus-visible { outline:none; box-shadow:none; border-color:var(--focus); animation:lzBreathBorder 1.8s ease-in-out infinite alternate; }
  /* Cifras de resumen en cajas (Alex, 15-oct; antes una tira en bloque, 13-oct). Ver .lz-metrics arriba. */
  .lz-kpis { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,180px),1fr)); gap:12px; margin:0 0 16px; }
  .lz-kpi { display:flex; flex-direction:column; gap:4px; min-width:0; padding:14px 16px; background:var(--surface-anidada); border:1px solid var(--border); border-radius:var(--r-control); }
  .lz-kpi > .lz-kpi__t, .lz-kpi > .lz-kpi__v + .lz-kpi__t { order:-1; }
  /* «sin dato» como cifra: misma altura que el número para que las etiquetas de la tira alineen. */
  .lz-kpi > .lz-nd, .lz-kpi > b > .lz-nd { display:block; font-size:16px; line-height:29px; font-weight:500; }
  .lz-kpi b, .lz-kpi .lz-kpi__v { font-size:var(--fs-6); font-weight:600; letter-spacing:-.02em; line-height:1.15; font-variant-numeric:tabular-nums; }
  .lz-kpi .lz-kpi__t { font-size:var(--fs-2); font-weight:400; letter-spacing:0; text-transform:none; color:var(--text-2); }
  .lz-kpi__n { font-size:var(--fs-6); font-weight:600; letter-spacing:-.02em; line-height:1.15; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
  .lz-kpi__t { font-size:var(--fs-2); font-weight:400; color:var(--text-2); }
  .lz-kpi__p { font-size:11.5px; color:var(--text-muted); }
  .lz-delta { display:inline-flex; align-items:center; gap:4px; font-size:11.5px; font-weight:500; }
  .lz-delta svg { width:11px; height:11px; }
  .lz-delta--up { color:var(--ok-text); }
  .lz-delta--down { color:var(--bad-text); }
  /* Dentro de un bloque también van en cajas: son el «módulo interno» de la tarjeta (--surface-anidada). */
  .lz-blk .lz-kpis { margin:0 0 12px; }
  .lz-blk .lz-kpis:last-child { margin-bottom:0; }
  @media (max-width:560px) { .lz-kpis, .lz-metrics { grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px; } .lz-kpi, .lz-stat { padding:12px; } .lz-kpi__n, .lz-kpi b, .lz-stat b { font-size:var(--fs-5); } }
  .lz-blk .zgrid { gap:0; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); }
  .lz-blk .zgrid > .zcard { background:none; border:0; box-shadow:none; border-radius:0; border-left:1px solid var(--border); padding:4px 16px; }
  .lz-blk .zgrid > .zcard:first-child { border-left:0; padding-left:0; }
  .zcard__k { font-size:var(--fs-1); font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); }
  .zcard__v { font-size:28px; font-weight:700; letter-spacing:-.03em; line-height:1.05; margin:2px 0; font-variant-numeric:tabular-nums; }
  /* El patrón viejo de cifras (zgrid de zcard con __k/__v, en Citas, Pérdidas, Ingesta, Perfil y el
     reporte de cadencias) se vuelve la misma tira única que .lz-kpis sin tocar cada vista. */
  .zgrid:has(> .zcard > .zcard__k) { display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:1px; border:1px solid var(--border); border-radius:var(--r-card); background:var(--border); box-shadow:var(--shadow-sm); overflow:hidden; }
  .zgrid:has(> .zcard > .zcard__k) > .zcard { border:0; border-radius:0; box-shadow:none; background:var(--surface); padding:14px 18px; display:grid; gap:4px; align-content:start; }
  .zgrid:has(> .zcard > .zcard__k) > .zcard .muted { font-size:var(--fs-1); }
  /* Semáforo: punto y texto, nunca solo color. El ok es círculo y el mal rombo, así que la forma
     también distingue cuando el color no se percibe. */
  [data-sem] { display:inline-flex; align-items:center; gap:7px; }
  [data-sem]::before { content:""; width:8px; height:8px; flex:0 0 auto; }
  [data-sem="ok"] { color:var(--ok-text); }
  [data-sem="ok"]::before { background:var(--ok); border-radius:50%; }
  [data-sem="bad"] { color:var(--bad-text); }
  [data-sem="bad"]::before { background:var(--bad); border-radius:1px; transform:rotate(45deg); }
  .lz-scroll-x { min-width:0; overflow-x:auto; }
  .lz-sem-bad { color:var(--bad-text); }
  .lz-sem-warn { color:var(--warn-text); }
  .lz-sem-ok { color:var(--ok-text); }
  .lz-tabla { width:100%; border-collapse:separate; border-spacing:0; margin:0; }
  .lz-tabla th { text-align:left; font-size:11.5px; font-weight:600; letter-spacing:.03em; text-transform:uppercase; color:var(--text-muted); padding:0 10px; height:36px; border-bottom:1px solid var(--line-2); white-space:nowrap; vertical-align:middle; }
  .lz-tabla td { padding:6px 10px; min-height:40px; height:40px; border-bottom:1px solid var(--border); font-size:13px; vertical-align:middle; font-variant-numeric:tabular-nums; }
  .lz-tabla tbody tr:last-child td { border-bottom:0; }
  .lz-tabla th.n, .lz-tabla td.n { text-align:right; }
  .lz-tabla td.n + td:not(.n), .lz-tabla th.n + th:not(.n) { padding-left:18px; }
  /* HOVER DE FILA (15-oct, Alex: «en ningún lado selecciona bien… haz el hover con bordes redondeados»). Una sola regla
     para toda tabla del panel: pinta TODAS las celdas de la fila, también la primera columna fija de .lz-scroll-x, que antes
     ganaba con su fondo (selector de 3 clases contra 2) y dejaba el hover empezando en la segunda columna; y redondea los
     extremos con --r-control. Las celdas solo redondean con bordes separados, de ahí border-collapse:separate en .lz-tabla
     (las líneas entre renglones son border-bottom de cada celda y se ven igual). Regla en DESIGN.md · Tablas. */
  @media (hover:hover) {
    .lz-tabla tbody tr:hover > td, .lz-scroll-x .lz-tabla tbody tr:hover > td:first-child { background:var(--surface-2); }
    .lz-tabla tbody tr:hover > td:first-child { border-top-left-radius:var(--r-control); border-bottom-left-radius:var(--r-control); }
    .lz-tabla tbody tr:hover > td:last-child { border-top-right-radius:var(--r-control); border-bottom-right-radius:var(--r-control); }
  }
  .lz-tabla tr.lz-total td, .lz-tabla tfoot td { border-top:1px solid var(--line-2); font-weight:600; }
  .lz-tabla tr:has(+ tr.lz-total) > td, .lz-tabla:has(> tfoot) > tbody > tr:last-child > td { border-bottom:0; }
  /* Etapa en la tabla: punto de 8 px en el color de su etapa y el nombre; el color no va solo. */
  .lz-st { display:inline-flex; align-items:center; gap:7px; }
  .lz-st i { width:8px; height:8px; border-radius:50%; background:var(--st, var(--st1)); flex:0 0 auto; }
  /* Chips de grupo y de estado de los reportes: 22 px, fondo tintado, texto del mismo tono y punto. */
  .lz-gchip { display:inline-flex; align-items:center; gap:6px; height:22px; padding:0 9px; border-radius:var(--r-pill); font-size:11.5px; font-weight:500; background:var(--surface-2); color:var(--text-2); white-space:nowrap; }
  .lz-gchip i { width:6px; height:6px; border-radius:50%; background:currentColor; flex:0 0 auto; }
  .lz-gchip--ok i { background:var(--ok); }
  .lz-gchip--bad i { background:var(--bad); }
  .lz-gchip--warn i { background:var(--warn); }
  .lz-gchip--acc i { background:var(--accent); }
  .lz-gchip--ok, .lz-gchip--bad, .lz-gchip--warn, .lz-gchip--acc { color:var(--text); }
  .lz-blk .lz-kpi__t .lz-gchip { margin-bottom:2px; }
  .lz-dir-in { color:var(--text); font-weight:600; }
  .lz-dir-out { color:var(--ok-text); font-weight:600; }
  /* Misma regla que .zinline (DESIGN.md · Alineación vertical): un eje por fila; abajo solo si una etiqueta va
     encima de su campo, y entonces la etiqueta no lleva margen (el margen inferior de label bajaba el campo
     7 px por encima del botón en Ajustes · Campos). */
  .lz-inline { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
  .lz-inline:has(> label > :is(.zinput, .zfield, select), > div > label > :is(.zinput, .zfield, select), > div > label + :is(.zinput, .zfield, select)) { align-items:flex-end; }
  .lz-inline label:has(> :is(.zinput, .zfield, select)) { margin:0; display:grid; gap:6px; }
  .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 8px; flex:0 0 auto; }
  /* El separador de día es una píldora de superficie, sin borde ni mayúsculas: el día es contexto
     y no debe competir con los mensajes. */
  .lz-ibx-dia span { display:inline-block; font-size:var(--fs-1); font-weight:500; color:var(--hilo-meta); background:var(--hilo-in); border:1px solid var(--hilo-in-line); border-radius:var(--r-pill); padding:2px 10px; font-variant-numeric:tabular-nums; }
  /* 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:9px 12px 7px; border-radius:var(--r-card); font-size:15px; line-height:1.5; word-wrap:break-word; overflow-wrap:anywhere; }
  .lz-bb-tx { white-space:pre-wrap; }
  .lz-bb-mt { font-size:var(--fs-1); line-height:1.3; margin-top:4px; text-align:right; color:var(--hilo-meta); font-variant-numeric:tabular-nums; }
  .lz-bb--in { align-self:flex-start; background:var(--hilo-in); border:1px solid var(--hilo-in-line); box-shadow:var(--shadow-sm); border-bottom-left-radius:4px; }
  /* La saliente es el acento SUAVE con texto normal, no cobalto sólido con texto blanco: el cobalto
     queda para lo que se pulsa (enviar), y un hilo largo de bloques azules cansa. */
  .lz-bb--out { align-self:flex-end; background:var(--hilo-out); color:var(--hilo-out-text); border-bottom-right-radius:4px; }
  /* Recibos: entregado en la tinta apagada del hilo, leído y escuchada en la encendida. El estado
     lo dicen el glifo (una paloma, dos, o micrófono y dos) y la etiqueta además del color, y la
     opacidad no se usa porque rompe el contraste del texto apagado. */
  .lz-bb-rc { color:var(--hilo-meta); }
  .lz-bb-rc.on { color:var(--hilo-meta-on); }
  /* 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; vertical-align:middle; }
  .lz-bb-rc .lz-glifo { width:1.25em; height:1.25em; stroke-width:1.75; flex:none; }
  .lz-bb-rt { margin-left:2px; }
  /* La hora de la etiqueta («Leído 21:58») va en mono y en 24 h, como la del encabezado. */
  .lz-bb-rh { font-family:var(--mono); font-size:var(--fs-1); }
  .lz-bb--err { align-self:flex-end; background:var(--bad-soft); color:var(--bad-text); border:1px solid transparent; border-bottom-right-radius:4px; }
  /* 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(--hilo-in); border:1px solid var(--hilo-in-line); border-radius:var(--r-card); 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:12px; line-height:1.45; color:var(--hilo-meta); overflow-wrap:normal; word-break:normal; hyphens:none; }
  .lz-bb-sis-n { white-space:nowrap; }
  .lz-bb-sis-h { font-size:var(--fs-1); color:var(--hilo-meta); margin-left:8px; white-space:nowrap; font-variant-numeric:tabular-nums; }
  .lz-bb--err .lz-bb-mt { color:var(--bad-text); }
  /* 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 color-mix(in oklch, currentColor 20%, transparent); font-size:12px; line-height:1.45; 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; color:var(--text-muted); }
  .lz-bb-cod { font-size:11.5px; color:var(--text-muted); white-space:nowrap; font-variant-numeric:tabular-nums; }
  .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. */
  /* AL COSTADO del mensaje, centradas en su alto, en el canalón que deja el ancho máximo del grupo (Alex, 14-oct:
     arriba tapaban el nombre y la primera línea). 24 px = el relleno del grupo más el borde más 9 de aire. */
  .lz-bb-acc { display:none; position:absolute; top:50%; transform:translateY(-50%); gap:3px; z-index:var(--z-base); }
  .lz-feed-js .lz-bb-acc { display:flex; opacity:0; transition:opacity .12s; }
  .lz-bb--in .lz-bb-acc { left:calc(100% + 24px); }
  .lz-bb--out .lz-bb-acc { right:calc(100% + 24px); }
  .lz-bb:hover .lz-bb-acc, .lz-bb:focus-within .lz-bb-acc, .lz-bb-acc:has(.lz-bb-emojis:not([hidden])) { opacity:1; transition-delay:0s; }
  /* El hueco de 24 px entre la burbuja y la barra hacía parpadear la barra al cruzarlo (F2-15): un área invisible lo tapa
     y la salida lleva 100 ms de gracia. */
  .lz-feed-js .lz-bb-acc { transition:opacity .12s .1s; }
  /* z-index:-1: la barra ya es contexto de apilamiento (z-base) y el puente queda DETRÁS de los botones; sin eso se
     comía los clics de Responder, Tarea y Reaccionar (lo midió el corrector F2 el 14-oct). */
  .lz-feed-js .lz-bb-acc::before { content:""; position:absolute; inset:-6px -26px; z-index:-1; }
  /* El globo con los seis emojis cuelga de «Reaccionar». */
  .lz-bb-emojis { position:absolute; top:calc(100% + 6px); left:0; display:flex; gap:3px; padding:4px; border-radius:var(--r-pill); background:var(--surface); border:1px solid var(--border); box-shadow:var(--shadow-md); z-index:var(--z-dropdown); }
  .lz-bb--out .lz-bb-emojis { left:auto; right:0; }
  .lz-bb-emojis[hidden] { display:none; }
  .lz-bb-act--abrir[aria-expanded="true"] { color:var(--text); background:var(--surface-2); }
  /* La sombra propia pisaba el anillo genérico (F2-02: 1.02:1 de anillo): aquí van los dos. */
  .lz-bb-act:focus-visible { box-shadow:var(--ring), var(--shadow-sm); }
  .lz-bb-act { width:24px; height:24px; padding:0; border-radius:50%; border:1px solid var(--border);
    background:var(--surface); color:var(--text-2); display:inline-flex; align-items:center;
    justify-content:center; cursor:pointer; box-shadow:var(--shadow-sm); }
  @media (hover:hover) { .lz-bb-act:hover { color:var(--text); background:var(--surface-2); } }
  .lz-bb-act svg { width:12px; height:12px; stroke:currentColor; fill:none; }

  .lz-bb-cita { display:block; margin:0 0 6px; padding:6px 9px; border-radius:var(--r-control);
    background:color-mix(in oklch, var(--text) 6%, transparent); font-size:12px;
    line-height:1.35; text-decoration:none; color:var(--text-2); cursor:pointer; }
  @media (hover:hover) { .lz-bb-cita:hover { background:color-mix(in oklch, var(--text) 10%, transparent); color:var(--text); } }
  /* 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; 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(--accent) 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:11.5px; color:var(--text-muted); list-style:none; }
  .lz-bb-rf > summary::-webkit-details-marker { display:none; }
  @media (hover:hover) { .lz-bb-rf > summary:hover, .lz-bb-rf[open] > summary { color:var(--text); } }
  .lz-bb-rf-in { display:flex; gap:6px; margin-top:6px; }
  .lz-bb-rf-in input[name="texto"] { flex:1; min-width:0; height:32px; font-size:13px; }
  .lz-bb-rf-in .zbtn { height:32px; padding:0 12px; font-size:12px; }
  .lz-bb-rf-in select[name="emoji"] { flex:1; min-width:0; height:32px; 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:var(--z-base); 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:var(--surface); }
  .lz-bb-rx-c b { font-size:var(--fs-1); font-weight:500; color:var(--text-2); font-variant-numeric:tabular-nums; }
  /* 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:var(--surface-3); }
  /* 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:var(--ink-on-accent);
    display:inline-flex; align-items:center; justify-content:center; border-radius:50%;
    background:var(--accent); border:0; }
  @media (hover:hover) { .lz-au-pp:hover { background:var(--accent-hover); } }
  .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; color:var(--text-muted); }
  .lz-au-cara { position:absolute; inset:0; display:flex; align-items:center; gap:2px; }
  .lz-au-cara--base { opacity:.5; }
  .lz-au-cara--hecho { opacity:1; color:var(--accent-text); 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-size:var(--fs-1); color:var(--text-muted); 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:inherit; font-size:var(--fs-1); font-weight:500; height:22px; padding:0 8px; cursor:pointer;
    color:var(--text-2); background:transparent; border-radius:var(--r-pill); border:1px solid var(--border); }
  @media (hover:hover) { .lz-au-vel:hover { background:var(--surface-2); color:var(--text); } }
  .lz-au-vel[data-v="1.5"], .lz-au-vel[data-v="2"] { background:var(--surface-3); color:var(--text); }
  /* 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. */
  /* Ya no hay burbuja invertida (la saliente es el acento suave), pero el contorno en currentColor
     se queda: en el botón de play, que es acento macizo, el anillo suave solo no basta en oscuro. */
  .lz-au-pp:focus-visible, .lz-au-vel:focus-visible, .lz-au-onda:focus-visible {
    outline:1px solid currentColor; outline-offset:2px; box-shadow:var(--ring); }

  /* ---- 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 color-mix(in oklch, var(--text) 14%, transparent); font-size:12.5px;
    line-height:1.5; color:var(--text-2); white-space:normal; }
  .lz-bb-tr--pendiente, .lz-bb-tr--sinmotor { font-style:italic; color:var(--text-muted); }
  .lz-bb-tr--fallo { color:var(--text-2); }
  /* 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; }
  .lz-bb-tr--lista > summary::-webkit-details-marker { display:none; }
  @media (hover:hover) { .lz-bb-tr--lista > summary:hover, .lz-bb-tr--lista[open] > summary { color:var(--text); } }
  .lz-bb-tr--baja > summary { color:var(--text); }
  /* 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.5; white-space:pre-line;
    overflow-wrap:anywhere; 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:11.5px; font-weight:500; color:var(--accent-text);
    cursor:pointer; }
  @media (hover:hover) { .lz-bb-tr-mas:hover { text-decoration:none; color:var(--link-hover); } }
  /* 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; color:var(--text-muted); }

  /* 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:10px; padding:9px 11px; border-radius:var(--r-control);
    border:1px solid var(--border); background:var(--surface); color:inherit; text-decoration:none; }
  @media (hover:hover) { .lz-bb-md--doc:hover { border-color:var(--line-2); background:var(--surface-2); } }
  /* Dentro de una saliente (--accent-soft) la tarjeta de documento conserva fondo propio, derivado del
     tema y no fijo: sin esto se funde con la burbuja y el documento deja de leerse como adjunto. */
  .lz-bb--out .lz-bb-md--doc { background:color-mix(in srgb, var(--bg) 70%, transparent); border-color:color-mix(in srgb, var(--accent) 22%, transparent); }
  .lz-bb--out .lz-bb-md--no { background:color-mix(in srgb, var(--bg) 70%, transparent); border-color:color-mix(in srgb, var(--accent) 22%, transparent); }
  .lz-bb-md--doc svg { width:19px; height:19px; flex:none; stroke:currentColor; fill:none; stroke-width:1.75; color:var(--text-2); }
  .lz-bb-doc-t { min-width:0; display:block; }
  .lz-bb-doc-t b { display:block; font-size:13px; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-bb-doc-t i { display:block; font-style:normal; font-size:11.5px; color:var(--text-muted); margin-top:2px;
    font-variant-numeric:tabular-nums; }

  /* 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(--line-2); border-radius:var(--r-control);
    font-size:12px; color:var(--text-2); }
  .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. */
  /* Sobre la burbuja saliente (acento suave) las tarjetas de documento y de "no disponible" se
     quedan en superficie plena: el borde las separa del fondo tintado en los dos temas. */
  @media (hover:hover) { .lz-bb--out .lz-bb-md--doc:hover { border-color:var(--accent); } }
  .lz-bb--out .lz-bb-md--bajando, .lz-bb--out .lz-bb-md--no { background:var(--surface); }
  /* 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 var(--border); border-radius:var(--r-control); background:var(--surface); }
  .lz-bb-fc-c + .lz-bb-fc-c { margin-top:5px; }
  .lz-bb-fc-c b { display:block; font-size:13.5px; }
  .lz-bb-fc-l { font-size:12.5px; color:var(--text-2); margin-top:2px; }
  .lz-bb-fc-l .mono { font-size:12px; font-variant-numeric:tabular-nums; }
  .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 var(--border); border-radius:var(--r-control); background:var(--surface); }
  .lz-bb-ub-c b { display:block; font-size:13.5px; }
  .lz-bb-ub-l { font-size:12.5px; color:var(--text-2); margin-top:2px; }
  .lz-bb-ub-l .mono { font-size:12px; font-variant-numeric:tabular-nums; }
  /* 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-flex; align-items:center; height:28px; margin-top:8px; padding:0 12px; border-radius:var(--r-btn);
    border:1px solid var(--border); background:var(--surface); font-size:12.5px; font-weight:500; text-decoration:none; color:var(--accent-text); }
  @media (hover:hover) { .lz-bb-ub-a:hover { background:var(--surface-2); } }
  .lz-bb-ub-a:focus-visible { outline:none; box-shadow:var(--ring); }

  /* 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:13px; line-height:1.45; margin-top:8px; color:var(--text-2); }
  .lz-bb-nv-m { font-size:12px; line-height:1.4; margin-top:6px; padding:6px 8px; color:var(--text-2);
    border-radius:var(--r-control); background:var(--surface-2); }
  .lz-wa-tpl { display:inline-block; font-size:var(--fs-1); font-weight:500; padding:1px 7px; border-radius:var(--r-chip); background:var(--surface-3); color:var(--text-2); 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-size:var(--fs-1); font-weight:500; padding:0 6px; border-radius:var(--r-chip); background:var(--surface-3); color:var(--text-2); margin:0 2px; vertical-align:middle; }

  /* ==== El hilo como TRANSCRIPCIÓN AGRUPADA (versión B del lienzo, elegida el 13-oct) ==========
     Los mensajes seguidos del mismo remitente son un grupo: avatar de iniciales, nombre y la hora
     del primero, y debajo cada mensaje como una línea (15 px, interlineado 1.45, 4 px entre
     líneas). El lead va sin burbuja, texto sobre el fondo del hilo; lo saliente va en UNA caja a
     la derecha (hilo-out, esquina superior derecha de 4 px) con el recibo una sola vez al pie.

     CADA LÍNEA SIGUE SIENDO UN ".lz-bb" con su data-id, su recibo y sus acciones: el grupo
     (".lz-hl-g > .lz-hl-b") es solo el envoltorio, y por eso el sondeo y los parches de estado
     funcionan sin saber que existe. Lo que hace este bloque es quitarle a la burbuja su caja
     cuando vive dentro de un grupo. Una burbuja suelta (la previa del editor de plantillas, el
     Design System) conserva la caja de arriba.

     SOLO LEE LAS SIETE VARIABLES DEL HILO (bg, in, in-line, out, out-text, meta, meta-on): el
     tema que elige la persona en Ajustes · Apariencia las cambia y esto se entera. El texto
     secundario de adentro de la caja saliente (--text-2, --text-muted) y la tinta apagada del
     recibo (--hilo-meta) se redefinen ahí mismo mezclando hilo-out-text con hilo-out, para que
     la cita, la transcripción, las tarjetas y el «Entregado» pasen 4.5:1 sobre el fondo que de
     verdad tienen: el --hilo-meta de los temas pizarra y cobalto está pensado para el fondo del
     hilo, no para la caja saliente (medido: 4.06 y 3.51 en oscuro). */
  .lz-hl-g { flex:0 0 auto; display:flex; align-items:flex-start; gap:12px; min-width:0; max-width:min(640px,86%); margin-top:10px; }
  .lz-hl-g--in { align-self:flex-start; }
  .lz-hl-g--out { align-self:flex-end; flex-direction:row-reverse; }
  .lz-hl-av { flex:none; display:grid; place-items:center; width:28px; height:28px; margin-top:2px; border-radius:50%;
    font-size:11px; font-weight:600; line-height:1; letter-spacing:.02em; background:var(--hilo-in); color:var(--hilo-meta);
    border:1px solid var(--hilo-in-line); }
  .lz-hl-av .lz-glifo { width:15px; height:15px; }
  /* El avatar del asesor va en la tinta del texto saliente sobre su fondo, invertido: es el que
     ancla el grupo y no se confunde con el del lead en ningún tema. */
  .lz-hl-g--out .lz-hl-av { background:var(--hilo-out-text); color:var(--hilo-out); border-color:transparent; }
  .lz-hl-b { min-width:0; display:flex; flex-direction:column; gap:4px; }
  .lz-hl-g--out .lz-hl-b { padding:10px 14px; background:var(--hilo-out); color:var(--hilo-out-text); border-radius:var(--r-card); border-top-right-radius:4px;
    --text-2:color-mix(in oklch, var(--hilo-out-text) 90%, var(--hilo-out));
    --text-muted:color-mix(in oklch, var(--hilo-out-text) 82%, var(--hilo-out));
    --hilo-meta:var(--text-muted); }
  .lz-hl-h { display:flex; align-items:baseline; gap:8px; min-width:0; font-size:var(--fs-2); line-height:1.3; }
  .lz-hl-nom { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-hl-hr { flex:none; font-family:var(--mono); font-size:var(--fs-1); color:var(--hilo-meta); font-variant-numeric:tabular-nums; }
  .lz-hl-h .lz-bb-tel { margin:0; background:color-mix(in oklch, currentColor 12%, transparent); color:inherit; }

  /* La línea: sin caja, sin borde, sin sombra y a todo el ancho del grupo. */
  .lz-hl-b > .lz-bb { align-self:stretch; max-width:none; padding:0; border:0; border-radius:0; background:none; box-shadow:none;
    color:inherit; font-size:15px; line-height:1.45; }
  /* El recibo es del grupo, no de cada línea: se muestra solo en la que lo cierra (y en la que
     falló, que lleva su propio motivo). La hora y el distintivo de teléfono ya están arriba. */
  .lz-hl-b > .lz-bb .lz-bb-mt { display:none; }
  .lz-hl-b > .lz-bb .lz-bb-h, .lz-hl-b > .lz-bb .lz-bb-tel { display:none; }
  .lz-hl-g--out .lz-hl-b > .lz-bb:last-child .lz-bb-mt:has(.lz-bb-rc),
  .lz-hl-b > .lz-bb--err .lz-bb-mt { display:flex; justify-content:flex-end; align-items:center; margin-top:4px; padding:0; }
  /* Una línea que falló: el motivo no cabe en la caja del grupo sin separarse de las demás. */
  .lz-hl-b > .lz-bb--err { padding:6px 10px; border-radius:var(--r-control); background:var(--bad-soft); color:var(--bad-text); }
  /* Archivos dentro de una línea: el tope de ancho lo marca el archivo, no el grupo. */
  .lz-hl-b > .lz-bb--md { max-width:min(360px,100%); }
  .lz-hl-b > .lz-bb--md:has(.lz-bb-md--doc) { max-width:min(340px,100%); }
  .lz-hl-b > .lz-bb--md:has(.lz-bb-md--aud) { width:min(340px,100%); max-width:100%; }
  .lz-hl-b > .lz-bb--stk { max-width:132px; }
  /* Un archivo pide más aire que una línea de texto: el reproductor y la tarjeta no se pegan al
     renglón de al lado. */
  .lz-hl-b > .lz-bb + .lz-bb--md, .lz-hl-b > .lz-bb--md + .lz-bb { margin-top:4px; }
  .lz-hl-b > .lz-bb--md .lz-bb-pie { padding:6px 0 0; }
  /* Las tarjetas que sí son caja (documento, ubicación, ficha de contacto, plantilla) van en
     hilo-in con su línea en el grupo del lead, y translúcidas sobre la caja saliente. */
  .lz-hl-g--in .lz-bb-md--doc, .lz-hl-g--in .lz-bb-fc-c, .lz-hl-g--in .lz-bb-ub-c { background:var(--hilo-in); border-color:var(--hilo-in-line); }
  @media (hover:hover) { .lz-hl-g--in .lz-bb-md--doc:hover { background:var(--hilo-in); border-color:var(--hilo-meta); } }
  .lz-hl-g--out .lz-bb-md--doc, .lz-hl-g--out .lz-bb-md--no, .lz-hl-g--out .lz-bb-md--bajando,
  .lz-hl-g--out .lz-bb-fc-c, .lz-hl-g--out .lz-bb-ub-c { background:color-mix(in oklch, var(--hilo-out-text) 9%, transparent); border-color:color-mix(in oklch, var(--hilo-out-text) 24%, transparent); }
  @media (hover:hover) { .lz-hl-g--out .lz-bb-md--doc:hover { background:color-mix(in oklch, var(--hilo-out-text) 14%, transparent); border-color:var(--hilo-out-text); } }
  .lz-hl-g--out .lz-wa-tpl { background:color-mix(in oklch, var(--hilo-out-text) 14%, transparent); color:inherit; }
  .lz-hl-g--in .lz-wa-tpl { background:var(--hilo-in); border:1px solid var(--hilo-in-line); color:var(--hilo-meta); }
  .lz-hl-g--in .lz-bb-nv-m { background:var(--hilo-in); }
  .lz-hl-g--out .lz-bb-cita { background:color-mix(in oklch, var(--hilo-out-text) 10%, transparent); }
  @media (hover:hover) { .lz-hl-g--out .lz-bb-cita:hover { background:color-mix(in oklch, var(--hilo-out-text) 16%, transparent); color:var(--hilo-out-text); } }
  /* Las acciones al pasar el ratón cuelgan del borde de arriba de la línea y se abren hacia el lado
     libre: a la izquierda en lo saliente (que vive pegado a la derecha) y a la derecha en lo del lead. */
  /* En el hilo agrupado el mensaje ocupa todo el ancho del grupo, así que «100 % + 24 px» cae 9 px fuera de la caja
     del grupo: las acciones quedan en el canalón, al costado del mensaje sobre el que está el puntero. */
  .lz-hl-g--out .lz-hl-b > .lz-bb .lz-bb-acc { top:50%; right:calc(100% + 24px); left:auto; }
  .lz-hl-g--in .lz-hl-b > .lz-bb .lz-bb-acc { top:50%; left:calc(100% + 24px); right:auto; }
  /* Las reacciones ya puestas se montan sobre el borde de abajo de su línea, a la izquierda. */
  .lz-hl-b > .lz-bb:has(.lz-bb-rx) { padding-bottom:24px; margin-bottom:0; }
  .lz-hl-b > .lz-bb .lz-bb-rx { bottom:0; left:0; right:auto; }
  /* El salto a la línea citada y la entrada de un grupo nuevo, sin la caja que ya no tiene la línea:
     un tinte del acento que se apaga, en vez del aro interior de la burbuja. */
  .lz-hl-g.nueva { animation:lzEntra .18s ease-out; }
  .lz-hl-b > .lz-bb--flash { border-radius:var(--r-control); animation:lz-hl-flash 1.1s ease-out; }
  @keyframes lz-hl-flash {
    0% { background:color-mix(in oklch, var(--accent) 26%, transparent); box-shadow:0 0 0 4px color-mix(in oklch, var(--accent) 26%, transparent); }
    100% { background:transparent; box-shadow:0 0 0 4px transparent; }
  }
  @media (prefers-reduced-motion:reduce) { .lz-bb.nueva, .lz-hl-g.nueva, .lz-hl-b > .lz-bb--flash { animation:none; } }
  @media (max-width:820px){
    .lz-hl-g { max-width:94%; gap:10px; }
    .lz-hl-g--out .lz-hl-b { padding:9px 12px; }
  }
  .lz-wa-user { font-size:var(--fs-1); color:var(--text-muted); white-space:nowrap; }
  .lz-pill { display:inline-flex; align-items:center; gap:6px; height:22px; padding:0 9px; font-size:11.5px; font-weight:500; border-radius:var(--r-pill); background:var(--surface-2); color:var(--text-2); white-space:nowrap; }
  .lz-pill::before { content:""; width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; opacity:.55; }
  .lz-pill--on { background:var(--ok-soft); color:var(--ok-text); }
  .lz-pill--on::before { opacity:1; }
  /* 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; }

  /* ==== 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:12px 16px; }
  .lz-acc > summary::-webkit-details-marker { display:none; }
  @media (hover:hover) { .lz-acc > summary:hover { background:var(--surface-2); } }
  .lz-acc > summary:focus-visible { outline:none; box-shadow:var(--ring-inset); }
  .lz-acc-hd { display:flex; align-items:center; gap:8px; }
  .lz-acc-t { flex:1; font-size:12.5px; font-weight:600; color:var(--text-2); }
  .lz-acc[open] .lz-acc-t { color:var(--text); }
  .lz-acc-n { font-size:11.5px; font-weight:500; color:var(--text-muted); white-space:nowrap; font-variant-numeric:tabular-nums; }
  .lz-acc-cv { width:14px; height:14px; stroke:var(--text-muted); fill:none; stroke-width:1.75; transition:transform .15s; flex:0 0 auto; }
  .lz-acc[open] .lz-acc-cv { transform:rotate(90deg); }
  .lz-acc-peek { font-size:12px; color:var(--text-muted); margin:3px 0 0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .lz-acc[open] .lz-acc-peek { display:none; }
  .lz-acc-body { padding:2px 16px 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; gap:2px; padding:0 8px; border-bottom:1px solid var(--border); }
  .lz-ptabs button { height:42px; padding:0 12px; border:0; background:transparent; color:var(--text-2); font-family:inherit; font-size:13px; font-weight:500; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; display:inline-flex; align-items:center; justify-content:center; gap:6px; }
  @media (hover:hover) { .lz-ptabs button:hover { color:var(--text); } }
  .lz-ptabs button:focus-visible { outline:none; box-shadow:var(--ring-inset); border-radius:var(--r-control); }
  .lz-ptabs button.on { color:var(--text); border-bottom-color:var(--text); }
  .lz-ptabs .n { font-size:11.5px; font-weight:500; color:var(--text-muted); font-variant-numeric:tabular-nums; }
  .lz-ptabs button.on .n { color:var(--accent-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:var(--z-fab); 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:var(--shadow-md); }
  @media (hover:hover) { .lz-fab:hover { background:var(--accent); color:var(--ink-on-accent); border-color:var(--accent); } }
  .lz-fab:focus-visible { outline:none; box-shadow:var(--ring); border-color:var(--accent); }
  .lz-fab svg { width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:1.75; }
  .lz-fab-n { position:absolute; top:-4px; right:-4px; min-width:18px; height:18px; padding:0 5px; border-radius:var(--r-pill);
    background:var(--accent); color:var(--ink-on-accent); border:1px solid var(--surface);
    font-size:var(--fs-1); font-weight:600; display:grid; place-items:center; }
  @media (hover:hover) { .lz-fab:hover .lz-fab-n { background:var(--surface); color:var(--accent-text); border-color:var(--accent); } }
  /* El contador del botón "Nota" de la cabecera es un chip en línea, no la insignia flotante del FAB. */
  .zbtn .lz-fab-n { position:static; height:18px; min-width:18px; background:var(--sel-bg); color:var(--sel-text); border:0; }
  .lz-velo { position:fixed; inset:0; background:color-mix(in oklch, black 30%, transparent); opacity:0; pointer-events:none; transition:opacity .3s; z-index:var(--z-cajon-velo); }
  .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:var(--z-cajon);
    background:var(--surface); border-left:1px solid var(--border); box-shadow:var(--shadow-md), 0 0 0 1px var(--hairline);
    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:10px; padding:14px 16px; border-bottom:1px solid var(--border); }
  .lz-cajon-h b { flex:1; font-size:14px; font-weight:600; }
  .lz-cajon-h svg { width:16px; height:16px; stroke:currentColor; fill:none; stroke-width:1.75; }
  .lz-cajon-top { flex:0 0 auto; padding:12px 16px; border-bottom:1px solid var(--border); }
  .lz-cajon-list { flex:1; min-height:0; overflow-y:auto; padding:4px 16px 24px; }

  /* ==== Ayudas compartidas por inbox, hilo, ficha y reportes ===========================
     .lz-sr: texto solo para lector de pantalla. Dice lo que un punto, un glifo o un color dicen
     a la vista (ventana abierta, vencida) sin ocupar lugar. */
  .lz-sr { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0; }
  /* Ventana de 24 h cerrada: mismo componente que la abierta, con su estado propio. */
  .lz-pill--off { background:var(--bad-soft); color:var(--bad-text); }
  /* Botón de quitar etiqueta: 24 px de blanco, sin opacidad (la opacidad bajaba el contraste a 3:1). */
  .lz-etq-x { width:24px; height:24px; border-radius:50%; background:none; border:0; padding:0; margin:0 0 0 -2px; cursor:pointer;
    color:inherit; font-size:14px; line-height:1; display:inline-flex; align-items:center; justify-content:center; }
  @media (hover:hover) { .lz-etq-x:hover { background:color-mix(in oklch, var(--accent) 16%, transparent); } }
  .lz-etq-x:focus-visible { outline:2px solid transparent; outline-offset:2px; background:color-mix(in oklch, var(--accent) 16%, transparent); box-shadow:var(--ring); }
  /* Una tabla ancha vive en una región con scroll propio: nombre, foco de teclado y primera
     columna fija para no perder de quién es cada fila al desplazar. */
  .lz-scroll-x:focus-visible { outline:2px solid transparent; box-shadow:var(--ring); border-radius:var(--r-control); }
  .lz-scroll-x .lz-tabla th:first-child, .lz-scroll-x .lz-tabla td:first-child { position:sticky; left:0; z-index:var(--z-base); background:var(--surface); }
  /* Texto de ayuda largo: ni a todo el ancho de la tarjeta. */
  /* Teléfono: lo que se toca mide 44 px (meta táctil); la burbuja ofrece sus acciones al tocarla
     y no con el hover, que no existe; el cajón de notas es una hoja que sube desde abajo. */
  @media (pointer:coarse){
    .lz-ico, .lz-lead .lz-ico { width:44px; height:44px; }
    .lz-etq-x { width:32px; height:32px; }
    .lz-check input { width:22px; height:22px; }
    .lz-check { min-height:44px; }
    .lz-au-pp { width:44px; height:44px; }
    .lz-au-vel { height:32px; min-width:44px; }
    .lz-ptabs button { height:48px; }
  }
  @media (hover:none){
    .lz-feed-js .lz-bb-acc { pointer-events:none; }
    .lz-feed-js .lz-bb--acc .lz-bb-acc { opacity:1; pointer-events:auto; }
    .lz-feed-js .lz-bb-act { width:36px; height:36px; }
    .lz-feed-js .lz-bb-act svg { width:16px; height:16px; }
    /* En un dedo no hay canalón: las acciones se abren DEBAJO del mensaje al tocarlo, ocupando su sitio. */
    /* Como superposición bajo la burbuja, no en el flujo: tocarla no debe agrandarla 52 px (F2-16). */
    .lz-feed-js .lz-bb-acc { gap:8px; position:absolute; top:calc(100% + 6px); left:0; right:auto; transform:none; display:none; z-index:var(--z-dropdown); }
    /* Las reglas del hilo agrupado (0,4,0) ganaban a esta (0,2,0) y la barra caía fuera de la ventana en 390: aquí van con
       la misma especificidad (lo midió el corrector F2 el 14-oct). */
    .lz-feed-js .lz-hl-g--in .lz-hl-b > .lz-bb .lz-bb-acc { left:0; right:auto; top:calc(100% + 6px); transform:none; }
    .lz-feed-js .lz-hl-g--out .lz-hl-b > .lz-bb .lz-bb-acc { left:auto; right:0; top:calc(100% + 6px); transform:none; }
    .lz-feed-js .lz-bb--acc .lz-bb-acc { display:flex; }
    .lz-feed-js .lz-bb-emojis { position:static; margin-left:4px; }
  }
  @media (max-width:820px){
    .lz-fab { display:none; }
    .lz-cajon { top:auto; left:0; width:auto; max-width:none; max-height:85vh; max-height:85dvh; border-left:0; border-top:1px solid var(--hairline);
      border-radius:var(--r-card) var(--r-card) 0 0; transform:translateY(100%); padding-bottom:env(safe-area-inset-bottom); touch-action:manipulation; }
    .lz-cajon.on { transform:translateY(0); }
    .lz-cajon.ancho { width:auto; }
    .lz-velo { touch-action:manipulation; }
  }
  @media (prefers-reduced-motion:reduce){
    .lz-cajon, .lz-velo, .lz-fab { transition:none; }
  }

  /* 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.
     El markup y su JS estan en leadz-selector-plantillas.js. Las medidas salen del ANCHO DEL
     SELECTOR (container query), no del de la ventana: en la ficha vive en una columna de ~400 px
     aunque la pantalla mida 1454. */
  .lz-tpl { display:block; margin-top:10px; container:lztpl / inline-size; }
  .lz-tpl [hidden] { display:none !important; }
  .lz-tpl-bar { margin-bottom:8px; }
  /* Campo compuesto: el contorno y el foco viven en el contenedor (.zfield:focus-within); el input
     de dentro no pinta borde ni anillo propio (dos rectangulos concentricos leen como error). */
  .lz-tpl-campo { display:flex; align-items:center; gap:4px; height:36px; padding:0 4px 0 12px; border:1px solid var(--field-line); border-radius:var(--r-input); background:var(--field); }
  .lz-tpl-campo:focus-within { background:var(--surface); }
  .lz-tpl-campo .lz-tpl-q { flex:1; min-width:0; height:34px; padding:0; font-size:13px; -webkit-appearance:none; appearance:none; }
  .lz-tpl-campo .lz-tpl-q::-webkit-search-cancel-button, .lz-tpl-campo .lz-tpl-q::-webkit-search-decoration { -webkit-appearance:none; display:none; }
  .lz-tpl-kbd { flex:none; margin-right:8px; min-width:20px; height:20px; padding:0 5px; display:inline-flex; align-items:center; justify-content:center; font-family:var(--mono); font-size:11px; color:var(--text-muted); border:1px solid var(--border); border-radius:var(--r-chip); background:var(--surface); }
  .lz-tpl-x { flex:none; width:28px; height:28px; display:inline-flex; align-items:center; justify-content:center; border:0; border-radius:var(--r-chip); background:transparent; color:var(--text-muted); cursor:pointer; }
  .lz-tpl-x .lz-glifo { width:14px; height:14px; }
  @media (hover:hover) { .lz-tpl-x:hover { background:var(--surface-2); color:var(--text); } }
  .lz-tpl-x:focus-visible { outline:none; box-shadow:var(--ring); }
  .lz-tpl mark { background:color-mix(in oklch, var(--accent) 22%, transparent); color:inherit; border-radius:2px; padding:0 1px; }

  /* Categorias: chips en radiogroup, con su cuenta. Una sola fila que se desplaza si no cabe. */
  .lz-tpl-cats { display:flex; gap:6px; margin:0 0 8px; padding:2px; overflow-x:auto; scrollbar-width:none; }
  .lz-tpl-cats::-webkit-scrollbar { display:none; }
  .lz-tpl-cat { flex:none; display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 11px; border:1px solid var(--border-control); border-radius:var(--r-pill); background:transparent; color:var(--text-2); font:inherit; font-size:12.5px; font-weight:500; cursor:pointer; white-space:nowrap; }
  .lz-tpl-cn { font-family:var(--mono); font-size:11px; font-weight:400; color:var(--text-muted); font-variant-numeric:tabular-nums; }
  @media (hover:hover) { .lz-tpl-cat:hover { background:var(--surface-2); color:var(--text); } }
  .lz-tpl-cat[aria-checked="true"] { background:var(--sel-bg); border-color:var(--accent); color:var(--text); }
  .lz-tpl-cat[data-vacia="1"]:not([aria-checked="true"]) { opacity:.55; }
  .lz-tpl-cat:focus-visible { outline:none; box-shadow:var(--ring); }

  /* La lista: unas 6 filas a la vista y desplazamiento propio. No empuja la pantalla. */
  .lz-tpl-lista { max-height:min(calc(6 * 40px + 34px), 34vh); min-height:calc(3 * 40px + 34px); overflow-y:auto; overscroll-behavior:contain; border:1px solid var(--border); border-radius:var(--r-card); padding:0 4px 4px; background:var(--surface); }
  .lz-tpl-gr { position:sticky; top:0; z-index:2; display:flex; align-items:center; justify-content:space-between; margin:0 -4px 2px; padding:9px 12px 5px; background:var(--surface); font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--text-muted); }
  .lz-tpl-gc { font-family:var(--mono); font-weight:400; letter-spacing:0; font-variant-numeric:tabular-nums; }

  /* La fila: UNA linea. El radio de verdad cubre toda la fila (invisible) y lo que se ve es el
     borde, el check y el texto. El nombre tiene columna fija para que las previas se alineen. */
  .lz-tpl-op { position:relative; display:grid; grid-template-columns:16px minmax(0,190px) 138px minmax(0,1fr) auto 26px; align-items:center; column-gap:10px; min-height:40px; margin:0; padding:0 8px; border:1px solid transparent; border-radius:var(--r-control); font-size:13px; font-weight:400; cursor:pointer; }
  .lz-tpl-op input { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:inherit; }
  @media (hover:hover) { .lz-tpl-op:hover { background:var(--surface-2); } }
  .lz-tpl-op:has(input:checked) { border-color:var(--accent); background:var(--sel-bg); }
  .lz-tpl-op:has(input:focus-visible) { box-shadow:var(--ring-inset); }
  /* El indicador de la opción (la fila es un radio: se elige UNA y luego «Enviar plantilla»). Se ve en reposo, aro en
     --border-control, y elegido, relleno --accent-control con la palomita (Alex, 15-oct: «debería estar visible el
     estado inactivo; ahorita no se ve nada»). Antes solo existía elegido y en reposo era un hueco de 16 px sin razón. */
  .lz-tpl-ck { display:inline-grid; place-items:center; width:16px; height:16px; box-sizing:border-box; border:1.5px solid var(--border-control); border-radius:50%; color:var(--surface); }
  .lz-tpl-ck .lz-glifo { width:10px; height:10px; stroke-width:2.5; opacity:0; }
  .lz-tpl-op:has(input:checked) .lz-tpl-ck { background:var(--accent-control); border-color:var(--accent-control); }
  .lz-tpl-op:has(input:checked) .lz-tpl-ck .lz-glifo { opacity:1; }
  .lz-tpl-n { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:500; color:var(--text); }
  .lz-tpl-mt { display:flex; align-items:center; gap:8px; white-space:nowrap; }
  .lz-tpl-cp { display:inline-flex; align-items:center; height:20px; padding:0 8px; border-radius:var(--r-pill); background:var(--surface-2); color:var(--text-2); font-size:11.5px; font-weight:500; }
  .lz-tpl-op:has(input:checked) .lz-tpl-cp { background:var(--surface); }
  .lz-tpl-id { font-family:var(--mono-code); font-size:11px; color:var(--text-muted); }
  .lz-tpl-pv { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-2); }
  .lz-tpl-falta { display:none; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; color:var(--warn-text); }
  /* Lo que no se puede mandar se atenúa, pero la RAZÓN no: es lo que hay que leer para decidir (PCB9A-29, ola 9).
     Antes la opción entera iba a .6 y la razón quedaba a 2.85:1. */
  .lz-tpl-op.is-off { cursor:not-allowed; }
  /* :not(input): el radio real cubre la fila con opacity:0, y esta regla (más específica) lo subía a .6 y el navegador
     pintaba su círculo nativo en medio de la fila apagada (Alex, 15-oct: «un círculo extraño»). */
  .lz-tpl-op.is-off > :not(.lz-tpl-falta):not(.lz-tpl-fav):not(input) { opacity:.6; }
  .lz-tpl-op.is-off .lz-tpl-falta { color:var(--warn-text); opacity:1; }
  .lz-tpl-op.is-off .lz-tpl-pv { display:none; }
  .lz-tpl-op.is-off .lz-tpl-falta { display:block; grid-column:4; }
  @media (hover:hover) { .lz-tpl-op.is-off:hover { background:none; } }
  .lz-tpl-ver { position:relative; z-index:1; display:none; height:26px; padding:0 8px; border:0; border-radius:var(--r-chip); background:transparent; color:var(--accent-text); font:inherit; font-size:12px; font-weight:500; cursor:pointer; }
  .lz-tpl--js .lz-tpl-ver { display:inline-flex; align-items:center; }
  .lz-tpl-op.is-off .lz-tpl-ver { display:none; }
  @media (hover:hover) { .lz-tpl-ver:hover { color:var(--link-hover); background:var(--surface); } }
  .lz-tpl-ver:focus-visible { outline:none; box-shadow:var(--ring); }
  /* «Ver»: el cuerpo completo baja a su propio renglon dentro de la fila. */
  .lz-tpl-op.is-abierta { align-items:start; padding-top:8px; padding-bottom:9px; }
  .lz-tpl-op.is-abierta .lz-tpl-pv { grid-column:2 / -1; grid-row:2; margin-top:4px; white-space:pre-wrap; overflow:visible; text-overflow:clip; line-height:1.45; color:var(--text); }
  .lz-tpl-op.is-abierta > .lz-tpl-ver { grid-row:1; grid-column:5; }
  .lz-tpl-op.is-abierta > .lz-tpl-mt { height:24px; }
  .lz-tpl-op.is-abierta > .lz-tpl-n { line-height:24px; }

  /* La estrella de favorita (Alex, 14-oct noche: «se debe de poder quitar o poner»): última columna de la fila, 26 px,
     relleno con currentColor cuando está marcada; el área táctil de 44 px es un ::after para no tocar la rejilla. */
  /* La estrella de favorita: ultima columna de la fila (grid-column:-2 / -1 la ancla a la ultima
     columna de cada una de las tres rejillas, tambien en .is-abierta). 26 px; al tacto el area
     de toque llega a 44 con ::after sin tocar la rejilla. */
  .lz-tpl-fav { position:relative; z-index:1; grid-column:-2 / -1; grid-row:1; display:inline-flex; align-items:center; justify-content:center; width:26px; height:26px; padding:0; border:0; border-radius:var(--r-chip); background:transparent; color:var(--text-muted); cursor:pointer; }
  .lz-tpl-fav .lz-glifo { width:16px; height:16px; }
  @media (hover:hover) { .lz-tpl-fav:hover { color:var(--text); } }
  .lz-tpl-fav[aria-pressed="true"], .lz-tpl-fav--ro { color:var(--accent-text); }
  .lz-tpl-fav[aria-pressed="true"] .lz-glifo, .lz-tpl-fav--ro .lz-glifo { fill:currentColor; }
  .lz-tpl-fav:focus-visible { outline:none; box-shadow:var(--ring); }
  .lz-tpl-fav[aria-busy="true"] { opacity:.6; cursor:progress; }
  .lz-tpl-fav--ro { cursor:default; }
  /* Lo que de verdad no existe (sin cita, sin asesor): una linea con su accion. */
  .lz-tpl-bloq { margin:8px 0 0; font-size:12.5px; line-height:1.45; color:var(--warn-text); }
  .lz-tpl-ag { display:inline-flex; align-items:center; gap:4px; color:var(--accent-text); font-weight:500; text-decoration:none; }
  .lz-tpl-ag .lz-glifo { width:14px; height:14px; }
  @media (hover:hover) { .lz-tpl-ag:hover { color:var(--link-hover); } }
  .lz-tpl-ag:focus-visible { outline:none; box-shadow:var(--ring); border-radius:var(--r-chip); }
  .lz-tpl-prev:focus-visible { outline:none; box-shadow:var(--ring); }
  /* El área táctil ya es 44 x 44 (26 + 9 + 9 por lado) por el pseudo-elemento; getBoundingClientRect mide solo el dibujo
     de 26, que es lo que vio la ola 9 (PCB9B-17). Se deja así: agrandar la celda rompe la rejilla de la opción. */
  @media (pointer:coarse) { .lz-tpl-fav::after { content:''; position:absolute; inset:-9px; } }
  .lz-tpl-nada { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin:0; padding:14px 12px; border:1px dashed var(--border); border-radius:var(--r-card); font-size:12.5px; color:var(--text-2); }
  .lz-tpl-estado { position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }

  /* La elegida, ya resuelta con los datos del lead, encima del boton de envio. Si falta una
     variable, aparece aqui como campo: el envio espera a que este llena. */
  .lz-tpl-prev { margin-top:10px; padding:10px 12px; border:1px solid var(--border); border-radius:var(--r-card); background:var(--surface-2); max-height:200px; overflow-y:auto; }
  .lz-tpl-prev-t { margin:0 0 4px; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; font-size:11.5px; color:var(--text-muted); }
  .lz-tpl-prev-k { font-weight:600; letter-spacing:.04em; text-transform:uppercase; font-size:11px; }
  .lz-tpl-prev-n { font-size:13px; font-weight:600; color:var(--text); }
  .lz-tpl-prev-tx { margin:0; font-size:13px; line-height:1.5; white-space:pre-wrap; color:var(--text); }
  .lz-tpl-hueco { padding:0 4px; border-radius:var(--r-chip); background:var(--warn-soft); color:var(--warn-text); }
  .lz-tpl-lleno { padding:0 2px; border-radius:var(--r-chip); background:var(--accent-soft); }
  .lz-tpl-prev-f { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:8px 12px; margin-top:10px; }
  .lz-tpl-vf label { display:block; margin:0 0 4px; font-size:11.5px; font-weight:500; color:var(--text-2); }
  .lz-tpl-vf .zinput { height:34px; font-size:13px; }

  .lz-tpl-pie { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:10px; }
  .lz-tpl-pie .lz-nada { flex:1; min-width:140px; }
  /* El boton va a la IZQUIERDA del pie: el boton flotante de acciones rapidas (.lz-fab) vive fijo abajo a la
     derecha y tapaba el de enviar en pantallas anchas. */
  .lz-tpl-env { order:-1; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  /* Tres medidas segun el ANCHO DEL SELECTOR. Mediano (la columna del Inbox, ~600 px): se va el
     idioma y la previa se queda. Angosto (la ficha, un telefono): se va tambien la previa y la
     fila sigue en UNA linea y a 44 px; el cuerpo completo sigue a un toque en «Ver» y, ya elegida,
     en la caja de abajo. */
  @container lztpl (max-width:620px) {
    .lz-tpl-op { grid-template-columns:16px minmax(0,190px) 92px minmax(0,1fr) auto 26px; }
    .lz-tpl-id { display:none; }
    .lz-tpl-op.is-off .lz-tpl-falta { grid-column:4; }
    .lz-tpl-kbd { display:none; }
  }
  @container lztpl (max-width:430px) {
    .lz-tpl-op { grid-template-columns:16px minmax(0,1fr) auto auto 26px; min-height:44px; }
    .lz-tpl-pv { display:none; }
    /* La razon de una fila bloqueada sustituye a la categoria y se recorta: la fila sigue en UNA linea. El texto
       completo viaja en el title y en el aria-label de la fila. */
    .lz-tpl-op.is-off { grid-template-columns:16px minmax(0,42%) minmax(0,1fr) 26px; }
    .lz-tpl-op.is-off .lz-tpl-mt { display:none; }
    .lz-tpl-op.is-off .lz-tpl-falta { grid-column:3; grid-row:1; }
    .lz-tpl-op.is-abierta .lz-tpl-pv { display:block; }
    .lz-tpl-op.is-abierta > .lz-tpl-ver { grid-column:4; }
    .lz-tpl-lista { max-height:min(calc(6 * 44px + 34px), 40vh); min-height:calc(3 * 44px + 34px); }
    .lz-tpl-env { scroll-margin-bottom:96px; }
    .lz-tpl-cat { height:36px; }
  }
  /* 44 px al tacto en las tres piezas del selector (F3: medían 30, 40 y 26 en 390). */
  @media (pointer:coarse) { .lz-tpl-op { min-height:44px; } .lz-tpl-cat { height:44px; } .lz-tpl-ver { height:44px; min-width:44px; } .lz-tpl-kbd { display:none; } }
  @media (prefers-reduced-motion:reduce) { .lz-tpl * { transition:none !important; } }

  /* ---- 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:var(--font); font-size:var(--fs-1); 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.75; 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:var(--font); font-size:var(--fs-1); letter-spacing:.05em; 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:var(--font); font-size:var(--fs-1); letter-spacing:.05em; 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:var(--font); font-size:var(--fs-1); letter-spacing:.05em; text-transform:uppercase; color:var(--text-muted); margin-bottom:6px; }
  .lz-ed-c .cont { float:right; font-family:var(--font); 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:var(--font); 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:var(--fs-1); color:var(--text-muted); margin-right:2px; }
  .lz-tk button { font-family:var(--font); font-size:10px; padding:3px 8px; border-radius:var(--r-chip); border:1px solid var(--border); background:transparent; color:var(--text-muted); cursor:pointer; }
  @media (hover:hover) { .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:var(--font); 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:var(--font); font-size:var(--fs-1); letter-spacing:.05em; 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:var(--font); font-size:var(--fs-1); letter-spacing:.05em; 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)). */
  /* Un solo interruptor en toda la app: el .zswitch del cromo. Esta etiqueta solo da el renglon
     (interruptor + texto) y un objetivo de al menos 24 px de alto; en tactil, 44. */
  .lz-perfil-toggle { display:inline-flex; align-items:center; gap:7px; cursor:pointer; user-select:none; min-height:24px; margin:0; font-weight:400; }
  .lz-perfil-toggle .tx { font-size:var(--fs-1); color:var(--text-2); }
  .lz-perfil-toggle input:checked ~ .tx { color:var(--text); font-weight:500; }
  @media (pointer:coarse){ .lz-perfil-toggle { min-height:44px; } }

  /* --- Modal de "¿con qué número marco?" ---------------------------------------------------- */
  .lz-tel-back { position:fixed; inset:0; background:color-mix(in oklch, var(--text) 45%, transparent); z-index:var(--z-sf-velo);
    display:flex; align-items:center; justify-content:center; padding:20px; }
  /* en oscuro el velo es el fondo oscurecido: una tinta clara al 45 % aclararia la pagina */
  [data-ds-theme="dark"] .lz-tel-back, [data-ds-theme="dark"] .lz-llam-back { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-tel-modal { background:var(--surface); color:var(--text); border:1px solid var(--hairline);
    border-radius:var(--r-card); box-shadow:var(--shadow-md); 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:var(--font); font-variant-numeric:tabular-nums; 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; }
  @media (hover:hover) { .lz-tel-obj:hover { border-color:var(--text-muted); } }
  .lz-tel-obj--on { background:var(--accent-soft); color:var(--accent-text); border-color:var(--accent); }
  .lz-tel-aviso { position:fixed; top:calc(16px + env(safe-area-inset-top)); right:16px; z-index:var(--z-toast); 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:var(--shadow-md); }
  .lz-tel-aviso--ok { border-color:var(--ok); }
  /* 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; }
  @media (hover:hover) { .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; }
  @media (hover:hover) { .lz-tel-op:hover:not([disabled]) { border-color:var(--accent); } }
  .lz-tel-op--pri { background:var(--accent); color:var(--ink-on-accent); border-color:var(--accent); }
  @media (hover:hover) { .lz-tel-op--pri:hover:not([disabled]) { background:var(--accent-hover); border-color:var(--accent-hover); } }
  .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:var(--font); font-variant-numeric:tabular-nums;
    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; }
  @media (hover:hover) { .lz-tel-cancel:hover { color:var(--text); } }

  /* 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:var(--z-sf); font-size:13px; }
  /* <= 820: la barra de navegacion pasa abajo (ver ESTILOS_LEADZ) y la pastilla flotante dejaba de
     tapar un enlace de la tira de arriba para quedarse sobre el borde derecho; ahora flota justo
     encima de la barra, dentro de la pantalla y en la zona del pulgar. */
  @media (max-width:820px) {
    .lz-sf { top:auto; right:12px; bottom:calc(var(--lz-bar, 60px) + 10px + env(safe-area-inset-bottom)); }
    /* En reposo la pastilla de 129×44 tapaba «Hecha» y «Llamar» en la esquina del pulgar (Ola 4):
       queda el punto en 44×44 y el estado viaja en title y aria-label del botón. */
    .lz-sf:not(#lz-sf-curso) .lz-sf__pill { width:44px; height:44px; padding:0; justify-content:center; position:relative; }
    /* EL BOTÓN DICE «TELÉFONO» (15-oct, Alex: «este icono debería ser un teléfono en tablet»). Solo con el punto no se
       leía qué abre: lleva el glifo tel (Lucide phone, el ICO de telefonia.js) a 20 px y el punto pasa a ser la señal de
       estado en la esquina superior derecha, con un aro --surface que lo despega del borde. */
    .lz-sf:not(#lz-sf-curso) .lz-sf__ico { display:block; width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:1.75; flex:none; }
    .lz-sf:not(#lz-sf-curso) .lz-sf__dot { position:absolute; top:2px; right:2px; width:10px; height:10px; box-shadow:0 0 0 2px var(--surface); }
    .lz-sf--otra:not(#lz-sf-curso) .lz-sf__dot { box-shadow:inset 0 0 0 1.5px var(--text-muted), 0 0 0 2px var(--surface); background:var(--surface); }
    .lz-sf:not(#lz-sf-curso) .lz-sf__txt, .lz-sf:not(#lz-sf-curso) .lz-sf__stchip { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
  }
  /* La cabina de la llamada en curso (#lz-sf-curso) se define con el softphone D, más abajo. */
  .lz-sf__pill { display:flex; align-items:center; gap:8px; height:38px; padding:0 14px;
    border:1px solid var(--border-control); border-radius:var(--r-pill); background:var(--surface);
    color:var(--text); box-shadow:var(--shadow-sm); cursor:pointer; font-family:inherit; font-size:var(--fs-2); }
  .lz-sf__pill:focus-visible { outline:none; box-shadow:var(--ring); }
  @media (pointer:coarse) { .lz-sf__pill { height:44px; } }
  /* 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:var(--ok); }
  .lz-sf--dnd .lz-sf__dot { background:var(--bad); }
  /* 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(--bad); }
  .lz-sf--err .lz-sf__pill { border-color:var(--bad); }
  /* 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:var(--font); font-variant-numeric:tabular-nums; font-size:11.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:calc(var(--z-sf-velo) + 1);
    width:320px; max-width:calc(100vw - 32px); max-height:calc(100vh - 32px); max-height:calc(100dvh - 32px); overflow:auto; touch-action:manipulation;
    border:1px solid var(--hairline); border-radius:var(--r-card); background:var(--surface);
    box-shadow:var(--shadow-md); }
  .lz-sf__panel[hidden] { display:none; }
  /* En la capa superior (popover manual, ver activaPanelModal): el agente de usuario pone a [popover] inset:0,
     margin:auto, borde y padding propios y fondo Canvas; aquí se reponen los nuestros. El velo conserva inset:0. */
  .lz-tel-back[popover] { margin:0; border:0; padding:0; width:auto; height:auto; }
  .lz-sf__panel[popover], .lz-sfd--reposo[popover] { right:auto; bottom:auto; margin:0; padding:0; color:inherit; }
  /* El campo del número no lleva anillo de foco (Alex, 14-oct noche): el panel ya es modal y el foco entra solo ahí;
     la línea de acento debajo basta para decir que se está escribiendo. */
  .lz-sfd__in:focus, .lz-sfd__in:focus-visible { outline:none; box-shadow: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:var(--z-base); 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; }
    /* La regla de arriba apaga box-shadow y le ganaba al :focus-visible general: el anillo parpadeaba (F1-02). */
    .lz-side-foot .lz-sf__pill:focus-visible { box-shadow:var(--ring); }
    @media (hover:hover) { .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-soft); color:var(--accent-text); font-weight:600; }
    .lz-side-foot .lz-sf__ico { display:block; width:17px; height:17px; stroke:currentColor; fill:none;
      stroke-width:1.75; 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. */
    /* El punto vuelve, pero como SEMÁNTICA y no como color inventado: apagado en línea neutra,
       en línea en --ok con halo suave. Es el mismo lenguaje que la ventana de 24 h del inbox. */
    .lz-side-foot .lz-sf__dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--line-2); flex:0 0 auto; }
    .lz-side-foot .lz-sf--on .lz-sf__dot { background:var(--ok); box-shadow:0 0 0 3px var(--ok-soft); }
    /* El chip OFF no es una acción ni una selección: va neutro, no en cobalto como el contador. */
    .lz-side-foot .lz-sf__stchip { background:var(--surface-3); color:var(--text-2); }
    .lz-side-foot .lz-sf--err .lz-sf__stchip { background:var(--bad-soft); color:var(--bad-text); }
    .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:11.5px; color:var(--text-muted); line-height:1.5; margin:6px 0 8px; }

  .lz-sf__lbl { font-size:12px; color:var(--text-muted); }
  .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; }

  /* Lo que sigue en uso del softphone de antes: el botón chico del aviso de «no arrancó», de la franja
     de «otra pestaña» y del diagnóstico. */
  .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__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); }

  /* =============================================================================================
     SOFTPHONE D (14-oct-2026, prototipo aprobado por Alex: softphone-d/index.html)
     ---------------------------------------------------------------------------------------------
     UNA sola pieza visual para los estados del teléfono: teclado, llamando, en curso, retenida,
     entrante, «¿Qué pasó?» y la pastilla. Dos instancias comparten estas reglas: el panel en
     reposo (dentro de #lz-sf, con velo) y la cabina de la llamada (#lz-sf-curso, acoplada abajo a
     la derecha y sin velo para no tapar la pantalla donde el asesor toma notas). El prototipo es
     oscuro: en claro los círculos y los botones bajan a los grises del DS y los de oscuro conservan
     el valor literal (#1c1c1c · #262626 · #333). Verde y rojo salen de los semánticos del DS
     (--wa y --bad con su tinta), no de un color suelto.
     ============================================================================================= */
  .lz-sfd { --sfd-bg:var(--surface); --sfd-k:oklch(94% 0 0); --sfd-k2:oklch(90% 0 0); --sfd-k3:oklch(85% 0 0);
    --sfd-b:oklch(94% 0 0); --sfd-b2:oklch(90% 0 0); --sfd-on:oklch(84% 0 0); --sfd-velo:color-mix(in oklch, var(--text) 45%, transparent);
    position:relative; width:348px; max-width:calc(100vw - 32px); box-sizing:border-box; background:var(--sfd-bg); color:var(--text);
    border:1px solid var(--hairline); border-radius:18px; box-shadow:var(--shadow-md); overflow:hidden;
    font-family:var(--font); font-size:14px; line-height:1.45; max-height:calc(100vh - 32px); max-height:calc(100dvh - 32px);
    overflow-y:auto; touch-action:manipulation; }
  [data-ds-theme="dark"] .lz-sfd { --sfd-bg:#0d0d0d; --sfd-k:#1c1c1c; --sfd-k2:#262626; --sfd-k3:#333; --sfd-b:#1f1f1f; --sfd-b2:#2a2a2a; --sfd-on:#3a3a3a;
    --sfd-velo:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-sfd[hidden], .lz-sfd [hidden] { display:none !important; }
  .lz-sfd button { font-family:inherit; }
  .lz-sfd__ic { display:block; flex:none; stroke-width:1.75; }
  /* El panel en reposo es la ventana centrada de siempre (velo + foco atrapado); la cabina se acopla. */
  .lz-sfd--reposo { position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); z-index:calc(var(--z-sf-velo) + 1); }
  .lz-sfd--cab { position:relative; }
  /* El panel en reposo es una columna: cabecera y pestañas fijas, y el cuerpo (recientes, ajustes) es lo
     que se desplaza cuando la ventana no da para los 700 px del teclado. */
  .lz-sfd--reposo { display:flex; flex-direction:column; overflow:hidden; }
  .lz-sfd--reposo .lz-sfd__cuerpo { overflow-y:auto; min-height:0; flex:1 1 auto; overscroll-behavior:contain; }
  /* Con la barra superior (≥ 821 px) este panel vive dentro de la columna lateral, cuyo z-index queda por debajo de la barra. Centrado en la
     ventana entera y con 100dvh - 32 de alto, sus primeros 36 px (el título y «Cerrar») quedaban DEBAJO de la barra: Cerrar en y=30..66 y
     elementFromPoint = header.lz-top (medido el 14-oct-2026 en Recientes y Ajustes, 1454x938 y 1024x768). Se centra en lo que la barra deja libre. */
  @media (min-width:821px) {
    .lz-sfd--reposo { top:calc(var(--lz-top, 52px) + (100vh - var(--lz-top, 52px)) / 2); top:calc(var(--lz-top, 52px) + (100dvh - var(--lz-top, 52px)) / 2);
      max-height:calc(100vh - var(--lz-top, 52px) - 24px); max-height:calc(100dvh - var(--lz-top, 52px) - 24px); }
  }

  /* --- cabecera: punto de estado, rótulo, cronómetro en mono --- */
  .lz-sfd__hd { display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px; min-height:56px; }
  .lz-sfd__st { display:flex; align-items:center; gap:9px; font-size:15px; font-weight:500; white-space:nowrap; min-width:0; }
  .lz-sfd__st i { width:9px; height:9px; border-radius:50%; background:var(--ok); display:inline-block; flex:none; }
  .lz-sfd__st i.ring { animation:lz-sfd-lat 1s infinite; }
  .lz-sfd__st i.hold { background:var(--warn); }
  .lz-sfd__st i.off { background:var(--text-muted); }
  .lz-sfd__st .sep { color:var(--text-muted); }
  .lz-sfd__t { font-family:var(--mono); font-weight:500; font-variant-numeric:tabular-nums; }
  @keyframes lz-sfd-lat { 50% { opacity:.3; } }
  @media (prefers-reduced-motion: reduce) { .lz-sfd__st i.ring, .lz-sfd-pill__dot { animation:none; } }
  .lz-sfd__ico { width:36px; height:36px; border:0; background:transparent; color:var(--text-2); border-radius:9px; display:grid; place-items:center; cursor:pointer; flex:none; padding:0; }
  @media (hover:hover) { .lz-sfd__ico:hover { background:var(--surface-2); color:var(--text); } }
  .lz-sfd__ico:focus-visible, .lz-sfd__k:focus-visible, .lz-sfd__bar button:focus-visible, .lz-sfd-pill button:focus-visible,
  .lz-sfd__tab:focus-visible, .lz-sfd__it:focus-visible, .lz-sfd__pilln:focus-visible, .lz-sfd__acts button:focus-visible,
  .lz-sfd__op:focus-visible, .lz-sfd__sw:focus-visible { outline:none; box-shadow:0 0 0 2px var(--sfd-bg, var(--surface)), 0 0 0 4px var(--focus); }

  /* --- pestañas del panel en reposo --- */
  /* Centradas (Alex, 15-oct, nota 11): el teclado, el número y la barra van al centro del panel y las pestañas
     alineadas a la izquierda dejaban un hueco de 56 px a la derecha. Padding simétrico para que el centro medido coincida. */
  .lz-sfd__tabs { display:flex; justify-content:center; gap:4px; padding:0 12px 8px; }
  .lz-sfd__tab { height:30px; padding:0 10px; border:0; border-radius:999px; background:transparent; color:var(--text-muted); font:500 12.5px var(--font);
    cursor:pointer; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
  .lz-sfd__tab[aria-selected="true"] { background:var(--surface-3); color:var(--text); }
  @media (hover:hover) { .lz-sfd__tab:hover:not([aria-selected="true"]) { color:var(--text); } }
  .lz-sfd__n { font:500 10.5px var(--mono); background:var(--text); color:var(--bg); border-radius:999px; padding:1px 6px; }
  .lz-sfd__n[hidden] { display:none; }

  /* --- el bloque de quién es: empresa, nombre, número --- */
  .lz-sfd__who--reposo { }
  .lz-sfd__who { text-align:center; padding:14px 18px 20px; border-bottom:1px solid var(--hairline); min-height:132px; }
  .lz-sfd__emp { font-size:15px; color:var(--text-muted); margin-bottom:6px; min-height:20px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-sfd__nom { margin:0 0 6px; font-size:24px; font-weight:600; letter-spacing:-.01em; line-height:1.25; min-height:30px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-sfd__nom a { color:inherit; text-decoration:none; }
  @media (hover:hover) { .lz-sfd__nom a:hover { color:var(--accent-text); } }
  .lz-sfd__num { font:400 19px var(--mono); color:var(--text); letter-spacing:.02em; min-height:26px; font-variant-numeric:tabular-nums; }
  .lz-sfd__quien { font-size:13px; color:var(--accent-text); margin-top:6px; display:flex; justify-content:center; gap:6px; align-items:center; min-height:19px; }
  .lz-sfd__quien--bad { color:var(--bad-text); }
  .lz-sfd__quien--warn { color:var(--warn-text); }
  .lz-sfd__pilln { display:inline-flex; align-items:center; gap:8px; height:40px; padding:0 16px; border-radius:10px; background:var(--surface-3); color:var(--text);
    font:500 15px var(--font); border:0; cursor:pointer; margin-top:12px; max-width:100%; }
  div.lz-sfd__pilln { cursor:default; font-weight:400; font-size:13.5px; height:auto; min-height:40px; padding:8px 14px; text-align:left; }
  @media (hover:hover) { button.lz-sfd__pilln:not([aria-pressed="true"]):hover { background:var(--sfd-k3); } }
  .lz-sfd__pilln[aria-pressed="true"] { background:var(--text); color:var(--bg); }
  .lz-sfd__mudo:empty { display:none; }
  .lz-sfd__mudo { margin-top:8px; font-size:12px; color:var(--text-muted); line-height:1.45; }
  /* El número a marcar: mono de 30 px centrado. El campo no se dibuja como campo (es la pantalla del
     teléfono), pero conserva una línea transparente de 1 px que se enciende con el foco de teclado. */
  .lz-sfd__in { width:100%; box-sizing:border-box; border:0; border-bottom:1px solid transparent; background:transparent; color:var(--text); font:400 30px/1.25 var(--mono);
    letter-spacing:.03em; text-align:center; outline:none; padding:4px 0 0; caret-color:var(--accent); font-variant-numeric:tabular-nums; }
  .lz-sfd__in::placeholder { color:var(--text-muted); }
  .lz-sfd__in:focus-visible { border-bottom-color:var(--focus); }

  /* --- el teclado: doce círculos llenos de 84 px --- */
  .lz-sfd__pad { display:grid; grid-template-columns:repeat(3, 84px); justify-content:space-between; gap:14px 0; padding:18px 32px; border-bottom:1px solid var(--hairline); }
  .lz-sfd__k { width:84px; height:84px; border-radius:50%; border:0; background:var(--sfd-k); color:var(--text); display:flex; flex-direction:column; align-items:center; justify-content:center;
    cursor:pointer; font:400 30px/1 var(--font); gap:2px; padding:0; transition:background .08s, transform .08s; user-select:none; -webkit-user-select:none; -webkit-tap-highlight-color:transparent; }
  @media (hover:hover) { .lz-sfd__k:hover:not([disabled]):not([aria-disabled="true"]) { background:var(--sfd-k2); } }
  .lz-sfd__k[disabled], .lz-sfd__k[aria-disabled="true"] { cursor:not-allowed; opacity:.45; }
  .lz-sfd__k:active, .lz-sfd__k.down { background:var(--sfd-k3); transform:scale(.96); }
  .lz-sfd__k small { font:400 12.5px/1 var(--font); letter-spacing:.06em; color:var(--text); min-height:12px; }
  /* * y # no llevan letras: el asterisco vive alto en la tipografía y se baja para centrarlo ópticamente. */
  .lz-sfd__k--sym small { display:none; }
  .lz-sfd__k--sym[data-t="*"], .lz-sfd__k--sym[data-dtmf="*"] { padding-top:12px; }
  .lz-sfd__k--sym[data-t="#"], .lz-sfd__k--sym[data-dtmf="#"] { padding-top:2px; }

  /* --- la barra inferior: botones cuadrados de 62 px --- */
  .lz-sfd__bar { display:grid; grid-template-columns:1fr 1fr 1fr 1.4fr; gap:10px; padding:18px; }
  .lz-sfd__bar button { height:62px; border-radius:12px; border:0; background:var(--sfd-b); color:var(--text); display:grid; place-items:center; cursor:pointer; position:relative; transition:background .1s; padding:0; min-width:0; }
  @media (hover:hover) { .lz-sfd__bar button:hover:not([disabled]) { background:var(--sfd-b2); } }
  .lz-sfd__bar button:active:not([disabled]) { transform:translateY(1px); }
  .lz-sfd__bar button.on { background:var(--sfd-on); }
  .lz-sfd__bar button.col { background:var(--bad); color:var(--ink-on-accent); }
  @media (hover:hover) { .lz-sfd__bar button.col:hover:not([disabled]) { background:var(--bad); filter:brightness(1.08); } }
  .lz-sfd__bar button.ok { background:var(--wa); color:var(--ink-on-wa); }
  @media (hover:hover) { .lz-sfd__bar button.ok:hover:not([disabled]) { background:var(--wa); filter:brightness(1.08); } }
  .lz-sfd__bar button[disabled], .lz-sfd__bar button[aria-disabled="true"] { opacity:.45; cursor:not-allowed; filter:none; }
  /* «Llamar» sin número es un botón desactivado como los demás: gris neutro (no un verde pálido que parece un estado de éxito), y el porqué viaja en su globo. */
  .lz-sfd__bar button.ok[disabled], .lz-sfd__bar button.ok[aria-disabled="true"] { background:var(--sfd-b); color:var(--text-muted); }
  .lz-sfd__bar--reposo { grid-template-columns:62px 1fr 62px; }
  .lz-sfd__bar--reposo .ok { display:flex; align-items:center; justify-content:center; gap:10px; font:600 16px var(--font); }
  .lz-sfd__bar--ent { grid-template-columns:1fr 1fr; }
  .lz-sfd__bar--ent button { display:flex; align-items:center; justify-content:center; gap:10px; font:600 15px var(--font); }
  .lz-sfd__bar--fin { grid-template-columns:62px 1fr; }
  .lz-sfd__bar--fin .ok { display:flex; align-items:center; justify-content:center; gap:10px; font:600 15px var(--font); }
  .lz-sfd__bar--fin3 { grid-template-columns:62px 1fr 1fr; }
  .lz-sfd__bar--fin3 button.sec { font:500 13px/1.2 var(--font); padding:0 8px; }

  /* --- contexto con nota (en curso): ocupa el hueco del teclado --- */
  /* Ritmo del contexto en escala de 4 (Alex, 15-oct, nota 14): renglones de 8 arriba y 8 abajo entre hairlines, 12 entre
     bloques (filas, acciones, nota) y 16 al pie. Antes los renglones sumaban 9 y el gap de 8 de la rejilla (17 contra 9),
     «Ver más» quedaba pegado a la última línea y el sobrante del min-height caía al pie. Ahora la nota crece y se come el
     sobrante: el pie mide siempre 16. Los 18 laterales son los del resto del panel (cabecera, quién, barra). */
  .lz-sfd__ctx { padding:8px 18px 16px; display:flex; flex-direction:column; gap:12px; min-height:286px; border-bottom:1px solid var(--hairline); }
  .lz-sfd__filas { display:grid; }
  .lz-sfd__fila { display:flex; justify-content:space-between; gap:8px; font-size:14px; line-height:20px; padding:8px 0; border-bottom:1px solid var(--hairline); }
  .lz-sfd__fila span { color:var(--text-muted); flex:none; }
  .lz-sfd__fila b { font-weight:500; text-align:right; min-width:0; text-wrap:pretty; }
  .lz-sfd__alerta { font-size:11.5px; text-transform:uppercase; letter-spacing:.04em; background:var(--warn-soft); color:var(--warn-text); border-radius:999px; padding:4px 8px; margin:4px 0; justify-self:start; }
  .lz-sfd__mas summary { font-size:12px; color:var(--text-muted); cursor:pointer; min-height:32px; display:flex; align-items:center; }
  .lz-sfd__mas div { font-size:12px; color:var(--text-muted); line-height:1.6; margin-top:4px; }
  .lz-sfd__acts { display:flex; gap:8px; }
  .lz-sfd__acts button { flex:1; height:36px; border-radius:9px; border:1px solid var(--border-control); background:var(--surface-2); color:var(--text); font:500 13px var(--font); cursor:pointer; display:inline-flex; align-items:center; justify-content:center; gap:6px; padding:0; }
  @media (hover:hover) { .lz-sfd__acts button:hover { background:var(--surface-3); } }
  .lz-sfd__ctx textarea { width:100%; box-sizing:border-box; min-height:84px; flex:1 0 auto; resize:none; border-radius:12px; border:1px solid var(--field-line); background:var(--field); color:var(--text);
    font:400 14px/1.5 var(--font); padding:12px; outline:none; }
  .lz-sfd__ctx textarea:focus { border-color:var(--focus); box-shadow:0 0 0 3px color-mix(in oklch, var(--focus) 30%, transparent); }
  .lz-sfd__alta { margin:0; }
  .lz-sfd__alta .lz-curso__alta-c { display:flex; flex-direction:column; gap:6px; margin-top:8px; }
  .lz-sfd__alta summary { cursor:pointer; font-size:12.5px; color:var(--accent-text); }
  .lz-sfd__alta .zinput { height:32px; font-size:13px; }
  .lz-sfd__alta-msg { font-size:12px; color:var(--text-muted); line-height:1.4; }
  .lz-sfd__alta-ok { height:32px; border-radius:9px; border:1px solid var(--border-control); background:var(--surface-2); color:var(--text); font:500 13px var(--font); cursor:pointer; }

  /* --- recientes --- */
  .lz-sfd__lista { padding:6px 10px 10px; min-height:430px; }
  .lz-sfd__filtros { display:flex; gap:6px; margin:4px 8px 8px; }
  .lz-sfd__f { height:28px; padding:0 12px; border-radius:999px; border:1px solid var(--border-control); background:none; color:var(--text-muted); font:500 12px var(--font); cursor:pointer; }
  .lz-sfd__f.on { background:var(--chip-on-bg); border-color:var(--chip-on-bg); color:var(--chip-on-text); }
  .lz-sfd__it { display:flex; align-items:center; gap:12px; padding:10px 8px; border-radius:12px; text-decoration:none; color:var(--text); }
  @media (hover:hover) { .lz-sfd__it:hover { background:var(--surface-2); } }
  .lz-sfd__av { width:40px; height:40px; border-radius:50%; background:var(--surface-3); display:grid; place-items:center; font-weight:600; font-size:13px; flex:none; color:var(--text); }
  .lz-sfd__tx { flex:1; min-width:0; }
  .lz-sfd__tx b { display:block; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-sfd__tx b.vacio { color:var(--text-muted); font-style:italic; font-weight:500; }
  .lz-sfd__tx span { font-size:12.5px; color:var(--text-muted); display:flex; align-items:center; gap:6px; }
  .lz-sfd__tx span.miss { color:var(--bad-text); }
  .lz-sfd__it--mal .lz-sfd__tx b { font-weight:700; }
  .lz-sfd__who--ent { min-height:186px; }
  .lz-sfd__go, .lz-sfd__nuevo { width:40px; height:40px; border-radius:50%; border:0; background:var(--wa); color:var(--ink-on-wa); display:grid; place-items:center; cursor:pointer; flex:none; padding:0; }
  .lz-sfd__nuevo { background:transparent; border:1px solid var(--border-control); color:var(--text-2); width:36px; height:36px; }
  @media (hover:hover) { .lz-sfd__go { opacity:0; transition:opacity .12s; } .lz-sfd__it:hover .lz-sfd__go, .lz-sfd__it:focus-within .lz-sfd__go, .lz-sfd__go:focus-visible { opacity:1; } }
  .lz-sfd__go:focus-visible, .lz-sfd__nuevo:focus-visible { outline:none; box-shadow:0 0 0 2px var(--sfd-bg), 0 0 0 4px var(--focus); }
  .lz-sfd__nada { font-size:12.5px; color:var(--text-muted); padding:24px 0; text-align:center; }
  .lz-sfd__todas { display:block; margin-top:10px; font-size:12.5px; color:var(--accent-text); text-align:center; text-decoration:none; }
  .lz-sfd__alta-caja { padding:0 8px 10px 60px; }

  /* --- ajustes --- */
  .lz-sfd__ajs { padding:10px 18px 18px; min-height:430px; }
  .lz-sfd__lineas { display:grid; gap:6px; padding:4px 0 12px; border-bottom:1px solid var(--hairline); }
  .lz-sfd__cab { font-size:14px; margin-bottom:2px; }
  .lz-sfd__cab span { color:var(--text-muted); font-size:12.5px; display:block; }
  .lz-sfd__op { display:flex; align-items:center; gap:12px; width:100%; padding:10px 12px; border-radius:12px; border:1px solid var(--border-control); background:var(--surface-2); color:var(--text); cursor:pointer; text-align:left; font-family:inherit; }
  @media (hover:hover) { .lz-sfd__op:hover:not([disabled]) { background:var(--surface-3); } }
  .lz-sfd__op[aria-checked="true"] { border-color:var(--text); }
  .lz-sfd__op[disabled] { opacity:.5; cursor:not-allowed; }
  .lz-sfd__op .ck { width:20px; height:20px; border-radius:50%; border:1.5px solid var(--border-control); display:grid; place-items:center; flex:none; color:var(--bg); }
  .lz-sfd__op[aria-checked="true"] .ck { background:var(--text); border-color:var(--text); }
  .lz-sfd__op b { display:block; font-weight:600; font-size:14px; }
  .lz-sfd__op div > span { font:400 12.5px var(--mono); color:var(--text-muted); font-variant-numeric:tabular-nums; }
  .lz-sfd__row { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:12px 0; border-bottom:1px solid var(--hairline); font-size:14px; }
  .lz-sfd__row > div { min-width:0; }
  .lz-sfd__row span.sub { color:var(--text-muted); font-size:12.5px; display:block; }
  .lz-sfd__row select { margin-top:5px; width:100%; height:32px; font-size:12.5px; }
  .lz-sfd__row--col { display:block; }
  .lz-sfd__lista-ok { color:var(--ok-text); font-size:13px; white-space:nowrap; display:inline-flex; align-items:center; gap:6px; }
  .lz-sfd__lista-ok::before { content:''; width:8px; height:8px; border-radius:50%; background:currentColor; }
  .lz-sfd__lista-ok--off { color:var(--text-muted); }
  .lz-sfd__sw, .lz-sf__sw { position:relative; width:40px; height:24px; border-radius:999px; border:1px solid var(--border-control); background:var(--surface-3); cursor:pointer; flex:none; padding:0; }
  .lz-sfd__sw::after, .lz-sf__sw::after { content:''; position:absolute; top:3px; left:3px; width:16px; height:16px; border-radius:50%; background:var(--text-2); transition:transform var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out); }
  .lz-sfd__sw[aria-checked="true"], .lz-sf__sw[aria-checked="true"] { background:var(--accent); border-color:var(--accent); }
  .lz-sfd__sw[disabled], .lz-sf__sw[disabled], .lz-sfd__sw[aria-disabled="true"], .lz-sf__sw[aria-disabled="true"] { cursor:not-allowed; }
  .lz-sfd__sw[aria-checked="true"]::after, .lz-sf__sw[aria-checked="true"]::after { transform:translateX(16px); background:var(--ink-on-accent); }
  .lz-sfd__sw[disabled] { opacity:.5; cursor:not-allowed; }
  .lz-sfd__est { font-size:12px; color:var(--text-muted); line-height:1.45; margin-top:12px; }
  .lz-sfd__diag { margin-top:12px; padding-top:12px; border-top:1px solid var(--hairline); }

  /* --- «¿Qué pasó con {nombre}?»: la hoja desde abajo --- */
  .lz-sfd__quedo { position:absolute; inset:0; background:var(--sfd-velo); display:flex; align-items:flex-end; z-index:5; }
  .lz-sfd__hoja { display:flex; flex-direction:column; width:100%; max-height:100%; overflow:hidden; background:var(--surface); border-top:1px solid var(--line-2); border-radius:18px 18px 0 0; padding:16px 18px 18px; box-sizing:border-box; }
  /* El cuerpo de la hoja se desplaza y Atrás/Listo se quedan fijos abajo: con «No le interesa» la lista de
     razones es larga y los botones no pueden irse fuera de la vista. */
  .lz-sfd__scroll { overflow-y:auto; min-height:0; flex:1 1 auto; overscroll-behavior:contain; }
  .lz-sfd__hoja h4 { margin:0 0 4px; font-size:16px; font-weight:600; }
  .lz-sfd__sub { color:var(--text-muted); font-size:12.5px; margin:0 0 12px; }
  .lz-sfd__grupo { margin:10px 0 6px; font:500 10.5px/1 var(--mono); letter-spacing:.14em; text-transform:uppercase; color:var(--text-muted); }
  .lz-sfd__q { display:flex; align-items:center; gap:10px; width:100%; height:44px; padding:0 12px; border-radius:10px; border:1px solid var(--border-control); background:var(--surface-2);
    color:var(--text); font:500 14px var(--font); cursor:pointer; margin-bottom:6px; text-align:left; box-sizing:border-box; }
  @media (hover:hover) { .lz-sfd__q:hover:not([aria-pressed="true"]) { background:var(--surface-3); } }
  .lz-sfd__q[aria-pressed="true"] { border-color:var(--text); background:var(--text); color:var(--bg); }
  .lz-sfd__q .hu { width:16px; height:16px; flex:none; }
  .lz-sfd__q:focus-visible { outline:none; box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--focus); }
  .lz-sfd__det { margin:4px 0 6px; padding:10px 0 2px; border-top:1px solid var(--hairline); }
  .lz-sfd__det .lbl { display:block; font-size:12.5px; color:var(--text-muted); margin-bottom:6px; }
  .lz-sfd__det .zinput { width:100%; box-sizing:border-box; }
  .lz-sfd__razones { display:grid; gap:6px; margin:0; padding:0; border:0; }
  .lz-sfd__razones legend { font-size:12.5px; color:var(--text-muted); margin-bottom:6px; padding:0; }
  .lz-sfd__razones .lz-razon { display:flex; align-items:center; gap:8px; font-size:13.5px; }
  .lz-sfd__presets { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
  .lz-sfd__presets button { height:30px; padding:0 11px; border-radius:999px; border:1px solid var(--border-control); background:none; color:var(--text); font:500 12px var(--font); cursor:pointer; }
  .lz-sfd__fin { display:flex; gap:8px; margin-top:10px; flex:none; }
  .lz-sfd__fin button { flex:1; height:44px; border-radius:10px; border:1px solid var(--border-control); background:var(--surface-2); color:var(--text); font:600 14px var(--font); cursor:pointer; }
  .lz-sfd__fin button.pri { background:var(--text); color:var(--bg); border-color:var(--text); }
  .lz-sfd__fin button[disabled], .lz-sfd__fin button[aria-disabled="true"] { opacity:.5; cursor:not-allowed; }
  .lz-sfd__fin button:focus-visible { outline:none; box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--focus); }
  /* La misma hoja, suelta: cuando se registra a mano (sin llamada) o hay otra llamada encima. */
  .lz-sfd--sola { position:relative; display:flex; flex-direction:column; overflow:hidden; }
  .lz-sfd--sola .lz-sfd__quedo { position:static; background:transparent; flex:1 1 auto; min-height:0; align-items:stretch; }
  .lz-sfd--sola .lz-sfd__hoja { border-top:0; border-radius:0; }

  .lz-sfd__toast { position:absolute; left:18px; right:18px; bottom:98px; background:var(--text); color:var(--bg); border-radius:10px; padding:10px 12px; font-size:13px; font-weight:500; box-shadow:var(--shadow-md); z-index:6; }

  /* --- la cabina: dónde vive la llamada --- */
  #lz-sf-curso.lz-sf { position:fixed; top:auto; left:auto; right:18px; bottom:18px; z-index:var(--z-sf); font-size:14px; }
  /* En teléfono se centra con flex y no con transform: un transform en el contenedor se volvería el
     bloque de contención de la pastilla (position:fixed) y la ataría al contenedor, no a la ventana. */
  @media (max-width:820px) { #lz-sf-curso.lz-sf { right:0; left:0; display:flex; justify-content:center; pointer-events:none; bottom:calc(var(--lz-bar, 60px) + 10px + env(safe-area-inset-bottom)); }
    #lz-sf-curso .lz-sfd--cab { pointer-events:auto; } }
  /* La hoja abierta nunca sube sobre la barra superior (PCB9B-06): su techo es lo que queda entre la barra de arriba y la de abajo. */
  @media (max-width:820px) { #lz-sf-curso .lz-sfd--cab { max-height:calc(100vh - var(--lz-bar, 60px) - max(var(--lz-top, 48px), env(safe-area-inset-top)) - 24px - env(safe-area-inset-bottom)); max-height:calc(100dvh - var(--lz-bar, 60px) - max(var(--lz-top, 48px), env(safe-area-inset-top)) - 24px - env(safe-area-inset-bottom)); overflow-y:auto; } }
  /* Entrante: pide la atención entera (centrada, con velo) hasta que se contesta o se rechaza. */
  #lz-sf-curso.lz-sf--ent { inset:0; display:flex; pointer-events:auto; align-items:center; justify-content:center; background:var(--sfd-velo, color-mix(in oklch, var(--text) 45%, transparent));
    backdrop-filter:blur(2px); z-index:var(--z-softphone-curso); }
  [data-ds-theme="dark"] #lz-sf-curso.lz-sf--ent { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  #lz-sf-curso.lz-sf--min { pointer-events:none; }
  #lz-sf-curso.lz-sf--min .lz-sfd-pill { pointer-events:auto; }

  /* --- la pastilla (llamada minimizada): se arrastra y recuerda dónde la dejaste --- */
  .lz-sfd-pill { position:fixed; left:24px; top:200px; z-index:var(--z-sf); display:inline-flex; align-items:center; gap:10px; height:44px; padding:0 10px 0 6px; border-radius:999px;
    background:var(--surface); border:1px solid var(--line-2); box-shadow:var(--shadow-md); cursor:grab; user-select:none; -webkit-user-select:none; touch-action:none; color:var(--text); font-family:var(--font); }
  .lz-sfd-pill.arrastrando { cursor:grabbing; box-shadow:0 18px 40px rgba(0,0,0,.35); }
  .lz-sfd-pill__asa { width:24px; height:24px; display:grid; grid-template-columns:1fr 1fr; gap:3px; place-items:center; color:var(--text-muted); flex:none; border-radius:6px; }
  .lz-sfd-pill__asa i { width:3px; height:3px; border-radius:50%; background:currentColor; }
  .lz-sfd-pill__asa:focus-visible { outline:none; box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--focus); }
  .lz-sfd-pill__dot { width:10px; height:10px; border-radius:50%; background:var(--ok); animation:lz-sfd-lat 1.2s infinite; flex:none; }
  .lz-sfd-pill__dot.hold { background:var(--warn); animation:none; }
  .lz-sfd-pill__dot.off { background:var(--text-muted); animation:none; }
  .lz-sfd-pill b { font-weight:600; font-size:13px; max-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-sfd-pill__t { font-family:var(--mono); font-size:12.5px; color:var(--text-2); font-variant-numeric:tabular-nums; }
  .lz-sfd-pill button { width:32px; height:32px; border-radius:50%; border:1px solid var(--border-control); background:var(--surface-2); color:var(--text); display:grid; place-items:center; cursor:pointer; padding:0; flex:none; }
  .lz-sfd-pill button.col { background:var(--bad); color:var(--ink-on-accent); border-color:var(--bad); }
  .lz-sfd-pill button[aria-pressed="true"] { background:var(--text); color:var(--bg); border-color:var(--text); }

  /* --- el módulo de la barra superior (cuando el cascarón trae #lz-top-llamada) --- */
  .lz-sfd-top { display:inline-flex; align-items:center; gap:8px; height:38px; padding:0 4px 0 12px; border-radius:999px; background:var(--surface); border:1px solid var(--line-2); color:var(--text);
    font-family:var(--font); font-size:13px; max-width:100%; box-sizing:border-box; }
  .lz-sfd-top__dot { width:9px; height:9px; border-radius:50%; background:var(--ok); animation:lz-sfd-lat 1.2s infinite; flex:none; }
  .lz-sfd-top__dot.hold { background:var(--warn); animation:none; }
  .lz-sfd-top__dot.off { background:var(--text-muted); animation:none; }
  .lz-sfd-top__n { font-weight:600; max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; background:none; border:0; color:inherit; padding:0; cursor:pointer; font-size:13px; font-family:inherit; }
  .lz-sfd-top__t { font-family:var(--mono); font-size:12.5px; color:var(--text-2); font-variant-numeric:tabular-nums; }
  .lz-sfd-top button { height:30px; min-width:30px; border-radius:999px; border:0; background:transparent; color:var(--text-2); display:inline-flex; align-items:center; justify-content:center; gap:0; cursor:pointer; padding:0; flex:none; }
  @media (hover:hover) { .lz-sfd-top button:hover { background:var(--surface-2); color:var(--text); } }
  .lz-sfd-top button[aria-pressed="true"] { background:var(--sfd-on, var(--surface-3)); color:var(--text); }
  .lz-sfd-top button.col { background:var(--bad); color:var(--ink-on-accent); transition:padding var(--dur-2) var(--ease-out); }
  .lz-sfd-top button.col span { max-width:0; overflow:hidden; white-space:nowrap; font-size:12px; font-weight:600; opacity:0; transition:max-width var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out), margin var(--dur-2) var(--ease-out); }
  .lz-sfd-top button.col:focus-visible { padding-left:10px; }
  .lz-sfd-top button.col:focus-visible span { max-width:60px; opacity:1; margin:0 12px 0 6px; }
  @media (hover:hover) { .lz-sfd-top button.col:hover { padding-left:10px; } .lz-sfd-top button.col:hover span { max-width:60px; opacity:1; margin:0 12px 0 6px; } }
  .lz-sfd-top button:focus-visible { outline:none; box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--focus); }
  @media (max-width:820px) {
    .lz-sfd-top { position:fixed; top:var(--lz-top, 48px); left:0; right:0; height:44px; border-radius:0; border-width:0 0 1px; justify-content:flex-start; padding:0 8px 0 14px; z-index:var(--z-sf); }
    .lz-sfd-top__n { flex:1 1 auto; min-width:0; text-align:left; max-width:none; }
    .lz-sfd-top button { height:44px; min-width:44px; }
    .lz-sfd-top button.col span { display:none !important; }
  }
  .lz-sfd-top[hidden] { display:none; }
  /* La franja (position:fixed, 44 px) no empujaba nada: en el hilo del Inbox tapaba Volver, Llamar, Agendar y la ficha (medido el 14-oct-2026 a 390).
     telefonia.js pone la clase en <html> solo mientras la franja se ve (≤ 820 px y panel minimizado): la barra conserva sus 48 px, la franja se pega
     debajo, el contenido baja 44 y --lz-top (de lo que dependen las alturas y los sticky de todas las pantallas) pasa a 92. Con el panel abierto la franja
     se esconde: el panel ya trae esos mismos controles y ella le tapaba «Minimizar». La pastilla arrastrable sobra con la franja y tapaba el compositor. */
  @media (max-width:820px) {
    html.lz-llamada-franja { --lz-top:92px; }
    html.lz-llamada-franja .lz-top { height:calc(48px + env(safe-area-inset-top)); margin-bottom:44px; }
    html.lz-llamada-franja .lz-sfd-top { top:calc(48px + env(safe-area-inset-top)); }
    html.lz-llamada-franja .lz-sfd-pill { display:none; }
  }
  /* --- Escala de glifo por botón (Alex, 15-oct, notas 12 y 15: «los iconos se ven muy pequeños para el tamaño del botón»).
     El glifo lo decide el lado del botón, no quien lo pinta: 30-32 px lleva 16, 36-40 lleva 18, 44-48 lleva 22 y 56-64
     lleva 26. Con rótulo al lado baja un paso, porque ahí manda el texto: Llamar, Contestar o Rechazar (62) llevan 22,
     Agendar, Mover o «Añadir nota» (36-40) llevan 16. Se fija aquí por CSS para el panel, la cabina, la pastilla y el
     módulo de la barra; el width/height del SVG queda como respaldo. Documentado en DESIGN.md (Iconos). */
  .lz-sfd, .lz-sfd-pill, .lz-sfd-top { --sfd-g1:16px; --sfd-g2:18px; --sfd-g3:22px; --sfd-g4:26px; }
  .lz-sfd-pill button .lz-sfd__ic, .lz-sfd-top button .lz-sfd__ic, .lz-sfd__pilln .lz-sfd__ic, .lz-sfd__acts button .lz-sfd__ic { width:var(--sfd-g1); height:var(--sfd-g1); }
  .lz-sfd__ico .lz-sfd__ic, .lz-sfd__go .lz-sfd__ic, .lz-sfd__nuevo .lz-sfd__ic { width:var(--sfd-g2); height:var(--sfd-g2); }
  .lz-sfd__bar button .lz-sfd__ic { width:var(--sfd-g4); height:var(--sfd-g4); }
  .lz-sfd__bar--reposo .ok .lz-sfd__ic, .lz-sfd__bar--ent button .lz-sfd__ic, .lz-sfd__bar--fin .ok .lz-sfd__ic { width:var(--sfd-g3); height:var(--sfd-g3); }
  @media (max-width:820px) { .lz-sfd-top button .lz-sfd__ic { width:var(--sfd-g3); height:var(--sfd-g3); } }
  @media (pointer:coarse) { .lz-sfd__ico .lz-sfd__ic, .lz-sfd__go .lz-sfd__ic, .lz-sfd__nuevo .lz-sfd__ic { width:var(--sfd-g3); height:var(--sfd-g3); } }

  /* Objetivos de 44 px al tacto en el panel (Cerrar 36, pestañas 30, filtros 28). */
  @media (pointer:coarse) {
    .lz-sfd__ico { width:44px; height:44px; }
    .lz-sfd__tab { height:44px; }
    .lz-sfd__f { height:44px; }
    .lz-sfd__go, .lz-sfd__nuevo { width:44px; height:44px; }
    .lz-sfd__mas summary { min-height:44px; }
  }

  /* El aviso de «no arrancó» sigue siendo el panel de siempre. */

  .lz-avc-back { position:fixed; inset:0; z-index:calc(var(--z-toast) + 1); display:flex; align-items:center; justify-content:center;
    padding:20px; background:color-mix(in oklch, var(--text) 45%, transparent); }
  /* en oscuro el velo es el fondo oscurecido: una tinta clara al 45 % aclararia la pagina */
  [data-ds-theme="dark"] .lz-avc-back { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-avc { width:min(380px, calc(100vw - 32px)); box-sizing:border-box; background:var(--surface); color:var(--text);
    border:1px solid var(--hairline); border-radius:var(--r-card); box-shadow:var(--shadow-md);
    padding:26px 24px; text-align:center; max-height:calc(100dvh - 32px); overflow:auto; }
  .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(--accent-soft); color:var(--accent-text); 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; } }
  /* Reduced motion: el pulso es un anillo fijo (el fotograma final del pulso es transparente). */
  @media (prefers-reduced-motion: reduce) { .lz-avc__av::after { animation:none; opacity:.5; transform:none; } }
  .lz-avc__tit { font-size:var(--fs-5); font-weight:600; letter-spacing:-.02em; 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; }
  /* Avisos dentro de la tarjeta: solo el borde --warn y radio de control, sin relleno (Alex, 15-oct: la píldora amarilla
     «tiene demasiado redondeado, no luce; con un borde es más que suficiente»). El texto queda en --warn-text. */
  .lz-avc__mudo, .lz-avc__sinliga { font-size:12px; line-height:1.5; margin-top:12px; padding:9px 12px;
    border:1px solid var(--warn); border-radius:var(--r-control); background:transparent; color:var(--warn-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-control); min-height:44px; }
  .lz-avc__bt--pri { background:var(--accent); color:var(--ink-on-accent); border-color:var(--accent); }
  @media (hover:hover) { .lz-avc__bt--pri:hover { background:var(--accent-hover); border-color:var(--accent-hover); } }
  .lz-avc__bt--sec { background:var(--surface); color:var(--text); font-weight:500; }
  @media (hover:hover) { .lz-avc__bt--sec:hover { background:var(--surface-2); } }
  .lz-avc__bt:focus-visible { outline:none; box-shadow:var(--ring); }

  /* 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:calc(16px + env(safe-area-inset-bottom)); z-index:var(--z-toast); max-width:320px;
    box-shadow:var(--shadow-md); 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:10px 12px; margin:-10px -10px 0 0; min-width:44px; min-height:44px; }
  @media (hover:hover) { .lz-avc-previo__cerrar:hover { color:var(--text); } }

  /* [hidden] pierde contra cualquier regla con display: se reafirma para todo lo de este módulo. */
  .lz-fecha [hidden], .lz-agendar [hidden], .lz-cal__panel [hidden], .lz-agendar__tabs[hidden] { display:none !important; }
  html.lz-hoja-abierta { overflow:hidden; }
  /* El panel de la llamada en curso queda por ENCIMA de la hoja (y no inerte, ver inertar() en
     calendario.js): con el lead en la línea hay que poder colgar con el ratón. En móvil la hoja es inferior
     y el panel tiene su propio lugar sobre la barra, así que solo aplica con espacio de sobra. */
  @media (min-width:821px) { html.lz-hoja-abierta #lz-sf-curso.lz-sf { z-index:var(--z-softphone-curso); } }

  /* ---- Campo de fecha (botón + popover) ---- */
  .lz-fecha__lbl { display:block; margin:0 0 4px; font-size:var(--fs-2); font-weight:500; color:var(--text-2); }
  .lz-fecha { position:relative; display:block; max-width:100%; }
  .lz-fecha--linea { position:static; }
  .lz-fecha__btn { width:100%; min-height:38px; display:inline-flex; align-items:center; gap:8px; padding:0 12px; border:1px solid var(--field-line); border-radius:var(--r-input); background:var(--field); color:var(--text); font:inherit; font-size:var(--fs-3); text-align:left; cursor:pointer; font-variant-numeric:tabular-nums; }
  .lz-fecha__g { display:inline-flex; color:var(--text-2); }
  .lz-fecha__btn .lz-glifo { width:16px; height:16px; }
  .lz-fecha__t--vacio { color:var(--text-muted); }
  @media (hover:hover) { .lz-fecha__btn:hover { background:var(--surface-2); } }
  /* El foco de un campo con borde es SU borde: un anillo exterior encima leería como dos contornos. */
  .lz-fecha__btn[aria-expanded="true"], .lz-fecha__btn:focus-visible { border-color:var(--focus); }
  .lz-fecha__btn:focus-visible { outline:none; box-shadow:none; animation:lzBreathBorder 1.8s ease-in-out infinite alternate; }
  .lz-fecha__err { margin:6px 0 0; font-size:var(--fs-2); color:var(--bad-text); }
  .lz-fecha__velo { display:none; }
  /* La nota del día reserva su alto para que la columna no salte al llegar los horarios (ACB-189). */
  .lz-cal__nota { min-height:2.6em; }
  .lz-fecha__pop { position:absolute; left:0; top:calc(100% + 6px); z-index:var(--z-dropdown); width:min(332px, 94vw); padding:12px; background:var(--surface); color:var(--text); border:1px solid var(--hairline); border-radius:var(--r-card); box-shadow:var(--shadow-md); }
  .lz-fecha__pop--arriba { top:auto; bottom:calc(100% + 6px); }
  .lz-fecha__pop--der { left:auto; right:0; }
  /* Sin lugar arriba ni abajo (dentro de un modal): hoja centrada en la ventana. El calendario.js fija
     el left/top en px y el max-height al alto de la ventana; aquí solo lo que no es geometría. */
  .lz-fecha__pop--centro { border-color:var(--border-control); }
  /* Muestra estática del popover abierto (Design System): en flujo, sin flotar. */
  .lz-fecha--abierto .lz-fecha__pop { position:static; margin-top:6px; }

  /* ---- Rejilla del mes ---- */
  .lz-cal__panel { display:grid; gap:12px; min-width:0; }
  .lz-cal__wrap { position:relative; }
  /* Los divisores (hairline bajo la cabecera y entre semanas) son el border-bottom de la tabla global del panel.
     Con border-spacing la línea salía en tramos con huecos de 2 px y el botón quedaba pegado a la de abajo y a 2 px
     de la de arriba (nota de Alex del 15-oct). Sin spacing la línea es una, y el aire lo pone el padding de la celda:
     --cal-aire arriba y abajo de cada línea, y 2 px entre botones vecinos (1 px por lado). */
  .lz-cal { --cal-aire:3px; width:100%; margin:0; border-collapse:separate; border-spacing:0; table-layout:fixed; }
  .lz-cal caption { caption-side:top; padding:0; height:32px; line-height:32px; font-size:var(--fs-3); font-weight:600; color:var(--text); text-align:center; }
  /* La cabecera mide su renglón (21 px) más el mismo aire bajo el texto que hay bajo la línea hacia la primera semana. */
  .lz-cal th { height:auto; padding:0 0 var(--cal-aire); line-height:21px; font-size:var(--fs-1); font-weight:500; color:var(--text-muted); text-align:center; vertical-align:middle; }
  .lz-cal td { padding:var(--cal-aire) 1px; vertical-align:middle; }
  .lz-cal__nav { position:absolute; top:0; width:32px; height:32px; padding:0; display:inline-flex; align-items:center; justify-content:center; border:1px solid transparent; border-radius:var(--r-control); background:transparent; color:var(--text-2); cursor:pointer; }
  .lz-cal__nav .lz-glifo { width:16px; height:16px; }
  .lz-cal__nav--ant { left:0; }
  .lz-cal__nav--ant .lz-glifo { transform:rotate(180deg); }
  .lz-cal__nav--sig { right:0; }
  @media (hover:hover) { .lz-cal__nav:hover { background:var(--surface-2); color:var(--text); } }
  .lz-cal__dia { display:flex; align-items:center; justify-content:center; width:100%; height:38px; padding:0; border:1px solid transparent; border-radius:var(--r-control); background:transparent; color:var(--text); font:inherit; font-size:var(--fs-3); line-height:1; font-variant-numeric:tabular-nums; cursor:pointer; }
  /* El número va al centro geométrico del botón en todos los días: lo que se le pinta encima (la cuenta, el borde de hoy)
     es absoluto o es borde, nunca padding, así que no lo mueve (tolerancia 1 px, DESIGN.md «Calendario»). 38 px y no
     36: con el número al centro, la cuenta de abajo necesita esos 2 px para no pegarse a él. */
  .lz-cal__n { display:block; line-height:1; }
  .lz-cal__dia { position:relative; }
  /* Un punto en el día dice que ahí hay horarios libres (UCB8-07). Solo aparece en los días ya consultados: un día
     sin punto puede ser uno que nadie ha mirado, y por eso el punto es la única señal y no hay otra para «lleno». */
  .lz-cal__dia[data-libres]:not([data-libres="0"]):not([data-n])::after { content:""; position:absolute; left:50%; bottom:4px; width:4px; height:4px; margin-left:-2px; border-radius:50%; background:var(--accent); }
  .lz-cal__dia[aria-selected="true"]::after { background:currentColor; }
  /* UCB9-08: en lugar del punto, la cuenta en texto chico (libres, o sin verificar con «?»). El aria-label dice lo mismo en frase. */
  /* El punto de arriba cedía ante la cuenta solo en los días sin libres: con libres ganaba el punto por especificidad y el
     número subía 4,5 px por un padding que era para la cuenta. Ahora la cuenta siempre es texto y el punto solo queda
     para un día con libres sin cuenta. La cuenta cuelga del borde de abajo, fuera del flujo: el número no se mueve. */
  .lz-cal__dia[data-n]::after { content:attr(data-n); position:absolute; left:0; right:0; bottom:1px; width:auto; height:auto; margin:0; border-radius:0; background:none; font-size:10px; line-height:1; color:var(--text-muted); text-align:center; }
  .lz-cal__dia[data-n][aria-selected="true"]::after { background:none; color:inherit; }
  .lz-cal__dia.fuera { color:var(--text-muted); }
  .lz-cal__dia.is-hoy { border-color:var(--border-control); font-weight:600; }
  @media (hover:hover) { .lz-cal__dia[aria-selected="false"]:not([aria-disabled="true"]):hover { background:var(--surface-2); } }
  .lz-cal__dia[aria-selected="true"] { background:var(--accent); border-color:var(--accent); color:var(--ink-on-accent); font-weight:600; }
  .lz-cal__dia[aria-disabled="true"] { color:var(--text-muted); opacity:.55; cursor:not-allowed; }

  /* ---- Horarios ---- */
  .lz-cal__horas { min-width:0; }
  .lz-cal__dlbl { margin:0 0 8px; font-size:var(--fs-2); font-weight:600; color:var(--text); }
  .lz-slots { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:6px; }
  .lz-slot { position:relative; margin:0; display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:34px; padding:4px 6px; border:1px solid var(--border-control); border-radius:var(--r-control); background:var(--surface); color:var(--text); text-align:center; line-height:1.2; cursor:pointer; }
  /* El radio cubre toda la etiqueta y no se ve: el clic y el teclado son nativos. */
  .lz-slot input { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:inherit; }
  .lz-slot input:focus-visible { box-shadow:none; animation:none; }
  .lz-slot:has(input:focus-visible), .lz-slot:has(input:focus) { box-shadow:var(--ring); }
  .lz-slot__h { font-family:var(--mono); font-size:var(--fs-2); font-variant-numeric:tabular-nums; }
  .lz-slot__m { font-size:var(--fs-1); color:var(--text-2); }
  @media (hover:hover) { .lz-slot:not(:has(input:disabled)):not(:has(input:checked)):hover { background:var(--surface-2); } }
  .lz-slot:has(input:checked) { background:var(--accent); border-color:var(--accent); color:var(--ink-on-accent); font-weight:600; }
  .lz-slot:has(input:checked) .lz-slot__m { color:inherit; }
  /* Campana (Lucide bell) en la hora elegida de una cita: lleva recordatorio al asesor (htmlRanuras, «aviso»). Va en la
     esquina y fuera del flujo para no mover la hora ni cambiar el alto del horario; solo se ve en el elegido. */
  .lz-slot__h { position:relative; }
  .lz-slot__rec { position:absolute; left:calc(100% + 3px); top:50%; display:none; width:13px; height:13px; margin-top:-6.5px; color:inherit; pointer-events:none; }
  .lz-slot__rec .lz-glifo { display:block; width:13px; height:13px; }
  .lz-slot:has(input:checked) .lz-slot__rec { display:block; }
  /* En un ocupado la hora va a la izquierda y el motivo sigue en el renglón: ahí la campana entra en flujo. */
  .lz-slot--ocupado .lz-slot__h { display:inline-flex; align-items:center; gap:3px; }
  .lz-slot--ocupado .lz-slot__rec { position:static; margin-top:0; }
  .lz-slot:has(input:disabled) { opacity:.45; cursor:not-allowed; }
  /* Ocupado: ocupa la fila entera porque el motivo se ESCRIBE al lado, no vive en un tooltip. */
  .lz-slot--ocupado { grid-column:1 / -1; flex-direction:row; justify-content:flex-start; gap:6px; padding:4px 10px; border-style:dashed; background:var(--surface-2); color:var(--text-2); text-align:left; }
  .lz-slot--ocupado .lz-slot__m { font-size:var(--fs-2); }
  .lz-slot--ocupado .lz-slot__m::before { content:"· "; }
  .lz-slot--ocupado:has(input:checked) { border-style:solid; background:var(--warn-soft); border-color:var(--warn); color:var(--warn-text); }
  /* Sin verificar: borde punteado en ámbar. Nunca se pinta como libre (invariante 5). */
  .lz-slot--duda { border-style:dotted; border-color:var(--warn); }
  .lz-slot--duda .lz-slot__m { color:var(--warn-text); }
  .lz-slot--duda:has(input:checked) { background:var(--warn-soft); border-style:solid; color:var(--warn-text); }
  .lz-slot--sk { min-height:34px; border-color:transparent; background:var(--surface-3); pointer-events:none; animation:lzSk 1.1s ease-in-out infinite alternate; }
  @keyframes lzSk { to { opacity:.45; } }
  .lz-slot__forzar { display:flex; align-items:flex-start; gap:8px; margin:10px 0 0; padding:10px 12px; border:1px solid var(--warn); border-radius:var(--r-control); background:var(--warn-soft); color:var(--warn-text); font-size:var(--fs-2); line-height:1.4; cursor:pointer; }
  .lz-slot__forzar input { flex:none; width:16px; height:16px; margin:1px 0 0; accent-color:var(--accent); }
  .lz-cal__nota { min-height:1.45em; margin:10px 0 0; font-size:var(--fs-2); line-height:1.45; color:var(--text-2); }
  .lz-cal__nota button { margin-left:2px; padding:0; border:0; background:none; font:inherit; color:var(--accent-text); cursor:pointer; }
  @media (hover:hover) { .lz-cal__nota button:hover { color:var(--link-hover); } }
  .lz-cal__ayuda { margin-top:10px; padding:10px 12px; border-radius:var(--r-control); background:var(--surface-2); }
  .lz-cal__ayuda a { display:inline-flex; align-items:center; gap:4px; }
  .lz-cal__ayuda .lz-glifo { width:13px; height:13px; }
  /* Pegados al borde del selector: si la rejilla y los horarios no caben, «Usar esta fecha» no se va. */
  .lz-fecha__pop { max-height:calc(100dvh - 24px); overflow:auto; }
  .lz-cal__acc { position:sticky; bottom:-12px; display:grid; gap:8px; margin:12px -12px -12px; padding:12px; background:var(--surface); border-top:1px solid var(--border); }
  .lz-fecha--abierto .lz-fecha__pop { max-height:none; overflow:visible; }
  /* En las muestras (sin contenedor con scroll) un sticky se pegaría al borde de la ventana. */
  .lz-fecha--abierto .lz-cal__acc, .lz-agendar--muestra .lz-agendar__pie { position:static; }
  .lz-cal__motivo { margin:0; font-size:var(--fs-2); color:var(--text-muted); }
  .lz-cal__motivo:empty { display:none; }
  .lz-cal__botones { display:flex; justify-content:flex-end; gap:8px; }
  .lz-cal__muestra { display:grid; gap:10px; margin:0 0 28px; max-width:680px; }
  .lz-cal__muestra-t { margin:0; font-size:var(--fs-2); font-weight:600; color:var(--text-2); }

  /* ---- Hoja de agendar ---- */
  .lz-agendar .lz-modal__box { width:min(760px, 94vw); max-height:calc(100dvh - 40px); overflow:auto; padding:20px 24px; }
  .lz-agendar__cab { display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
  .lz-agendar__t { margin:0 !important; font-size:16px; font-weight:600; }
  .lz-tabs.lz-agendar__tabs { position:static; margin:12px 0 14px; padding:0; overflow:visible; background:transparent; -webkit-mask-image:none; mask-image:none; }
  .lz-agendar__tabs button { display:inline-flex; align-items:center; min-height:36px; padding:0 12px; margin-bottom:-1px; border:0; border-bottom:2px solid transparent; background:transparent; font:inherit; font-size:var(--fs-3); font-weight:500; color:var(--text-2); cursor:pointer; white-space:nowrap; }
  @media (hover:hover) { .lz-agendar__tabs button:hover { color:var(--text); } }
  .lz-agendar__tabs button[aria-selected="true"] { color:var(--text); border-bottom-color:var(--text); font-weight:600; }
  .lz-agendar__fila { display:grid; grid-template-columns:minmax(0, 1fr) 120px; gap:10px; margin-bottom:14px; }
  .lz-agendar__c { display:grid; gap:4px; margin:0; font-size:var(--fs-2); font-weight:500; color:var(--text-2); }
  .lz-agendar__c .zinput { font-weight:400; color:var(--text); }
  .lz-agendar__aviso { margin:0 0 14px; font-size:var(--fs-2); color:var(--warn-text); }
  .lz-agendar__res { list-style:none; margin:0; padding:0; display:grid; font-size:var(--fs-2); line-height:1.45; color:var(--text-2); }
  .lz-agendar__res li { display:grid; grid-template-columns:84px minmax(0, 1fr); gap:0 8px; padding:6px 0; border-top:1px solid var(--border); }
  .lz-agendar__res li:first-child { padding-top:0; border-top:0; }
  .lz-agendar__res strong { font-weight:600; color:var(--text); }
  .lz-agendar__res li > span > span { display:block; }
  /* «Cambiar» en el renglón «Con» (UCB8-07): un enlace de texto en acento, sin subrayado, y el select que lo reemplaza. */
  .lz-agendar__cambiar { display:inline-flex; align-items:center; gap:4px; min-height:24px; padding:0; border:0; background:none; font:inherit; font-weight:500; color:var(--accent-text); cursor:pointer; }
  @media (hover:hover) { .lz-agendar__cambiar:hover { color:var(--link-hover); } }
  .lz-agendar__cambiar .lz-glifo { width:13px; height:13px; }
  .lz-agendar__cambiar:focus-visible { outline:none; box-shadow:var(--ring); border-radius:var(--r-chip); }
  .lz-agendar__sel { display:block; max-width:100%; margin-top:4px; }
  @media (pointer:coarse) { .lz-agendar__cambiar { min-height:44px; } .lz-agendar__tabs button { min-height:44px; } }
  .lz-agendar__motivo { min-height:1.45em; margin:8px 0 0; font-size:var(--fs-2); color:var(--text-muted); }
  .lz-agendar__acc { display:flex; gap:8px; justify-content:flex-end; margin-top:10px; }
  /* El pie fijo lleva el resumen («Cuándo» y «Qué pasa»), el motivo y los botones: la consecuencia se lee
     junto al botón que la dispara, a cualquier alto de pantalla (UCB5-05). Antes el resumen quedaba
     bajo el pie o fuera de la vista y «Qué pasa» es justo lo que avisa que no se le va a avisar al lead.
     Pegado al borde de la hoja aunque el contenido la haga desplazarse: un «Agendar» fuera de la vista
     es una hoja que parece no tener salida. */
  .lz-agendar__pie { position:sticky; bottom:-20px; margin:14px -24px -20px; padding:12px 24px 20px; background:var(--surface); border-top:1px solid var(--hairline); }
  /* La ayuda de Google es una línea plegada: el detalle está a un clic y no gasta 130 px antes de elegir hora. */
  .lz-cal__ayuda > details > summary { min-height:24px; display:flex; align-items:center; cursor:pointer; font-size:var(--fs-2); font-weight:500; color:var(--text-2); }
  .lz-cal__ayuda > details[open] > summary { margin-bottom:8px; }
  .lz-cal__ayuda > details > summary:focus-visible { outline:none; box-shadow:var(--ring); border-radius:var(--r-chip); }
  /* En escritorio el selector y la hoja ponen la rejilla a la izquierda y los horarios a la derecha:
     apilados medían casi toda la pantalla y «Usar esta fecha» quedaba fuera de la vista. */
  @media (min-width:821px) {
    .lz-fecha__pop { width:min(660px, 94vw); }
    .lz-fecha--abierto .lz-fecha__pop { width:auto; }
    .lz-fecha__pop .lz-cal__panel, .lz-agendar .lz-cal__panel { grid-template-columns:288px minmax(0, 1fr); gap:20px; align-items:start; }
    .lz-agendar .lz-slots { grid-template-columns:repeat(4, minmax(0, 1fr)); }
  }
  /* Muestra del Design System: la hoja pintada en flujo, sin velo ni posición fija. */
  .lz-modal.lz-agendar.lz-agendar--muestra { position:static; inset:auto; display:block; padding:0; background:none; z-index:auto; }
  .lz-agendar--muestra .lz-modal__box { max-height:none; margin:0; }

  /* ---- Móvil y táctil: hoja inferior, dedos de 44 px, campos a 16 px para que Safari no haga zoom ---- */
  @media (max-width:820px), (pointer:coarse) {
    .lz-fecha__btn, .lz-agendar .zinput { min-height:44px; font-size:16px; }
    .lz-fecha__pop, .lz-fecha__pop--arriba { position:fixed; inset:auto 0 0 0; width:auto; max-height:88dvh; overflow:auto; padding:12px 16px 0; border-width:1px 0 0; border-radius:var(--r-card) var(--r-card) 0 0; z-index:var(--z-modal); }
    .lz-fecha--abierto .lz-fecha__pop { position:static; border-width:1px; border-radius:var(--r-card); padding-bottom:12px; }
    .lz-fecha__pop .lz-cal__acc { bottom:0; margin:12px -16px 0; padding:12px 16px calc(12px + env(safe-area-inset-bottom)); }
    .lz-fecha--abierto .lz-fecha__pop .lz-cal__acc { margin-bottom:-12px; padding-bottom:12px; }
    .lz-agendar--muestra .lz-agendar__pie { position:static; }
    .lz-fecha__velo:not([hidden]) { display:block; position:fixed; inset:0; z-index:calc(var(--z-modal) - 1); background:color-mix(in oklch, var(--text) 45%, transparent); }
    /* El botón flotante del panel tapaba «Guardar nueva fecha» a 390 px: mientras la hoja está abierta no tiene sentido. */
    html.lz-hoja-abierta .lz-fab { display:none; }
    .lz-slots { grid-template-columns:repeat(3, minmax(0, 1fr)); }
    .lz-slot, .lz-slot--sk { min-height:44px; }
    .lz-cal__dia { height:44px; }
    .lz-cal caption { height:44px; line-height:44px; }
    .lz-cal__nav { width:44px; height:44px; }
    .lz-slot__forzar { min-height:44px; }
    .lz-agendar:not(.lz-agendar--muestra) { align-items:flex-end; padding:0; }
    .lz-agendar:not(.lz-agendar--muestra) .lz-modal__box { width:100%; max-height:92dvh; padding:16px 16px 0; border-width:1px 0 0; border-radius:var(--r-card) var(--r-card) 0 0; }
    /* En 390 solo los botones quedan pegados abajo: el pie entero medía 282 px y tapaba la quinta semana y las horas (F2-12). */
    .lz-agendar__pie { position:static; margin:12px -16px 0; padding:10px 16px 0; }
    .lz-agendar__acc { position:sticky; bottom:0; margin:10px -16px 0; padding:10px 16px calc(12px + env(safe-area-inset-bottom)); background:var(--surface); border-top:1px solid var(--hairline); }
    .lz-agendar__acc .zbtn { flex:1; justify-content:center; }
    .lz-agendar__acc .zbtn--pri { flex:2; }
    .lz-agendar__res li { grid-template-columns:76px minmax(0, 1fr); }
  }
  /* ---- Selector de fecha: un input[type=date] cualquiera (filtros de los reportes), DESIGN.md «Selector de fecha» ----
     El botón lleva las clases y el estilo del input que reemplaza (.zinput, width:auto): alto, borde, fondo y
     padding los decide el campo de esa fila y el alto de control del cascarón, no este módulo. Aquí solo lo que
     hace de un campo un botón con glifo y texto, y el ancho mínimo para que «1 oct» y «12 sep» no lo hagan saltar. */
  .lz-fecha__btn.lz-fecha__btn--dia { min-height:0; min-width:10.5em; padding-top:0; padding-bottom:0; display:flex; align-items:center; gap:8px; text-align:left; white-space:nowrap; cursor:pointer; }
  .lz-fecha__btn--dia .lz-fecha__t { min-width:0; overflow:hidden; text-overflow:ellipsis; }
  /* Es un campo: en hover cambia el borde (lo hace .zinput), no el fondo como el botón de agendar. */
  @media (hover:hover) { .lz-fecha__btn.lz-fecha__btn--dia:hover { background:var(--field); } }
  /* El aviso de «el hasta se movió» flota bajo el campo como globo (fondo, hairline y sombra): en una fila de
     filtros alineada abajo, un renglón en flujo subiría el campo respecto de sus vecinos. Vacío no mide nada; el
     JS lo corre a la izquierda si se saldría de la ventana y lo quita a los diez segundos o al volver a elegir. */
  .lz-fecha--dia { position:relative; }
  .lz-fecha__aviso { position:absolute; left:0; top:calc(100% + 4px); z-index:var(--z-dropdown); width:max-content; max-width:min(320px, calc(100vw - 24px)); margin:0; font-size:var(--fs-2); line-height:1.4; color:var(--text); }
  .lz-fecha__aviso:not(:empty) { padding:6px 10px; background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-control); box-shadow:var(--shadow-md); }
  .lz-fecha__pop--dia .lz-cal__panel { gap:0; }
  .lz-fecha__pop--dia .lz-cal__nota { min-height:0; margin:8px 0 0; }
  .lz-fecha__pop--dia .lz-cal__nota:empty { display:none; }
  .lz-cal__acc.lz-cal__acc--dia { display:flex; justify-content:flex-end; gap:8px; }
  .lz-cal__acc--dia [data-limpiar] { margin-right:auto; }
  /* Solo la rejilla del mes: 288 px más el padding del popover. En táctil y a 820 px o menos es la hoja inferior. */
  @media (min-width:821px) and (pointer:fine) {
    .lz-fecha__pop.lz-fecha__pop--dia { width:314px; }
    .lz-fecha__pop--dia .lz-cal__panel { grid-template-columns:minmax(0, 1fr); }
  }
  .lz-fecha--abierto .lz-fecha__pop.lz-fecha__pop--dia { width:314px; max-width:100%; }
  .lz-fecha--abierto .lz-fecha__pop--dia .lz-cal__panel { grid-template-columns:minmax(0, 1fr); }
  /* Sin JavaScript queda el selector nativo: que siga al tema del panel y no al del sistema. :root ya declara
     color-scheme, pero el campo lo repite para que ningún contenedor intermedio con otro esquema lo vuelva blanco. */
  input[type="date"], input[type="datetime-local"] { color-scheme:light; }
  [data-ds-theme="dark"] input[type="date"], [data-ds-theme="dark"] input[type="datetime-local"] { color-scheme:dark; }
  [data-ds-theme="dark"] .lz-fecha__velo:not([hidden]) { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  @media (prefers-reduced-motion:reduce) {
    .lz-slot--sk { animation:none; }
    .lz-fecha__btn:focus-visible { animation:none; }
  }

  /* ───────── Moléculas del asesor (Ola 2, 14-oct-2026) ─────────
     Solo tokens del tema. Los colores de banda y de etapa llegan como --st desde el servidor. */

  /* Globo: lo comparten el menú de etapa y la ayuda de la calificación. Es el mismo patrón que ya usa
     la bandeja (details que abre un panel anclado), con las mismas medidas; aquí queda en la hoja
     compartida para que cualquier pantalla lo tenga sin traer el CSS de la bandeja. */
  .lz-pop { display:inline-block; position:relative; vertical-align:middle; }
  .lz-pop > summary { list-style:none; cursor:pointer; }
  .lz-pop > summary::-webkit-details-marker { display:none; }
  .lz-pop__p { position:absolute; right:0; top:calc(100% + 6px); z-index:var(--z-dropdown); min-width:280px; padding:12px 14px;
    background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-card); box-shadow:var(--shadow-md);
    display:grid; gap:8px; text-align:left; white-space:normal; }

  /* ───────── Tira de calificación ───────── */
  .lz-califica { display:flex; align-items:center; flex-wrap:wrap; gap:6px 12px; min-width:0; }
  /* En 390 px el globo de ayuda salía hasta 607 px y estiraba la página (Ola 4): va al ancho de la tira. */
  @media (max-width:820px) { .lz-califica { position:relative; } .lz-califica__ayuda { position:static; } .lz-califica__ayuda .lz-pop__p { left:0; right:0; width:auto; min-width:0; box-sizing:border-box; max-width:100%; } }
  .lz-califica__b { height:24px; padding:0 10px; font-weight:600; color:var(--text); }
  .lz-califica__b--ok { --st:var(--ok); }
  .lz-califica__b--acc { --st:var(--accent); }
  .lz-califica__b--warn { --st:var(--warn); }
  .lz-califica__b--bad { --st:var(--bad); }
  .lz-califica__b--nd { color:var(--text-muted); font-weight:500; --st:var(--text-muted); }
  .lz-califica__n { font-size:var(--fs-4); font-weight:600; letter-spacing:-.01em; color:var(--text); font-variant-numeric:tabular-nums; }
  .lz-califica__o { font-size:var(--fs-2); color:var(--text-muted); }
  .lz-califica__perfil { display:inline-flex; }
  .lz-califica__perfil .lz-perfil-toggle-f { margin:0; }
  .lz-califica__q { display:inline-flex; align-items:center; flex-wrap:wrap; gap:6px; margin:0; font-size:var(--fs-2); color:var(--text-2); }
  .lz-califica__q a { display:inline-flex; align-items:center; gap:4px; color:var(--accent-text); text-decoration:none; font:inherit; font-weight:500; background:transparent; border:0; padding:4px 2px; min-height:24px; cursor:pointer; }
  @media (hover:hover) { .lz-califica__q a:hover { color:var(--link-hover); text-decoration:none; } }
  .lz-califica__q a:focus-visible { outline:none; box-shadow:var(--ring); border-radius:var(--r-chip); }
  .lz-califica__q .lz-glifo { width:12px; height:12px; }
  /* «Enviarle el cuestionario»: un botón de verdad (era un enlace de acento con flecha) cuya confirmación
     abre debajo, en el mismo sitio, con lo que se manda. */
  .lz-califica__mandar { gap:6px; white-space:nowrap; }
  .lz-califica__q--no { flex-wrap:wrap; }
  @media (max-width:560px) { .lz-califica__q--no > span[aria-hidden="true"] { display:none; } }
  /* En teléfono el (i) caía solo en su propia línea, 50 px debajo del botón que explica (PCB7A-28): el formulario deja sitio
     a su derecha y el (i) se queda junto a él. */
  /* El (i) mide 44 px con puntero grueso y la tira deja 12 px entre elementos: el formulario cede 56 y no 46, o el (i) cae a su
     línea (PCB8A-08, medido en la Ficha a 390). Donde no hay formulario (Enfoque: solo el texto «No contestó el cuestionario»)
     el texto toma lo que sobra de la línea y se parte en dos renglones antes de mandar el (i) abajo. */
  @media (max-width:560px) {
    .lz-califica__q--no { max-width:calc(100% - 58px); } /* 56 exactos dejaban el (i) abajo por redondeo de subpíxel (Ficha a 390, 15-oct) */
    .lz-califica__q:not(.lz-califica__q--no) { flex:1 1 8em; min-width:0; } /* base 8em: con base 0 se quedaba en 5 px al final de una línea llena y su enlace salía 11 px del borde (DS a 390, 15-oct); así baja entero */
    .lz-califica__q--no + .lz-califica__ayuda, .lz-califica__ayuda { align-self:flex-start; }
  }
  .lz-califica__mandar .lz-glifo { width:14px; height:14px; }
  .lz-califica__mandar-p { left:0; right:auto; min-width:min(360px, 86vw); }
  .lz-califica__mandar-t { margin:0; font-size:var(--fs-3); font-weight:600; color:var(--text); }
  .lz-califica__mandar-acc { display:flex; justify-content:flex-end; flex-wrap:wrap; gap:8px; padding-top:4px; }
  .lz-califica__mandar-acc .lz-glifo { width:14px; height:14px; }
  @media (max-width:820px) { .lz-califica__mandar-pop { position:static; } .lz-califica__mandar-p { left:0; right:0; width:auto; min-width:0; box-sizing:border-box; max-width:100%; } }
  .lz-califica__ayuda .lz-pop__p { left:0; right:auto; min-width:min(340px, 82vw); }
  .lz-califica--compacta { gap:6px 8px; flex-wrap:nowrap; }
  .lz-califica--compacta .lz-califica__n { font-size:var(--fs-3); }

  /* ───────── Chip de origen ───────── */
  .lz-chip--origen { color:var(--text-2); }
  .lz-chip--origen .lz-glifo { width:12px; height:12px; }

  /* ───────── Control de etapa ───────── */
  .lz-etapa { display:inline-flex; align-items:center; flex-wrap:wrap; gap:6px; }
  .lz-etapa__sig { margin:0; display:inline-flex; }
  .lz-etapa__sig .zbtn { white-space:nowrap; }
  /* 5 · a 390 px la tira de calificación parte el botón de ayuda y sus enlaces miden 26 px (Ola 4). */
  @media (pointer:coarse) { .lz-califica a, .lz-califica button, .lz-califica__mandar { min-height:44px; display:inline-flex; align-items:center; } }
  .lz-etapa__sig .lz-glifo { width:14px; height:14px; }
  .lz-etapa__sum .lz-glifo { width:14px; height:14px; transition:transform var(--dur-1) var(--ease-out); transform:rotate(90deg); }
  .lz-etapa__menu[open] > .lz-etapa__sum .lz-glifo { transform:rotate(-90deg); }
  .lz-etapa__sum { max-width:100%; }
  .lz-etapa__sum > span:not(.lz-etapa-dot) { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lz-etapa__lista { left:0; right:auto; min-width:240px; max-width:min(320px, 92vw); padding:6px; gap:2px; }
  .lz-etapa__f { margin:0; display:block; }
  .lz-etapa__op { display:flex; align-items:center; gap:8px; width:100%; min-height:36px; padding:0 10px; border:0; border-radius:var(--r-control);
    background:transparent; color:var(--text); font:inherit; font-size:var(--fs-3); text-align:left; text-decoration:none; cursor:pointer; box-sizing:border-box; }
  @media (hover:hover) { .lz-etapa__op:hover { background:var(--surface-2); text-decoration:none; } }
  .lz-etapa__op:focus-visible { outline:none; box-shadow:var(--ring-inset); background:var(--surface-2); }
  .lz-etapa__op .lz-glifo { width:14px; height:14px; flex:none; }
  .lz-etapa__op.is-actual { color:var(--text-muted); cursor:default; }
  @media (hover:hover) { .lz-etapa__op.is-actual:hover { background:transparent; } }
  .lz-etapa__act { margin-left:auto; font-size:var(--fs-1); color:var(--text-muted); }
  .lz-etapa__sep { height:1px; margin:4px 2px; background:var(--hairline); }
  .lz-etapa__op--won .lz-etapa-dot { background:var(--st-won); }
  .lz-etapa__op--lost { color:var(--bad-text); }
  @media (hover:hover) { .lz-etapa__op--lost:hover { background:var(--bad-soft); } }
  @media (pointer:coarse) { .lz-etapa__op { min-height:44px; } }

  /* ───────── Modales de perdido y ganado ───────── */
  /* Sin JS el modal se abre por :target (la ficha lo trae con id="perder"); con JS lo gobierna
     el atributo hidden y el hash se limpia al abrir. */
  .lz-perdida:target, .lz-ganado:target { display:flex; }
  .lz-perdida .lz-modal__box, .lz-ganado .lz-modal__box { width:min(440px, 94vw); max-height:calc(100dvh - 40px); overflow:auto; }
  /* 440 en escritorio como dice DESIGN.md y pantalla completa bajo 600 px (PCB9A-23, ola 9). */
  @media (max-width:599px) { .lz-perdida:not(.lz-modal--muestra), .lz-ganado:not(.lz-modal--muestra) { padding:0; } .lz-perdida:not(.lz-modal--muestra) .lz-modal__box, .lz-ganado:not(.lz-modal--muestra) .lz-modal__box { width:100vw; max-width:100vw; height:100dvh; max-height:100dvh; border-radius:0; border-width:0; box-sizing:border-box; } }
  .lz-perdida__razones { border:0; margin:0 0 16px; padding:0; min-width:0; display:grid; gap:6px; }
  .lz-perdida__razones legend { padding:0; margin:0 0 8px; font-size:var(--fs-2); font-weight:600; color:var(--text-2); }
  .lz-razon { display:flex; align-items:center; gap:10px; min-height:40px; margin:0; padding:6px 12px; border:1px solid var(--border-control);
    border-radius:var(--r-control); background:var(--surface); color:var(--text); font-size:var(--fs-3); font-weight:400; cursor:pointer; }
  @media (hover:hover) { .lz-razon:hover { border-color:var(--text-muted); } }
  .lz-razon input { margin:0; flex:none; accent-color:var(--accent); }
  .lz-razon:has(input:checked) { border-color:var(--accent); background:var(--accent-soft); }
  .lz-razon:has(input:focus-visible), .lz-razon:has(input:focus) { box-shadow:var(--ring); }
  .lz-razon input:focus-visible { outline:none; box-shadow:none; animation:none; }
  .lz-razon-otra { display:none; }
  .lz-perdida__razones:has(input[data-otra]:checked) .lz-razon-otra { display:block; }
  /* Cancelar es un enlace (sin JS cierra por :target) y hereda el interlineado de la página; el botón de al lado
     usa normal, y esa diferencia bajaba el texto un píxel en Chromium. */
  .lz-perdida .zbtn, .lz-ganado .zbtn { line-height:normal; }
  .lz-perdida__h { margin:0 0 6px; font-size:var(--fs-2); font-weight:600; color:var(--text-2); }
  .lz-perdida__que { margin:0 0 4px; padding-top:12px; border-top:1px solid var(--hairline); }
  .lz-modal__box .lz-perdida__que { font-size:var(--fs-2); }
  .lz-perdida__motivo { margin:10px 0 0; color:var(--text-muted); }
  @media (pointer:coarse) {
    .lz-razon { min-height:44px; }
    .lz-perdida .zinput { font-size:16px; }
  }
  /* Con 11 razones el pie quedaba debajo del pliegue de un diálogo que scrollea (PCB8B-06, medido y=915 en 844): en un teléfono
     «Cancelar» y «Marcar perdido» se quedan pegados al borde de abajo, a la altura del pulgar, y siempre a la vista. El pie
     se extiende hasta los bordes de la caja (su relleno es de 24 px) para que el contenido no se vea pasar por los lados. */
  @media (max-width:720px) {
    .lz-perdida .lz-modal__acc { position:sticky; bottom:-24px; z-index:1; margin:16px -24px -24px; padding:12px 24px; background:var(--surface); border-top:1px solid var(--hairline); border-radius:0 0 var(--r-card) var(--r-card); }
    .lz-perdida .lz-modal__acc .zbtn { flex:1 1 0; min-height:48px; justify-content:center; }
  }
  /* En el Design System la caja se pinta en la página, no como velo. */
  .lz-modal--muestra { position:static; inset:auto; display:block; padding:0; background:none; z-index:auto; }
  .lz-modal--muestra .lz-modal__box { width:100%; max-width:480px; box-sizing:border-box; }
  [data-ds-theme="dark"] .lz-modal--muestra { background:none; }

  /* ───────── Cabecera de contacto ───────── */
  .lz-contacto { display:grid; gap:2px; min-width:0; }
  .lz-contacto__nombre { font-size:var(--fs-5); font-weight:600; letter-spacing:-.01em; line-height:1.25; overflow-wrap:anywhere; }
  .lz-contacto__linea { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .lz-contacto__tel { color:var(--text-2); text-decoration:none; font-variant-numeric:tabular-nums; width:fit-content; }
  @media (pointer:coarse) { .lz-contacto__tel { display:inline-flex; align-items:center; min-height:44px; } }
  @media (hover:hover) { .lz-contacto__tel:hover { color:var(--accent-text); text-decoration:none; } }
  .lz-contacto__chips { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }

  /* ───────── Acordeón ───────── */
  .lz-acordeon { border:1px solid var(--border); border-radius:var(--r-card); background:var(--surface); }
  .lz-acordeon > summary { list-style:none; display:flex; align-items:center; gap:10px; min-height:44px; padding:0 14px; cursor:pointer; border-radius:inherit; }
  .lz-acordeon > summary::-webkit-details-marker { display:none; }
  @media (hover:hover) { .lz-acordeon > summary:hover { background:var(--surface-2); } }
  .lz-acordeon > summary h3 { margin:0; font-size:var(--fs-3); font-weight:600; color:var(--text); }
  .lz-acordeon__es { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:right; font-size:var(--fs-2); color:var(--text-muted); }
  .lz-acordeon[open] .lz-acordeon__es { display:none; }
  .lz-acordeon__chev { margin-left:auto; display:inline-grid; place-items:center; color:var(--text-muted); transition:transform var(--dur-1) var(--ease-out); }
  .lz-acordeon__chev .lz-glifo { width:16px; height:16px; }
  .lz-acordeon[open] .lz-acordeon__chev { transform:rotate(90deg); }
  .lz-acordeon__cuerpo { padding:12px 14px 14px; border-top:1px solid var(--hairline); }
  .lz-acordeon--menor { border-color:transparent; background:transparent; }
  .lz-acordeon--menor > summary h3 { font-weight:500; color:var(--text-muted); }
  .lz-acordeon--menor .lz-acordeon__cuerpo { border-top-color:transparent; padding-left:0; padding-right:0; }
  @media (pointer:coarse) { .lz-acordeon > summary { min-height:48px; } }

  /* ───────── Progreso ───────── */
  .lz-progreso { display:flex; align-items:center; gap:10px; min-width:0; }
  .lz-progreso__pista { flex:1; height:6px; border-radius:var(--r-pill); background:var(--surface-3); overflow:hidden; }
  .lz-progreso__pista > i { display:block; height:100%; width:var(--p, 0%); background:var(--accent); border-radius:inherit; transition:width var(--dur-3) var(--ease-out); }
  .lz-progreso__t { font-size:var(--fs-2); color:var(--text-muted); font-variant-numeric:tabular-nums; white-space:nowrap; }

  /* ───────── Patrones para la ola 3 (sin helper, solo clases) ───────── */
  /* Bloque de contexto: identidad, calificación, etapa, próxima cita, pendientes, datos y, al fondo, lo
     de menor jerarquía. Un solo orden en todas las pantallas; cada bloque lleva su h3. */
  .lz-ctx { display:grid; gap:14px; align-content:start; min-width:0; }
  .lz-ctx > * + * { padding-top:14px; border-top:1px solid var(--hairline); }
  .lz-ctx h3 { margin:0 0 6px; font-size:var(--fs-2); font-weight:600; color:var(--text-muted); }
  .lz-ctx__id { display:grid; gap:10px; }
  .lz-ctx__bajo { display:grid; gap:8px; color:var(--text-2); font-size:var(--fs-2); }

  /* Acciones de una fila: Llamar, WhatsApp, Agendar, Más. 30 px con ratón, 44 px al tacto. */
  .lz-fila-acc { display:inline-flex; align-items:center; gap:2px; }
  .lz-fila-acc .lz-ico { width:30px; height:30px; border-color:transparent; background:transparent; color:var(--text-2); cursor:pointer; }
  @media (hover:hover) { .lz-fila-acc .lz-ico:hover { background:var(--accent-soft); color:var(--accent-text); border-color:transparent; } }
  @media (hover:hover) { .lz-fila-acc .lz-ico--wa, .lz-fila-acc .lz-ico--wa:hover { color:var(--wa); } }
  @media (hover:hover) { .lz-fila-acc .lz-ico--wa:hover { background:var(--surface-2); } }
  @media (pointer:coarse) { .lz-fila-acc .lz-ico { width:44px; height:44px; } }

  /* Muestras del Design System */
  .lz-mol-m { display:grid; gap:12px; align-content:start; padding:16px 0; border-top:1px solid var(--hairline); }
  .lz-mol-m:first-child { border-top:0; }
  .lz-mol-m > h4 { margin:0; font-size:var(--fs-3); font-weight:600; }
  .lz-mol-m__p { margin:0; font-size:var(--fs-1); color:var(--text-muted); }
  .lz-mol-m__fila { display:flex; align-items:flex-start; flex-wrap:wrap; gap:16px 24px; }
  .lz-mol-m__menu { min-height:340px; }

  @media (prefers-reduced-motion: reduce) {
    .lz-etapa__sum .lz-glifo, .lz-acordeon__chev, .lz-progreso__pista > i { transition:none; }
  }
  /* El modal «En espera hasta»: el calendario abre su popover dentro de la caja, sin recorte. */
  .lz-espera .lz-modal__box { width:min(480px, 94vw); max-height:calc(100dvh - 40px); overflow:visible; }
  .lz-espera__presets { display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 14px; }
  .lz-espera__m { display:block; margin:0 0 4px; font-size:var(--fs-2); font-weight:600; color:var(--text-2); }
  .lz-espera .lz-modal__acc .zbtn { line-height:normal; }
  .lz-espera .lz-perdida__h { margin-top:18px; }

  /* ───────── Cifras de reporte (15-oct-2026) ─────────
     Rejilla que se ajusta sola (auto-fill, minmax) y una cifra por renglón en teléfono. La hairline vertical entre cifras
     es una sombra de 1 px a la izquierda de cada una, recortada por el contenedor: así la primera columna nunca la lleva,
     envuelva como envuelva la rejilla (el border-left con :first-child dejaba la línea suelta al inicio del segundo
     renglón). Entre renglones separa el aire, no una línea: una horizontal solo bajo las cifras que caben en el segundo
     renglón se leía como tabla rota. */
  /* En cajas (Alex, 15-oct: «en cajas, en vez de que el texto esté flotando»): una caja por cifra en --surface-anidada,
     rótulo arriba, número y nota debajo. Mismas medidas que .lz-kpis y .lz-metrics (leadz-vistas.js). */
  .lz-cifras { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,180px),1fr)); gap:12px; margin:0 0 16px; }
  .lz-cifra { display:flex; flex-direction:column; gap:4px; min-width:0; padding:14px 16px; background:var(--surface-anidada); border:1px solid var(--border); border-radius:var(--r-control); }
  .lz-cifra__n { order:1; font-size:var(--fs-6); font-weight:600; line-height:1.15; letter-spacing:-.02em; font-variant-numeric:tabular-nums; color:var(--text); overflow-wrap:anywhere; }
  .lz-cifra__n > .lz-nd { display:inline-block; font-size:var(--fs-3); font-weight:400; line-height:calc(var(--fs-6) * 1.15); letter-spacing:0; }
  .lz-cifra__t { order:0; font-size:var(--fs-2); font-weight:400; line-height:1.35; color:var(--text-2); }
  .lz-cifra__p { order:2; font-size:var(--fs-1); line-height:1.4; color:var(--text-muted); }
  /* Dentro de una tarjeta de reporte también van en cajas: son su módulo interno. */
  .lz-blk .lz-cifras:not(:last-child) { margin-bottom:12px; }
  .lz-blk .lz-cifras:last-child { margin-bottom:0; }
  /* Teléfono: dos cajas por renglón, el número un paso más chico. */
  @media (max-width:560px) {
    .lz-cifras { grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px; }
    .lz-cifra { padding:12px; }
    .lz-cifra__n { font-size:var(--fs-5); }
  }

  /* ───────── Bloque de información plegable (15-oct-2026) ─────────
     details plegado por omisión; el summary es un botón ghost con el glifo info, texto visible y chevron. Sin el triángulo
     nativo. Abierto, el botón queda en selección neutra y el panel es la lista .zayuda sobre --surface-2 a todo el ancho. */
  .lz-info { margin:0 0 12px; min-width:0; }
  .lz-info > summary { list-style:none; width:max-content; max-width:100%; color:var(--text-2); }
  .lz-info > summary::-webkit-details-marker { display:none; }
  .lz-info > summary::marker { content:""; }
  /* El chevron del catálogo apunta a la derecha: plegado mira abajo, abierto arriba. */
  .lz-info__chev { display:inline-flex; color:var(--text-muted); transform:rotate(90deg); transition:transform var(--dur-1) var(--ease-out); }
  .lz-info__chev .lz-glifo { width:14px; height:14px; }
  .lz-info[open] > summary { background:var(--sel-bg); color:var(--sel-text); }
  .lz-info[open] .lz-info__chev { transform:rotate(-90deg); }

  .lz-info__panel { margin:8px 0 0; padding:12px 16px; border-radius:var(--r-control); background:var(--surface-2); }
  .lz-info__panel a { font-weight:500; }
  /* .zayuda separa la clave con 4 px a su derecha; una negrita en medio de la frase no la lleva («hecho.», no «hecho .»). */
  .lz-info__panel > div > b:not(:first-child) { margin-right:0; }
  .lz-info--reporte { margin:0 0 16px; }
  /* En su propio renglón, el glifo alinea con el borde del contenido; el fondo del botón (hover, abierto) sale al margen,
     como un ghost. En el renglón del título (bloque en escritorio) no hace falta. */
  .lz-info > summary { margin-left:-12px; }

  /* En una tarjeta: el botón sube al renglón del h2, a la derecha; el título reserva su hueco para no pasar por debajo. */
  .lz-blk:has(> .lz-info--bloque) { position:relative; }
  @media (min-width:561px) {
    .lz-blk:has(> .lz-info--bloque) > h2 { padding-right:132px; }
    .lz-info--bloque > summary { position:absolute; top:11px; right:12px; margin-left:0; }

    .lz-info--bloque > .lz-info__panel { margin-top:0; }
    .lz-info--bloque { margin:0; }
    .lz-info--bloque[open] { margin:0 0 14px; }
  }
  @media (max-width:560px) {
    .lz-info--bloque { margin:-4px 0 12px; }
  }
  @media (prefers-reduced-motion: reduce) { .lz-info__chev { transition:none; } }

  /* ───────── Ficha de datos: rejilla etiqueta/valor ───────── */
  .lz-datos { --lz-etq-w:168px; display:grid; margin:0; min-width:0; }
  .lz-datos__f { display:grid; grid-template-columns:var(--lz-etq-w) minmax(0,1fr); gap:2px 16px; align-items:baseline; padding:7px 0; border-top:1px solid var(--border); min-width:0; }
  .lz-datos__f:first-child { border-top:0; }
  .lz-datos dt { margin:0; font-size:var(--fs-2); font-weight:500; color:var(--text-muted); }
  .lz-datos dd { margin:0; min-width:0; font-size:var(--fs-3); line-height:1.5; color:var(--text); overflow-wrap:anywhere; }
  .lz-datos__f--hoy { padding:12px 0; }
  .lz-datos__f--hoy dt { font-size:var(--fs-3); font-weight:600; color:var(--text); }
  .lz-datos__f--hoy dd { font-size:var(--fs-4); font-weight:600; line-height:1.45; }
  @media (max-width:520px) { .lz-datos__f { grid-template-columns:minmax(0,1fr); gap:2px; } }

  /* ───────── Cuestionario puntuado: pregunta · respuesta · puntos ───────── */
  .lz-pts { width:100%; border-collapse:collapse; table-layout:fixed; font-size:var(--fs-3); }
  .lz-pts td, .lz-pts th { padding:8px 0; border-top:1px solid var(--border); vertical-align:baseline; text-align:left; overflow-wrap:anywhere; word-break:break-word; }
  .lz-pts th { height:auto; font-family:inherit; font-size:var(--fs-3); letter-spacing:0; text-transform:none; white-space:normal; border-bottom:0; }
  .lz-pts tbody tr:first-child td { border-top:0; padding-top:0; }
  .lz-pts__cq { width:40%; }
  .lz-pts__cp { width:52px; }
  .lz-pts td.lz-pts__q { padding-right:16px; color:var(--text-2); font-size:var(--fs-2); }
  .lz-pts td.lz-pts__a { color:var(--text); padding-right:12px; }
  .lz-pts .lz-pts__p { text-align:right; font-family:var(--mono); font-variant-numeric:tabular-nums; color:var(--text-2); white-space:nowrap; }
  .lz-pts__n { color:var(--text-muted); font-size:var(--fs-2); }
  .lz-pts tfoot th { font-weight:600; color:var(--text); border-top:1px solid var(--border-control, var(--border)); }
  .lz-pts tfoot .lz-pts__p { font-weight:600; color:var(--text); border-top:1px solid var(--border-control, var(--border)); }
  @media (max-width:520px) { .lz-pts__cq { width:38%; } .lz-pts__cp { width:40px; } .lz-pts td.lz-pts__q { padding-right:12px; } }

  /* ───────── Cuerpo de la espera: ayuda en lista y botones ───────── */
  .lz-espera__ayuda { margin-top:16px; }
  .lz-espera .lz-modal__acc .zbtn, #lz-espera-modal .lz-modal__acc .zbtn { display:inline-flex; align-items:center; justify-content:center; gap:6px; }
  @media (max-width:520px) {
    .lz-espera .lz-modal__acc, #lz-espera-modal .lz-modal__acc { flex-direction:column-reverse; }
    .lz-espera .lz-modal__acc .zbtn, #lz-espera-modal .lz-modal__acc .zbtn { width:100%; min-height:44px; }
  }

  .lz-conf { position:fixed; inset:0; z-index:var(--z-modal); display:flex; align-items:center; justify-content:center; padding:20px;
    background:color-mix(in oklch, var(--text) 45%, transparent); }
  [data-ds-theme="dark"] .lz-conf { background:color-mix(in oklch, var(--bg) 70%, transparent); }
  .lz-conf[hidden] { display:none; }
  .lz-conf__box { background:var(--surface); color:var(--text); border:1px solid var(--hairline); border-radius:var(--r-card);
    box-shadow:var(--shadow-md); padding:24px; width:min(440px, 94vw); max-height:calc(100dvh - 40px); overflow:auto; }
  .lz-conf__box h3 { margin:0 0 12px; font-size:var(--fs-5, 18px); font-weight:600; letter-spacing:-.01em; line-height:1.3; overflow-wrap:anywhere; }
  .lz-conf__q { margin:0 0 16px; }
  .lz-conf__q > div { padding:8px 0; border-top:1px solid var(--hairline); font-size:var(--fs-2, 12.5px); line-height:1.45; color:var(--text); }
  .lz-conf__q > div:first-child { border-top:0; padding-top:0; }
  .lz-conf__q b { font-weight:600; margin-right:4px; }
  .lz-conf__campo { display:grid; gap:6px; }
  .lz-conf__campo label { font-size:var(--fs-2, 12.5px); font-weight:600; color:var(--text); }
  .lz-conf__campo .zta { min-height:64px; }
  .lz-conf__h { margin:0; font-size:var(--fs-1, 11.5px); color:var(--text-muted); }
  .lz-conf__h[data-error] { color:var(--danger); }
  .lz-conf__acc { display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; margin-top:20px; }
  .lz-conf__acc .zbtn { display:inline-flex; align-items:center; gap:6px; }
  .lz-conf__acc .lz-glifo { width:16px; height:16px; }
  .lz-conf-sinjs { display:inline-flex; align-items:center; gap:6px; }
  @media (max-width: 820px) { .lz-conf__acc .zbtn { flex:1 1 auto; justify-content:center; } }

  /* Quitar el contraste que no informa: un dato por fila, un peso por nivel, un color por significado. */
  /* Título de pantalla en 500 (la regla compartida lo fija en 600 con la misma especificidad) y su icono sin caja. */
  :root .lz-h1, :root .zcab h1 { font-weight:500; }
  :root .lz-h1__ic { background:transparent; color:var(--text-muted); }
  /* Chip: punto de color (si lo trae) más texto, sin relleno ni borde. Dos chips seguidos en una línea de texto se
     separan con un punto medio; dentro de una fila de chips (.lz-chips, cabecera de la Ficha) ya los separa el gap y
     el chip lleva su propia pastilla, así que ahí el punto se metía dentro (PCB9A-15, ola 9). */
  :root .lz-chip { height:auto; padding:0; background:transparent; border-color:transparent; font-size:var(--fs-2); font-weight:400; }
  :root :not(.lz-chips, .lz-fx-sub) > .lz-chip + .lz-chip::before { content:"·"; color:var(--text-muted); margin-right:3px; }
  :root .lz-califica__b { height:auto; padding:0; font-weight:500; }
  :root .lz-califica__n { font-weight:500; }
  /* WhatsApp es un botón gris como los demás: la regla compartida lo pinta de verde pleno en cualquier .zbtn con su glifo. */
  :root .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar) { background:var(--surface-2); border-color:var(--border-control); color:var(--text); }
  :root .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar) .lz-glifo--wa { color:var(--text-2) !important; }
  @media (hover:hover) { :root .zbtn:has(> .lz-glifo--wa):not(.lz-califica__mandar):hover { background:var(--surface-3); border-color:var(--border-control); color:var(--text); filter:none; } }
  /* Estado de la ventana, etiqueta de grupo y plantilla: punto más texto, sin relleno (el punto lleva el color que significa). */
  :root .lz-pill { height:auto; padding:0; background:transparent; font-size:var(--fs-2); font-weight:400; color:var(--text-2); }
  :root .lz-pill::before { opacity:1; background:var(--text-muted); }
  :root .lz-pill--on::before { background:var(--ok-text); }
  :root .lz-pill--off::before { background:var(--bad-text); }
  :root .lz-gchip { height:auto; padding:0; background:transparent; font-size:var(--fs-2); font-weight:400; }
  :root .lz-wa-tpl { background:transparent; padding:0; font-weight:400; color:var(--text-muted); }
  /* Contador: cifra tabular en atenuado, sin pastilla ni borde. */
  :root .lz-count { border-color:transparent; padding:0; font-weight:400; font-variant-numeric:tabular-nums; }
  :root .lz-tabs a.on { font-weight:500; }
  /* Los estilos en línea que piden 600 o 700 (rótulos sueltos dentro de bloques) bajan a 500: un peso por nivel. */
  :root [style*="font-weight:600"], :root [style*="font-weight: 600"], :root [style*="font-weight:700"] { font-weight:500 !important; }
  :root .lz-acc-t { font-weight:500; }
  :root .zayuda b, :root .lz-pop__t, :root .lz-ayuda > summary { font-weight:500; }
  /* Tablas: cabecera atenuada en 500 sin mayúsculas ni mono, hairline entre filas, sin raya tras la última. */
  :root table th, :root .lz-tabla th { font-family:inherit; font-size:var(--fs-2); font-weight:500; letter-spacing:0; text-transform:none; color:var(--text-muted); border-bottom-color:var(--border); }
  :root table td, :root .lz-tabla td { border-bottom-color:var(--border); }
  :root .lz-tabla td { padding-block:10px; height:auto; min-height:44px; }
  :root .lz-tabla tr.lz-total td, :root .lz-tabla tfoot td { font-weight:500; border-top-color:var(--border); }
  /* Cifras EN CAJAS (Alex, 15-oct: «en cajas, en vez de que el texto esté flotando»; antes aquí iban sin caja): una caja
     por cifra en --surface-anidada con hairline y radio de control, rótulo arriba en --text-2 y número debajo. Vale para
     .lz-kpis y para las rejillas de tarjetas clave/valor (.zgrid con .zcard__k). */
  :root .lz-kpis, :root .zgrid:has(> .zcard > .zcard__k) { gap:12px; border:0; background:none; box-shadow:none; border-radius:0; overflow:visible; margin-bottom:24px; }
  :root .lz-kpi, :root .zgrid:has(> .zcard > .zcard__k) > .zcard { display:flex; flex-direction:column; gap:4px; background:var(--surface-anidada); padding:14px 16px; border:1px solid var(--border); border-radius:var(--r-control); box-shadow:none; }
  :root .lz-blk .lz-kpi, :root .lz-blk .zgrid > .zcard { border:1px solid var(--border); padding:14px 16px; }
  :root .lz-blk .lz-kpis, :root .lz-blk .zgrid { gap:12px; }
  :root .lz-kpi b, :root .lz-kpi .lz-kpi__v, :root .zcard__v { font-size:var(--fs-6); font-weight:600; letter-spacing:-.02em; }
  :root .lz-kpi__n { font-weight:600; }
  :root .lz-kpi .lz-kpi__t, :root .zcard__k { order:-1; font-size:var(--fs-2); font-weight:400; letter-spacing:0; text-transform:none; color:var(--text-2); }
  /* Bloques de un reporte: hairline sin sombra, más aire, y el título es un rótulo pequeño en atenuado. */
  :root .zcard.lz-blk { border-color:var(--border); padding:20px 22px; }
  :root .lz-blk h2 { font-size:var(--fs-3); font-weight:500; color:var(--text-2); margin-bottom:14px; }
  :root .lz-rep-h h1, :root .lz-rep-h h2 { font-weight:500; }
  /* Pestañas por enlace (.znav): la activa en tinta suave y en 500. */
  :root .znav a.on { font-weight:500; }
  /* Filtros de formulario: la etiqueta en 500 y atenuada. */
  :root form.lz-filtros label { font-weight:500; color:var(--text-muted); }
  :root .lz-delta { font-weight:400; }
  /* Semáforo: la cifra va en tinta y solo el marcador (círculo u rombo) lleva el color que significa. */
  :root [data-sem="ok"], :root [data-sem="bad"] { color:var(--text); }
  :root .lz-blk b, :root .lz-blk strong { font-weight:500; }
  /* Énfasis dentro del contenido: 500, un solo peso (la negrita de 600 y 700 grita junto a un texto de 400). */
  :root main b, :root main strong, :root .lz-sheet b, :root .lz-sheet strong { font-weight:500; }
  :root main h4 { font-weight:500; }
  :root .zaviso { background:transparent; }
  :root .lz-sheet__h2, :root .lz-sheet__h3 { font-weight:500; }
  /* Días hábiles: el marcado en tinta suave, no en tinta invertida. */
  :root .lz-dia > span:not(.lz-sr) { font-weight:500; }
  :root .lz-dia input:checked + span { background:var(--sel-bg); color:var(--text); border-color:var(--border-control); }
  /* Encabezado de una lista de filas (cadencias): atenuado, sans, sin mayúsculas. */
  :root .lz-cad__hd { font-family:inherit; font-size:var(--fs-2); letter-spacing:0; text-transform:none; font-weight:500; }
  /* Avisos de advertencia (no de error): sin relleno ámbar; el texto y el hairline bastan. El error (.zalert) conserva su color. */
  :root .lz-count--warn { background:transparent; color:var(--text-2); border-color:transparent; }
  :root [style*="background:var(--warn-soft)"] { background:transparent !important; color:var(--text-2) !important; border:1px solid var(--border) !important; }
  /* Columna secundaria (Reportes, Ajustes): grupos en atenuado sin mayúsculas, título en 500. */
  :root .lz-sub h3 { font-weight:500; }
  :root .lz-sub__g { font-weight:500; letter-spacing:0; text-transform:none; font-size:var(--fs-2); }
  /* Barras de etapa del embudo: gris, la etapa ya la dice el punto y el nombre. */
  :root .lz-emb__bar span { background:var(--text-muted); }
