    /* ---- Stat cards: pasteles con texto oscuro ---- */
    .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
    .stat-card {
      border-radius: var(--radius-lg); padding: 1.15rem 1.3rem; color: var(--text);
      box-shadow: var(--shadow); background: var(--card-bg);
    }
    .stat-card .label { font-size: .85rem; color: #6d7280; }
    .stat-card .value { font-size: 2rem; font-weight: 800; margin-top: .25rem; }
    .stat-card.green  { background: #e3f7f0; }
    .stat-card.blue   { background: #efeafc; }
    .stat-card.orange { background: #fdeedd; color: var(--text); }
    .stat-card.red    { background: #fde7ef; }

    /* ---- Cards / panels ---- */
    .card {
      background: var(--card-bg); border-radius: var(--radius-lg); box-shadow: var(--shadow);
      padding: 1.3rem 1.5rem; margin-bottom: 1.4rem;
    }
    /* El primer h2 de un panel titula el panel: el margen de arriba sobra. */
    .card > h2:first-child { margin-top: 0; }
    /* Segundo nivel: lo que vive DENTRO de una .card (cada cobro, cada ítem de
       una lista). Borde en vez de sombra — sombra sobre sombra se lee como dos
       paneles del mismo rango y se pierde la jerarquía. */
    .tile {
      background: var(--card-bg); border: 1px solid var(--border);
      border-radius: var(--radius); padding: 1rem 1.15rem; margin-bottom: .75rem;
    }
    .tile:last-child { margin-bottom: 0; }

    /* ---- Filter pills ---- */
    .pills { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
    .pills a {
      text-decoration: none; color: var(--text-muted); background: var(--card-bg);
      border: var(--btn-border-width) solid var(--btn-border);
      border-radius: 999px; padding: .45rem 1rem; min-height: 40px;
      display: inline-flex; align-items: center; font-size: .85rem; box-shadow: var(--shadow);
    }
    .pills a:hover { color: var(--text); }
    .pills a[aria-current="true"] { background: var(--lime); color: var(--lime-ink); font-weight: 700; }

    /* Filas con destino (data-href): toda la fila navega, como las tarjetas
       de conversación. El JS de delegación vive en base.html. */
    tbody tr[data-href] { cursor: pointer; }

    /* ---- Botón de navegación entre páginas (pill del ERP, hover lima) ---- */
    .btn-nav {
      display: inline-flex; align-items: center; gap: .4rem;
      background: var(--card-bg); color: var(--text); text-decoration: none;
      padding: .45rem 1rem; min-height: 40px; border-radius: 999px;
      border: var(--btn-border-width) solid var(--btn-border);
      box-shadow: var(--shadow); font-size: .88rem; font-weight: 600;
    }
    .btn-nav:hover { background: var(--lime); color: var(--lime-ink); }

    /* ---- Table (como la referencia: banda gris redondeada de encabezado,
       filas altas con alternado lila tenue) ---- */
    .table-wrap { overflow-x: auto; border-radius: 14px; }
    /* separate (no collapse): sin él, el border-radius de la banda del thead
       no se pinta. */
    table { border-collapse: separate; border-spacing: 0; width: 100%; }
    th, td { padding: .85rem .9rem; text-align: left; vertical-align: middle; }
    td { border-bottom: 1px solid #eef0f4; }
    thead th { background: #ececf0; color: #4a4f59; font-size: .85rem; font-weight: 600; }
    thead th:first-child { border-radius: 12px 0 0 12px; }
    thead th:last-child { border-radius: 0 12px 12px 0; }
    tbody tr:nth-child(even) { background: #f7f8fd; }
    tbody tr:hover { background: #f4f6f2; }

    /* ---- Paginación (píldoras numeradas, activa en lima, flechas en círculo) ---- */
    .pagination {
      display: inline-flex; align-items: center; gap: .45rem;
      background: rgba(236, 237, 240, .9); border-radius: 999px;
      padding: .4rem .5rem; margin-top: 1rem; box-shadow: var(--shadow);
    }
    .pagination a, .pagination .page-off {
      min-width: 38px; height: 38px; padding: 0 .55rem; border-radius: 999px;
      display: inline-flex; align-items: center; justify-content: center;
      text-decoration: none; color: var(--text); font-size: .88rem; font-weight: 600;
    }
    .pagination a { background: #f6f7f9; border: 1px solid #e3e4e9; }
    .pagination a:hover { background: #fff; }
    .pagination a[aria-current="page"] { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); }
    .pagination .page-arrow { background: #fff; border: 0; box-shadow: var(--shadow); }
    /* Flecha sin destino (primera/última página): visible pero apagada. */
    .pagination .page-off { color: #a2a7b0; }

    .avatar {
      display: inline-flex; align-items: center; justify-content: center;
      width: 36px; height: 36px; border-radius: 50%; color: #fff; font-weight: 700; font-size: .8rem;
      margin-right: .6rem; flex-shrink: 0;
    }
    .cell-person { display: flex; align-items: center; }
    .cell-person .sub { color: var(--text-muted); font-size: .8rem; }

    /* ---- Badges (estados con color + texto, como la referencia) ---- */
    .badge {
      display: inline-block; padding: .25rem .7rem; border-radius: 999px;
      font-size: .75rem; font-weight: 700; letter-spacing: .3px;
    }
    .badge.nuevo      { background: #fde7ef; color: #be1e51; }
    .badge.tomado     { background: #fdeedd; color: #92590a; }
    .badge.en_proceso { background: #e6ecfd; color: #1d4fd7; }
    .badge.cerrado    { background: #e3f7f0; color: #0b6e5d; }
    .badge.escalado   { background: #22242a; color: #ffd35c; }
    .badge.disponible { background: #e3f7f0; color: #0b6e5d; }
    .badge.ocupado    { background: #fdeedd; color: #92590a; }
    .badge.ausente    { background: #eef0f3; color: #666; }
    .badge.urgente    { background: #be1e51; color: #fff; }
    /* Canal: qué cuenta atiende esta conversación. El color NO es el único
       indicador — el texto dice el nombre del canal (WCAG 1.4.1). */
    .badge.canal-twilio { background: #e6ecfd; color: #1d4fd7; }
    .badge.canal-meta   { background: #e3f7f0; color: #0b6e5d; }

    /* ---- Forms & buttons ---- */
    label { display: block; margin-bottom: .35rem; font-size: .85rem; color: var(--text-muted); }
    input[type=text], input[type=password], input[type=tel], input[type=date], select, textarea {
      width: 100%; max-width: 320px; padding: .6rem .85rem; border: 1px solid var(--border);
      border-radius: 12px; font-size: .95rem; background: #fff; min-height: 44px; font-family: inherit;
    }
    textarea { max-width: none; min-height: 70px; resize: vertical; }
    input:focus, select:focus, textarea:focus {
      border-color: var(--blue); outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 235, .13);
    }
    /* Borde oliva en los botones de acción: el primario oscuro, los claros
       (.btn-sm), los de navegación (.btn-nav) y los filtros (.pills a).
       Las variantes de color (.btn-approve, .btn-ignore, .btn-danger,
       .btn-ghost) conservan su propio borde, y el menú lateral no se toca
       porque son enlaces de `.sidebar nav`. */
    button {
      background: #22242a; color: #fff; border-radius: 999px;
      border: var(--btn-border-width) solid var(--btn-border);
      padding: .6rem 1.4rem; font-size: .92rem; font-weight: 600; cursor: pointer; min-height: 44px;
    }
    button:hover { background: #3a3d45; }
    .btn-sm {
      /* border-radius aquí y no solo en `button`: la clase también viste
         <a> y <summary> (p.ej. "Restablecer contraseña" en /users), que sin
         esto salían con esquinas cuadradas. */
      border-radius: 999px;
      padding: .35rem 1rem; font-size: .82rem; min-height: 36px;
      background: var(--card-bg); color: var(--text); box-shadow: var(--shadow);
      border: var(--btn-border-width) solid var(--btn-border);
    }
    .btn-sm:hover { background: var(--lime); color: var(--lime-ink); }
    /* Aprobar (verde) / Ignorar (gris): el color acompaña al ícono + texto,
       nunca es el único indicador. */
    .btn-approve { background: #e3f7f0; color: #0b6e5d; border: 1px solid #b3e6d5; }
    .btn-approve:hover { background: #cdf0e3; border-color: #93dbc3; color: #08533f; }
    .btn-ignore { background: #eef0f3; color: #4b5563; border: 1px solid #dcdfe4; }
    .btn-ignore:hover { background: #e1e4e9; border-color: #cbcfd6; color: #22242a; }
    .btn-danger { background: #fde7ef; color: #be1e51; border: 1px solid #f8cfdd; }
    .btn-danger:hover { background: #fbd3e1; border-color: #f3b6cc; color: #a01141; }
    .btn-ghost { background: transparent; color: var(--blue-2); border: 1px solid var(--blue); }
    .btn-ghost:hover { background: #e6ecfd; }
    .error {
      background: #fde7ef; color: #be1e51; border-radius: 12px; padding: .75rem 1rem; margin-bottom: 1rem;
    }

    /* ---- Inbox ---- */
    .convo-list { display: flex; flex-direction: column; gap: .6rem; }
    .convo-card {
      display: flex; align-items: center; gap: .75rem; text-decoration: none; color: inherit;
      background: var(--card-bg); border: 1px solid transparent; border-radius: var(--radius);
      padding: .8rem 1rem; box-shadow: var(--shadow);
    }
    .convo-card:hover { border-color: var(--lime); }
    .convo-card .body { flex: 1; min-width: 0; }
    .convo-card .preview {
      color: var(--text-muted); font-size: .85rem; white-space: nowrap;
      overflow: hidden; text-overflow: ellipsis;
    }
    .convo-card .when { color: var(--text-muted); font-size: .78rem; flex-shrink: 0; align-self: flex-start; }
    .convo-card .badges { display: flex; gap: .35rem; margin-top: .3rem; flex-wrap: wrap; }
    .badge.esperando { background: #fdeedd; color: #92590a; }
    .badge.caducada  { background: #fde7ef; color: #be1e51; }
    .badge.pausado   { background: #22242a; color: #9fd8ff; }
    .badge.asignada  { background: #eef0f3; color: #444; }

    /* ---- Composer (estilo WhatsApp: adjuntar + escribir + enviar en una barra) ---- */
    .composer { border-top: 1px solid var(--border); padding-top: 1rem; margin-top: 1rem; }
    .composer .row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .5rem; }

    /* Texto solo para lectores de pantalla. Con clip (no display:none) para que
       el input de archivo siga siendo enfocable con teclado. */
    .sr-only {
      position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
      overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
    }

    .composer-bar { display: flex; align-items: flex-end; gap: .5rem; }
    /* La "píldora" que contiene clip + texto, como la barra de WhatsApp. */
    .composer-bar .field {
      flex: 1; min-width: 0; display: flex; align-items: flex-end; gap: .25rem;
      background: #fff; border: 1px solid var(--border); border-radius: 22px;
      padding: .2rem .2rem .2rem .35rem;
    }
    .composer-bar .field:focus-within {
      border-color: var(--blue); box-shadow: 0 0 0 3px rgba(37, 99, 235, .13);
    }
    .composer-bar textarea {
      flex: 1; min-width: 0; max-width: none; min-height: 40px; max-height: 140px;
      border: 0; background: transparent; resize: none; padding: .55rem .35rem;
      font: inherit; line-height: 1.4; overflow-y: auto;
    }
    .composer-bar textarea:focus { outline: none; box-shadow: none; border: 0; }

    /* Clip de adjuntar: botón redondo dentro de la barra. */
    .attach {
      display: inline-flex; align-items: center; justify-content: center;
      width: 40px; height: 40px; flex-shrink: 0; margin: 0; border-radius: 50%;
      font-size: 1.15rem; cursor: pointer; color: var(--text-muted);
      background: transparent; border: 1px solid transparent; line-height: 1;
    }
    .attach:hover { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); }
    /* El input real está oculto: el foco del teclado se refleja en el clip. */
    .composer-bar input[type=file]:focus-visible + .field .attach { outline: 3px solid var(--blue); outline-offset: 2px; }

    .btn-send {
      flex-shrink: 0; background: #22242a; color: #fff; border-radius: 999px;
      border: var(--btn-border-width) solid var(--btn-border);
      padding: .6rem 1.3rem; min-height: 44px; font-weight: 600; cursor: pointer;
    }
    .btn-send:hover { background: #3a3d45; }

    /* Ficha del archivo adjunto: el color no es el único indicador (nombre,
       peso y botón de quitar con texto). */
    .attach-chip {
      display: flex; align-items: center; gap: .6rem; margin-top: .6rem;
      background: #eef7cf; border: 1px solid #dcf24c; border-radius: 14px;
      padding: .5rem .7rem; font-size: .85rem; color: var(--lime-ink);
    }
    /* Sin esto la regla de arriba (origen autor) le gana al [hidden] del
       navegador y queda una barra lima vacía bajo el composer para siempre. */
    .attach-chip[hidden] { display: none; }
    .attach-chip img { width: 40px; height: 40px; object-fit: cover; border-radius: 8px; }
    .attach-chip .name { font-weight: 700; word-break: break-all; }
    .attach-chip .peso { color: #55611f; }
    .attach-chip .chip-x {
      margin-left: auto; flex-shrink: 0; background: #fff; color: var(--text);
      border: 1px solid var(--border); border-radius: 999px; min-height: 32px;
      padding: .2rem .7rem; font-size: .8rem; cursor: pointer;
    }
    .attach-chip .chip-x:hover { background: #fde7ef; border-color: #f8cfdd; color: #be1e51; }
    /* #5f6572 sobre blanco = 5.85:1. Con --text-muted quedaba en 3.86:1, por
       debajo del 4.5:1 que pide WCAG AA para texto de este tamaño. */
    .composer-hint { color: #5f6572; font-size: .78rem; margin: .5rem 0 0; }
    .qr-bar { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: .5rem; }
    .qr-bar button {
      background: var(--card-bg); color: var(--text); border: 1px solid var(--border);
      padding: .3rem .9rem; font-size: .8rem; min-height: 36px;
    }
    .qr-bar button:hover { background: var(--lime); border-color: var(--lime); color: var(--lime-ink); }
    .banner-warn {
      background: #fdeedd; color: #92590a; border-radius: 12px; padding: .75rem 1rem; margin: .75rem 0;
    }
    /* Ventana cerrada: el compositor no está, así que este aviso ocupa su lugar
       y tiene que explicarse solo. Renglones separados y no un párrafo corrido
       — se lee de un vistazo entre chat y chat. */
    .banner-cerrada p { margin: 0 0 .5rem; line-height: 1.5; }
    .banner-cerrada p:last-child { margin-bottom: 0; }
    .banner-cerrada .banner-titulo { font-weight: 700; }
    /* Cuánto queda de ventana, junto al compositor. El color acompaña al texto:
       «Queda poco» y el icono dicen lo mismo sin depender del tono (WCAG 1.4.1).
       #5f6572 sobre blanco = 5.85:1; #be1e51 sobre #fde7ef ≈ 5:1, ambos por
       encima del 4.5:1 de AA. Sin animación a propósito: un aviso que parpadea
       toda la jornada cansa y obligaría a un `prefers-reduced-motion` que aquí
       no hace falta. */
    .window-note {
      display: flex; gap: .4rem; align-items: baseline; flex-wrap: wrap;
      color: #5f6572; font-size: .8rem; margin: 0 0 .5rem; line-height: 1.4;
    }
    .window-note strong { color: var(--text); font-weight: 700; }
    .window-note.urgente {
      background: #fde7ef; color: #be1e51; font-weight: 600;
      border-left: 4px solid #be1e51; border-radius: 8px; padding: .4rem .7rem;
    }
    .window-note.urgente strong { color: #be1e51; }
    .window-note .window-ico { flex-shrink: 0; }
    .bubble img { max-width: 220px; border-radius: 10px; display: block; margin-top: .3rem; }

    /* ---- Chat ---- */
    /* max-height y no height: un folio de tres mensajes no deja una caja vacía
       debajo. El panel scrollea solo, así el compositor no se va de pantalla. */
    .chat {
      display: flex; flex-direction: column; gap: .5rem;
      max-height: 58vh; overflow-y: auto; overscroll-behavior: contain;
      padding-right: .25rem;
    }
    .chat:focus-visible { outline: 2px solid var(--btn-border); outline-offset: 2px; }
    .chat-scope {
      display: flex; gap: .75rem; align-items: center; justify-content: space-between;
      flex-wrap: wrap; margin-bottom: .75rem; padding-bottom: .6rem;
      border-bottom: 1px solid var(--border);
    }
    .chat-scope .scope-label { margin: 0; display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
    .chat-scope .scope-note { color: var(--text-muted); font-size: .8rem; }
    .bubble {
      max-width: 70%; padding: .6rem .9rem; border-radius: 16px; line-height: 1.45;
      overflow-wrap: break-word;
    }
    .bubble .meta { display: block; font-size: .72rem; color: var(--text-muted); margin-top: .25rem; }
    .bubble.in  { background: #f0f1f4; align-self: flex-start; border-bottom-left-radius: 4px; }
    .bubble.out { background: #eef7cf; align-self: flex-end; border-bottom-right-radius: 4px; }

    /* ---- Login (sin sidebar) ---- */
    .login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; }
    .login-card { width: 100%; max-width: 380px; }
    .login-card input { max-width: none; }
    .login-card button { width: 100%; margin-top: .5rem; }

    .empty { color: var(--text-muted); padding: 2rem 0; text-align: center; }

/* Aviso de la auto-recarga en pausa (static/js/estado-vista.js). Fijo abajo a
   la izquierda: no tapa el compositor de mensajes ni los botones de acción.
   Es un role="status", así que el lector de pantalla lo anuncia sin robar el
   foco de quien está escribiendo. */
.auto-recarga-aviso {
  position: fixed;
  left: 1rem;
  bottom: 1rem;
  margin: 0;
  padding: .45rem .8rem;
  font-size: .78rem;
  background: var(--card, #fff);
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 999px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
  z-index: 40;
}

/* Texto solo para lector de pantalla: un encabezado de tabla que es únicamente
   un emoji no tiene nombre accesible, y su <title> no llega por teclado. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Una región con overflow necesita ser enfocable para poder desplazarla con el
   teclado (WCAG 2.1.1) — y si es enfocable, necesita contorno visible, o el
   arreglo crea una trampa de foco invisible. */
[tabindex]:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}
