/* ===========================================================================
   DENTRO · panel de conversaciones
   ---------------------------------------------------------------------------
   UN SOLO TEMA, CLARO. No hay modo oscuro y no es un olvido: el recurso de
   jerarquia de esta marca es INVERTIR un bloque entero a Petroleo. Si toda la
   app ya es oscura, la barra y el panel de detalle dejan de destacarse y el
   mecanismo se muere. La oscuridad de esta app es ESTRUCTURAL (barra + panel
   tecnico + login), no un tema.
   ---------------------------------------------------------------------------
   Los ratios anotados estan MEDIDOS (WCAG 2.1, sRGB). Si cambias un color,
   volve a medirlos: la trampa de esta paleta es que el Verde Clinico se ve
   bien y no llega.
   ---------------------------------------------------------------------------
   ⚠️ NADA DE url(data:...) EN ESTE ARCHIVO. El parser se atraganta con esa
   URL y descarta la regla Y TODO EL RESTO DE LA HOJA: quedan los colores del
   :root pero ninguna burbuja con fondo ni alineacion, o sea "casi bien", que
   es la peor forma de estar roto. Los iconos van como <svg> en el HTML.
   Se detecta midiendo document.styleSheets[0].cssRules.length, no mirando.
   =========================================================================== */
:root{
  /* ======================================================== 1 · MARCA */
  --petroleo:        #0B3B36;
  --petroleo-900:    #072723;
  --petroleo-700:    #0F4A44;
  --verde:           #3C7A70;  /* ICONO/FILETE/PUNTO. NUNCA TEXTO */
  --verde-claro:     #7FB0A6;  /* el unico verde legible sobre oscuro */
  --hueso:           #E9EDEA;
  --hueso-puro:      #F4F7F5;
  --tinta:           #0E1513;
  --gris:            #5C6B66;
  --linea:           #CFD8D3;
  --linea-oscura:    #17514A;

  /* ======================================================== 2 · SUPERFICIES */
  --fondo-app:       var(--hueso);
  --fondo-lista:     var(--hueso-puro);
  --fondo-hilo:      #DCE2DF;
  --fondo-barra:     var(--petroleo);
  --fondo-detalle:   var(--petroleo-900);
  --fila-hover:      #E7EEEC;
  --fila-activa:     #DEE8E5;
  --trama:           rgba(60,122,112,.09);
  --trama-paso:      24px;

  /* ======================================================== 3 · BURBUJAS */
  --burbuja-paciente:  var(--hueso-puro);
  --burbuja-bot:       #C6D3CF;
  --burbuja-doctora:   #ACC3BE;
  --burbuja-max:       62%;
  --pastilla-sistema:  #EFF3F1;
  /* El unico gris valido para 11px DENTRO de una burbuja: el --gris de marca
     da 3.63:1 sobre --burbuja-bot y NO PASA. */
  --sello:             #44504D;

  /* ======================================================== 4 · ESTADOS */
  --ok-claro:        var(--verde);
  --ok-oscuro:       #7FB0A6;
  --att-claro:       #A8721A;  /* PUNTO, NUNCA TEXTO (3.49:1) */
  --att-oscuro:      #D9A62E;
  --alerta-claro:    #A32A1E;  /* el unico color habilitado como texto */
  --alerta-oscuro:   #F0A099;
  --chip-ok:         #E2EAE8;
  --chip-att:        #ECEADF;
  --chip-alerta:     #ECE2E0;

  /* ======================================================== 5 · TEXTO */
  --txt-fuerte:      var(--tinta);
  --txt-medio:       #243330;
  --txt-suave:       var(--gris);
  --txt-titulo:      var(--petroleo);
  --txt-inv:         var(--hueso);
  --txt-inv-2:       rgba(233,237,234,.70);
  --txt-inv-3:       rgba(233,237,234,.55);  /* piso: no bajar */
  --txt-rotulo:      var(--verde-claro);

  /* ======================================================== 6 · TIPOGRAFIA */
  --fuente-ui:    Archivo, system-ui, -apple-system, sans-serif;
  --fuente-texto: "Source Serif 4", Georgia, serif;
  --fuente-dato:  "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
  --logo-wdth:       112;
  --logo-track:      .11em;

  --t-mensaje:       16px;
  --t-mensaje-alt:   1.5;
  --t-nombre:        16px;
  --t-previo:        14px;
  --t-boton:         15px;
  --t-sello:         11px;
  --t-rotulo:        10.5px;
  --t-dato:          12.5px;
  --t-titulo:        22px;
  --track-rotulo:    .14em;

  /* ======================================================== 7 · RADIOS */
  --r-boton: 3px; --r-campo: 4px; --r-tarjeta: 4px; --r-chip: 3px;
  --r-burbuja: 8px;

  /* ======================================================== 8 · SOMBRAS */
  --sombra-burbuja:  0 1px 1px rgba(11,59,54,.14);
  --sombra-carta:    0 1px 2px rgba(11,59,54,.06), 0 8px 24px -12px rgba(11,59,54,.18);

  /* ======================================================== 9 · ESPACIADO */
  --e-1:4px; --e-2:8px; --e-3:12px; --e-4:16px; --e-5:20px; --e-6:24px; --e-8:32px;

  /* ======================================================= 10 · ESTRUCTURA */
  --alto-barra:      56px;
  --alto-fila:       72px;
  --ancho-lista:     30%;
  --ancho-lista-min: 320px;
  --ancho-lista-max: 440px;
  --ancho-detalle:   340px;
  --marca-barra:     26px;   /* NO bajar de 24: bajo eso la guia obliga a la
                                version micro de 6 segmentos */
  --avatar:          44px;
  --punto-estado:    8px;

  /* ======================================================= 11 · MOVIMIENTO */
  --trans-rapida: .12s ease;
  --trans: .16s ease;
  --foco-claro:  2px solid var(--verde);
  --foco-oscuro: 2px solid var(--verde-claro);
  --foco-offset: 3px;

  /* ======================================================= 12 · CAPAS */
  --z-hilo:1; --z-barra:50; --z-menu:60; --z-modal:80;
}

