:root {
    --azul: #1e3a8a;
    --azul-claro: #3b82f6;
    --verde: #16a34a;
    --amarillo: #ca8a04;
    --rojo: #dc2626;
    --morado: #7c3aed;
    --naranja: #ea580c;
    --gris: #6b7280;
    --bg: #f4f6fb;
    --texto: #1f2937;
    --borde: #e2e8f0;
}
* { box-sizing: border-box; }
body {
    margin: 0;
    font-family: 'Segoe UI', system-ui, sans-serif;
    background: var(--bg);
    color: var(--texto);
}
.contenedor { max-width: 900px; margin: 0 auto; padding: 16px; }

/* Acceso directo a "Asistencia" en la pantalla principal (index.php),
   fijo debajo del header — separado de las tarjetas normales de
   .landing-opciones porque el operador lo usa a diario (marcar entrada/
   salida) y conviene que esté siempre a mano en la esquina superior
   izquierda, sin tener que buscarlo entre el resto de opciones. */
.landing-acceso-asistencia { padding: 10px 16px 0; }
.landing-boton-asistencia {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border-radius: 20px;
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    color: var(--azul);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 600;
}
.landing-boton-asistencia:hover { background: #dbeafe; }

/* Pantalla inicial ("¿Qué deseas hacer?"): logo grande animado,
   pregunta y una lista de tarjetas de acción con ícono + flecha,
   una por cada punto de entrada real del sistema. */
.landing-inicio {
    max-width: 480px;
    margin: 0 auto;
    padding: 40px 20px 24px;
    text-align: center;
}
@media (max-width: 480px) {
    /* En celular, el badge de rol + el botón "Cerrar sesión" (ambos
       position:absolute en las esquinas) pueden ocupar más alto que
       en escritorio y solaparse con el logo si el padding es chico. */
    .landing-inicio { padding-top: 76px; }
}
/* El "escenario" es el contenedor FIJO (no se mueve): dentro de él,
   el logo salta en Y libremente mientras la sombra se queda anclada
   en el piso, solo cambiando de tamaño/opacidad — igual que una sombra
   real, que no sube y baja con el objeto que la proyecta. */
.landing-logo-escenario {
    width: 150px;
    height: 190px;
    margin: 0 auto 4px;
    position: relative;
}
.landing-logo-brinco {
    width: 150px;
    height: 150px;
    animation: logo-splash-brinco 3.2s cubic-bezier(.3,0,.4,1) infinite;
}
.landing-logo-giro3d {
    width: 150px;
    height: 150px;
    animation: logo-splash-giro 3.2s ease-in-out infinite;
    will-change: transform;
    filter: drop-shadow(0 8px 14px rgba(30,58,138,.3));
}
.landing-logo-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 30px;
    background: #fff;
    box-shadow: inset 0 0 0 1px rgba(15,23,42,.05);
    animation: logo-splash-blur 3.2s ease-in-out infinite;
}
.landing-logo-sombra {
    position: absolute;
    left: 50%;
    bottom: 6px;
    width: 90px;
    height: 16px;
    margin-left: -45px;
    border-radius: 50%;
    background: rgba(30,58,138,.22);
    animation: logo-splash-sombra 3.2s cubic-bezier(.3,0,.4,1) infinite;
}
.landing-marca { font-size: 34px; font-weight: 800; color: var(--azul); margin: 4px 0 0; letter-spacing: .5px; }
.landing-eslogan { font-size: 12px; font-weight: 700; color: var(--gris); letter-spacing: 1px; margin: 2px 0 28px; }
.landing-pregunta { font-size: 20px; font-weight: 800; color: var(--texto); margin: 0 0 4px; }
.landing-subpregunta { font-size: 14px; color: var(--gris); margin: 0 0 20px; }

.landing-opciones { display: flex; flex-direction: column; gap: 14px; }
.landing-tarjeta {
    display: flex;
    align-items: center;
    gap: 14px;
    background: #fff;
    border-radius: 16px;
    padding: 14px 16px;
    text-decoration: none;
    color: inherit;
    box-shadow: 0 2px 10px rgba(15,23,42,.06);
    text-align: left;
    transition: transform .15s ease, box-shadow .15s ease;
}
.landing-tarjeta:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(15,23,42,.1); }
.landing-tarjeta-icono {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    overflow: hidden;
}
.landing-tarjeta-icono img { width: 100%; height: 100%; object-fit: cover; display: block; }
.landing-tarjeta-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.landing-tarjeta-texto strong { font-size: 16px; color: var(--azul); font-weight: 800; }
.landing-tarjeta-texto span { font-size: 12.5px; color: var(--gris); line-height: 1.35; }
.landing-tarjeta-flecha { flex-shrink: 0; font-size: 22px; color: var(--azul); font-weight: 700; }

.landing-rastreo { margin-top: 22px; }
.landing-rastreo a {
    color: var(--azul);
    font-weight: 600;
    font-size: 14px;
    text-decoration: underline;
    text-decoration-style: dashed;
    text-underline-offset: 4px;
}
.landing-rastreo a:hover { text-decoration-style: solid; }

/* Botón "Login" del header de la pantalla de inicio (sin sesión
   activa): ícono circular con fondo BLANCO sólido (no el semi-
   transparente genérico de .btn-atras), con la palabra "Login" al
   lado, igual que el resto de headers del sistema ("Operador
   NOMBRE", etc.). Lleva directo al login único. */
