:root {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --app-height: 100dvh;
}

html {
  min-height: 100%;
  background: var(--paper, #f4f1ea);
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100svh;
  min-height: var(--app-height);
}

.app-screen .app {
  min-height: var(--app-height);
}

.conversation-screen .app,
.conversation-screen .main {
  height: var(--app-height) !important;
  min-height: 0;
}

.app-screen .side {
  padding-top: calc(22px + var(--safe-top));
  padding-bottom: calc(14px + var(--safe-bottom));
  padding-left: calc(16px + var(--safe-left));
}

.app-screen .top {
  padding-top: calc(16px + var(--safe-top));
  padding-right: calc(22px + var(--safe-right));
  padding-left: calc(22px + var(--safe-left));
}

.conversation-screen .top {
  padding-top: calc(12px + var(--safe-top));
}

.conversation-screen .composer {
  padding-bottom: calc(16px + var(--safe-bottom));
}

.conversation-screen .contact-close {
  top: calc(10px + var(--safe-top));
  right: calc(12px + var(--safe-right));
  width: 44px;
  height: 44px;
}

.conversation-screen .side {
  height: var(--app-height) !important;
}

/* El contacto vive dentro del workspace, debajo de la cabecera. Darle otra
   pantalla completa empuja el compositor fuera del viewport en escritorio. */
.conversation-screen .contact {
  height: 100% !important;
  min-height: 0;
}

.overlay,
.conversation-screen .contact {
  padding-top: var(--safe-top);
  padding-right: var(--safe-right);
  padding-bottom: var(--safe-bottom);
  padding-left: var(--safe-left);
}

.toasts,
#toasts,
.toast {
  bottom: calc(18px + var(--safe-bottom));
}

.auth-screen {
  min-height: var(--app-height) !important;
  padding-top: max(24px, calc(5vh + var(--safe-top))) !important;
  padding-right: calc(24px + var(--safe-right)) !important;
  padding-bottom: max(24px, calc(5vh + var(--safe-bottom))) !important;
  padding-left: calc(24px + var(--safe-left)) !important;
  overflow-y: auto;
}

.hub-screen {
  min-height: var(--app-height) !important;
  padding-top: max(28px, calc(6vh + var(--safe-top))) !important;
  padding-right: calc(24px + var(--safe-right)) !important;
  padding-bottom: calc(32px + var(--safe-bottom)) !important;
  padding-left: calc(24px + var(--safe-left)) !important;
}

.mobile-nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line, #d9d3c7);
  border-radius: 12px;
  background: var(--card, #fbfaf6);
  color: var(--ink, #15201b);
  font: inherit;
}

@media (max-width: 820px) {
  .app-screen:not(.conversation-screen) .mobile-nav-toggle {
    display: inline-flex;
  }

  .app-screen:not(.conversation-screen) .top {
    min-height: calc(68px + var(--safe-top));
    padding: calc(10px + var(--safe-top)) calc(14px + var(--safe-right)) 10px calc(14px + var(--safe-left));
  }

  .app-screen:not(.conversation-screen) .side {
    display: flex !important;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 80;
    width: min(82vw, 280px);
    height: var(--app-height);
    transform: translateX(-105%);
    transition: transform .22s ease;
    box-shadow: 18px 0 44px rgba(0, 0, 0, .24);
  }

  .app-screen.mobile-nav-open:not(.conversation-screen) .side {
    transform: translateX(0);
  }

  .app-screen.mobile-nav-open:not(.conversation-screen)::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 70;
    background: rgba(8, 20, 14, .42);
  }

  .app-screen:not(.conversation-screen) .wrap {
    padding-right: calc(18px + var(--safe-right));
    padding-bottom: calc(50px + var(--safe-bottom));
    padding-left: calc(18px + var(--safe-left));
  }

  .app-screen table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  button,
  .btn,
  select,
  input {
    min-height: 44px;
  }
}

@media (max-width: 780px) {
  .conversation-screen .top {
    padding: calc(9px + var(--safe-top)) calc(12px + var(--safe-right)) 9px calc(12px + var(--safe-left));
  }

  .conversation-screen .mobile-bar {
    min-height: 56px;
    padding-right: calc(8px + var(--safe-right)) !important;
    padding-left: calc(8px + var(--safe-left)) !important;
  }

  .conversation-screen .composer {
    padding-right: calc(12px + var(--safe-right));
    padding-left: calc(12px + var(--safe-left));
  }

  /* iOS amplía automáticamente controles con fuente menor a 16px. Ese zoom es
     lo que descuadra el chat al enfocar el compositor — y hace saltar el zoom
     al enfocar cualquier campo (login, ajustes, agenda…). Se fuerza 16px en
     TODAS las pantallas del CRM para que iOS no haga zoom. Se excluyen los
     inputs de tamaño fijo pequeño que no reciben foco de texto (checkbox/radio). */
  .app-screen input:not([type=checkbox]):not([type=radio]),
  .app-screen textarea,
  .app-screen select,
  .auth-screen input,
  .auth-screen select,
  .hub-screen input {
    /* `max` y no un valor fijo: la escala tipográfica puede agrandarlo, pero
       nunca bajarlo de 16px, o iOS haría zoom al enfocarlo. */
    font-size: max(16px, calc(16px * var(--fs, 1))) !important;
    touch-action: manipulation;
  }

  /* Con el teclado abierto se conserva la cabecera propia del chat y se quita
     la barra global; el compositor ocupa una posición estable sobre el teclado.
     Se exige `chat-open`: en la bandeja la barra global reserva el hueco de la
     barra de estado, y si `keyboard-open` se quedara pegado la lista subiría
     debajo del reloj. */
  .conversation-screen.chat-open.keyboard-open .top {
    display: none;
  }

  .conversation-screen.chat-open.keyboard-open .composer {
    padding-top: 8px;
    padding-bottom: 8px;
  }

  .conversation-screen.chat-open.keyboard-open .human-banner,
  .conversation-screen.chat-open.keyboard-open .draftbar {
    display: none !important;
  }
}

@supports not (height: 100dvh) {
  :root { --app-height: 100vh; }
}

/* =======================================================================
   TACTO
   ======================================================================= */

* {
  /* el recuadro gris que iOS pinta al tocar cualquier cosa */
  -webkit-tap-highlight-color: transparent;
  /* el menú de "mantener pulsado" (copiar/compartir) donde no toca */
  -webkit-touch-callout: none;
}

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

/* `manipulation` desactiva el doble-tap-zoom, que es lo que introduce la espera
   de ~300 ms antes de que llegue el `click`. Antes solo estaba en los campos. */
a, button, [role="button"], label, summary, select,
.tappable, .chat-item, .bub, .tab, .seg button {
  touch-action: manipulation;
}

a, button, [role="button"], .tappable, .chat-item {
  -webkit-user-select: none; user-select: none;
  -webkit-user-drag: none;
}

/* …pero el contenido del chat SÍ se selecciona y se comparte: es su función. */
.bub-text, .quotebar-text, .cc-tel, .poll-q, input, textarea, [data-selectable] {
  -webkit-user-select: text; user-select: text;
  -webkit-touch-callout: default;
}
.lightbox img, .media-img img { -webkit-touch-callout: default; }

/* El rebote al final del hilo no debe arrastrar la página ni disparar
   pull-to-refresh. `overflow-anchor` no sirve: WebKit no lo implementa. */
.thread, #chatList, .chats { overscroll-behavior: contain; }

/* --- Feedback de pulsación -------------------------------------------
   `.is-pressed` la pone y la quita mobile-shell.js en pointerdown/up.
   `:active` queda de respaldo para ratón y por si el JS no cargó. */
button, a, [role="button"], .tappable {
  transition: transform var(--dur-tap) var(--ease-standard),
              background-color var(--dur-tap) linear;
}
button.is-pressed, a.is-pressed, [role="button"].is-pressed, .tappable.is-pressed,
button:active, a:active, [role="button"]:active, .tappable:active {
  transform: scale(.97);
  transition-duration: 0s;   /* al presionar, sin animación: respuesta en 0 ms */
}
/* Controles grandes: el hundido se nota más si se escala un poco más. */
.send.is-pressed, .sp-send.is-pressed, .send:active, .sp-send:active { transform: scale(.92); }
/* La fila de la lista lleva su propio transform (el swipe sigue al dedo):
   nunca la escalamos, solo cambia el fondo. */
.chat-item.is-pressed { background: var(--paper-2); transition-duration: 0s; }
/* El botón "ir al final" usa transform para aparecer; le damos el suyo. */
.jump-bottom.is-pressed, .jump-bottom:active { transform: scale(.92); }
/* Escape para elementos que no deben hundirse al tocarlos. */
.no-press.is-pressed, .no-press:active { transform: none; }

/* --- Área táctil de 44 px sin agrandar el botón -----------------------
   Apple pide 44×44 pt. Se extiende la zona sensible con un pseudo-elemento
   invisible; el icono se ve igual. Solo en pantallas táctiles. */
@media (pointer: coarse) {
  /* `.jump-bottom` ya es `position:absolute`: ponerle `relative` lo devolvía al
     flujo y abría un hueco de 44 px sobre el hilo. Solo se le añade el ::after. */
  .cbtn, .mbtn, .sp-close { position: relative; }
  .cbtn::after, .mbtn::after, .jump-bottom::after, .sp-close::after {
    content: ""; position: absolute; inset: -4px;
  }
  /* Los botones redondos de la bandeja miden 36-38 px para no recargar la
     cabecera; el area sensible se extiende hasta los 44 sin deformarlos.
     `position:relative` en el boton NO es opcional: sin el, el ::after se ancla
     al ancestro posicionado mas cercano y `inset:-4px` lo convierte en una
     lamina invisible que tapa media cabecera y se traga los toques. */
  .me, .hamb-m, .icon-btn, .new-chat-btn { position: relative; }
  .me::after, .hamb-m::after, .icon-btn::after, .new-chat-btn::after {
    content: ""; position: absolute; inset: -4px;
  }
}

/* --- Movimiento reducido ---------------------------------------------
   0.01ms y no 0s a propósito: con 0s algunos navegadores no disparan
   `transitionend`, y el JS que espera ese evento se queda colgado. */
@media (prefers-reduced-motion: reduce) {
  html:focus-within { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   Barra inferior de navegación compartida (.ms-tabbar)
   La inyecta mobile-shell.js en todas las páginas del /app SALVO operador.html
   (que trae la suya, #navBar). Misma apariencia que aquella: pastilla flotante.
   Solo en móvil, justo donde .side se oculta (≤820px). auth.js oculta por CSS
   los enlaces solo-admin, así que el operador ve una barra recortada sola.
   ============================================================================ */
.ms-tabbar { display: none; }

@media (max-width: 820px) {
  .ms-tabbar {
    position: fixed;
    left: 10px; right: 10px;
    bottom: calc(6px + var(--safe-bottom, 0px));
    z-index: 40;
    display: flex;
    justify-content: space-around;
    padding: 6px 4px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 20px;
    box-shadow: var(--shadow);
  }
  .ms-tabbar .ms-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 6px 2px;
    text-decoration: none;
    color: var(--ink-soft);
    font-size: calc(9.5px * var(--fs, 1));
    font-weight: 600;
    border-radius: 14px;
  }
  .ms-tabbar .ms-tab svg { width: 21px; height: 21px; }
  .ms-tabbar .ms-tab.on { color: var(--nav-active-ink); }
  .ms-tabbar .ms-tab.on svg { stroke-width: 2.3; }

  /* Deja aire al final para que la barra no tape el último contenido. */
  body.has-tabbar .wrap { padding-bottom: calc(100px + var(--safe-bottom, 0px)); }
}