/* Respetar la preferencia del sistema. Va siempre, en todas las piezas de
   esta marca. */
@media (prefers-reduced-motion: reduce){
  *{animation:none!important; transition:none!important; scroll-behavior:auto}
}

*,*::before,*::after{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--fondo-app); color:var(--txt-fuerte);
  font-family:var(--fuente-ui); font-size:15px; line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
button,input,select{font-family:inherit; font-size:inherit}
:focus-visible{outline:var(--foco-claro); outline-offset:var(--foco-offset)}
.oscuro :focus-visible{outline:var(--foco-oscuro)}
[hidden]{display:none!important}

/* ═══════════════════════════════════════════════════════ LOGIN */
.login{
  min-height:100vh; background:var(--petroleo); color:var(--txt-inv);
  display:flex; flex-direction:column; align-items:center;
  justify-content:center; padding:var(--e-6);
}
.login__marca{width:320px; max-width:78vw; height:auto}
.login__bajada{
  margin:48px 0 0; max-width:36ch; text-align:center;
  font-family:var(--fuente-texto); font-size:20px; line-height:1.45;
  color:var(--txt-inv-2);  /* 5.99:1 sobre Petroleo */
}
.login__form{width:100%; max-width:380px; margin-top:var(--e-8)}
.campo{position:relative; margin-bottom:var(--e-6)}
.campo__rotulo{
  display:block; font-family:var(--fuente-dato); font-size:var(--t-rotulo);
  letter-spacing:var(--track-rotulo); text-transform:uppercase;
  color:var(--txt-rotulo); margin-bottom:var(--e-2);
}
.campo__input{
  width:100%; padding:var(--e-2) 0; border:0;
  border-bottom:1px solid var(--linea-oscura); background:transparent;
  color:var(--txt-inv); font-size:16px;
}
.campo__input:focus{outline:none; border-bottom:2px solid var(--verde-claro)}
.boton{
  display:inline-flex; align-items:center; justify-content:center; gap:11px;
  padding:12px 20px; border-radius:var(--r-boton); border:1px solid transparent;
  font-family:var(--fuente-ui); font-weight:600; font-size:var(--t-boton);
  letter-spacing:-.006em; cursor:pointer; transition:background var(--trans);
  /* Hay botones que son <a> (cambiar contrasena, reintentar): sin esto
     salen subrayados y se leen como un enlace de texto adentro del borde. */
  text-decoration:none;
}
.boton--claro{background:var(--hueso); color:var(--petroleo); border-color:var(--hueso); width:100%}
.boton--claro:hover{background:var(--hueso-puro)}
.boton--fantasma{
  background:transparent; color:var(--txt-inv-2);
  border-color:var(--linea-oscura); padding:8px 14px; font-size:13px;
}
.boton--fantasma:hover{background:var(--petroleo-700); color:var(--txt-inv)}
.error{
  margin:0 0 var(--e-4); font-family:var(--fuente-dato); font-size:12px;
  color:var(--alerta-oscuro);  /* 6.02:1 sobre Petroleo */
}
/* La explicacion en las pantallas de pie de login (sin conexion, cambiar
   contrasena). NO usar .login__pie para esto: ese es `position:fixed` y
   pensado para UNA sola linea pegada abajo de todo — dos seguidos se dibujan
   uno ENCIMA del otro. Ya paso. */
.login__nota{
  margin:var(--e-5) 0 0; max-width:44ch; text-align:center;
  font-family:var(--fuente-ui); font-size:13.5px; line-height:1.5;
  color:var(--txt-inv-2);
}
.login__accion{margin:var(--e-5) 0 0}

/* ⚠️ UNO SOLO POR PANTALLA: es `position:fixed`, asi que el segundo se
   superpone al primero. La explicacion va en .login__nota. */
.login__pie{
  position:fixed; bottom:var(--e-4); left:0; right:0; text-align:center;
  font-family:var(--fuente-dato); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--txt-inv-3);
}

/* ═══════════════════════════════════════════════════════ ESTRUCTURA */
.app{display:flex; flex-direction:column; height:100vh; height:100dvh}