.landing-header-login {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: #fff;
    font-size: 15px;
}
.landing-header-login strong { font-weight: 700; }
.landing-header-login .btn-atras,
.topbar-simple .btn-atras { background: #fff; color: var(--azul); }
.landing-header-login .btn-atras:hover,
.topbar-simple .btn-atras:hover { background: #fff; }

/* ------------------------------------------------------------
   Pantallas de login (operador y vendedor): mismo layout que la
   landing (logo grande centrado + eslogan), pero con un formulario
   de campos "con ícono a la izquierda dentro del input" y un botón
   sólido grande, más accesos rápidos de Ubicación/WhatsApp al pie.
   ------------------------------------------------------------ */
.login-pantalla {
    max-width: 440px;
    margin: 0 auto;
    padding: 32px 20px 24px;
    text-align: center;
}
.login-campo { position: relative; margin-bottom: 14px; }
.login-campo-icono {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--gris);
    font-size: 18px;
    pointer-events: none;
    display: flex;
}
.login-campo input {
    width: 100%;
    padding: 14px 14px 14px 44px;
    border-radius: 12px;
    border: 1px solid var(--borde);
    font-size: 15px;
    background: #fff;
}
.login-campo.login-campo-oscuro input {
    background: var(--azul);
    color: #fff;
    border-color: var(--azul);
}
.login-campo.login-campo-oscuro input::placeholder { color: rgba(255,255,255,.75); }
.login-campo.login-campo-oscuro .login-campo-icono { color: #fff; }
.login-campo .btn-ver-password { right: 14px; }
.login-boton {
    width: 100%;
    padding: 15px;
    border-radius: 12px;
    background: var(--azul);
    color: #fff;
    font-size: 16px;
    font-weight: 700;
    border: none;
    cursor: pointer;
    margin-top: 6px;
}
.login-boton:hover { background: #16306e; }
.login-accesos-rapidos {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 22px;
    margin-top: 26px;
}
.login-acceso-rapido {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-decoration: none;
    color: var(--texto);
    font-size: 12px;
    font-weight: 600;
}
.login-acceso-rapido .login-acceso-icono {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--bg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
}
.login-acceso-rapido .login-acceso-icono svg { display: block; }
.login-acceso-rapido.login-acceso-whatsapp .login-acceso-icono { color: #25D366; }
.login-acceso-rapido.login-acceso-ubicacion .login-acceso-icono { color: var(--azul); }
.login-accesos-separador { width: 1px; height: 32px; background: var(--borde); }
.login-nota { font-size: 12.5px; color: var(--gris); margin-top: 18px; text-align: center; }
.login-nota a { color: var(--azul); }

/* ------------------------------------------------------------
   Formularios "tipo ficha con ícono" (Pre-registro, Recepción):
   cabecera con ícono circular + título + subtítulo, y cada campo
   en su propia fila con ícono circular a la izquierda, número de
   paso opcional, etiqueta+ayuda y el input debajo.
   ------------------------------------------------------------ */
.formulario-cabecera {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 4px 4px 18px;
}
.formulario-cabecera-icono {
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--bg);
}
.formulario-cabecera-icono img { width: 100%; height: 100%; object-fit: cover; }
.formulario-cabecera-texto strong { display: block; font-size: 22px; color: var(--azul); font-weight: 800; }
.formulario-cabecera-texto span { font-size: 13px; color: var(--gris); }

.formulario-fichas { background: #fff; border-radius: 16px; box-shadow: 0 2px 10px rgba(15,23,42,.06); overflow: hidden; }
.formulario-fila {
    display: flex;
    gap: 14px;
    padding: 16px;
    border-bottom: 1px solid var(--borde);
}
.formulario-fila:last-child { border-bottom: none; }

/* Dos filas hermanas puestas lado a lado (ej. Descripción del paquete +
   ¿Es frágil? en el pre-registro) en pantallas anchas; en móvil se apilan
   como cualquier fila normal. */
@media (min-width: 720px) {
    .formulario-fila-2col { display: grid; grid-template-columns: 1fr 1fr; }
    .formulario-fila-2col .formulario-fila:first-child {
        border-bottom: none;
        border-right: 1px solid var(--borde);
    }
}

/* Apartados del formulario de pre-registro agrupados por PERSONA (vendedor
   / comprador), cada uno en su propio subrecuadro punteado con título —
   así en pantallas anchas quedan uno al lado del otro (2 columnas) sin
   mezclar sus campos por simple posición, y en móvil se apilan uno debajo
   del otro como el resto del formulario. */
.formulario-apartados-2col { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }
.formulario-apartado { padding: 12px; }
.formulario-apartado .formulario-fichas { box-shadow: none; margin-top: 6px; }
.formulario-apartado .formulario-fila { padding: 10px 0; }
@media (min-width: 720px) {
    .formulario-apartados-2col { flex-direction: row; align-items: stretch; }
    .formulario-apartado { flex: 1; }
}
.formulario-fila-icono {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--bg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    position: relative;
}
.formulario-fila-paso {
    position: absolute;
    top: -4px;
    right: -4px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--azul);
    color: #fff !important;
    font-size: 11px;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
}
.formulario-fila-cuerpo { flex: 1; min-width: 0; }
.formulario-fila-titulo { font-weight: 700; font-size: 14.5px; color: var(--texto); }
.formulario-fila-titulo .req { color: var(--rojo); }
.req { color: var(--rojo); }
.formulario-fila-ayuda { font-size: 12px; color: var(--gris); margin: 1px 0 8px; }
.formulario-fila-cuerpo input,
.formulario-fila-cuerpo textarea,
.formulario-fila-cuerpo select { width: 100%; }
.formulario-fila-checkbox { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.formulario-fila-checkbox input { width: auto; }

/* Chips de precio rápido (Bs 2, 3, 5) junto al campo de costo: un
   clic rellena el monto sin tener que escribirlo, pero el campo
   sigue siendo editable libremente para cualquier otro precio. */
.chips-precio { display: flex; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.chip-precio {
    padding: 8px 16px;
    border-radius: 999px;
    border: 1.5px solid var(--borde);
    background: #fff;
    color: var(--texto);
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
}
.chip-precio:hover { border-color: var(--azul); color: var(--azul); }
.chip-precio.activo { background: var(--azul); border-color: var(--azul); color: #fff; }
.formulario-boton-guardar {
    width: 100%;
    padding: 16px;
    border-radius: 12px;
    background: var(--azul);
    color: #fff;
    font-size: 16px;
    font-weight: 700;
    border: none;
    cursor: pointer;
    margin-top: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.formulario-boton-guardar:hover { background: #16306e; }

/* Header estilo "logo de marca": ícono redondo + nombre, con
   degradado azul→naranja (colores de AKISITO). Todo agrupado a
   la izquierda; solo el enlace de acción secundaria (ej. "Rastrear
   envío", "Cerrar sesión") queda empujado al extremo derecho. */
header.topbar {
    background: linear-gradient(135deg, var(--azul) 0%, var(--azul-claro) 55%, var(--naranja) 130%);
    color: #fff;
    padding: 8px 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}
header.topbar a { color: #fff; text-decoration: none; }
.landing-rastreo-header { text-decoration: underline !important; text-decoration-style: dashed !important; text-underline-offset: 4px; }
header.topbar span { display: flex; align-items: center; gap: 8px; min-width: 0; flex-shrink: 1; }
header.topbar span .btn-atras { flex-shrink: 0; align-self: center; }
/* min-width:0 + overflow:hidden es necesario para que un <strong> dentro
   de un contenedor flex pueda achicarse por debajo de su ancho natural
   y truncarse con "…" — sin esto, un nombre largo (ej. "Operador
   Operador Prueba") empuja al botón "Cerrar sesión" fuera de la fila y
   fuerza un salto de línea en vez de recortarse. */
header.topbar span strong { line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Bloque de nombre + negocio del vendedor, apilado en dos líneas
   (no en fila como el resto de <span> del header). */
header.topbar .topbar-nombre-bloque {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    min-width: 0;
}
header.topbar .topbar-nombre-bloque strong { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
header.topbar .topbar-nombre-bloque small { font-size: 11.5px; color: rgba(255,255,255,.8); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
/* Solo el ÚLTIMO enlace directo del header (la acción secundaria, ej.
   "Rastrear envío"/"Cerrar sesión") se empuja al extremo derecho — NO
   el botón de Atrás, que va primero y debe quedar pegado a la izquierda
   junto al logo. Usar :last-child evita que ambos <a> reciban el auto-margin. */
header.topbar > a:last-child:not(.btn-atras) { margin-left: auto; flex-shrink: 0; white-space: nowrap; }
@media (max-width: 640px) {
    /* En celular, el header con accesos rápidos (.topbar-accesos, ej.
       Reimprimir/Asistencia en algunas páginas) no cabe en una sola
       fila — el nombre pasa a ocupar toda la fila de arriba, y accesos
       + Cerrar sesión bajan a su propia fila, más compactos.
       Cuando el header solo tiene DOS hijos (nombre/ícono a la
       izquierda + un único botón "Cerrar sesión" a la derecha — el
       caso de la landing, y también operador/tablero.php desde que
       sus accesos rápidos se movieron al menú de pestañas), ambos
       deben quedar en la MISMA fila alineados, sin envolver ni forzar
       ancho completo en el primer span. */
    header.topbar { flex-wrap: wrap; row-gap: 8px; }
    header.topbar > span:first-child strong { font-size: 14px; }
    /* Solo el header con .topbar-accesos (chips de Reimprimir/
       Asistencia, ej. operador/asistencia.php, imprimir.php) necesita
       partirse en 2 filas: el nombre ocupa toda la fila de arriba, y
       accesos + Cerrar sesión bajan a su propia fila, más compactos.
       Cuando el header solo tiene nombre + un único "Cerrar sesión"
       (la landing, y operador/tablero.php), ambos quedan en la misma
       fila — por eso este ancho completo va condicionado a la
       presencia real de .topbar-accesos, no aplicado siempre. */
    header.topbar > span:first-child:has(+ .topbar-accesos) { width: 100%; }
    /* .topbar-accesos (Reimprimir/Asistencia) + el <a> suelto de Cerrar
       sesión comparten la fila de abajo, Cerrar sesión pegado a la
       derecha de esa misma fila gracias al margin-left:auto que ya le
       da la regla header.topbar > a:last-child de más arriba. */
    header.topbar > .topbar-accesos { flex: 1; }
    header.topbar > .topbar-accesos + span:last-child { width: 100%; justify-content: flex-end; margin-left: 0 !important; }
}
.topbar-logo { display: flex; align-items: center; gap: 8px; min-width: 0; }
.topbar-logo-icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    flex-shrink: 0;
    background: #fff;
    object-fit: contain;
}
.topbar-logo-texto strong { font-size: 15px; line-height: 1; white-space: nowrap; }

/* Botón "Atrás": círculo con sombra suave y flecha SVG vectorial
   (en vez de la entidad de texto "←", que se ve distinto según
   fuente/plataforma). */
.btn-atras {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    color: #fff;
    text-decoration: none;
    border-radius: 50%;
    border: none;
    background: rgba(255,255,255,.15);
    box-shadow: 0 1px 3px rgba(0,0,0,.1);
    margin: 0;
}
.btn-atras svg { width: 18px; height: 18px; display: block; }
.btn-atras:hover { background: rgba(255,255,255,.28); }
.contenedor .btn-atras,
.login-pantalla .btn-atras {
    color: #fff;
    background: var(--azul);
    box-shadow: 0 2px 8px rgba(15,23,42,.15);
    margin-bottom: 10px;
}
.contenedor .btn-atras:hover,
.login-pantalla .btn-atras:hover { background: #16306e; }

/* "Cerrar sesión" también en su propio contenedor rectangular,
   para que combine visualmente con el botón de Atrás. */
.btn-cerrar-sesion {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,.4);
    background: rgba(255,255,255,.1);
    font-size: 13px;
}
.btn-cerrar-sesion:hover { background: rgba(255,255,255,.25); }

/* Accesos rápidos del header del operador (operador/tablero.php):
   antes eran enlaces de texto sueltos con emoji separados por espacio;
   ahora cada uno es su propio recuadro (mismo look que .btn-cerrar-
   sesion de arriba, para que todo el header se vea uniforme) con un
   ícono SVG outline propio en vez de emoji. */
.topbar-accesos {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.topbar-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,.4);
    background: rgba(255,255,255,.1);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}
.topbar-chip:hover { background: rgba(255,255,255,.25); }
.topbar-chip svg { width: 16px; height: 16px; flex-shrink: 0; }
@media (max-width: 640px) {
    /* En celular, los chips pierden el texto y quedan solo como
       botones-ícono cuadrados — el mismo patrón que .menu-inferior-fijo
       ya usa más abajo en la página, para que quepan todos en una fila
       sin desbordar ni obligar a scroll horizontal. */
    .topbar-chip span.topbar-chip-texto { display: none; }
    .topbar-chip { padding: 8px; }
    .topbar-chip svg { width: 18px; height: 18px; }
}
h1, h2, h3 { color: var(--azul); }
.card {
    background: #fff;
    border-radius: 12px;
    padding: 20px;
    box-shadow: 0 1px 3px rgba(0,0,0,.08);
    margin-bottom: 16px;
}
fieldset {
    border: 1px solid var(--borde);
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 16px;
}
legend { font-weight: 600; color: var(--azul); padding: 0 8px; }
label { display: block; font-size: 14px; font-weight: 500; margin: 10px 0 4px; }

/* Formulario más liviano: menos padding, fieldsets más juntos, campos
   secundarios (checkbox, observaciones) no ocupan una línea entera. */
.formulario-compacto fieldset { padding: 10px 14px; margin-bottom: 10px; }
.formulario-compacto label { margin: 6px 0 3px; }
.formulario-compacto input, .formulario-compacto textarea { padding: 8px 10px; font-size: 14px; }
.formulario-compacto .campo-checkbox { display: flex; align-items: flex-end; padding-bottom: 2px; }
.formulario-compacto .campo-checkbox label { display: flex; align-items: center; gap: 6px; font-weight: 400; margin: 0; }
.retraible-observaciones { margin-top: 6px; }
.retraible-observaciones summary {
    cursor: pointer;
    font-size: 13px;
    color: var(--azul-claro);
    font-weight: 600;
    list-style: none;
}
.retraible-observaciones summary::-webkit-details-marker { display: none; }
.retraible-observaciones textarea { margin-top: 6px; }
input, select, textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid var(--borde);
    border-radius: 8px;
    font-size: 15px;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--azul-claro); }
/* Texto de ejemplo (placeholder) más discreto y en otra fuente que el
   texto real que escribe el usuario, para que no compita visualmente ni
   se confunda con contenido ya ingresado. */
input::placeholder, textarea::placeholder {
    font-family: Georgia, 'Times New Roman', serif;
    font-style: italic;
    opacity: .55;
}
/* Campos de nombre de persona/negocio en todo el sistema: mayúsculas
   visuales aquí (evita el parpadeo antes de que el JS convierta el valor
   real) + assets/js/pwa.js hace el toUpperCase() real mientras se escribe. */
.campo-mayusculas { text-transform: uppercase; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 600px) { .grid-2 { grid-template-columns: 1fr; } }
button, .btn {
    display: inline-block;
    background: var(--azul);
    color: #fff;
    border: none;
    padding: 12px 22px;
    border-radius: 8px;
    font-size: 15px;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
}
button:hover, .btn:hover { background: var(--azul-claro); }
/* Outline nativo del navegador al enfocar un botón (ej. el modal de
   doble confirmación enfoca "Continuar"/"Guardar" automáticamente):
   se quita porque se veía como un recuadro extra sin estilizar. Se usa
   :focus-visible (no :focus a secas) para no perder el indicador de
   foco al navegar con teclado/Tab — solo se quita en clic/touch. */
button:focus:not(:focus-visible), .btn:focus:not(:focus-visible) { outline: none; }
.btn-secundario { background: var(--naranja); }
.btn-secundario:hover { background: #f97316; }
.btn-verde { background: var(--verde); }
.btn-rojo { background: var(--rojo); }
table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 10px; overflow: hidden; }
th, td { padding: 10px 12px; border-bottom: 1px solid var(--borde); text-align: left; font-size: 14px; }
th { background: #f1f5f9; }

/* En pantallas angostas, las tablas se convierten en tarjetas apiladas
   (cada <tr> es una tarjeta, cada <td> una línea con su etiqueta) para
   no forzar scroll horizontal en el celular. Requiere que cada <td>
   lleve un atributo data-label="Nombre de columna". */
@media (max-width: 640px) {
    table.tabla-responsive thead { display: none; }
    table.tabla-responsive, table.tabla-responsive tbody, table.tabla-responsive tr, table.tabla-responsive td {
        display: block;
        width: 100%;
    }
    table.tabla-responsive tr {
        margin-bottom: 12px;
        border: 1px solid var(--borde);
        border-radius: 10px;
        padding: 8px 0;
    }
    table.tabla-responsive td {
        border-bottom: none;
        padding: 6px 12px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        text-align: right;
    }
    table.tabla-responsive td[data-label]:not([data-label=""])::before {
        content: attr(data-label);
        font-weight: 600;
        color: var(--gris);
        text-align: left;
    }
    /* Celdas sin etiqueta (ej. columna de acciones/botones) se centran
       en vez de ocultarse, para no perder el botón "Ver / Gestionar". */
    table.tabla-responsive td[data-label=""] {
        justify-content: center;
    }
    table.tabla-responsive td:empty { display: none; }
}

/* Paginación del historial completo (admin/historial.php): Anterior /
   ir a página X / Siguiente, para no cargar miles de filas de golpe. */
.paginacion-historial {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--borde);
}
.paginacion-historial .btn.paginacion-deshabilitado {
    pointer-events: none;
    opacity: 0.4;
}
.paginacion-ir-a {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
}
.paginacion-input {
    width: 60px;
    text-align: center;
    padding: 6px;
}

.badge { padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; color: #fff; display: inline-block; white-space: nowrap; }
.badge-gris { background: var(--gris); }
.badge-azul { background: var(--azul-claro); }
.badge-morado { background: var(--morado); }
.badge-amarillo { background: var(--amarillo); }
.badge-verde { background: var(--verde); }
.badge-rojo { background: var(--rojo); }
.badge-naranja { background: var(--naranja); }
.alerta { padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; }
.alerta-exito { background: #dcfce7; color: #166534; }
.alerta-error { background: #fee2e2; color: #991b1b; }

/* Alerta con acciones en formato ícono (ej. "sesión activa" en el
   formulario público: texto a la izquierda, botones-ícono a la derecha
   dentro de contenedores rectangulares, mismo lenguaje visual del header). */
.alerta-sesion {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}
.alerta-sesion-acciones { display: flex; gap: 8px; flex-shrink: 0; }
.btn-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 6px;
    border: 1px solid rgba(22,101,52,.3);
    background: rgba(255,255,255,.6);
    font-size: 16px;
    text-decoration: none;
    flex-shrink: 0;
}
.btn-icono:hover { background: #fff; }
.tracking-box {
    text-align: center;
    padding: 24px;
    background: #eff6ff;
    border: 2px dashed var(--azul-claro);
    border-radius: 12px;
}
.tracking-box .codigo { font-size: 28px; font-weight: 700; color: var(--azul); letter-spacing: 1px; }

/* Número(s) de bolsa recién registrada, protagonista de la pantalla de
   éxito — lo que el vendedor realmente debe anotar/decir en la agencia,
   más grande que el código de seguimiento interno (que queda chico). */
.bolsas-generadas { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 8px; }
.bolsa-generada-numero {
    display: inline-block;
    background: var(--azul);
    color: #fff;
    font-size: 26px;
    font-weight: 800;
    letter-spacing: .5px;
    padding: 10px 20px;
    border-radius: 10px;
}
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.stat-card { background: #fff; border-radius: 10px; padding: 16px; text-align: center; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.stat-card .num { font-size: 26px; font-weight: 700; color: var(--azul); }
.stat-card .lbl { font-size: 13px; color: var(--gris); }
/* Tarjeta de "ganancia total" (admin/index.php): se resalta en verde para
   distinguirla de las dos tarjetas que la componen (servicio + mora). */
.stat-card-destacada { background: #ecfdf5; border: 1px solid #6ee7b7; }
.stat-card-destacada .num { color: #047857; }
/* Pestañas tipo navegador (Chrome): unidas lado a lado, sin separación
   entre ellas, con la pestaña activa "elevada" y conectada visualmente
   al contenido de abajo (sin borde inferior, mismo blanco de fondo);
   las inactivas quedan un poco más abajo y con fondo gris, como si
   estuvieran "detrás" de la activa. */
nav.menu {
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    margin-bottom: 0;
    border-bottom: 1px solid var(--borde);
}
nav.menu a {
    padding: 10px 18px;
    background: var(--bg);
    text-decoration: none;
    color: var(--gris);
    font-weight: 600;
    font-size: 13.5px;
    border: 1px solid var(--borde);
    border-bottom: none;
    border-radius: 10px 10px 0 0;
    margin-bottom: -1px;
    margin-right: -1px;
    position: relative;
}
nav.menu a.activo {
    background: #fff;
    color: var(--azul);
    border-bottom: 1px solid #fff;
    z-index: 1;
}
/* Pestaña "Tablero de operador" del menú general: cuando está activa,
   se destaca con azul pastel oscuro sólido + texto blanco, en vez del
   fondo blanco/texto azul que usan las demás pestañas activas — para
   que se note de un vistazo que es la sección "principal" del día a
   día del operador, distinta del resto de pestañas administrativas. */
nav.menu a.activo-tablero {
    background: #5b7fc4;
    color: #fff;
    border-color: #5b7fc4;
    border-bottom: 1px solid #5b7fc4;
}
/* Segunda fila de pestañas en operador/tablero.php (filtros de estado
   de bolsas, DEBAJO del menú general de secciones) — mismo patrón de
   "pestañas tipo navegador", pero con su propio color para distinguirla
   de un vistazo de la fila de arriba: inactivas en un tono más neutro,
   activa en naranja (acento ya usado en el resto del sistema) en vez
   del azul que ya usa el menú de secciones. */
nav.menu.menu-escritorio a { background: #f3f4f6; }
nav.menu.menu-escritorio a.activo {
    background: #fff7ed;
    color: var(--naranja);
    border-color: #fed7aa;
    border-bottom: 1px solid #fff7ed;
}
@media (max-width: 480px) {
    /* Pestañas más compactas y repartidas a lo ancho de la pantalla,
       para que textos largos (ej. "Registrar sin pre-registro") no
       desborden ni obliguen a hacer scroll horizontal en celular. */
    nav.menu a {
        flex: 1;
        text-align: center;
        padding: 9px 8px;
        font-size: 12px;
    }
}
.menu-movil { display: none; }
@media (max-width: 640px) {
    .menu-escritorio { display: none; }
    .menu-movil {
        display: block;
        width: 100%;
        margin-bottom: 16px;
        padding: 10px 12px;
        border-radius: 8px;
        border: 1px solid var(--borde);
        background: #fff;
        font-weight: 600;
        color: var(--azul);
    }
}
.search-bar { display: flex; gap: 8px; margin-bottom: 16px; }
.search-bar input { flex: 1; }
small.ayuda { color: var(--gris); display: block; margin-top: 4px; }

/* Fila de formulario inline oculta por defecto (ej. editar teléfono en admin/usuarios.php) */
tr.oculto-form, div.oculto-form { display: none; }

/* Advertencia de contenido frágil (banner visible al recepcionar/ver bolsa) */
.alerta-fragil {
    background: #fef9c3;
    color: #854d0e;
    border: 2px solid var(--amarillo);
    font-weight: 600;
    text-align: center;
}

/* Desglose de cobro (recepción + entrega + mora) */
.desglose-cobro { width: 100%; border-collapse: collapse; margin: 10px 0; }
.desglose-cobro td { padding: 6px 4px; border-bottom: 1px dashed var(--borde); }
.desglose-cobro tr.total td { font-weight: 700; color: var(--azul); border-bottom: none; border-top: 2px solid var(--azul); }

/* Desglose de cobro con color, pensado para que el operador entienda
   de un vistazo qué parte del total es costo fijo, qué parte es mora
   (y si hay mora o no) y cuál es el total final a cobrar. */
.desglose-cobro-colores { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.desglose-fila {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 10px;
    font-size: 13.5px;
}
.desglose-costo { background: #eff6ff; color: var(--azul); }
.desglose-mora-cero { background: var(--bg); color: var(--gris); }
.desglose-mora-activa { background: #fff7ed; color: var(--naranja); }
.desglose-total { background: #ecfdf5; color: var(--verde); font-weight: 800; font-size: 15px; }

/* Línea separadora entre las sumas parciales (costo, mora) y el total
   general, en el resumen de entrega múltiple (operador/entrega.php). */
.separador-antes-total { border-top: 2px solid #1f2937; margin: 14px 0; }

/* Bloque del total: el círculo con la cantidad de paquetes queda como
   una insignia pequeña sobrepuesta en la esquina superior derecha del
   recuadro verde del total (no centrado arriba). */
.bloque-total-entregas { position: relative; margin-top: 14px; }
.circulo-cantidad-paquetes {
    position: absolute;
    top: -8px;
    right: -8px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #7f1d1d;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
    border: 2px solid #fff;
    box-shadow: 0 2px 4px rgba(0,0,0,.2);
    z-index: 1;
}
.fila-total-entregas {
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
}
.fila-total-entregas span { font-size: 13.5px; font-weight: 600; }
.fila-total-entregas strong { font-size: 24px; }

/* Ticket "guía por pagar" — HTML y CSS basados en el modelo de
   referencia del usuario (gemini-code-1787166024688.html), con el
   header y los tamaños ajustados a pedido del usuario en revisiones
   posteriores. Ancho fijo en 70mm (impresora térmica) en vez de los
   500px del modelo: TODAS las medidas de abajo (fuentes, paddings,
   iconos) están recalculadas multiplicando el valor del diseño de
   pantalla ya aprobado por el factor de escala k = 264.6/500 = 0.529
   (donde 264.6px es 70mm a 96dpi), para preservar las proporciones en
   vez de ajustarlas a ojo. Header: el logo va al lado (no encima) de
   dos líneas de texto apiladas (AKISITO / RECEPCIÓN Y ENTREGA DE
   MERCANCÍA) — columna izquierda; teléfono+dirección siguen en su
   propia columna a la derecha, sin cambios de posición. El emoji de
   logo (📦📍) se reemplaza por el <img> real (logo-ticket.png) y los
   emojis de teléfono/ubicación (💬📍📞) por SVG inline — una térmica
   B/N no imprime emojis a color de forma confiable; el ícono de
   teléfono usa el logo oficial de WhatsApp (includes/svg_whatsapp.php). */
.ticket-container {
    width: 70mm;
    max-width: 100%;
    background-color: #ffffff;
    border: 1px solid #2a4163;
    border-radius: 6px;
    padding: 4px 0 4px 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    text-align: left;
    font-family: Arial, Helvetica, sans-serif;
    margin: 0 auto;
}
.ticket-container * { box-sizing: border-box; }

.ticket-container .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3px; }
.ticket-container .header-left { width: 55%; }
.ticket-container .logo-row { display: flex; align-items: center; }
.ticket-container .logo-icon-img { width: 42px; height: 42px; margin-right: -2px; flex-shrink: 0; object-fit: contain; position: relative; top: -3px; clip-path: inset(0 1px 0 0); }
.ticket-container .logo-lineas { min-width: 0; text-align: left; }
.ticket-container .logo-text { color: #122855; font-weight: 900; font-size: 23px; letter-spacing: -0.5px; line-height: 1; }
/* Ancho forzado a lo que mide "AKISITO" y texto justificado
   (text-align-last, también aplica a una sola línea) para que la línea
   entera se estire y ocupe ese mismo ancho, a pedido del usuario. */
/* En una sola línea sin salto (white-space:nowrap), text-align-last:
   justify NO estira el texto — esa propiedad solo actúa cuando hay
   salto de línea real. Para que ocupe exactamente el mismo ancho que
   "AKISITO" en una sola línea, el JS (ver ajustarAnchoSubtextoTicket en
   pwa.js) mide ambos anchos y aplica un transform:scaleX() calculado. */
.ticket-container .logo-subtext { color: #000; font-size: 8.5px; font-weight: bold; margin-top: 0; letter-spacing: 0; line-height: 1; white-space: nowrap; display: inline-block; vertical-align: top; transform-origin: left top; }
/* Fuente condensada (alta y angosta): usa Arial Narrow si el
   dispositivo la tiene instalada; si no, "font-stretch: condensed" pide
   al navegador la variante angosta de la fuente que sí haya. */
.ticket-container .no-fiscal { font-size: 7.8px; font-weight: 900; margin-left: 0; margin-top: -4px; font-family: 'Arial Narrow', Arial, sans-serif; font-stretch: condensed; white-space: nowrap; }
.ticket-container .header-right { width: 45%; text-align: right; }
.ticket-container .phone-row { display: flex; align-items: center; justify-content: flex-end; font-size: 14px; font-weight: 900; margin-bottom: 2px; }
.ticket-container .phone-row .icono-whatsapp { width: 18.7px; height: 18.7px; margin-right: 3px; flex-shrink: 0; color: #25D366; }
.ticket-container .address-row { display: flex; align-items: flex-start; justify-content: flex-end; font-size: 6.7px; font-weight: bold; text-align: left; line-height: 1.3; }
.ticket-container .address-row .icono-pin { width: 16px; height: 16px; margin-right: -1px; margin-top: -3.5px; flex-shrink: 0; }
.ticket-container .person-phone .icono-whatsapp { width: 12.5px; height: 12.5px; margin-right: 2px; flex-shrink: 0; color: #25D366; }

.ticket-container .box { border: 1px solid #000; border-radius: 4px; margin-bottom: 2px; overflow: hidden; }
.ticket-container .box-header { background-color: #000; color: #fff; text-align: center; font-weight: bold; padding: 1px 0; font-size: 9px; }
.ticket-container .box-content { background-color: #fff; }
.ticket-container .bg-lightblue { background-color: #e5f4fb; }

.ticket-container .emission-content { display: flex; justify-content: space-between; align-items: center; padding: 1px 3px; font-size: 6.96px; font-weight: bold; white-space: nowrap; }
.ticket-container .emision-label { font-size: 6.96px; }
.ticket-container .emission-date { font-size: 8.22px; font-weight: 900; }
.ticket-container .emission-user { background-color: #e5f4fb; padding: 0 3px; }

.ticket-container .code-content { display: flex; align-items: stretch; }
.ticket-container .schedule { width: 40%; padding: 2px; font-size: 7px; text-align: center; display: flex; flex-direction: column; justify-content: center; border-right: 1px solid #000; line-height: 1.35; }
.ticket-container .main-code {
    width: 60%;
    font-size: 36px;
    font-weight: 900;
    text-align: center;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    letter-spacing: -1px;
    /* Siempre en una sola línea: si el código es muy largo para caber
       con el font-size base, el script de la página (ver ajustarTamanoCodigoTicket
       en pwa.js) lo reduce hasta que quepa, en vez de partirlo en dos líneas. */
    white-space: nowrap;
}

.ticket-container .people-row { display: flex; gap: 2px; margin-bottom: 2px; }
.ticket-container .person-box { flex: 1; border: 1px solid #000; border-radius: 4px; overflow: hidden; display: flex; flex-direction: column; }
.ticket-container .person-content { flex: 1; display: flex; flex-direction: column; text-align: center; font-weight: bold; font-size: 9.5px; }
.ticket-container .person-name { padding: 1px 0; word-break: break-word; }
.ticket-container .person-phone { background-color: #e5f4fb; padding: 1px 0; display: flex; justify-content: center; align-items: center; gap: 2px; font-weight: 900; }

.ticket-container .details-grid { display: grid; grid-template-columns: 26px 1fr 53px; }
.ticket-container .details-header { background-color: #000; color: #fff; font-weight: bold; font-size: 9px; text-align: center; padding: 1px 0; }
.ticket-container .details-row { display: grid; grid-template-columns: 26px 1fr 53px; font-weight: bold; font-size: 11px; text-align: center; min-height: 15px; }
.ticket-container .details-row > div { display: flex; align-items: center; justify-content: center; padding: 1px; word-break: break-word; }
.ticket-container .border-right { border-right: 1px solid #000; }

.ticket-container .limit-section { text-align: right; font-size: 9.4px; margin-bottom: 2px; line-height: 1.3; padding-right: 3px; }
.ticket-container .limit-fecha { font-weight: 900; font-size: 8.4px; }

/* Campos de firma: el espacio para escribir a mano queda ARRIBA de cada
   línea (border-top, en vez de border-bottom del modelo original), y
   la etiqueta (NOMBRE Y APELLIDO, FIRMA, etc.) va pegada DEBAJO de esa
   línea — al revés del modelo, que ponía la etiqueta pegada arriba de
   la línea con el espacio libre para firmar abajo. */
.ticket-container .signature-content { display: flex; height: 73px; }
.ticket-container .signature-half { flex: 1.4; display: flex; flex-direction: column; justify-content: flex-end; padding: 0 5px 5px 5px; }
.ticket-container .signature-half:last-child { flex: 1; }
.ticket-container .sig-line-solid { border-top: 1px solid #000; text-align: center; font-size: 4.9px; font-weight: bold; margin-top: 33px; padding-top: 2px; }
.ticket-container .sig-line-dotted { border-top: 1px dotted #000; text-align: center; font-size: 4.9px; font-weight: bold; margin-top: 23px; padding-top: 2px; }

/* Ticket "fantasma": existe en el DOM solo para imprimirse (ej. tras
   confirmar una recepción desde el modal de vista previa), sin
   ocupar espacio ni verse en pantalla. */
.solo-impresion { display: none; }

/* Impresión del ticket: SOLO se imprime lo que
   lleve la clase .imprimir-esto, todo lo demás de la página se oculta
   con display:none (no visibility, para que el navegador no calcule
   páginas extra ni deje huecos en blanco). Cada pantalla marca con
   .imprimir-esto UN ticket — el visible en etiqueta.php, la copia
   oculta "solo-impresion" en recepcion.php (nunca la del modal, para
   no imprimir dos veces) — o, en confirmaciones masivas de
   preregistros.php, VARIOS tickets seguidos dentro del mismo bloque
   .imprimir-esto (ver .etiqueta-salto-pagina más abajo). */
/* .imprimir-esto DEBE ser hijo directo de <body> en las 3 páginas que
   lo usan (recepcion.php, preregistros.php, etiqueta.php) — si queda
   anidado más adentro (ej. dentro de .contenedor) esta regla lo oculta
   igual, porque .contenedor en sí no lleva la clase (bug real que pasó
   en etiqueta.php: el ticket nunca aparecía al imprimir). */
body.modo-impresion-ticket > *:not(.imprimir-esto) { display: none !important; }
body.modo-impresion-ticket .imprimir-esto { display: block !important; }

@media print {
    /* Ticket reescalado a 70mm (ver comentario arriba): vuelve a
       imprimirse en rollo térmico continuo, como la impresora real del
       usuario (Epson TM-T20III, 80mm de papel). */
    @page { size: 80mm auto; margin: 2mm; }
    body { background: #fff; }
    body:not(.modo-impresion-ticket) * { visibility: visible; }
    .ticket-container {
        border: none;
        box-shadow: none;
        width: 70mm;
        margin: 0;
    }
    /* Confirmación masiva de pre-registros: cada ticket a partir del
       segundo empieza en una página térmica nueva, para que la Epson
       corte el rollo entre paquete y paquete en vez de imprimirlos
       todos pegados uno debajo del otro. */
    .etiqueta-salto-pagina { break-before: page; page-break-before: always; }
    /* La térmica imprime en blanco/negro puro (sin escala de grises
       real): forzamos negro 100% en el texto normal. Las franjas de
       fondo negro (box-header, details-header) mantienen su texto
       blanco real, y se fuerza print-color-adjust para que el
       navegador no omita los fondos al imprimir. */
    .ticket-container, .ticket-container * { color: #000 !important; }
    .ticket-container .box-header,
    .ticket-container .details-header {
        background-color: #000 !important;
        color: #fff !important;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    .ticket-container .box-header *,
    .ticket-container .details-header * {
        color: #fff !important;
    }
    /* Fondo celeste oculto al imprimir: la térmica es B/N puro, un
       fondo de color se traduciría en gris sucio o se ignora según el
       navegador; el texto ya queda en negro puro por la regla de
       arriba, así que el dato sigue siendo legible sin el fondo. */
    .ticket-container .bg-lightblue,
    .ticket-container .emission-user,
    .ticket-container .person-phone {
        background-color: transparent !important;
    }
}

/* ------------------------------------------------------------
   Fichas desplegables (<details>/<summary> nativo, sin JS) con
   flecha circular que gira 180° al abrir. Útil para secciones
   opcionales (ej. historial largo, datos secundarios) sin
   ocupar espacio en pantallas chicas.
   ------------------------------------------------------------ */
.retraible { margin: 0 0 16px; }
.retraible-resumen {
    list-style: none;
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 600;
    color: var(--azul);
}
.retraible-resumen::-webkit-details-marker { display: none; }
.retraible-flecha {
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--naranja);
    color: #fff;
    font-size: 14px;
    font-weight: 900;
    line-height: 1;
    transition: transform 0.18s ease, background 0.18s ease;
}
.retraible-resumen:hover .retraible-flecha { transform: scale(1.1); }
.retraible[open] .retraible-flecha { transform: rotate(180deg); background: var(--azul); }
.retraible[open] .retraible-resumen:hover .retraible-flecha { transform: rotate(180deg) scale(1.1); }
.retraible[open] .retraible-resumen { margin-bottom: 10px; }

/* Variante con la flecha a la IZQUIERDA del nombre (en vez de a la
   derecha), y debajo del nombre un subdato (ej. celular + conteo). */
.retraible-resumen-izq { justify-content: flex-start; gap: 12px; }
.retraible-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.retraible-nombre { color: var(--azul); font-size: 15px; }
.retraible-numeros-bolsa { color: var(--azul); font-size: 26px; font-weight: 800; line-height: 1.2; letter-spacing: .3px; }
.retraible-subdato { color: var(--gris); font-weight: 500; }

/* Ficha de entrega (operador/entrega.php): la línea grande del resumen
   pasó de mostrar "DÍA - CÓDIGO" a mostrar el contenido del paquete, con
   el código chico y en otro color al lado, para no perder esa referencia.
   Tamaño reducido respecto al código-solo (.retraible-numeros-bolsa base),
   porque el contenido puede ser un texto más largo que un código corto. */
.retraible-numeros-bolsa-contenido { font-size: 17px; }
.campo-resumen-codigo-chico { color: var(--naranja); font-size: 15px; font-weight: 700; }

/* Costo/total del paquete, mostrados a la derecha del resumen colapsado
   (antes del botón "✕"), alineados en columna y ocultos al expandir la
   ficha ya que esos datos se repiten en el desglose de abajo. */
.retraible-resumen-costos {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    text-align: right;
}
.retraible-resumen-costos strong { color: var(--verde); font-size: 15px; font-weight: 800; }
.retraible-resumen-costos small { color: var(--gris); font-size: 12px; font-weight: 600; }

/* Botón "✕" para quitar una ficha dinámica de entrega múltiple (operador/entrega.php).
   Empujado al extremo derecho del resumen; stopPropagation en JS evita que
   el clic también abra/cierre el <details>. */
.btn-quitar-ficha-entrega {
    position: relative;
    flex-shrink: 0;
    margin-left: auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg);
    color: var(--rojo);
    border: 2px solid var(--rojo);
    cursor: pointer;
    padding: 0;
    font-size: 0;
}
.btn-quitar-ficha-entrega::before {
    content: '✕';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 13px;
    font-weight: 800;
    line-height: 1;
}
.btn-quitar-ficha-entrega:hover { background: var(--rojo); color: #fff; }

/* Botón "+" para agregar otra ficha de entrega múltiple: un recuadro
   pequeño y centrado con solo el signo, no un botón de ancho completo. */
.fila-btn-agregar-ficha { display: flex; justify-content: center; margin-top: 10px; }
.btn-agregar-ficha-entrega {
    position: relative;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    border: 2px dashed var(--naranja);
    background: #fff7ed;
    color: var(--naranja);
    cursor: pointer;
    padding: 0;
    font-size: 0;
}
.btn-agregar-ficha-entrega::before {
    content: '+';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 22px;
    font-weight: 700;
    line-height: 1;
}
.btn-agregar-ficha-entrega:hover { background: #ffedd5; }

/* Alerta de "quién retira" distinto entre fichas de entrega múltiple
   (operador/entrega.php): el teléfono de esta ficha no coincide con el
   de la primera ficha cargada, así que probablemente no es la misma
   persona retirando todos los paquetes. Borde punteado rojo parpadeante,
   solo de advertencia (no bloquea la entrega, el operador decide). */
.ficha-entrega-alerta .retraible.marco-punteado {
    border-width: 3px;
    animation: parpadeo-alerta-entrega 1.2s ease-in-out infinite;
}
@keyframes parpadeo-alerta-entrega {
    0%, 100% { border-color: var(--rojo); background: #fee2e2; }
    50% { border-color: #f87171; background: #fff5f5; }
}

/* Subrecuadros fijos con título, dentro del contenido expandido de la
   ficha de entrega (operador/entrega.php): mientras el <summary>
   colapsado da un vistazo rápido, estos subrecuadros dejan datos clave
   (comprador, contenido) siempre visibles y aislados al expandir, sin
   repetirse mezclados con el resto del formulario. */
.subrecuadro-punteado {
    border: 2px dashed;
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 12px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.subrecuadro-titulo {
    text-transform: uppercase;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .4px;
    opacity: .75;
    margin-bottom: 2px;
}
.subrecuadro-verde { border-color: var(--verde); background: #ecfdf5; }
.subrecuadro-verde .subrecuadro-titulo,
.subrecuadro-verde strong { color: var(--verde); }
.subrecuadro-verde span { color: #047857; font-size: 13px; font-weight: 600; }

.subrecuadro-azul { border-color: var(--azul); background: #eff6ff; }
.subrecuadro-azul .subrecuadro-titulo { color: var(--azul); }
.subrecuadro-azul p { color: #1e3a8a; font-size: 13px; margin: 2px 0; }

.subrecuadro-naranja { border-color: var(--naranja); background: #fff7ed; }
.subrecuadro-naranja .subrecuadro-titulo { color: var(--naranja); }

/* Oculta el nombre/celular del resumen del <summary> mientras la ficha
   está expandida (ya se ve en el subrecuadro verde "Comprador" de
   abajo) — vuelven a mostrarse al colapsar, para que el resumen
   colapsado siga siendo útil de un vistazo. */
details[open] .oculto-si-abierto { display: none; }

/* Íconos de acción (editar/eliminar) en el resumen de una ficha
   desplegable, empujados al extremo derecho. onclick="event.stopPropagation()"
   en el HTML evita que el clic también abra/cierre el <details>. */
.retraible-acciones-icono { display: flex; gap: 6px; flex-shrink: 0; }
/* Se usa tanto en <a> como en <button type="button"> (para poder abrir
   el modal de confirmación con JS en vez de navegar). Como el estilo
   base "button { background: var(--azul); color:#fff; }" del sistema
   tiene la misma especificidad, forzamos aquí explícitamente fondo
   blanco y color propio para que nunca quede invisible (ícono blanco
   sobre fondo azul, imperceptible). */
button.btn-svg-icono,
a.btn-svg-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 6px;
    border: 1px solid var(--borde);
    background: #fff !important;
    color: var(--azul) !important;
    flex-shrink: 0;
    font-size: inherit;
    cursor: pointer;
}
.btn-svg-icono svg { width: 16px; height: 16px; display: block; }
.btn-svg-icono:hover { background: var(--bg) !important; }
button.btn-svg-icono-rojo,
a.btn-svg-icono-rojo { color: var(--rojo) !important; }
.btn-svg-icono-rojo:hover { background: #fee2e2 !important; }

/* Marco punteado bien delimitado, para agrupar visualmente una ficha
   desplegable (ej. panel de cliente: un pre-registro con sus bolsas). */
.marco-punteado {
    border: 2px dashed var(--azul-claro);
    border-radius: 14px;
    padding: 14px 16px;
    background: #fff;
    margin-bottom: 14px;
}
.marco-punteado .retraible-resumen { flex-wrap: wrap; gap: 8px; }

.ficha-subtitulo {
    font-size: 13px;
    color: var(--gris);
    margin: 0 0 12px;
}

/* Cada bolsa dentro de la ficha desplegable del pre-registro:
   sub-contenedor rectangular punteado, bien delimitado dentro del
   marco punteado mayor. */
.ficha-bolsa {
    position: relative;
    border: 2px dashed var(--naranja);
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 10px;
    background: var(--bg);
}
.ficha-bolsa:last-child { margin-bottom: 0; }
.ficha-bolsa-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}
.subficha-codigo {
    display: inline-block;
    background: #c2410c;
    color: #fff;
    font-weight: 800;
    font-size: 14px;
    letter-spacing: .4px;
    padding: 4px 10px;
    border-radius: 6px;
}
.subficha-codigo-esquina {
    background: var(--verde);
    margin-left: auto;
}
/* Día de la semana abreviado (LUN, MAR...) junto al código, para
   ubicar rápido cuándo llegó/se recepcionó el paquete de un vistazo. */
.dia-abreviado {
    display: inline-block;
    background: rgba(255,255,255,.25);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .3px;
    margin-left: 4px;
    vertical-align: middle;
}
.retraible-numeros-bolsa .dia-abreviado { background: var(--bg); color: var(--gris); }
.etiqueta-codigo .dia-abreviado {
    display: inline;
    background: none;
    color: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    padding: 0;
    border-radius: 0;
    margin-left: 0;
    vertical-align: baseline;
}
.ficha-bolsa-detalle {
    font-size: 13px;
    color: var(--texto);
    margin: 0;
    line-height: 1.5;
}
.ficha-bolsa-acciones {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 10px;
}
.ficha-bolsa-acciones .btn { padding: 8px 14px; font-size: 13px; }

/* ------------------------------------------------------------
   Menú inferior fijo estilo app móvil (ej. pestañas Pre-registros
   / Paquetería del panel de vendedor). Queda pegado abajo de la
   pantalla sin moverse al hacer scroll.
   ------------------------------------------------------------ */
/* Altura FIJA del nav definida una sola vez en una variable — el
   padding del contenedor y la altura real del nav SIEMPRE usan el
   mismo número, así nunca pueden desincronizarse aunque se agreguen
   más elementos (badges, etc.) adentro del menú. */
:root { --alto-menu-fijo: 64px; }
.contenedor-con-menu-fijo { padding-bottom: calc(var(--alto-menu-fijo) + env(safe-area-inset-bottom, 0) + 260px); }
.menu-inferior-fijo {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--alto-menu-fijo);
    display: flex;
    background: #fff;
    border-top: 1px solid var(--borde);
    box-shadow: 0 -2px 10px rgba(0,0,0,.08);
    z-index: 50;
    padding-bottom: env(safe-area-inset-bottom, 0);
    box-sizing: content-box;
}
.menu-inferior-fijo a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    margin: 6px 4px;
    padding: 6px 4px 4px;
    text-decoration: none;
    color: var(--gris);
    font-size: 12px;
    font-weight: 600;
    border-radius: 8px;
    border: 2px solid transparent;
}
.menu-inferior-fijo a.activo {
    color: var(--azul);
    border-color: var(--azul);
    background: rgba(37, 99, 235, .06);
}
/* El ícono es un contenedor relativo para que el contador se pueda
   anclar como badge en su esquina superior derecha — así todas las
   pestañas miden lo mismo (con o sin contador) y el menú no "salta"
   de ancho/alto entre vistas distintas del mismo menú. */
.menu-inferior-icono { position: relative; display: inline-flex; font-size: 20px; line-height: 1; }
.menu-inferior-contador {
    position: absolute;
    top: -6px;
    right: -10px;
    display: inline-block;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--naranja);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px #fff;
}
.menu-inferior-fijo a:not(.activo) .menu-inferior-contador { background: var(--gris); }

/* ------------------------------------------------------------
   Ajustes adicionales para pantallas muy angostas (celulares
   pequeños) y tablets, complementando el breakpoint de 640px
   que ya convierte las tablas en fichas.
   ------------------------------------------------------------ */
@media (max-width: 480px) {
    .contenedor { padding: 10px; }
    h1 { font-size: 1.3rem; }
    .stat-card .num { font-size: 22px; }
    button, .btn { padding: 10px 16px; font-size: 14px; }
    .search-bar { flex-direction: column; }
}
@media (min-width: 768px) and (max-width: 1024px) {
    .contenedor { max-width: 95%; }
}

/* Pie de página discreto con crédito de autoría, en todas las páginas. */
.pie-creditos {
    text-align: center;
    padding: 16px 10px 24px;
    font-size: 11px;
    color: var(--gris);
    opacity: .8;
}
.pie-creditos a { color: inherit; }

/* Ficha desplegable de edición inline en el tablero de operador
   (pestaña Pre-registrados): evita salir a otra pantalla para
   cambiar el estado de una bolsa. */
.fila-ficha-desplegable td { background: var(--bg); padding: 0; }
.ficha-edicion-bolsa { padding: 14px 16px; border-top: 1px dashed var(--borde); }
.ficha-edicion-bolsa select,
.ficha-edicion-bolsa textarea,
.ficha-edicion-bolsa input[type="number"] { width: 100%; }
.btn-desplegar-ficha { white-space: nowrap; }

/* Campo de contraseña con botón "ojito" para mostrar/ocultar. El
   ícono empieza "apagado" (semi-transparente) y se enciende (opaco)
   solo mientras la contraseña está visible. */
.campo-password { position: relative; }
.campo-password input { padding-right: 42px; }
.btn-ver-password {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    background: none;
    border: none;
    padding: 4px 6px;
    font-size: 17px;
    cursor: pointer;
    opacity: .45;
    filter: grayscale(1);
    transition: opacity .15s ease, filter .15s ease;
}
.btn-ver-password:hover { opacity: .7; }
.btn-ver-password.activo { opacity: 1; filter: grayscale(0); }

/* ------------------------------------------------------------
   Logo animado tipo "splash" para la portada principal: salto con
   aplastado/estiramiento, giro 3D, sombra que reacciona, y texto
   con leve latido — inspirado en la animación de bienvenida de
   Disfraces Fantasía, adaptado a los colores de AKISITO.
   ------------------------------------------------------------ */
.logo-splash-brinco {
    transform-origin: center bottom;
    animation: logo-splash-brinco 3.2s cubic-bezier(.3,0,.4,1) infinite;
    will-change: transform;
    perspective: 520px;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.logo-splash-giro3d {
    width: 96px;
    height: 96px;
    animation: logo-splash-giro 3.2s ease-in-out infinite;
    will-change: transform;
    filter: drop-shadow(0 6px 10px rgba(30,58,138,.25));
}
.logo-splash-giro3d img {
    width: 100%;
    height: 100%;
    border-radius: 22px;
    background: #fff;
    animation: logo-splash-blur 3.2s ease-in-out infinite;
}
.logo-splash-sombra {
    width: 60px;
    height: 11px;
    border-radius: 50%;
    background: rgba(30,58,138,.2);
    margin-top: 8px;
    animation: logo-splash-sombra 3.2s cubic-bezier(.3,0,.4,1) infinite;
}
@keyframes logo-splash-brinco {
    0%    { transform: translateY(0)     scale(1,1); }
    3.4%  { transform: translateY(0)     scale(1.14,.8); }
    13.1% { transform: translateY(-40px) scale(.92,1.12); }
    18.9% { transform: translateY(0)     scale(1.08,.88); }
    24.1% { transform: translateY(-11px) scale(.98,1.05); }
    28.2% { transform: translateY(0)     scale(1.03,.97); }
    34.4% { transform: translateY(0)     scale(1,1); }
    36%   { transform: translateY(-8px)  scale(1,1); }
    64%   { transform: translateY(-8px)  scale(1,1); }
    65.6% { transform: translateY(0)     scale(1,1); }
    100%  { transform: translateY(0)     scale(1,1); }
}
@keyframes logo-splash-giro {
    0%, 34.4%   { transform: rotateY(0deg); }
    65.6%, 100% { transform: rotateY(1080deg); }
}
@keyframes logo-splash-blur {
    0%, 34.4%   { filter: blur(0); }
    42%, 58%    { filter: blur(2px); }
    65.6%, 100% { filter: blur(0); }
}
@keyframes logo-splash-sombra {
    0%, 100% { transform: scale(1);    opacity: .5; }
    3.4%     { transform: scale(1.18); opacity: .65; }
    13.1%    { transform: scale(.55);  opacity: .2; }
    18.9%    { transform: scale(1.12); opacity: .6; }
    24.1%    { transform: scale(.85);  opacity: .35; }
    28.2%    { transform: scale(1.05); opacity: .55; }
    34.4%    { transform: scale(1);    opacity: .5; }
    36%      { transform: scale(.82);  opacity: .3; }
    64%      { transform: scale(.82);  opacity: .3; }
    65.6%    { transform: scale(1);    opacity: .5; }
}
@media (prefers-reduced-motion: reduce) {
    .logo-splash-brinco, .logo-splash-giro3d, .logo-splash-giro3d img, .logo-splash-sombra { animation: none; }
    .landing-logo-brinco, .landing-logo-giro3d, .landing-logo-img, .landing-logo-sombra { animation: none; }
}

/* ------------------------------------------------------------
   Línea de tiempo del historial (rastreo público): puntos
   conectados por una línea vertical, cada evento con su fecha/hora
   y detalle. Sustituye la tabla plana por algo más visual.
   ------------------------------------------------------------ */
.linea-tiempo {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}
.linea-tiempo-item {
    position: relative;
    padding: 0 0 20px 26px;
}
.linea-tiempo-item:last-child { padding-bottom: 0; }
.linea-tiempo-item::before {
    /* Línea vertical conectando los puntos, salvo tras el último ítem */
    content: '';
    position: absolute;
    left: 6px;
    top: 16px;
    bottom: -4px;
    width: 2px;
    background: var(--borde);
}
.linea-tiempo-item:last-child::before { display: none; }
.linea-tiempo-punto {
    position: absolute;
    left: 0;
    top: 3px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--azul);
    border: 3px solid #fff;
    box-shadow: 0 0 0 2px var(--azul);
}
.linea-tiempo-cabecera {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.linea-tiempo-fecha { font-size: 12px; color: var(--gris); font-weight: 600; }
.linea-tiempo-detalle { margin: 4px 0 0; font-size: 13px; color: var(--texto); }

/* ------------------------------------------------------------
   Modal de confirmación propio (reemplaza el confirm() nativo del
   navegador, sin estilo propio, por una tarjeta con nuestro diseño).
   ------------------------------------------------------------ */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15,23,42,.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: modal-fondo-entra .2s ease both;
}
.modal-tarjeta {
    background: #fff;
    max-width: 380px;
    width: 100%;
    padding: 20px;
    box-shadow: 0 20px 60px rgba(0,0,0,.35);
    animation: modal-tarjeta-entra .22s cubic-bezier(.2,.8,.3,1.1) both;
}
.modal-acciones { display: flex; gap: 10px; margin-top: 16px; }
.modal-acciones .btn { flex: 1; }
@keyframes modal-fondo-entra {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes modal-tarjeta-entra {
    from { opacity: 0; transform: scale(.92) translateY(8px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* Doble confirmación antes de guardar en la base de datos (ver pwa.js):
   modal inyectado una sola vez y reutilizado por cualquier <form> con
   data-doble-confirmacion. Reusa .modal-overlay/.modal-tarjeta/
   .modal-acciones ya existentes, con su propio acento visual (borde
   naranja de advertencia + indicador de "Paso X de 2") para distinguirse
   de otros modales del sistema (ej. el de vista previa de tickets). */
.modal-doble-confirmacion-tarjeta {
    border-top: 4px solid var(--naranja);
}
.doble-confirmacion-paso-indicador {
    display: inline-block;
    background: #fff7ed;
    color: #c2410c;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 999px;
    margin-bottom: 8px;
}
.doble-confirmacion-mensaje {
    color: var(--gris);
    font-size: 14px;
    line-height: 1.4;
}

/* Aviso visual de "campo obligatorio faltante" (ej. al intentar agregar
   otro paquete en recepción masiva sin completar el costo de la ficha
   actual): el recuadro entero del input pulsa en rojo neón dos veces
   seguidas para llamar la atención de inmediato, además del mensaje
   nativo del navegador (reportValidity). El "neón con gradiente hacia
   afuera" se logra apilando varios box-shadow concéntricos: el primero
   bien saturado y pegado al borde, los siguientes cada vez más grandes
   y transparentes — simulan un halo de luz que se disipa, ya que
   box-shadow no soporta gradientes reales. */
@keyframes campo-pulso-invalido-anim {
    0%, 100% {
        border-color: var(--borde, #ccc);
        box-shadow: none;
    }
    25%, 75% {
        border-color: #ff1744;
        box-shadow:
            0 0 4px 1px rgba(255,23,68,.95),
            0 0 12px 4px rgba(255,23,68,.55),
            0 0 24px 10px rgba(255,23,68,.3),
            0 0 40px 16px rgba(255,23,68,.12);
    }
    50% { border-color: var(--borde, #ccc); box-shadow: none; }
}
.campo-pulso-invalido {
    animation: campo-pulso-invalido-anim 0.7s ease-in-out 2;
    position: relative;
    z-index: 1;
}

/* Modal de reconfirmación antes de entregar varios paquetes juntos
   (operador/entrega.php) — mismo sistema .modal-overlay/.modal-tarjeta
   del resto del sistema, con fondo desenfocado detrás (backdrop-filter
   ya definido en .modal-overlay). */
.modal-confirmar-icono { font-size: 40px; line-height: 1; margin-bottom: 6px; }
.modal-confirmar-destacado { color: var(--azul); }

/* Pre-registros agrupados por vendedor (operador/preregistros.php):
   dentro de la ficha colapsada del vendedor, cada bolsa pendiente es a
   su vez una mini-ficha retráctil propia (<details> anidado): colapsada
   muestra solo nombre/celular/costo de un vistazo; expandida muestra el
   detalle completo (contenido, frágil, chips de precio). El check de
   selección masiva queda afuera del recuadro, a la derecha, y el
   círculo con el número de bolsa en la esquina superior. */
.lista-paquetes-vendedor { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.fila-paquete-masivo {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}
.paquete-masivo-caja {
    position: relative;
    flex: 1;
    border-color: var(--naranja);
    background: #fff7ed;
    margin-bottom: 0;
    display: block;
}
.paquete-masivo-circulo {
    position: absolute;
    top: -12px;
    right: -12px;
    min-width: 38px;
    height: 38px;
    padding: 0 10px;
    border-radius: 999px;
    background: #7f1d1d;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 700;
    white-space: nowrap;
    border: 2px solid #fff;
    box-shadow: 0 2px 4px rgba(0,0,0,.2);
    z-index: 2;
}
.paquete-masivo-resumen {
    list-style: none;
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding-right: 30px;
}
.paquete-masivo-resumen::-webkit-details-marker { display: none; }
.paquete-masivo-flecha {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--naranja);
    color: #fff;
    font-size: 12px;
    font-weight: 900;
    line-height: 1;
    transform: rotate(0deg);
    transition: transform 0.18s ease, background 0.18s ease;
}
.paquete-masivo-caja[open] .paquete-masivo-flecha { transform: rotate(180deg); background: var(--azul); }
.paquete-masivo-resumen-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.paquete-masivo-resumen-info strong { font-size: 14px; }
.paquete-masivo-resumen-info span { font-size: 12.5px; color: var(--gris); }
.paquete-masivo-hora-registro { font-size: 11.5px !important; font-style: italic; opacity: .8; }

/* Precio: vive DENTRO del <summary> (única parte de un <details> que
   HTML nativo mantiene visible aunque esté colapsado), en su propia
   columna a la derecha de nombre/celular. preventDefault+stopPropagation
   en el onclick evita que escribir ahí abra/cierre la ficha o dispare
   la navegación por teclado del <summary>. */
.paquete-masivo-precio-summary {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 108px;
    cursor: default;
}
.paquete-masivo-precio-summary .paquete-masivo-label-precio { margin: 0; font-size: 10.5px; }
.paquete-masivo-precio-summary input { padding: 6px 8px; font-size: 13px; }
.paquete-masivo-precio-summary .chips-precio {
    display: flex;
    gap: 3px;
    margin-bottom: 0;
}
.paquete-masivo-precio-summary .chip-precio {
    flex: 1;
    padding: 3px 0;
    font-size: 11px;
}
.paquete-masivo-detalle {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--naranja);
}
.paquete-masivo-detalle label { margin: 8px 0 3px; font-size: 12.5px; }
.paquete-masivo-detalle input[type="text"] { font-size: 13px; padding: 8px 10px; }
.campo-checkbox-fragil {
    display: flex !important;
    align-items: center;
    gap: 6px;
    font-weight: 400 !important;
    cursor: pointer;
}
.campo-checkbox-fragil input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--rojo); }
.paquete-masivo-contenido { font-size: 12.5px; color: var(--gris); }
.etiqueta-fragil {
    display: inline-block;
    align-self: flex-start;
    background: #fee2e2;
    color: var(--rojo);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .3px;
    padding: 2px 7px;
    border-radius: 5px;
    margin-top: 2px;
}
.paquete-masivo-label-precio { margin-top: 6px; font-size: 12px; font-weight: 700; }
.check-paquete-masivo {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    margin-top: 10px;
    accent-color: var(--verde);
    cursor: pointer;
}
#btn-confirmar-todos-masivo { margin-top: 6px; width: 100%; }
#btn-confirmar-todos-masivo:disabled { opacity: .5; cursor: not-allowed; }

/* Pre-registro masivo del vendedor con cuenta (public/index.php): cada
   paquete declarado de una vez es un subcontenedor propio con sus
   subrecuadros de Comprador y Paquete, clonado desde <template> al
   presionar "+" — mismo patrón visual/JS que operador/entrega.php. */
.ficha-paquete-preregistro-masivo { position: relative; }
.ficha-paquete-preregistro-masivo-cabecera {
    list-style: none;
    cursor: pointer;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 0;
    padding-right: 34px;
}
.ficha-paquete-preregistro-masivo-cabecera::-webkit-details-marker { display: none; }
.ficha-paquete-preregistro-masivo[open] > .ficha-paquete-preregistro-masivo-cabecera { margin-bottom: 10px; }
.ficha-paquete-preregistro-masivo .paquete-masivo-flecha { background: var(--azul-claro); }
.ficha-paquete-preregistro-masivo[open] .paquete-masivo-flecha { transform: rotate(180deg); background: var(--azul); }
.ficha-paquete-preregistro-masivo-resumen-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ficha-paquete-preregistro-masivo-numero { color: var(--azul); font-size: 15px; }
.ficha-paquete-preregistro-masivo-resumen-datos { color: var(--gris); font-size: 12.5px; }
.btn-quitar-paquete-preregistro-esquina {
    position: absolute;
    top: -12px;
    right: -12px;
    margin-left: 0;
    background: #fff;
    z-index: 1;
}

/* Selector de tarifa de mora por día (operador/entrega.php): el
   operador puede reducirla como cortesía puntual al entregar, sin
   tocar la tarifa fija de Bs 1/día que usa el resto del sistema. */
.bloque-tarifa-mora-din { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--naranja); }

/* Autocompletado propio (no <datalist> nativo, que no se puede achicar
   ni darle scroll) para "Descripción del paquete": lista angosta justo
   debajo del campo, con altura máxima fija y scroll si hay muchas
   sugerencias. Vive suelta en <body> (creada por JS) con position:fixed
   y su posición se recalcula en cada apertura — así flota por encima de
   cualquier contenedor con overflow:hidden (ej. .formulario-fichas) en
   vez de quedar recortada dentro de él. */
.lista-sugerencias-descripcion {
    position: fixed;
    max-height: 180px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--borde);
    border-radius: 8px;
    box-shadow: 0 4px 14px rgba(0,0,0,.12);
    z-index: 999;
}
.opcion-sugerencia-descripcion {
    padding: 8px 12px;
    font-size: 13.5px;
    cursor: pointer;
}
.opcion-sugerencia-descripcion:hover { background: var(--bg); }
.opcion-sugerencia-descripcion:not(:last-child) { border-bottom: 1px solid var(--borde); }

/* Recepción y pre-registros masivos (operador/recepcion.php y
   operador/preregistros.php): a diferencia del resumen de
   texto de arriba, acá se quiere ver el DISEÑO REAL de cada ticket antes
   de imprimir el lote — todos apilados uno debajo del otro, con scroll
   propio para no alargar el modal sin límite. */
/* IMPORTANTE: el .ticket-container de acá adentro NUNCA se toca (ni
   padding, ni max-width, ni ninguna propiedad de tamaño) — debe quedar
   con las mismas dimensiones EXACTAS que el ticket real que se manda a
   imprimir ("igualito igualito a la de impresión", a pedido explícito
   del usuario). Tocar el padding del propio ticket (se probó 8px, 10px,
   16px de padding-right) comprimía su header (width:55%/45% fijos con
   contenido en white-space:nowrap) y provocaba superposiciones
   ("AKISITO" con el ícono de WhatsApp).
   En cambio, para correr el ticket (COMPLETO, intacto) un poco más
   hacia la derecha dentro del recuadro gris, se usa padding ASIMÉTRICO
   en este contenedor exterior (más a la izquierda que a la derecha):
   como .ticket-container tiene margin:0 auto, se centra dentro del
   espacio que quede tras restar este padding — si ese espacio es más
   angosto de un lado, el ticket completo (sin comprimirse) queda
   desplazado hacia el lado con menos padding. */
.lista-tickets-preview-completo {
    display: block;
    max-height: 420px;
    overflow-y: auto;
    margin-bottom: 4px;
    padding: 4px 12px 4px 28px;
    background: #f4f4f4;
    border-radius: 8px;
}
.lista-tickets-preview-completo > * + * {
    margin-top: 10px;
}
.preview-ticket-envoltura {
    display: block;
}
/* A pedido del usuario: el borde AZUL OSCURO del propio .ticket-container
   (el que envuelve TODO el ticket) crece un poco hacia la derecha, SOLO
   en la previsualización de pantalla. width fijo (no solo padding-right,
   que antes comprimía el contenido interno) porque ensancha el ticket
   ENTERO — el contenido de adentro usa anchos relativos (%, flex, grid),
   así que se reacomoda proporcionalmente al nuevo ancho total sin
   superponerse. Con ese ancho extra ya ganado, ahora SÍ hay lugar de
   sobra para separar el contenido (las cajas negras/celestes) del nuevo
   borde derecho más ancho — quedaban pegados directo al borde. */
.lista-tickets-preview-completo .ticket-container {
    width: calc(70mm + 14px);
    padding-right: 8px;
}

/* ============================================================
   Asistencia de operadores (operador/asistencia.php,
   admin/asistencias.php) — mismo lenguaje visual del resto del
   sistema: tarjetas .card, paleta --azul/--verde/--rojo/--naranja,
   badges redondeados, tabla .tabla-responsive.
   ============================================================ */
.tarjeta-asistencia { text-align: center; position: relative; }

.badge-proximo-marcado {
    display: inline-block;
    padding: 5px 14px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .3px;
    margin-bottom: 12px;
}
.badge-proximo-marcado-entrada { background: #dcfce7; color: #166534; }
.badge-proximo-marcado-salida { background: #fee2e2; color: #991b1b; }

/* Bloques "Hoy / Ayer / Antes de ayer" en "Tus últimos marcados"
   (operador/asistencia.php) — patrón "pestaña de carpeta": la etiqueta
   (.etiqueta-dia-asistencia) sobresale arriba-izquierda, por ENCIMA del
   marco que envuelve su tabla (.bloque-dia-asistencia) — el marco
   empieza una fila más abajo, a la altura del encabezado "Tipo/Fecha/
   Distancia", en vez de nacer detrás de la pestaña. Mismo color en
   ambos (pestaña y borde del marco) para que se lean como una sola
   pieza aunque no se solapen.
   .grupo-dia-asistencia es el envolvente SIN overflow (para que la
   pestaña, posicionada por fuera de .bloque-dia-asistencia, no quede
   recortada) — el overflow:hidden que sí necesita la tabla para
   respetar las esquinas redondeadas vive únicamente en .bloque-dia-
   asistencia, un nivel más adentro. */
.grupo-dia-asistencia {
    position: relative;
    margin-top: 32px;
}
.grupo-dia-asistencia:first-of-type { margin-top: 24px; }

.bloque-dia-asistencia {
    border: 2px solid transparent;
    /* Esquina superior izquierda recta (0), donde nace la pestaña, para
       que se una en escuadra con el marco — las otras 3 mantienen el
       redondeo normal. Orden: superior-izq, superior-der, inferior-der,
       inferior-izq. */
    border-radius: 0 10px 10px 10px;
    overflow: hidden;
}
.bloque-dia-asistencia table.tabla-responsive { margin: 0; border: none; border-radius: 0; }

.etiqueta-dia-asistencia {
    position: absolute;
    top: -26px;
    left: 0;
    display: inline-block;
    padding: 6px 16px;
    border-radius: 8px 8px 0 0;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .3px;
}
.bloque-dia-asistencia-hoy { border-color: var(--azul); }
.etiqueta-dia-asistencia-hoy { background: var(--azul); color: #fff; }

.bloque-dia-asistencia-ayer { border-color: var(--naranja); }
.etiqueta-dia-asistencia-ayer { background: var(--naranja); color: #fff; }

.bloque-dia-asistencia-anteayer { border-color: var(--gris); }
.etiqueta-dia-asistencia-anteayer { background: var(--gris); color: #fff; }

.mapa-asistencia-contenedor {
    width: 100%;
    height: 260px;
    border-radius: 12px;
    border: 1px solid var(--borde);
    margin-bottom: 12px;
    overflow: hidden;
    /* Leaflet necesita saber su propio tamaño para dibujar los tiles
       correctamente — sin esto, en algunos navegadores el mapa arranca
       colapsado a 0px de alto hasta el primer resize. */
    z-index: 0;
}
/* Emoji del mapa de asistencia (agencia 📦, operador 🧍) — a pedido
   explícito del usuario, que confirmó que se veían bien tal cual y
   prefiere mantenerlos así en vez de reemplazarlos por SVG. */
.icono-mapa-agencia, .icono-mapa-operador {
    font-size: 24px;
    text-align: center;
    line-height: 1;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,.35));
}

.estado-gps-asistencia {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 14px;
    background: var(--bg);
    border-radius: 10px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--texto);
    margin-bottom: 14px;
}
.estado-gps-punto {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.estado-gps-punto-buscando {
    background: var(--naranja);
    animation: estado-gps-parpadeo 1s ease-in-out infinite;
}
.estado-gps-punto-ok { background: var(--verde); }
.estado-gps-punto-error { background: var(--rojo); }
@keyframes estado-gps-parpadeo {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

/* Panel de admin: resumen de horas trabajadas por operador */
.filtro-asistencias-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.filtro-asistencias-form > div { flex: 1; min-width: 140px; }
.resumen-horas-operador {
    border: 1px solid var(--borde);
    border-radius: 12px;
    margin-bottom: 14px;
    overflow: hidden;
}
.resumen-horas-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    background: var(--bg);
    flex-wrap: wrap;
}
.resumen-horas-nombre { font-weight: 800; color: var(--azul); font-size: 15.5px; }
.resumen-horas-total {
    font-size: 20px;
    font-weight: 900;
    color: var(--verde);
    white-space: nowrap;
}
.resumen-horas-total small { font-size: 12px; font-weight: 700; color: var(--gris); display: block; text-align: right; }
.resumen-horas-detalle-toggle {
    background: none;
    border: none;
    color: var(--azul);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    padding: 0;
}
.aviso-marcado-incompleto {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #fff7ed;
    color: #c2410c;
    font-size: 11.5px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
}

/* Botones de acción por usuario en admin/usuarios.php (Desactivar,
   Editar teléfono, Cambiar contraseña, Editar permisos): antes eran
   botones .btn sueltos sin contenedor, con padding grande de formulario
   (12px 22px) — se amontonaban en filas irregulares y de distinto
   ancho. Acá van en su propia fila flexible, compactos y del mismo
   tamaño, para que se vean como un grupo ordenado en vez de una pila. */
.acciones-usuario {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.acciones-usuario .btn,
.acciones-usuario .btn-secundario {
    padding: 7px 12px;
    font-size: 12.5px;
    white-space: nowrap;
}
@media (max-width: 480px) {
    /* En celular no caben varios botones de texto largo ("Cambiar
       contraseña") en una sola fila sin que cada uno quede casi del
       ancho de la pantalla — se ven "chocados" aunque técnicamente el
       wrap los separa. Se apilan uno por fila, ancho completo, con
       espacio vertical claro entre ellos en vez de competir por espacio
       horizontal. */
    .acciones-usuario { flex-direction: column; align-items: stretch; gap: 8px; }
    .acciones-usuario .btn,
    .acciones-usuario .btn-secundario,
    .acciones-usuario .etiqueta-tu-cuenta {
        width: 100%;
        text-align: center;
        white-space: normal;
    }
}
.etiqueta-tu-cuenta {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 999px;
    background: #eff6ff;
    color: var(--azul);
    font-size: 12px;
    font-weight: 700;
}

/* admin/contador_codigos.php: el próximo código a asignar, destacado
   para que el admin lo vea de un vistazo antes de decidir si hace
   falta reajustar el contador. */
.proximo-codigo-destacado {
    display: inline-block;
    background: var(--azul);
    color: #fff;
    padding: 4px 12px;
    border-radius: 8px;
    font-size: 18px;
    letter-spacing: .5px;
}