.barra{
  flex:0 0 auto; height:var(--alto-barra); display:flex; align-items:center;
  gap:var(--e-4); padding:0 var(--e-4); background:var(--fondo-barra);
  color:var(--txt-inv); border-bottom:1px solid var(--linea-oscura);
  position:sticky; top:0; z-index:var(--z-barra);
}
.barra__marca{height:var(--marca-barra); width:auto; display:block}
.barra__filete{
  width:1px; height:24px; background:var(--linea-oscura); flex:0 0 auto;
}
.barra__grupo{display:flex; align-items:center; gap:var(--e-2); min-width:0}
.barra__espacio{flex:1 1 auto}
.rotulo{
  font-family:var(--fuente-dato); font-size:var(--t-rotulo);
  letter-spacing:var(--track-rotulo); text-transform:uppercase;
  color:var(--txt-rotulo); white-space:nowrap;
}
/* El selector de consultorio: un <select> desnudo. Con un solo cliente no se
   oculta — se muestra el nombre fijo, porque el nombre del consultorio activo
   tiene que estar SIEMPRE en pantalla. */
.selector{
  appearance:none; -webkit-appearance:none; background:transparent; border:0;
  color:var(--txt-inv); font-family:var(--fuente-ui); font-weight:600;
  font-size:15px; padding:6px 26px 6px 4px; cursor:pointer; max-width:44vw;
  /* Los tres juntos: sin white-space y overflow, text-overflow no hace
     nada y el nombre del consultorio queda cortado a filo. */
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Con UN solo consultorio el selector esta deshabilitado, asi que el
   chevron se saca: una flecha de menu que no abre nada hace buscar
   clientes que no existen. Cuando haya dos, vuelve sola. */
.selector:disabled{cursor:default; opacity:1}
.selector:disabled ~ .chevron{display:none}
.selector option{color:var(--tinta); background:var(--hueso-puro)}
/* 'Volver' solo existe cuando hay una pantalla anterior. Un boton que
   no hace nada ocupa el lugar del que si — y en la barra de un celular
   el lugar es todo. */
/* ── Los dos controles que SOLO existen en el celular ──────────────────
   MEDIDO el 9/9/2026 con la ventana en 1707px: apretar «Detalle» no
   cambiaba NADA (el panel de detalle ya es la columna de la derecha) y
   «Volver» no tenia de donde volver (la lista ya esta al lado). Un boton
   que no hace nada no es inofensivo: el que lo aprieta cree que algo se
   rompio. En el celular las tres columnas no caben y ahi si sirven, asi
   que viven adentro del @media de abajo. */
.volver{display:none}
#ver-detalle{display:none}
.selector-envoltorio{position:relative; display:flex; align-items:center}
.selector-envoltorio .chevron{
  position:absolute; right:6px; pointer-events:none; color:var(--verde-claro);
}
.vivo{display:flex; align-items:center; gap:var(--e-2)}
.vivo__anillo{width:18px; height:18px; display:block}
/* El anillo late. NUNCA gira: es un reloj y torcido deja de leerse. */
.vivo--activo .vivo__anillo{animation:latir 2s ease-in-out infinite}
@keyframes latir{0%,100%{opacity:1}50%{opacity:.35}}

.cuerpo{flex:1 1 auto; display:flex; min-height:0}

/* ── columna de chats ── */
.lista{
  flex:0 0 var(--ancho-lista); min-width:var(--ancho-lista-min);
  max-width:var(--ancho-lista-max); background:var(--fondo-lista);
  border-right:1px solid var(--linea); display:flex; flex-direction:column;
  min-height:0;
}
.buscador{
  flex:0 0 auto; padding:var(--e-3); border-bottom:1px solid var(--linea);
  position:relative; display:flex; align-items:center;
}
.buscador svg{position:absolute; left:24px; color:var(--verde); pointer-events:none}
.buscador input{
  width:100%; padding:9px 12px 9px 38px; border:1px solid var(--linea);
  border-radius:var(--r-campo); background:var(--hueso);
  font-family:var(--fuente-texto); font-size:15px; color:var(--txt-fuerte);
}
.buscador input::placeholder{color:var(--txt-suave)}
.lista__scroll{flex:1 1 auto; overflow-y:auto; min-height:0}

.fila{
  display:flex; align-items:center; gap:var(--e-3); min-height:var(--alto-fila);
  padding:0 13px; border-bottom:1px solid var(--linea); cursor:pointer;
  border-left:3px solid transparent; position:relative;
  transition:background var(--trans-rapida);
}
.fila:hover{background:var(--fila-hover)}
.fila--activa{background:var(--fila-activa); border-left-color:var(--petroleo)}
/* El avatar es un disco Petroleo con iniciales en Hueso, SIEMPRE igual. Los
   12 pasteles del lector viejo son una segunda paleta y son de WhatsApp. */
.avatar{
  flex:0 0 auto; width:var(--avatar); height:var(--avatar); border-radius:50%;
  background:var(--petroleo); color:var(--txt-inv); display:flex;
  align-items:center; justify-content:center; font-weight:600; font-size:15px;
  letter-spacing:.02em;
}
.avatar--handoff{background:var(--verde); color:var(--hueso-puro)}
.fila__medio{flex:1 1 auto; min-width:0}
.fila__nombre{
  font-weight:500; font-size:var(--t-nombre); color:var(--txt-fuerte);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.fila__previo{
  font-family:var(--fuente-texto); font-size:var(--t-previo);
  color:var(--txt-suave); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis;
}
.fila__derecha{
  flex:0 0 auto; display:flex; flex-direction:column; align-items:flex-end;
  gap:var(--e-1);
}
.fila__hora{
  font-family:var(--fuente-dato); font-size:var(--t-sello);
  color:var(--txt-suave); font-variant-numeric:tabular-nums;
}
.pastilla{
  background:var(--petroleo); color:var(--txt-inv); font-weight:600;
  font-size:11px; border-radius:999px; padding:1px 7px; min-width:20px;
  text-align:center;
}

/* ── el hilo ── */
.hilo-col{flex:1 1 auto; display:flex; flex-direction:column; min-width:0; min-height:0}
.cabecera{
  flex:0 0 auto; display:flex; align-items:center; gap:var(--e-3);
  padding:var(--e-2) var(--e-4); background:var(--hueso-puro);
  border-bottom:1px solid var(--linea); min-height:56px;
}
.cabecera__nombre{font-weight:600; font-size:16px}
.cabecera__sub{
  font-family:var(--fuente-dato); font-size:var(--t-sello);
  color:var(--txt-suave); font-variant-numeric:tabular-nums;
}
.hilo{
  flex:1 1 auto; overflow-y:auto; min-height:0; padding:14px 6%;
  background-color:var(--fondo-hilo);
  /* La trama: el reemplazo del empapelado de WhatsApp. Puntos de Verde
     Clinico al 9%, paso 24px. Lee como papel milimetrado clinico, no como
     garabatos. Es procedural, del mismo linaje que los fondos de la marca:
     no cambiarla por un degrade ni por una imagen. */
  background-image:radial-gradient(var(--trama) 1px, transparent 0);
  background-size:var(--trama-paso) var(--trama-paso);
}

.msj{display:flex; margin-bottom:var(--e-2)}
.msj--paciente{justify-content:flex-start}
.msj--bot,.msj--doctora{justify-content:flex-end}
.burbuja{
  max-width:var(--burbuja-max); padding:8px 10px 10px 12px;
  border-radius:var(--r-burbuja); box-shadow:var(--sombra-burbuja);
  position:relative;
}
.msj--paciente .burbuja{background:var(--burbuja-paciente)}
.msj--bot .burbuja{background:var(--burbuja-bot)}
.msj--doctora .burbuja{
  background:var(--burbuja-doctora); border-left:3px solid var(--petroleo);
}
/* La cola: solo en el primer mensaje de una tanda. */
.msj--primero.msj--paciente .burbuja{border-top-left-radius:0}
.msj--primero.msj--bot .burbuja,
.msj--primero.msj--doctora .burbuja{border-top-right-radius:0}

.burbuja__texto{
  font-family:var(--fuente-texto); font-size:var(--t-mensaje);
  line-height:var(--t-mensaje-alt); color:var(--txt-fuerte);
  white-space:pre-wrap; overflow-wrap:anywhere; margin:0;
}
.burbuja__texto b{font-weight:600}
.burbuja__pie{
  display:flex; align-items:center; justify-content:flex-end; gap:var(--e-2);
  margin-top:2px;
}
.sello{
  font-family:var(--fuente-dato); font-size:var(--t-sello); color:var(--sello);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
/* La etiqueta de la doctora es OBLIGATORIA: el tono solo la separa de la
   burbuja del bot por 1.10:1, que no es una senal confiable. */
.etiqueta-autor{
  font-family:var(--fuente-dato); font-size:10px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--petroleo); margin-bottom:3px;
}
.entrega{
  font-family:var(--fuente-dato); font-size:10px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--sello);
}
.entrega--no{color:var(--alerta-claro)}
.burbuja--no-salio{border-left:3px solid var(--alerta-claro)}
/* Lo que el paciente NO leyo (no salio, o el filtro lo corto) se ve apagado:
   la burbuja sigue ahi para auditar, pero no compite con la conversacion. */
.burbuja--no-salio .burbuja__texto{opacity:.62}

/* ── lo que salio por fuera de la conversacion ───────────────────────────
   El recordatorio, el instructivo de pago, la alerta a la doctora. Se alinea
   como el bot porque va en la misma direccion, pero con un tono aparte y la
   etiqueta obligatoria: leerlo como una respuesta del bot en esta charla hace
   entender mal la conversacion entera. Mismo criterio que la burbuja de la
   doctora, donde el color solo no alcanza. */
.msj--sistema{justify-content:flex-end}
.msj--sistema .burbuja{
  background:var(--hueso); border:1px dashed var(--linea);
  border-left:3px solid var(--verde);
}

/* ── lo que mandaste VOS desde el panel ──────────────────────────────────
   Lo escribio una persona a mano, igual que la burbuja de la doctora, y usa
   el mismo tono y el mismo filete: es la senal de "esto no lo decidio el
   bot". Lo que cambia es la etiqueta, que es obligatoria — el color solo
   nunca alcanza para distinguir dos burbujas del mismo lado. */
.msj--panel{justify-content:flex-end}
.msj--panel .burbuja{
  background:var(--burbuja-doctora); border-left:3px solid var(--petroleo);
}

/* El texto final, plegado. Se abre solo si alguien quiere verlo: el rotulo
   "salio recortado" ya dice lo que hay que saber. */
.final{margin-top:6px}
.final summary{
  font-family:var(--fuente-dato); font-size:10.5px; color:var(--sello);
  cursor:pointer; letter-spacing:.06em; text-transform:uppercase;
}
.final summary:focus-visible{outline:2px solid var(--verde); outline-offset:2px}
.final__texto{
  margin:6px 0 0; font-family:var(--fuente-texto); font-size:15px;
  line-height:1.45; color:var(--txt-fuerte);
  border-top:1px solid var(--linea); padding-top:6px;
}
.final__motivo{
  margin-top:6px; font-family:var(--fuente-dato); font-size:11px;
  color:var(--alerta-claro); overflow-wrap:anywhere;
}

/* Mensajes del sistema: centrados y en mono, nunca en serif. No son
   conversacion, son andamiaje. */
.dia{display:flex; justify-content:center; margin:var(--e-4) 0}
.dia span{
  background:var(--pastilla-sistema); border-radius:var(--r-campo);
  box-shadow:var(--sombra-burbuja); padding:4px 12px;
  font-family:var(--fuente-dato); font-size:var(--t-sello);
  letter-spacing:.1em; text-transform:uppercase; color:var(--sello);
}
.evento{
  display:flex; align-items:center; gap:var(--e-3); margin:var(--e-4) 0;
  font-family:var(--fuente-dato); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--txt-suave);
}
.evento::before,.evento::after{
  content:""; flex:1 1 auto; height:1px; background:var(--linea);
}
.evento--alerta{color:var(--alerta-claro)}
.evento--alerta::before,.evento--alerta::after{background:var(--alerta-claro)}

.adjunto{
  display:block; max-width:100%; border-radius:var(--r-campo);
  margin-bottom:var(--e-2);
}
.adjunto--hueco{
  font-family:var(--fuente-dato); font-size:12px; color:var(--sello);
  border:1px dashed var(--linea); border-radius:var(--r-campo);
  padding:var(--e-3); text-align:center;
}
.adjunto--imagen{cursor:zoom-in; max-height:340px; object-fit:cover; width:100%}
.adjunto--video{max-height:340px; background:#000}
.adjunto-caja{margin-bottom:var(--e-2)}
/* El reproductor nativo: es el que ya sabe usar cualquiera, trae la barra, la
   velocidad y el volumen del sistema, y no hay que mantenerlo. Solo se le da
   el ancho de la burbuja y una altura pareja. */
.adjunto-audio{display:block; width:100%; min-width:220px; height:40px}
.adjunto-archivo{
  display:block; font-family:var(--fuente-dato); font-size:12px;
  color:var(--petroleo); text-decoration:none;
  border:1px solid var(--linea); border-radius:var(--r-campo);
  padding:var(--e-3); margin-bottom:var(--e-2); text-align:center;
  overflow-wrap:anywhere;
}
.adjunto-archivo:hover{background:var(--petroleo); color:var(--hueso); border-color:var(--petroleo)}

/* ── la lupa: la imagen a pantalla completa ──────────────────────────────
   Se muestra y se oculta con el atributo `hidden`, nunca con style.display:
   la CSP del panel no tiene 'unsafe-inline' y un estilo embebido lo bloquea
   el navegador EN SILENCIO. */
.lupa-capa{
  position:fixed; inset:0; z-index:50; display:flex;
  align-items:center; justify-content:center;
  background:rgba(7,39,35,.94); padding:var(--e-4); cursor:zoom-out;
}
.lupa-capa[hidden]{display:none}
.lupa-img{
  max-width:100%; max-height:100%; object-fit:contain; cursor:default;
  border-radius:var(--r-campo);
}
.lupa-cerrar{
  position:absolute; top:var(--e-4); right:var(--e-4);
  font-family:var(--fuente-dato); font-size:var(--t-rotulo);
  letter-spacing:var(--track-rotulo); text-transform:uppercase;
  color:var(--hueso); background:none; border:1px solid var(--hueso);
  border-radius:999px; padding:6px 14px; cursor:pointer;
}
.lupa-cerrar:hover{background:var(--hueso); color:var(--petroleo)}

/* ── estado vacio ── */
.vacio{
  flex:1 1 auto; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; padding:var(--e-8);
  background:var(--hueso-puro); position:relative; overflow:hidden;
}
.vacio__marca{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:220px; height:220px; opacity:.07; pointer-events:none;
}
.vacio__titulo{
  font-weight:600; font-size:var(--t-titulo); color:var(--txt-titulo);
  margin:0 0 var(--e-3); position:relative;
}
.vacio__copy{
  font-family:var(--fuente-texto); font-size:16px; color:var(--txt-medio);
  max-width:46ch; margin:0; position:relative;
}
.vacio__aviso{
  margin-top:var(--e-6); padding-top:var(--e-4);
  border-top:1px solid var(--linea); font-family:var(--fuente-dato);
  font-size:11px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--txt-suave); position:relative;
}

/* ── panel de detalle tecnico ── */
.detalle{
  flex:0 0 var(--ancho-detalle); background:var(--fondo-detalle);
  color:var(--txt-inv); overflow-y:auto; min-height:0;
  font-family:var(--fuente-dato); font-size:var(--t-dato);
}
/* Los dos titulos del panel: el del consultorio y el de la conversacion.
   Antes los dos usaban .detalle__cabecera y salian IDENTICOS a los rotulos de
   la columna izquierda —mismo cuerpo, mismo color, mismo fondo— asi que las
   dos listas se leian como una sola tira de veinte filas y no se veia donde
   terminaba una cosa y empezaba la otra. Y los dos eran sticky con top:0, con
   lo cual al scrollear el de abajo se subia encima del de arriba.
   Ahora los dos son una banda: fondo un paso mas claro que el panel y el
   titulo en hueso lleno, para que se lean como titulo y no como una fila mas.
   Son pares a proposito: si solo se destacara el de abajo, la subseccion
   pesaria mas que el encabezado. */
.detalle__cabecera,
.detalle__seccion{
  padding:var(--e-3) var(--e-4) 11px;
  background:var(--petroleo);
  border-bottom:1px solid var(--linea-oscura);
}
.detalle__cabecera .rotulo,
.detalle__seccion .rotulo{color:var(--txt-inv); font-weight:600}
/* La de arriba es UNA sola y se queda pegada; la de adentro no, porque dos
   sticky en top:0 se pisan. */
.detalle__cabecera{position:sticky; top:0; z-index:1}
/* Y el corte propiamente dicho: aire arriba y un filete verde. El verde va de
   filete, nunca de texto (MARCA.md). */
.detalle__seccion{
  margin-top:var(--e-5);
  border-top:2px solid var(--verde);
}
.detalle__fila{
  display:flex; justify-content:space-between; gap:var(--e-3);
  padding:9px var(--e-4); border-bottom:1px solid var(--linea-oscura);
}
.detalle__fila:hover{background:var(--petroleo-700)}
.detalle__rotulo{
  color:var(--txt-rotulo); font-size:var(--t-rotulo);
  letter-spacing:var(--track-rotulo); text-transform:uppercase; flex:0 0 auto;
}
.detalle__valor{
  color:var(--txt-inv); text-align:right; overflow-wrap:anywhere;
  font-variant-numeric:tabular-nums;
}
.detalle__valor--suave{color:var(--txt-inv-2)}
.detalle__nota{
  padding:var(--e-3) var(--e-4); color:var(--txt-inv-2); font-size:11.5px;
  line-height:1.5;
}

/* ── el detras de escena de un mensaje ──────────────────────────────────
   El boton vive en el pie de la burbuja, en el lado claro, y tiene que
   distinguirse del sello de la hora sin gritar: es una puerta que casi nunca
   se abre. */
.lupa{
  font-family:var(--fuente-dato); font-size:10px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--sello);
  background:none; border:1px solid var(--linea); border-radius:999px;
  padding:1px 8px; cursor:pointer; line-height:1.6;
}
.lupa:hover{background:var(--petroleo); color:var(--hueso); border-color:var(--petroleo)}
.lupa:focus-visible{outline:2px solid var(--petroleo); outline-offset:2px}

.detras__bloque{
  padding:var(--e-3) var(--e-4); border-bottom:1px solid var(--linea-oscura);
}
.detras__pre{
  margin:6px 0 0; white-space:pre-wrap; overflow-wrap:anywhere;
  font-family:var(--fuente-dato); font-size:11.5px; line-height:1.55;
  color:var(--txt-inv);
  /* Tope de alto: un resultado de `terminal` puede ser el volcado entero de un
     script, y sin esto el panel se convierte en una tira infinita donde no se
     encuentra nada. */
  max-height:340px; overflow-y:auto;
  background:var(--petroleo); border-radius:var(--r-campo);
  padding:var(--e-3);
}

/* ── semaforo: PUNTO + PALABRA. El color vive en el punto, nunca en la
      palabra. Y cada estado lleva forma, no solo color: circulo lleno = OK,
      anillo hueco = esperando, cuadrado = frenado. Sobrevive al daltonismo y
      a una pantalla mala con luz de consultorio. ── */
.punto{
  width:var(--punto-estado); height:var(--punto-estado); border-radius:50%;
  flex:0 0 auto; display:inline-block;
}
.punto--ok{background:var(--ok-claro)}
.punto--att{background:transparent; border:2px solid var(--att-claro); border-radius:50%}
.punto--alerta{background:var(--alerta-claro); border-radius:1px}
.punto--sin{background:transparent; border:2px solid var(--gris); border-radius:50%}
.oscuro .punto--ok{background:var(--ok-oscuro)}
.oscuro .punto--att{border-color:var(--att-oscuro)}
.oscuro .punto--alerta{background:var(--alerta-oscuro)}
.chip{
  display:inline-flex; align-items:center; gap:6px; padding:3px 9px;
  border-radius:var(--r-chip); font-family:var(--fuente-dato);
  font-size:var(--t-sello); color:var(--txt-fuerte); background:var(--chip-ok);
}
.chip--att{background:var(--chip-att)}
.chip--alerta{background:var(--chip-alerta)}

/* ── el cajon para responder ─────────────────────────────────────────────
   Es lo unico de la pantalla que sale hacia afuera, asi que se lee como una
   pieza aparte del hilo: fondo claro, filete arriba, y el destinatario en
   mono para que no se confunda con un mensaje de la conversacion. */
.responder{
  flex:0 0 auto; background:var(--hueso-puro);
  border-top:1px solid var(--linea); padding:var(--e-3);
}
.responder[hidden]{display:none}
.responder__quien{
  display:flex; align-items:center; gap:var(--e-2); margin-bottom:6px;
}
.responder__dest{
  font-family:var(--fuente-dato); font-size:12px; color:var(--txt-fuerte);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.responder__caja{display:flex; gap:var(--e-2); align-items:flex-end}
.responder__texto{
  flex:1 1 auto; resize:vertical; min-height:44px; max-height:180px;
  padding:9px 12px; border:1px solid var(--linea);
  border-radius:var(--r-campo); background:var(--hueso);
  font-family:var(--fuente-texto); font-size:15px; line-height:1.4;
  color:var(--txt-fuerte);
}
.responder__texto:focus-visible{outline:2px solid var(--verde); outline-offset:2px}
.responder__caja .boton{flex:0 0 auto; width:auto; padding:11px 18px}
.responder__nota{
  margin:6px 0 0; font-family:var(--fuente-dato); font-size:11px;
  color:var(--sello); line-height:1.45;
}
/* Frenado: el boton queda en Petroleo pleno, que es el unico recurso de
   jerarquia de la marca. Prendido se ve prendido. */
.boton--activo{
  background:var(--petroleo); color:var(--hueso); border-color:var(--petroleo);
}

/* ── el filtro de "sin contestar" ───────────────────────────────────────
   Vive entre el buscador y la lista, y solo existe cuando hay algo que
   filtrar (lo oculta el JS con `hidden`, no con style). */
.filtros{
  flex:0 0 auto; display:flex; gap:var(--e-2);
  padding:0 var(--e-3) var(--e-3); border-bottom:1px solid var(--linea);
}
.filtros[hidden]{display:none}
.filtro{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  padding:5px 11px; border:1px solid var(--linea);
  border-radius:var(--r-chip); background:var(--hueso);
  font-family:var(--fuente-dato); font-size:var(--t-sello);
  color:var(--txt-fuerte);
}
.filtro:hover{background:var(--fila-hover)}
.filtro:focus-visible{outline:2px solid var(--verde); outline-offset:2px}
/* Prendido: Petroleo pleno, que es el unico recurso de jerarquia de la marca.
   El texto va en Hueso (10.49:1) y el punto pasa al rojo de fondo oscuro. */
.filtro--activo{
  background:var(--petroleo); border-color:var(--petroleo); color:var(--hueso);
}
.filtro--activo .punto--alerta{background:var(--alerta-oscuro)}

/* La fila sin contestar lleva filete izquierdo, no color de fondo: el fondo
   compite con el resaltado de la fila activa y se pierden los dos. */
.fila--sin-contestar{box-shadow:inset 3px 0 0 var(--alerta-claro)}

/* ── carga ── */
.cargando{
  position:fixed; inset:0; background:var(--petroleo); display:flex;
  align-items:center; justify-content:center; z-index:var(--z-modal);
}
.cargando img{width:72px; height:72px; animation:latir 2s ease-in-out infinite}


/* ── Clases que existen porque la CSP no tiene 'unsafe-inline' ──────────
   Ni un `style=` en el HTML ni un `elemento.style.x = ...` desde JS pasan la
   politica: los dos escriben el atributo style y el navegador los bloquea EN
   SILENCIO (se ve solo en la consola). Cada una de estas clases reemplaza un
   estilo embebido que se intento y quedo bloqueado. */
.cabecera__caja{min-width:0}
.boton--claro-borde{color:var(--petroleo); border-color:var(--linea)}
.boton--claro-borde:hover{background:var(--fila-hover)}
.nota-suave{color:var(--txt-suave)}
.nota-alerta{color:var(--alerta-claro)}

/* ═══════════════════════════════════════════════════════ CELULAR
   El panel se usa desde el telefono: es la razon por la que existe. En
   angosto se ve UNA pantalla a la vez —lista, hilo o detalle— y se navega
   con el boton Volver.

   ⚠️ Regla dura: el body NUNCA scrollea en horizontal. Lo que es ancho
   (la barra) recorta; lo que es largo (el hilo) scrollea en vertical.
   El nombre del consultorio se acorta con puntos suspensivos, pero no
   desaparece: en un panel multi-cliente no puede haber una pantalla donde
   no se sepa de que consultorio son los datos. */
@media (max-width: 900px){
  html,body{overflow-x:hidden}
  .cuerpo{flex-wrap:nowrap}

  /* La pantalla base en angosto es la LISTA, a todo el ancho. */
  .lista{
    flex:1 1 100%; width:100%; max-width:none; min-width:0; border-right:0;
  }
  .hilo-col,.detalle,.vacio{display:none}

  /* Aca si: en el celular las columnas se pisan y hacen falta. */
  #ver-detalle{display:inline-flex}
  body.viendo-chat .volver,body.viendo-detalle .volver{display:inline-flex}
  body.viendo-chat .lista{display:none}
  body.viendo-chat .hilo-col{display:flex; flex:1 1 100%; min-width:0}

  body.viendo-detalle .lista{display:none}
  body.viendo-detalle .hilo-col{display:none}
  body.viendo-detalle .detalle{display:block; flex:1 1 100%; min-width:0}

  /* La barra recorta en vez de empujar. */
  .barra{gap:var(--e-2); padding:0 var(--e-3); overflow:hidden}
  .barra__marca{height:22px; flex:0 0 auto}
  .barra__grupo{min-width:0; flex:1 1 auto; overflow:hidden}
  .selector{max-width:100%; font-size:14px; padding-right:22px}
  .rotulo--esconder{display:none}
  .barra__espacio{display:none}
  /* Del indicador de vivo sobrevive el anillo latiendo, que es la senal;
     la palabra se cae primero porque es la parte redundante. */
  #vivo-texto{display:none}
  .vivo{flex:0 0 auto}
  .boton--fantasma{flex:0 0 auto; padding:7px 10px; font-size:12px}

  .hilo{padding:12px 14px}
  .burbuja{max-width:86%}
  .cabecera{padding:var(--e-2) var(--e-3)}
  .detalle__fila{padding:11px var(--e-3)}
}

/* El grupo de la cuenta en la barra: cambiar la contrasena y salir. */
.barra__cuenta{display:flex; align-items:center; gap:var(--e-2); flex:0 0 auto}

/* Pantallas muy angostas: se cae tambien el grupo de la cuenta del
   encabezado. Los dos botones siguen estando en el panel de detalle. */
@media (max-width: 430px){
  .barra__filete{display:none}
  .barra__cuenta{display:none}
}

/* ═══════════════════════════════════════════════ LA APP INSTALADA (iPhone)
   Cuando el panel se abre desde el icono de la pantalla de inicio, la pagina
   ocupa el telefono ENTERO: llega hasta abajo del reloj y hasta abajo de la
   raya del gesto de inicio. Eso es lo que pedimos con `viewport-fit=cover` y
   `apple-mobile-web-app-status-bar-style: black-translucent`, y se ve bien
   —la hora queda apoyada sobre la barra Petroleo— SOLO si aca se reserva el
   hueco. Sin esto, el logo de DENTRO queda tapado por el reloj y el boton
   Enviar cae abajo de la raya del gesto: se toca y el telefono cierra la app.

   ⚠️ `env(safe-area-inset-*)` vale 0 en una computadora y en un telefono sin
   muesca, asi que estas reglas no cambian nada fuera del iPhone. Y si el
   navegador no entiende `env()`, descarta la declaracion entera y queda la
   de arriba, que es la que habia: no hay forma de que esto rompa algo.

   ⚠️ Los tres elementos de abajo son LOS TRES QUE TOCAN EL BORDE INFERIOR,
   uno por pantalla del celular: la lista, el hilo con su cajon de respuesta,
   y el panel tecnico. Si manana se agrega una cuarta pantalla, va aca. */
.barra{
  padding-top:env(safe-area-inset-top);
  height:calc(var(--alto-barra) + env(safe-area-inset-top));
  padding-left:calc(var(--e-4) + env(safe-area-inset-left));
  padding-right:calc(var(--e-4) + env(safe-area-inset-right));
}
/* El cajon de respuesta: lo que no puede quedar abajo de la raya es el boton
   Enviar, porque un toque ahi no manda el mensaje — cierra la app. */
.responder{
  padding-bottom:calc(var(--e-3) + env(safe-area-inset-bottom));
  padding-left:calc(var(--e-3) + env(safe-area-inset-left));
  padding-right:calc(var(--e-3) + env(safe-area-inset-right));
}
/* La ultima fila de la lista tiene que poder tocarse. */
.lista__scroll{padding-bottom:env(safe-area-inset-bottom)}
.detalle{padding-bottom:env(safe-area-inset-bottom)}

@media (max-width: 900px){
  /* En angosto la barra ya recorta con --e-3; se le suma el borde igual. */
  .barra{
    padding-left:calc(var(--e-3) + env(safe-area-inset-left));
    padding-right:calc(var(--e-3) + env(safe-area-inset-right));
  }
}

/* El login y la pantalla de sin conexion son una sola caja centrada: alcanza
   con que el padding respete los cuatro bordes. */
.login{
  padding-top:calc(var(--e-6) + env(safe-area-inset-top));
  padding-bottom:calc(var(--e-6) + env(safe-area-inset-bottom));
  padding-left:calc(var(--e-6) + env(safe-area-inset-left));
  padding-right:calc(var(--e-6) + env(safe-area-inset-right));
}
