/* ============================================
   Pilarica PDA — estilos compartidos
   ============================================
   Extracción de las clases ESTRUCTURALES y de COMPONENTES de las pantallas de
   Recepción de almacén (`PurchaseOrders.razor.css` + `PurchaseOrderDetail.razor.css`),
   trasladadas a CSS global para que las pantallas de Envío / Palés / Consulta
   las hereden automáticamente y mantengan consistencia visual con Recepción.

   Nota: los `.razor.css` scoped de Recepción siguen funcionando porque el scoping
   genera un atributo único `[b-xxxxx]` que NO está en este CSS global. Misma
   clase, dos especificidades — el global aplica solo donde no hay scope.
*/

/* ============================================
   Scope `.pilarica-pda` — accesibilidad PDA
   ============================================
   Redeclaramos los tokens de texto/separador SOLO dentro del wrapper Pilarica
   (`<div class="tentalo-app pilarica-pda">`). Subimos contraste para presbicia
   leve y entorno de almacén (cumple WCAG 2.2 AA — 4.5:1 mínimo).

   Fuera de `.pilarica-pda` los tokens globales de `tentalo-app.css` permanecen
   intactos → cero impacto en Ventas/Tentalo/Logística/Comercio/Home/etc.

   Origen → destino (ratio sobre #f4f4f4 fondo Pilarica):
     --tentalo-text-secondary   #5a6a7a → #43536b   (5.13 → 7.39:1, AAA)
     --tentalo-text-tertiary    #8a9aaa → #56657a   (2.61 → 5.79:1, AA — antes fallaba)
     --tentalo-text-quaternary  #b0b8c0 → #7a8595   (1.78 → 3.46:1, decorativo AA large)
     --tentalo-separator-opaque #d0d4d8 → #b9bfc6   (mejora visibilidad de bordes)
*/
.pilarica-pda {
    --tentalo-text-secondary: #2c3e54;       /* aún más oscuro — datos secundarios bien contrastados sobre fondo claro */
    --tentalo-text-tertiary: #3d4f66;        /* prácticamente legible como primary */
    --tentalo-text-quaternary: #5a6a7a;      /* lo que antes era secondary, ahora aceptable para decoración */
    --tentalo-separator-opaque: #a8b0b8;     /* bordes más visibles */
}

/* Dark mode: el texto blanco ya cumple AAA, solo subimos contraste del tertiary
   gris-claro para que datos secundarios (fechas, lotes, qty) no se pierdan en el
   fondo oscuro. */
@media (prefers-color-scheme: dark) {
    .pilarica-pda {
        --tentalo-text-tertiary: #c8d2dc;   /* 4.1:1 → 8.5:1 sobre #0a1520 */
    }
}

/* ===== Top controls (search + filtros) ===== */
.po-controls {
    position: sticky;
    top: calc(var(--tentalo-header-height) + var(--tentalo-safe-top));
    z-index: 50;
    background: var(--tentalo-bg);
    padding: 12px 12px 10px 12px;
    border-bottom: 1px solid var(--tentalo-separator-opaque);
}

.po-search-row {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.po-search-input {
    flex: 1;
    min-height: 44px;
    padding: 10px 14px;
    font-size: 1rem;
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 10px;
    background: var(--tentalo-bg-secondary);
    color: var(--tentalo-text-primary);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.po-search-input:focus {
    border-color: var(--tentalo-primary);
    box-shadow: 0 0 0 3px rgba(36, 105, 206, 0.15);
}

.po-filter-row {
    display: flex;
    gap: 6px;
    margin-top: 10px;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 2px;
}

.po-filter-row::-webkit-scrollbar { display: none; }

.po-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 16px;
    min-height: 48px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
    background: var(--tentalo-bg-secondary);
    border: 1px solid var(--tentalo-separator-opaque);
    /* Radius rectangular alineado con el segmented control de abajo. Antes era 999px
       (pill) — incoherente con el lenguaje BC. Material 3 Filter Chips usan radius
       pequeño (8px) precisamente porque son selección única, no badges. */
    border-radius: 8px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.po-filter-chip:active { transform: scale(0.97); }

.po-filter-chip-active {
    background: var(--tentalo-primary);
    color: #fff;
    border-color: var(--tentalo-primary);
}

/* Badge contador sólido (patrón GitHub Primer Counter / Linear) en lugar de un
   `opacity: 0.65` sobre el texto. Da jerarquía estable independiente del color base
   del chip, y al invertir bg en estado activo se mantiene legible. */
.po-filter-chip-count {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 0.9375rem;
    padding: 2px 9px;
    background: rgba(0, 0, 0, 0.06);
    border-radius: 5px;
    line-height: 1.3;
}

.po-filter-chip-active .po-filter-chip-count {
    background: rgba(255, 255, 255, 0.22);
}

.po-count-row {
    margin-top: 8px;
    font-size: 1rem;
    color: var(--tentalo-text-primary);
    font-weight: 600;
}

/* Contenedor del botón "Cargar más" al final de la lista. El botón reutiliza el estilo estándar
   de la PDA (`recep-btn-secondary recep-btn-large`: outline blanco, full-width); aquí solo damos
   el padding horizontal (12px) para alinearlo con las tarjetas de `.po-list`. */
.po-load-more-wrap {
    padding: 4px 12px 16px;
}
/* Feedback de fin de lista: no queda nada más por cargar (en vez de ocultar el botón). */
.po-load-more-done {
    margin: 0;
    padding: 6px 0 2px;
    text-align: center;
    color: var(--tentalo-text-tertiary, #8a9aaa);
    font-size: 0.9375rem;
    font-weight: 500;
}

/* ===== Card list (lista de pedidos / palés) ===== */
.po-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
    list-style: none;
    margin: 0;
}

.po-card {
    position: relative;
    background: var(--tentalo-bg-secondary);
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 12px;
    padding: 18px 18px;
    cursor: pointer;
    min-height: 100px;
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.po-card:active {
    transform: scale(0.985);
    background: var(--tentalo-bg-tertiary);
}

/* Card NO clickable — para pantallas informativas (e.g. detail header) */
.po-card-static {
    cursor: default;
}

.po-card-static:active { transform: none; background: var(--tentalo-bg-secondary); }

.po-card-top,
.po-card-header {
    display: flex;
    /* `flex-start` para que los chips de la derecha, cuando hagan wrap a 2 líneas
       (caso 3 chips en Zebra estrecha), no centren verticalmente el VPE — el VPE
       queda anclado arriba a la altura del primer chip. Material 3 List Item trailing
       supporting text pattern. */
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
    min-height: 28px;
}

.po-card-no {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
    letter-spacing: 0.4px;
    font-variant-numeric: tabular-nums;
}

.po-card-route {
    display: inline-flex;
    align-items: center;
    font-size: 0.875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(36, 105, 206, 0.10);
    color: #1e3a8a;
    border: 1px solid rgba(36, 105, 206, 0.30);
    white-space: nowrap;
    line-height: 1;
    height: 26px;
    box-sizing: border-box;
}

/* Contenedor derecho de la cabecera del card (ruta + chip de kg). Mantiene ambos chips juntos
   a la derecha sin romper el `space-between` del `.po-card-header`. */
.po-card-header-right {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Chip de kg de la cabecera del pedido — réplica del `.group-weight` del Sales Tree Board de BC:
   píldora OSCURA (navy corporativo, estable en claro/oscuro) con texto blanco y tabular-nums.
   El tamaño (alto 28px, padding, fuente) lo unifica la regla de chips de `.pilarica-pda` (abajo). */
.po-card-weight {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    background: var(--tentalo-primary-dark);
    color: #FFFFFF;
    white-space: nowrap;
    line-height: 1;
    box-sizing: border-box;
    font-variant-numeric: tabular-nums lining-nums;
    flex-shrink: 0;
}

.po-card-customer,
.po-card-vendor {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
    margin-bottom: 8px;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.po-card-bottom,
.po-card-meta {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    font-size: 1.0625rem;
    color: var(--tentalo-text-secondary);
    font-weight: 500;
    align-items: center;
    font-variant-numeric: tabular-nums;
}

/* Botón "Comentarios" en la fila meta del card. Compact pill con icono + label.
   stopPropagation en el onclick evita que dispare ToggleOrder al pulsar. */
.po-card-comments-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    background: rgba(36, 105, 206, 0.08);
    color: var(--tentalo-primary, #2469ce);
    border: 1px solid rgba(36, 105, 206, 0.2);
    border-radius: 999px;
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
}
.po-card-comments-btn:hover {
    background: rgba(36, 105, 206, 0.15);
}
.po-card-comments-btn:active {
    transform: scale(0.97);
}

/* Modal de comentarios — reutiliza .confirm-dialog-*, añade filtro segmentado
   Todos/Cabecera/Líneas arriba y bullet decoration en cada item para diferenciarlos
   cuando el modal scrollea con muchas líneas. */
.order-comments-dialog {
    max-width: 520px;
}
.order-comments-filter {
    display: flex;
    gap: 6px;
    margin: 12px 0 8px;
    padding: 4px;
    background: var(--tentalo-bg-secondary, #f5f6f8);
    border-radius: 10px;
}
.order-comments-filter-chip {
    flex: 1 1 0;
    min-height: 36px;
    padding: 6px 10px;
    background: transparent;
    border: 1.5px solid transparent;
    border-radius: 8px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--tentalo-text-secondary, #6b7280);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
    font-family: inherit;
}
.order-comments-filter-chip:active:not(:disabled) {
    transform: scale(0.97);
}
.order-comments-filter-chip:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.order-comments-filter-chip-active {
    background: var(--tentalo-bg-primary, #fff);
    color: var(--tentalo-primary, #2469ce);
    border-color: var(--tentalo-primary, #2469ce);
}
.order-comments-filter-count {
    font-size: 0.75rem;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--tentalo-bg-tertiary, #e5e7eb);
    color: var(--tentalo-text-secondary, #6b7280);
    min-width: 18px;
    text-align: center;
}
.order-comments-filter-chip-active .order-comments-filter-count {
    background: var(--tentalo-primary, #2469ce);
    color: #fff;
}
.order-comments-list {
    list-style: none;
    margin: 4px 0;
    padding: 0;
    max-height: 50vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.order-comments-item {
    position: relative;
    padding: 10px 12px 10px 28px;
    border-radius: 8px;
    background: var(--tentalo-bg-secondary, #f5f6f8);
}
.order-comments-item::before {
    content: "";
    position: absolute;
    left: 12px;
    top: 16px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--tentalo-primary, #2469ce);
    flex-shrink: 0;
}
.order-comments-text {
    font-size: 0.95rem;
    line-height: 1.4;
    color: var(--tentalo-text-primary, #1a1a1a);
    word-break: break-word;
}
.order-comments-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 20px 0;
    color: var(--tentalo-text-secondary, #6b7280);
}

/* Selección múltiple (Dispatch) */
.po-card-selected {
    border-color: var(--tentalo-primary);
    background: rgba(36, 105, 206, 0.06);
    box-shadow: 0 0 0 3px rgba(36, 105, 206, 0.18);
}

.po-card-selected::after {
    content: "✓";
    position: absolute;
    top: 10px;
    right: 12px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--tentalo-primary);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
}

.po-card-disabled {
    opacity: 0.40;
    cursor: not-allowed;
    pointer-events: none;
    filter: grayscale(0.4);
}

/* ===== Sections (detalle palé / detail) ===== */
.po-section {
    background: var(--tentalo-bg-secondary);
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 12px;
    margin: 12px;
    padding: 14px 16px;
}

.po-section h2 {
    font-size: 0.8125rem;
    font-weight: 700;
    margin: 0 0 10px 0;
    color: var(--tentalo-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.7px;
}

/* ===== Line cards (líneas de palé / pedido) ===== */
.po-line-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.po-line-card {
    background: var(--tentalo-bg);
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 10px;
    padding: 14px 16px;
}

/* Línea totalmente empaletada — verde sutil para que se vea de un vistazo
   qué líneas del pedido ya están listas. */
.po-line-card-done {
    background: rgba(21, 128, 61, 0.07);
    border-color: rgba(21, 128, 61, 0.25);
}

.po-line-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 4px;
}

.po-line-item {
    font-size: 1rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.3px;
}

.po-line-qty {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
    font-variant-numeric: tabular-nums;
}

.po-line-desc {
    font-size: 0.9375rem;
    color: var(--tentalo-text-secondary);
    line-height: 1.3;
    margin-bottom: 6px;
}

.po-line-meta {
    font-size: 0.875rem;
    color: var(--tentalo-text-secondary);
    line-height: 1.4;
    margin-top: 4px;
}

.po-line-meta--danger { color: #dc2626; font-weight: 600; }
.po-line-meta--warning { color: #b45309; font-weight: 600; }

.po-line-input-row {
    display: flex;
    gap: 6px;
    margin-top: 8px;
    flex-wrap: wrap;
}

.po-line-input {
    flex: 1;
    min-width: 70px;
    min-height: 40px;
    padding: 8px 10px;
    font-size: 1rem;
    border: 1.5px solid #cbd5e1;
    border-radius: 8px;
    background: #ffffff;
    color: var(--tentalo-text-primary);
    outline: none;
    box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.02);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    font-variant-numeric: tabular-nums;
}

.po-line-input:focus {
    border-color: var(--tentalo-primary);
    box-shadow: 0 0 0 3px rgba(36, 105, 206, 0.18);
}

/* Estado de error: borde rojo + halo de focus también rojo. Aplicar mediante
   clase `.po-line-input--error` cuando la validación client-side falle (ej. cantidad
   que excede lo pendiente de empaletar). */
.po-line-input--error {
    border-color: #dc2626;
}
.po-line-input--error:focus {
    border-color: #dc2626;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18);
}

/* Bloque "campo con label" — sustituye al patrón de inputs sueltos. El label
   evita la ambigüedad entre Cantidad / Bultos cuando los inputs van juntos. */
.po-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 10px;
    flex: 1;
    min-width: 0;
}

.po-field-label {
    font-size: 1rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
    letter-spacing: 0.02em;
    margin-bottom: 2px;
}

.po-field-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Fila del campo Lote: input + botón ✏️ manual + botón 📷 cámara. */
.po-lot-row {
    display: flex;
    gap: 6px;
    align-items: stretch;
}

.po-lot-row .po-line-input {
    flex: 1;
    min-width: 0;
}

.po-lot-btn {
    flex: 0 0 auto;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 8px;
    background: var(--tentalo-bg);
    cursor: pointer;
    color: var(--tentalo-text-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.po-lot-btn svg {
    display: block;
}

.po-lot-btn:active:not(:disabled) {
    background: var(--tentalo-bg-tertiary);
    border-color: #94a3b8;
}

/* Lista de lotes disponibles que aparece bajo el campo Lote en modo manual.
   Misma estética que las po-line-card pero compacta — el operario tap para elegir. */
.po-lot-list {
    list-style: none;
    margin: 8px 0 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 240px;
    overflow-y: auto;
}

.po-lot-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 8px;
    background: var(--tentalo-bg);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.po-lot-option:active:not(:disabled) {
    background: var(--tentalo-bg-tertiary);
}

.po-lot-option-selected {
    border-color: var(--tentalo-primary);
    background: rgba(36, 105, 206, 0.06);
    box-shadow: 0 0 0 2px rgba(36, 105, 206, 0.18);
}

.po-lot-option-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.po-lot-option-no {
    font-weight: 600;
    color: var(--tentalo-text-primary);
    font-family: var(--tentalo-font-mono, monospace);
}

.po-lot-option-exp {
    color: var(--tentalo-text-secondary, #6b7280);
    font-size: 0.875rem;
}

.po-lot-option-qty {
    flex-shrink: 0;
    color: var(--tentalo-text-primary);
    font-weight: 600;
    font-size: 0.9375rem;
}

/* Compatibilidad: la clase antigua sigue existiendo por si alguna otra vista
   la referenciaba. */
.po-lot-option-meta {
    color: var(--tentalo-text-secondary, #6b7280);
    font-size: 0.9375rem;
}

.po-actions-row {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    flex-wrap: wrap;
}

/* ===== Buttons (Recepción look) ===== */
.recep-btn-primary,
.recep-btn-secondary,
.recep-btn-warning,
.recep-btn-success,
.recep-btn-danger {
    min-height: 44px;
    padding: 11px 16px;
    font-size: 1rem;
    font-weight: 600;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: opacity 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.recep-btn-primary { background: var(--tentalo-primary); color: #fff; }

.recep-btn-secondary {
    background: #ffffff;
    color: var(--tentalo-text-primary);
    border: 1.5px solid #cbd5e1;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.recep-btn-secondary:active:not(:disabled) {
    background: var(--tentalo-bg-tertiary);
    border-color: #94a3b8;
}

/* Outline ámbar tostado: misma jerarquía visual que `.recep-btn-danger`
   (outline rojo) — acción importante pero no destructiva. El fondo sólido
   naranja brillante anterior (#f59e0b) era demasiado agresivo en una pila
   de botones donde Cerrar palé ya tiene el peso visual primario. */
.recep-btn-warning {
    background: #ffffff;
    color: #92400e;
    border-color: #fcd34d;
}

.recep-btn-warning:active:not(:disabled) {
    background: #fffbeb;
    border-color: #f59e0b;
}

.recep-btn-success {
    background: #16a34a;
    color: #fff;
    box-shadow: 0 2px 6px rgba(22, 163, 74, 0.25);
}

.recep-btn-danger {
    background: #ffffff;
    color: #dc2626;
    border: 1.5px solid #fecaca;
}

.recep-btn-danger:active:not(:disabled) {
    background: #fef2f2;
    border-color: #fca5a5;
}

.recep-btn-large {
    width: 100%;
    min-height: 50px;
    padding: 14px 20px;
    font-size: 1rem;
    letter-spacing: 0.2px;
}

.recep-btn-primary:disabled,
.recep-btn-secondary:disabled,
.recep-btn-warning:disabled,
.recep-btn-success:disabled,
.recep-btn-danger:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
}

.recep-btn-primary:active:not(:disabled),
.recep-btn-warning:active:not(:disabled),
.recep-btn-success:active:not(:disabled),
.recep-btn-danger:active:not(:disabled) {
    transform: scale(0.98);
}

/* Variante de line-card que aloja una acción inline (icono trash a la derecha).
   Mismo patrón que `.reservation-item` de Recepción: flex row con contenido flex
   y botón de borrado fijo a la derecha. */
.po-line-card-actionable {
    display: flex;
    align-items: center;
    gap: 8px;
}

.po-line-card-content {
    flex: 1 1 auto;
    min-width: 0;
}

.po-line-delete-btn {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border: none;
    background: transparent;
    color: var(--tentalo-text-secondary, #6b7280);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
}

.po-line-delete-btn:hover:not(:disabled) {
    background: rgba(220, 38, 38, 0.08);
    color: #b91c1c;
}

.po-line-delete-btn:active:not(:disabled) {
    background: rgba(220, 38, 38, 0.18);
    color: #991b1b;
    transform: scale(0.95);
}

.po-line-delete-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* Zona de escaneo de QR para Expedición — visual prominente sin estructura
   de "card" con header. Borde discontinuo invita a "escanea aquí". El
   capturador invisible captura keystrokes del Zebra HID sin abrir el
   teclado del PDA; al detectar Enter (sufijo Zebra) auto-asigna sin
   confirmación. Pattern NN/g 2024: scanning UX = visual cue + zero friction. */
.expedicion-scan-area {
    position: relative;
    margin: 16px 12px;
    padding: 28px 20px;
    background: var(--tentalo-bg-primary, #ffffff);
    border: 2px dashed var(--tentalo-separator-opaque, #d1d5db);
    border-radius: 14px;
    text-align: center;
}

.expedicion-scan-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 14px;
    color: var(--tentalo-primary, #2469ce);
}

.expedicion-scan-icon svg {
    width: 100%;
    height: 100%;
}

.expedicion-scan-title {
    margin: 0 0 6px;
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--tentalo-text-primary, #111827);
}

.expedicion-scan-hint {
    margin: 0;
    font-size: 0.9375rem;
    color: var(--tentalo-text-secondary, #6b7280);
}

/* Acciones del palé (Cerrar / Reabrir / Reimprimir / Desempaletar) — botones
   apilados verticalmente, full-width, sin contenedor "po-section" para que el
   thumb llegue cómodamente en mobile. Destructivo (Desempaletar) al final.
   Margen lateral igual que `.po-section` (12px) para que los botones queden
   alineados con las cards de arriba. */
.po-pallet-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 16px 12px 0 12px;
}

/* Estado seleccionado en listas tipo selector (motivo de reapertura, etc.) */
.po-line-card.po-line-selected {
    border-color: var(--tentalo-primary);
    background: rgba(36, 105, 206, 0.06);
    box-shadow: 0 0 0 2px rgba(36, 105, 206, 0.18);
}

/* Diálogo de confirmación reutilizable — sustituye al JS confirm() del navegador.
   Patrón Material Design / iOS HIG: card centrada, backdrop dimmed con blur,
   botones side-by-side alineados a la derecha. Destructivo en rojo (NN/g). */
.confirm-dialog-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.42);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1200;
    padding: 16px;
}

.confirm-dialog {
    background: var(--tentalo-bg-primary, #ffffff);
    border-radius: 14px;
    padding: 20px 22px;
    max-width: 380px;
    width: 100%;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.24);
    animation: confirm-dialog-in 180ms cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes confirm-dialog-in {
    from { transform: scale(0.94); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.confirm-dialog-title {
    margin: 0 0 8px;
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--tentalo-text-primary, #111827);
    line-height: 1.3;
}

.confirm-dialog-message {
    margin: 0 0 18px;
    font-size: 1rem;
    color: var(--tentalo-text-secondary, #4b5563);
    line-height: 1.45;
    /* Respetar saltos de línea (\n) en el mensaje. Usado p.ej. en el confirm de
       Desempaletar para separar la advertencia principal de la guía alternativa. */
    white-space: pre-line;
}

/* Slot para contenido custom dentro del ConfirmDialog (dropdowns, listas
   seleccionables, inputs cortos). Spacing equivalente al .message para que la
   tipografía y el ritmo vertical coincidan con el resto del modal. */
.confirm-dialog-body {
    margin: 0 0 18px;
    max-height: 50vh;
    overflow-y: auto;
}

.confirm-dialog-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

/* Input numérico del modal "Etiquetas a imprimir" — input grande, fácil de
   pulsar en PDA, centrado, con tipografía tabular para que el cursor no salte
   al cambiar de dígitos. */
.label-count-input-row {
    display: flex;
    justify-content: center;
    margin: 0 0 18px;
}

.label-count-input {
    width: 120px;
    height: 56px;
    padding: 0 12px;
    text-align: center;
    font-size: 1.6rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    border: 2px solid var(--tentalo-border, #e5e7eb);
    border-radius: 12px;
    background: var(--tentalo-bg-primary, #fff);
    color: var(--tentalo-text-primary, #111827);
    outline: none;
    transition: border-color 0.15s ease;
    -moz-appearance: textfield;
}

.label-count-input::-webkit-outer-spin-button,
.label-count-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.label-count-input:focus {
    border-color: var(--tentalo-primary, #2469ce);
}

.label-count-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Modal "etiquetas por lote": lista scrolleable con un input por lote.
   Tamaño máximo limitado para que en PDA el operario vea siempre los botones
   Cancelar/Imprimir sin necesidad de scroll del modal entero. */
.label-by-lot-dialog {
    max-width: 480px;
    width: 100%;
}

.label-by-lot-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px 0;
    color: var(--tentalo-text-secondary, #4b5563);
    font-size: 1rem;
}

.label-by-lot-list {
    max-height: 50vh;
    overflow-y: auto;
    margin: 0 0 16px;
    padding: 4px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.label-by-lot-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--tentalo-border, #e5e7eb);
    border-radius: 10px;
    background: var(--tentalo-bg-secondary, #f9fafb);
}

.label-by-lot-info {
    flex: 1;
    min-width: 0;
}

.label-by-lot-item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 0.9375rem;
    color: var(--tentalo-text-primary, #111827);
}

.label-by-lot-desc {
    color: var(--tentalo-text-secondary, #4b5563);
    font-size: 0.9375rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.label-by-lot-meta {
    margin-top: 2px;
    font-size: 0.875rem;
    color: var(--tentalo-text-secondary, #6b7280);
    font-variant-numeric: tabular-nums;
}

.label-by-lot-input {
    width: 72px;
    height: 44px;
    font-size: 1.2rem;
    flex-shrink: 0;
}

.label-by-lot-input--invalid,
.label-by-lot-input--invalid:focus {
    border-color: var(--tentalo-danger, #b91c1c);
    background: var(--tentalo-danger-soft, #fef2f2);
}

.label-by-lot-error {
    margin: 0 0 12px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--tentalo-danger-soft, #fef2f2);
    color: var(--tentalo-danger, #b91c1c);
    font-size: 0.9375rem;
    font-weight: 500;
}

.confirm-dialog-btn {
    min-height: 44px;
    min-width: 96px;
    padding: 10px 18px;
    border-radius: 10px;
    font-weight: 600;
    font-size: 1rem;
    cursor: pointer;
    border: 1px solid transparent;
    font-family: inherit;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.confirm-dialog-btn-secondary {
    background: var(--tentalo-bg-primary, #fff);
    border-color: var(--tentalo-separator-opaque, #d1d5db);
    color: var(--tentalo-text-primary, #374151);
}

.confirm-dialog-btn-secondary:active:not(:disabled) {
    background: var(--tentalo-bg-tertiary, #f3f4f6);
}

.confirm-dialog-btn-primary {
    background: var(--tentalo-primary, #2469ce);
    color: #fff;
}

.confirm-dialog-btn-primary:active:not(:disabled) {
    background: #1d57b0;
}

.confirm-dialog-btn-destructive {
    background: #dc2626;
    color: #fff;
}

.confirm-dialog-btn-destructive:active:not(:disabled) {
    background: #b91c1c;
}

.confirm-dialog-btn:active:not(:disabled) {
    transform: scale(0.97);
}

.confirm-dialog-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.confirm-dialog-btn-block {
    flex: 1 1 auto;
    width: 100%;
}

/* Overlay translúcido con spinner para feedback de operaciones en curso
   (asignar línea a palé, crear palé, quitar línea de palé, etc.). Patrón
   estándar mobile: NN/g recomienda mostrar progreso explícito para
   acciones >400ms. z-index alto para superponerse a cualquier modal. */
.busy-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.32);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1100;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.busy-overlay-card {
    background: var(--tentalo-bg-primary, #ffffff);
    padding: 22px 28px;
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    min-width: 220px;
    max-width: 80vw;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
}

.busy-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--tentalo-separator-opaque, #e5e7eb);
    border-top-color: var(--tentalo-primary, #2469ce);
    border-radius: 50%;
    animation: busy-spin 0.7s linear infinite;
}

@keyframes busy-spin {
    to { transform: rotate(360deg); }
}

.busy-message {
    font-size: 1rem;
    color: var(--tentalo-text-primary);
    text-align: center;
    font-weight: 500;
}

/* ===========================================================================
   Palé anclado — barra flotante (pantalla de Preparación de palés).
   NO es un "carrito": es el palé físico de salida al que se asignan directo las
   líneas que el operario empaleta mientras esté anclado. Misma mecánica que la
   context-bar de Ventas (barra fija inferior) pero superficie SÓLIDA primary +
   icono de palé (sin gradientes, coherente con la PDA).
   z-index 800: por encima del contenido pero por DEBAJO del modal backdrop (900),
   para que al abrir "Añadir línea" no estorbe; y como vive dentro de .tentalo-app,
   queda oculto en la pantalla de éxito (que pone ese wrapper en display:none).
   =========================================================================== */
.pinned-pallet-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 800;
    display: flex;
    align-items: stretch;
    background: var(--tentalo-primary, #2469ce);
    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.18);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    animation: pinned-pallet-in 0.22s ease;
}

@keyframes pinned-pallet-in {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

/* La barra entra muchas veces al día; respeta a quien prefiere menos movimiento (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
    .pinned-pallet-bar { animation: none; }
}

.pinned-pallet-main {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 12px 14px 16px;
    min-height: 76px;
    background: transparent;
    border: 0;
    color: #fff;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    -webkit-tap-highlight-color: transparent;
}

.pinned-pallet-main:active { background: rgba(0, 0, 0, 0.12); }

.pinned-pallet-icon { flex-shrink: 0; display: flex; }
.pinned-pallet-icon svg { width: 40px; height: 40px; color: #fff; }

/* Cuerpo en 2 filas: fila 1 = "PALÉ ANCLADO" + Nº; fila 2 = nombre del agente + contadores.
   Así el nombre dispone de casi todo el ancho del banner (antes compartía fila con el Nº). */
.pinned-pallet-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.pinned-pallet-row1,
.pinned-pallet-row2 {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.pinned-pallet-row1 { gap: 10px; }

.pinned-pallet-label {
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    opacity: 0.95;
    line-height: 1.2;
    flex-shrink: 0;
    white-space: nowrap;
}

.pinned-pallet-no {
    font-size: 1.3rem;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    white-space: nowrap;
}

/* Nombre del agente en su propia fila → casi todo el ancho. Trunca con … solo si es muy largo. */
.pinned-pallet-route {
    font-size: 1.1rem;
    font-weight: 500;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1 1 auto;
}

.pinned-pallet-counts {
    font-size: 0.95rem;
    opacity: 0.95;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
    white-space: nowrap;
}

.pinned-pallet-unpin {
    flex-shrink: 0;
    width: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 0 6px;
    background: rgba(0, 0, 0, 0.14);
    border: 0;
    color: #fff;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.pinned-pallet-unpin svg { width: 26px; height: 26px; }
.pinned-pallet-unpin-text { font-size: 0.7rem; font-weight: 600; line-height: 1; letter-spacing: 0.2px; }
.pinned-pallet-unpin:active { background: rgba(0, 0, 0, 0.26); }

/* Reserva espacio al final del scroll de Preparación cuando hay palé anclado, para que
   el último pedido no quede tapado por la barra. La clase `pp-has-pinned` la añade
   PendingSalesOrders al wrapper .pilarica-pda solo si hay palé anclado. */
.pilarica-pda.pp-has-pinned .tentalo-content {
    padding-bottom: calc(108px + var(--tentalo-safe-bottom, 0px));
}

/* Mientras hay palé anclado, sube los toasts (componente Toast → `.feedback-toast`) por encima
   de la barra flotante para que no la tapen. La variable se hereda al toast porque está dentro
   de este wrapper en el DOM; ~64px ≈ alto de la barra + un pequeño margen. */
.pilarica-pda.pp-has-pinned {
    --pp-toast-lift: 80px;
}

/* Botón "Anclar palé" en la barra de controles de Preparación. Tap target ancho y etiquetado
   (mejor que un icono en el header para PDA, evita mis-taps). Estilo outline primary: acción
   prominente pero no tan pesada como un botón sólido. */
.pp-anchor-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 48px;
    margin-top: 10px;
    padding: 12px 16px;
    border: 1px solid var(--tentalo-primary, #2469ce);
    border-radius: 10px;
    background: var(--tentalo-bg-secondary);
    color: var(--tentalo-primary, #2469ce);
    font-size: 1rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.12s ease;
}

.pp-anchor-btn:active:not(:disabled) { background: rgba(36, 105, 206, 0.08); }
.pp-anchor-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.pp-anchor-btn svg { width: 20px; height: 20px; flex-shrink: 0; }

/* El modal de anclar es más bajo que el resto (`.po-modal` global usa max-height 92vh) para que,
   en una PDA usada con una mano, los controles (tipo / material / crear) queden en la zona
   alcanzable por el pulgar. Es bottom-sheet (`align-items:flex-end`), así que al limitar la altura
   el modal queda anclado abajo y su contenido scrollea dentro. Solo afecta a este modal. */
.po-modal.po-modal-pin {
    max-height: 70vh;
}

/* Empty state global (Pilarica). Antes vivía solo en `PurchaseOrders.razor.css`
   (scoped) — al usarse desde otras vistas se quedaba sin estilo. Lo subimos al
   global para garantizar centrado consistente. */
.pilarica-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60px 20px;
    color: var(--tentalo-text-secondary, #6b7280);
    gap: 16px;
    text-align: center;
}

/* Iconos semánticos en cabecera/línea para que el operario distinga de un
   vistazo: cabecera (pedido o palé) vs bulto físico dentro del palé. */
.po-card-icon {
    display: inline-block;
    width: 20px;
    height: 20px;
    margin-right: 8px;
    vertical-align: -4px;
    color: var(--tentalo-text-secondary, #6b7280);
    flex-shrink: 0;
}

/* Cabecera de palé en PalletDetail — mismo tamaño que la del pedido pero
   color algo más prominente porque es la entidad principal de la pantalla. */
.po-card-icon-pallet {
    color: var(--tentalo-text-primary, #1f2937);
}

/* Bulto/producto físico dentro del pedido o del palé. Pequeño, neutro. */
.po-line-icon {
    display: inline-block;
    width: 18px;
    height: 18px;
    margin-right: 7px;
    vertical-align: -3px;
    color: var(--tentalo-text-secondary, #6b7280);
    flex-shrink: 0;
}

/* Badge de variante para Sales Lines — mismo lenguaje que el Kanban
   (`line-variant`): chip pequeño junto al item, en color primario para que
   se distinga de un vistazo como "esto es la variante", no parte del item. */
.po-line-variant {
    display: inline-flex;
    align-items: center;
    margin-left: 8px;
    padding: 2px 7px;
    border-radius: 5px;
    background: rgba(36, 105, 206, 0.12);
    color: var(--tentalo-primary, #2469ce);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    font-family: var(--tentalo-font-mono, ui-monospace, monospace);
    border: 1px solid rgba(36, 105, 206, 0.22);
    vertical-align: 1px;
}

/* Línea con prealbarán impreso — fondo verde tenue + check verde a la izquierda
   del item. Indica al operario que esa línea ya se incluyó en una impresión de
   prealbarán (Sales Header."Shipping No." asignado y la línea marcada vía
   `MarkPreparedLinesAsPrinted` en Codeunit 80040). */
.po-line-card-printed {
    background: rgba(22, 163, 74, 0.06);
    border-color: rgba(22, 163, 74, 0.35);
}

.po-line-printed-check {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-right: 5px;
    vertical-align: -2px;
    color: #16a34a;
    flex-shrink: 0;
}

.po-line-meta--printed {
    color: #15803d;
    font-weight: 500;
}

.po-card-printed-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(22, 163, 74, 0.12);
    color: #15803d;
    border: 1px solid rgba(22, 163, 74, 0.35);
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    line-height: 1;
    height: 26px;
    box-sizing: border-box;
}

.po-card-printed-badge svg {
    flex-shrink: 0;
}

/* Pedidos CASH en la vista de PREPARADOS: fondo amarillo claro para distinguirlos
   de los Delegación. Mismos tokens que `.order-group.is-cash` del Sales Tree Board
   en BC (#FFFBEB body / #FEF3C7 cabecera / #FCD34D borde). La pantalla de PENDIENTES
   ya filtra por modalidad, así que aquí no aplica; este coloreado es solo histórico. */
.po-card.po-card-cash {
    background: #FFFBEB;
    border-color: #FCD34D;
}
.po-card.po-card-cash:hover { border-color: #F59E0B; }

/* ===========================================================================
   Segmented control Delegación / CASH / Todos (vista Pedidos preparados).
   Lenguaje rectangular tipo Linear/Stripe/GitHub Primer/BC (radius 10px) —
   más cercano al "seguimiento pedido" de BC que un pill 999px iOS, pero
   manteniendo la pill animada interior con `transform: translateX`. Tap target
   ≥44px para PDA con guantes (Apple HIG, WCAG 2.5.5 AAA). Texto inactivo
   contrastado para affordance (NN/g: los segmentos inactivos deben verse
   clickables, no labels).
   =========================================================================== */
.po-cash-toggle {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-items: stretch;
    /* Container gris-200 (más oscuro que el fondo del body) para dar contraste real
       con la pill blanca interior. WCAG 2.2 SC 1.4.11 (non-text contrast 3:1) exige
       diferenciación clara del estado seleccionado; con #F3F4F6 anterior, el ratio
       contra blanco era ~1.07:1 — insuficiente. Patrón iOS UISegmentedControl real. */
    background: #E5E7EB;
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 10px;
    padding: 4px;
    margin-top: 10px;
    width: 100%;
}

.po-cash-toggle-pill {
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 4px;
    width: calc((100% - 8px) / 3);
    background: #fff;
    border-radius: 7px;
    /* Triple sombra iOS-like + ring 0.5px: la sombra ancha aporta elevation real, la
       corta refuerza el borde inferior, el ring marca el contorno aún en pantallas
       PDA outdoor con poco rango dinámico (donde las sombras finas se pierden). */
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.12),
        0 1px 2px rgba(0, 0, 0, 0.08),
        0 0 0 0.5px rgba(0, 0, 0, 0.10);
    transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 0;
    pointer-events: none;
}

/* Variantes por nº de segmentos. El default `.po-cash-toggle` es 3 segmentos (CASH toggle
   en Pedidos preparados, APTO/NO APTO en modal inspección). `data-segments="4"` es para la
   vista de palés (Todos/Abiertos/Cerrados/Expedidos). Mismo container, distinta grid y
   pill width — la animación translateX(N*100%) sigue funcionando porque está calculada
   sobre el width relativo de la pill. */
.po-cash-toggle[data-segments="4"] {
    grid-template-columns: 1fr 1fr 1fr 1fr;
}
.po-cash-toggle[data-segments="4"] .po-cash-toggle-pill {
    width: calc((100% - 8px) / 4);
    /* Sombra SIMÉTRICA en 4-segmentos: con `0 1px 3px` (offset Y) la pill parecía
       flotando hacia arriba — el ojo lee la sombra inferior como elevación y la
       ausencia de sombra superior como "el techo está cortado". Pasamos a sombra
       centrada (`0 0 4px`) + ring perimetral 1px para mantener definición sin
       sesgar la verticalidad. */
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.08),
        0 1px 2px rgba(0, 0, 0, 0.06);
}
/* Segmentos 4-col: padding y fuente reducidos para que "Expedidos" + contador
   quepan sin recortes en pantallas PDA estrechas. */
.po-cash-toggle[data-segments="4"] .po-cash-toggle-segment {
    /* line-height: 1 fija la altura visual del label exactamente al alto del glyph,
       evitando que el text-box "alto" del default (1.2+) descentre la unidad
       label+contador respecto a la pill blanca. */
    padding: 0 4px;
    min-height: 40px;
    font-size: 0.875rem;
    line-height: 1;
    gap: 5px;
    /* baseline en lugar de center: alinea el número del contador con la base del
       texto en vez de centrar dos cajas con altos distintos (lo que producía la
       sensación de "no centrado" en la pantalla del Zebra). */
    align-items: baseline;
    /* Re-centramos verticalmente el bloque baseline-alineado dentro del segmento. */
    padding-top: 12px;
    padding-bottom: 12px;
}
.po-cash-toggle[data-segments="4"] .po-cash-toggle-segment-count {
    margin-left: 0;
    font-size: 0.75rem;
    /* Sin chip background — solo número dimmed. El chip gris añadía altura propia
       que descentraba al label en cells estrechos. Patrón Stripe / Linear: número
       atenuado tras el label, sin caja. */
    padding: 0;
    background: transparent;
    border-radius: 0;
    opacity: 0.55;
    color: var(--tentalo-text);
    font-weight: 600;
    line-height: 1;
}
.po-cash-toggle[data-segments="4"] .po-cash-toggle-segment.active .po-cash-toggle-segment-count {
    background: transparent;
    color: var(--tentalo-primary);
    opacity: 0.75;
}

.po-cash-toggle[data-active="all"] .po-cash-toggle-pill { transform: translateX(0); }
.po-cash-toggle[data-active="delegacion"] .po-cash-toggle-pill { transform: translateX(100%); }
.po-cash-toggle[data-active="cash"] .po-cash-toggle-pill { transform: translateX(200%); }

/* Estados palés (4 segmentos): Todos / Abiertos / Cerrados / Expedidos */
.po-cash-toggle[data-active="Open"] .po-cash-toggle-pill { transform: translateX(100%); }
.po-cash-toggle[data-active="Closed"] .po-cash-toggle-pill { transform: translateX(200%); }
.po-cash-toggle[data-active="Shipped"] .po-cash-toggle-pill { transform: translateX(300%); }

/* Estado expediciones (3 segmentos): Todos / Abiertas / Registradas. `Open` ya cubierto arriba.
   `Registered` queda en la 3ª posición. */
.po-cash-toggle[data-active="Registered"] .po-cash-toggle-pill { transform: translateX(200%); }

/* Inspección sanitaria (2 segmentos): APTO / NO APTO. Usado en ExpedicionDetail. */
.po-cash-toggle[data-active="Apto"] .po-cash-toggle-pill { transform: translateX(0); }
.po-cash-toggle[data-active="No Apto"] .po-cash-toggle-pill { transform: translateX(100%); }

/* Variante 2 segmentos (`data-segments="2"`): grid de 2 columnas + pill de 1/2 width.
   Usado en `PdaErrorLog` para el filtro "Mis errores / Todos". El default del container
   es 3 segmentos (CASH toggle); este modifier ajusta a 2 sin tocar el patrón existente. */
.po-cash-toggle[data-segments="2"] {
    grid-template-columns: 1fr 1fr;
}
.po-cash-toggle[data-segments="2"] .po-cash-toggle-pill {
    width: calc((100% - 8px) / 2);
}

/* Filtro log de errores (2 segmentos): Mis errores / Todos. */
.po-cash-toggle[data-active="onlyMine"] .po-cash-toggle-pill { transform: translateX(0); }
.po-cash-toggle[data-active="allUsers"] .po-cash-toggle-pill { transform: translateX(100%); }
/* Si HealthStatus está vacío (sin captura todavía), ocultamos la pill — el operario
   debe pulsar APTO o NO APTO conscientemente, no asumir un default visual. */
.po-cash-toggle[data-active=""] .po-cash-toggle-pill,
.po-cash-toggle:not([data-active]) .po-cash-toggle-pill {
    opacity: 0;
}

/* Badge contador dentro del segmento del conmutador. Diferencia del `.po-filter-chip-count`:
   aquí no usa fondo propio (la pill blanca ya da contraste) — solo cambia weight + tono. */
.po-cash-toggle-segment-count {
    margin-left: 6px;
    font-weight: 700;
    font-size: 0.875rem;
    opacity: 0.55;
    font-variant-numeric: tabular-nums;
}
.po-cash-toggle-segment.active .po-cash-toggle-segment-count {
    opacity: 0.75;
}

.po-cash-toggle-segment {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 13px 10px;
    min-height: 48px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--tentalo-text);
    background: transparent;
    border: 0;
    border-radius: 7px;
    cursor: pointer;
    transition: color 0.2s ease;
    -webkit-tap-highlight-color: transparent;
    white-space: nowrap;
}

.po-cash-toggle-segment.active {
    color: var(--tentalo-primary);
    font-weight: 700;
}

@media (hover: hover) {
    .po-cash-toggle-segment:not(.active):hover {
        color: var(--tentalo-primary);
    }
}

.po-cash-toggle-segment:focus-visible {
    outline: 2px solid var(--tentalo-primary);
    outline-offset: 2px;
}

/* Contenedor de "tags" a la derecha del header (CASH + Ruta). Pills coherentes,
   alineados, con gap claro. */
.po-card-tags {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
    /* Evita que los chips se coman el espacio del VPE en pantallas estrechas
       (Zebra ~410px). Si no entran en una sola línea, hacen wrap dentro de
       este bloque (no del header completo). */
    flex: 0 1 auto;
    max-width: 60%;
}

/* Badge CASH — mismo tamaño/peso visual que `.po-card-route` (pill típico), pero en
   amarillo cálido y con borde para que destaque sobre el fondo amarillo claro del card. */
.po-card-cash-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 999px;
    background: #FEF3C7;
    color: #92400E;
    border: 1px solid #FCD34D;
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    line-height: 1;
    height: 26px;
    box-sizing: border-box;
}

/* Badge "servido parcial" cuando una línea ya tiene Quantity Shipped > 0 pero
   no completa. Mismo patrón que `line-partial-badge` del Kanban — informa al
   operario que parte ya salió en otro envío. */
.po-line-partial-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(245, 158, 11, 0.12);
    color: #b45309;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.2px;
}

/* Card en estado "escaneo parcial" — la línea SO tiene Pallet Lines pero aún no cubre el
   Outstanding. Sutil borde para que el operario distinga la card sin saturarla de color
   (la barra de progreso ya transmite el estado). Cuando llega a 100% el backend dispara
   Confirmed→Prepared y la línea desaparece de la lista (pending=0 → filtrada). */
.po-line-card-partial {
    border-color: var(--tentalo-separator-opaque);
}

/* Barra de progreso de escaneo parcial. Patrón visual idéntico al de Recepción de
   Compras (`.line-card-progress` + `.line-card-progress-bar` + `.line-card-progress-pct`):
   wrap flex con barra fina 6px a la izquierda y % al lado derecho fuera de la barra.
   Colores brand (azul Tentalo) — sin semántica de "alerta" porque la barra ya es
   informativa por sí sola, no necesita color ámbar/rojo. */
.po-line-progress-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.po-line-progress {
    flex: 1;
    height: 6px;
    background: var(--tentalo-bg-tertiary);
    border-radius: 3px;
    overflow: hidden;
    border: 1px solid var(--tentalo-separator-opaque);
}

.po-line-progress-fill {
    height: 100%;
    min-width: 2px;
    background: linear-gradient(90deg, var(--tentalo-primary), #6ea8ff);
    border-radius: 3px;
    transition: width 0.3s ease;
}

.po-line-progress-pct {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--tentalo-text-secondary);
    min-width: 36px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Toggle "Ver / Ocultar lotes escaneados" — pequeño button text-only bajo la barra de
   progreso. Sin background, solo color + chevron animado. Tap dispara expand/collapse
   del desglose. stopPropagation en razor para no chocar con el tap del card (que abre
   el modal de añadir). */
.po-line-scans-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 8px;
    padding: 4px 0;
    background: transparent;
    border: 0;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--tentalo-primary);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.po-line-scans-toggle-chevron {
    transition: transform 0.2s ease;
}

.po-line-scans-toggle-chevron-open {
    transform: rotate(180deg);
}

.po-line-scans-loading,
.po-line-scans-empty {
    margin-top: 6px;
    padding: 8px 10px;
    font-size: 0.875rem;
    color: var(--tentalo-text-secondary);
    background: rgba(0, 0, 0, 0.03);
    border-radius: 6px;
    text-align: center;
}

/* Lista de scans dentro del card expandido. Cada item es una "mini-card" con lote,
   cantidad, palé, fecha y un botón papelera al lado derecho. Pensado para PDA: tap
   targets grandes, separación clara entre filas. */
.po-line-scans-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.po-line-scans-item {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 10px;
    align-items: center;
    padding: 8px 10px;
    background: #fff;
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 6px;
}

.po-line-scans-info {
    grid-column: 1;
    grid-row: 1;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.po-line-scans-lot {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--tentalo-text);
    font-variant-numeric: tabular-nums;
}

.po-line-scans-qty {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--tentalo-primary);
    font-variant-numeric: tabular-nums;
}

.po-line-scans-meta {
    grid-column: 1;
    grid-row: 2;
    font-size: 0.8125rem;
    color: var(--tentalo-text-secondary);
}

.po-line-scans-delete {
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--tentalo-separator-opaque);
    border-radius: 6px;
    color: var(--tentalo-error, #b91c1c);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
    -webkit-tap-highlight-color: transparent;
}

.po-line-scans-delete:active:not(:disabled) {
    background: rgba(185, 28, 28, 0.08);
    border-color: rgba(185, 28, 28, 0.4);
}

.po-line-scans-delete:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Dot de disponibilidad de stock — mismo código de colores que el Kanban
   (Codeunit 80000 Sales Tree Mgt.ComputeAvailability):
   verde = stock cubre línea + hermanas; azul = parcial; rojo = sin stock; n/a = no aplica. */
.po-line-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: 1px;
    flex-shrink: 0;
}

.po-line-dot[data-avail="green"] { background: #047857; }
.po-line-dot[data-avail="blue"]  { background: #1D4ED8; }
.po-line-dot[data-avail="red"]   { background: #8B2838; }
.po-line-dot[data-avail="na"]    { background: var(--tentalo-separator-opaque, #d1d5db); }

/* ===== Header — chip de estado a la derecha ===== */
.po-status-chip {
    display: inline-flex;
    align-items: center;
    padding: 5px 11px;
    border-radius: 999px;
    font-size: 0.875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    white-space: nowrap;
}

.po-status-open {
    background: rgba(36, 105, 206, 0.12);
    color: #1e3a8a;
    border: 1px solid rgba(36, 105, 206, 0.35);
}

.po-status-closed {
    background: rgba(180, 83, 9, 0.12);
    color: #7c2d12;
    border: 1px solid rgba(180, 83, 9, 0.40);
}

.po-status-shipped {
    background: rgba(21, 128, 61, 0.12);
    color: #14532d;
    border: 1px solid rgba(21, 128, 61, 0.40);
}

/* ===== Empty / loading ===== */
.tentalo-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60px 20px;
    color: var(--tentalo-text-secondary);
    gap: 12px;
    text-align: center;
}

.tentalo-empty-inline {
    color: var(--tentalo-text-secondary);
    font-size: 0.9375rem;
    margin: 8px 0;
    text-align: center;
}

.tentalo-loading {
    text-align: center;
    padding: 40px 20px;
    color: var(--tentalo-text-secondary);
    font-size: 1rem;
}

/* ===== Footer fijo con CTA principal (cerrar palé, expedir) ===== */
.po-cta-footer {
    position: sticky;
    bottom: 0;
    background: var(--tentalo-bg);
    padding: 12px;
    border-top: 1px solid var(--tentalo-separator-opaque);
    z-index: 30;
}

/* ===== Build Pallet — captura de escaneo ===== */
.build-scan-input-wrap {
    display: flex;
    gap: 6px;
}

.build-scan-input {
    flex: 1;
    min-height: 50px;
    padding: 12px 14px;
    font-size: 1.125rem;
    font-weight: 600;
    border: 1.5px solid #cbd5e1;
    border-radius: 10px;
    background: #ffffff;
    color: var(--tentalo-text-primary);
    outline: none;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.5px;
    box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.02);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.build-scan-input:focus {
    border-color: var(--tentalo-primary);
    box-shadow: 0 0 0 3px rgba(36, 105, 206, 0.18);
}

.build-scan-hint {
    margin-top: 8px;
    text-align: center;
    font-size: 0.875rem;
    color: var(--tentalo-text-secondary);
    font-style: italic;
}

.po-cta-row {
    padding: 12px;
    display: flex;
    justify-content: stretch;
}

.po-cta-row > .recep-btn-large {
    width: 100%;
}

.po-cta-footer {
    position: sticky;
    bottom: 0;
    background: var(--tentalo-bg-primary, #ffffff);
    padding: 12px;
    border-top: 1px solid var(--tentalo-separator-opaque);
}

.po-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 900;
}

.po-modal {
    background: var(--tentalo-bg-primary, #ffffff);
    width: 100%;
    max-width: 600px;
    max-height: 92vh;
    overflow-y: auto;
    border-radius: 18px 18px 0 0;
    padding: 16px;
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.18);
    animation: po-modal-slide-up 0.2s ease-out;
}

/* Handle horizontal arriba del modal — affordance de swipe-down para cerrar.
   Mismo patrón que `line-modal-handle` de Recepción. */
.po-modal-handle {
    width: 100%;
    padding: 6px 0 12px 0;
    margin: -10px 0 4px 0;
    display: flex;
    justify-content: center;
    cursor: grab;
    touch-action: none;
}

.po-modal-handle::before {
    content: "";
    width: 40px;
    height: 4px;
    background: var(--tentalo-separator-opaque, #d1d5db);
    border-radius: 2px;
}

.po-modal-handle:active {
    cursor: grabbing;
}

/* Botón de acción que ocupa todo el ancho del modal (regla local: usado por
   el "Añadir" del modal de preparación de palés). */
.po-btn-block {
    width: 100%;
}

.po-modal h3 {
    margin: 0 0 14px;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
}

@keyframes po-modal-slide-up {
    from { transform: translateY(40px); opacity: 0.6; }
    to   { transform: translateY(0); opacity: 1; }
}

/* ============================================
   Post-success overlay (fin de flujo: cerrar palé, registrar expedición, etc.)
   Mismo patrón que la pantalla de éxito de Recepción.
   ============================================ */

.post-progress-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: rgba(36, 105, 206, 0.18);
    z-index: 9999;
    overflow: hidden;
}

.post-progress-bar::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 30%;
    background: var(--tentalo-primary);
    animation: post-progress-slide 1.2s ease-in-out infinite;
}

@keyframes post-progress-slide {
    0%   { left: -30%; }
    100% { left: 100%; }
}

.btn-inline-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btn-spinner-rotate 0.7s linear infinite;
    margin-right: 8px;
    vertical-align: -2px;
}

@keyframes btn-spinner-rotate {
    to { transform: rotate(360deg); }
}

.post-success {
    position: fixed;
    inset: 0;
    background: var(--tentalo-bg);
    z-index: 1000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    overflow-y: auto;
    padding: 60px 20px 24px;
}

.post-success-card {
    background: #fff;
    border-radius: 18px;
    padding: 28px 24px;
    width: 100%;
    max-width: 420px;
    box-shadow: 0 4px 20px rgba(15, 23, 42, 0.08);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.post-success-check {
    color: #16a34a;
    opacity: 0;
    animation: post-success-fade-in 0.2s ease-out forwards;
}

@keyframes post-success-fade-in {
    to { opacity: 1; }
}

.post-success-title {
    margin: 4px 0 0;
    font-size: 1.1875rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
    text-align: center;
}

.post-success-receipt-line {
    margin: 0 0 18px;
    font-size: 1rem;
    color: var(--tentalo-text-secondary);
    text-align: center;
}

.post-success-receipt-no {
    font-weight: 600;
    color: var(--tentalo-text-primary);
    font-variant-numeric: tabular-nums;
    margin-left: 4px;
}

.post-success-actions {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.post-success-cta {
    font-weight: 600;
}

/* ============================================
   Date filter strip — patrón Kanban Tatel: chips horizontal
   con dia/numero/mes + count, scroll-snap táctil. Default: hoy.
   ============================================ */

.po-date-filter {
    display: flex;
    gap: 8px;
    align-items: stretch;
    margin-top: 10px;
}

.po-date-strip {
    flex: 1;
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    /* Padding vertical generoso para que la sombra del pulso (overdue) no se
       recorte: overflow-x: auto implica overflow-y: hidden de facto. */
    padding: 6px 2px 8px 2px;
    scrollbar-width: thin;
}

.po-date-strip::-webkit-scrollbar {
    height: 4px;
}

.po-date-strip::-webkit-scrollbar-thumb {
    background: var(--tentalo-separator-opaque);
    border-radius: 2px;
}

.po-date-chip {
    flex: 0 0 auto;
    width: 92px;
    min-height: 100px;
    padding: 10px 8px 10px 8px;
    background: var(--tentalo-bg);
    border: 1.5px solid var(--tentalo-separator-opaque);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 1px;
    cursor: pointer;
    scroll-snap-align: center;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
    font-family: inherit;
}

.po-date-chip:active {
    transform: scale(0.97);
}

.po-date-chip-dow {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--tentalo-text-secondary);
    letter-spacing: 0.5px;
    line-height: 1;
}

.po-date-chip-day {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.po-date-chip-month {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--tentalo-text-secondary);
    letter-spacing: 0.5px;
    line-height: 1;
    margin-bottom: 5px;
}

.po-date-chip-meta {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--tentalo-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 4px;
    text-align: center;
    white-space: nowrap;
    /* Empuja el meta al fondo del chip para que el espacio meta↔bottom sea
       igual al espacio DOW↔top (ambos = padding 10px). Antes el meta quedaba
       pegado al month y el espacio abajo era mayor → asimetría visual. */
    margin-top: auto;
}

.po-date-chip-dot {
    color: #b91c1c;
    font-size: 0.875rem;
    line-height: 1;
}

.po-date-chip-empty {
    opacity: 0.55;
}

.po-date-chip-today .po-date-chip-day,
.po-date-chip-today .po-date-chip-dow,
.po-date-chip-today .po-date-chip-month {
    color: #b91c1c;
}

.po-date-chip-selected {
    border-color: #b91c1c;
    background: #fff5f5;
    box-shadow: 0 0 0 1px #b91c1c inset;
}

.po-date-chip-selected .po-date-chip-day {
    color: #b91c1c;
}

/* Sábado/domingo en gris para guiar la planificación. */
.po-date-chip-weekend {
    background: var(--tentalo-bg-secondary, #f3f4f6);
    color: var(--tentalo-text-secondary, #6b7280);
}

.po-date-chip-weekend .po-date-chip-day,
.po-date-chip-weekend .po-date-chip-dow,
.po-date-chip-weekend .po-date-chip-month {
    color: var(--tentalo-text-secondary, #6b7280);
}

/* Días pasados con pedidos pendientes = ATRASADO. Misma alarma visual y misma
   animación de pulso que el Kanban (overdueStrongBlink) — todos los pedidos
   visibles aquí están en Kanban=Confirmed, así que aplicamos el nivel "fuerte"
   (las del operario están "en preparación" → tienen que salir ya). */
@keyframes po-date-chip-overdue-blink {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(139, 40, 56, 0.0);
        border-color: #dc2626;
    }
    50% {
        box-shadow: 0 0 0 3px rgba(139, 40, 56, 0.32);
        border-color: #5C1A23;
    }
}

.po-date-chip-overdue {
    border-color: #dc2626;
    border-width: 2px;
    background: #fee2e2;
    font-weight: 700;
    animation: po-date-chip-overdue-blink 0.9s ease-in-out infinite;
}

.po-date-chip-overdue .po-date-chip-day,
.po-date-chip-overdue .po-date-chip-dow,
.po-date-chip-overdue .po-date-chip-month {
    color: #b91c1c;
}

.po-date-chip-overdue .po-date-chip-dot,
.po-date-chip-overdue .po-date-chip-count {
    color: #b91c1c;
}

/* Si está seleccionado Y atrasado, paramos la animación (ya el seleccionado destaca)
   y forzamos lectura legible — mismo patrón que el Kanban. */
.po-date-chip-selected.po-date-chip-overdue {
    animation: none;
    border-color: #b91c1c;
    background: #fee2e2;
    box-shadow: 0 0 0 1px #b91c1c inset;
}

/* Respeto a `prefers-reduced-motion` — los usuarios con este ajuste no quieren
   animaciones constantes (NN/g/WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
    .po-date-chip-overdue {
        animation: none;
    }
}

.po-date-actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.po-date-action {
    min-width: 64px;
    min-height: 48px;
    padding: 8px 12px;
    background: var(--tentalo-bg);
    border: 1.5px solid var(--tentalo-separator-opaque);
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
    font-family: inherit;
}

.po-date-action:active {
    transform: scale(0.96);
}

.po-date-action-active {
    border-color: #b91c1c;
    background: #fff5f5;
    color: #b91c1c;
}

/* ============================================
   Overrides scoped a `.pilarica-pda`
   ============================================
   Subimos tamaños de clases COMPARTIDAS (`tentalo-header-*`, `tentalo-empty-*`,
   etc. — definidas en `tentalo-app.css`) solo dentro del wrapper Pilarica para
   no afectar Ventas/Tentalo/Logística/Comercio/Home. Mismas reglas, mayor
   especificidad por el ancestro `.pilarica-pda`.
*/
.pilarica-pda .tentalo-header-title {
    font-size: 1.25rem;
    font-weight: 700;
}

.pilarica-pda .tentalo-empty-inline {
    font-size: 0.9375rem;
    color: var(--tentalo-text-secondary);
}

.pilarica-pda .tentalo-loading-container p {
    font-size: 1rem;
    color: var(--tentalo-text-secondary);
    font-weight: 500;
}

.pilarica-pda .busy-message {
    font-size: 1rem;
    font-weight: 600;
    color: var(--tentalo-text-primary);
}

/* Badge "IMPRESO" (visible en Pedidos preparados) — texto pequeño, hay que subirlo */
/* Chips del header (`.po-card-tags`) — altura y padding UNIFICADOS para los 3
   (`.po-card-route` + `.po-card-cash-badge` + `.po-card-printed-badge`) para que no
   se vean amontonados / desproporcionados al renderizarse juntos. */
.pilarica-pda .po-card-route,
.pilarica-pda .po-card-cash-badge,
.pilarica-pda .po-card-printed-badge,
.pilarica-pda .po-card-weight {
    font-size: 0.875rem;
    font-weight: 700;
    padding: 5px 11px;
    height: 28px;
    line-height: 1;
}

/* Descripción de línea (item desc) en cards de líneas: texto crítico para identificar
   el producto en la PDA, debe leerse de un vistazo. */
.pilarica-pda .po-line-desc {
    font-size: 1.0625rem;
    color: var(--tentalo-text-primary);
    font-weight: 600;
    line-height: 1.35;
}

.pilarica-pda .po-line-meta {
    font-size: 1.0625rem;
    color: var(--tentalo-text-secondary);
    font-weight: 500;
    line-height: 1.35;
}

/* Number / item code en cards de línea */
.pilarica-pda .po-line-item {
    font-size: 1.125rem;
    font-weight: 700;
}

.pilarica-pda .po-line-qty {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--tentalo-text-primary);
}

/* Input de búsqueda + inputs en general: que no se vea raquítico */
.pilarica-pda .po-search-input,
.pilarica-pda .po-line-input {
    font-size: 1.0625rem;
    min-height: 48px;
}

/* Placeholder de inputs en PDA Pilarica: el gris-claro default de los browsers
   (~#A0A0A0 con opacity 0.54) no cumple WCAG en almacén. Forzamos un gris
   medio oscuro con opacity 1 para que se lea desde lejos. */
.pilarica-pda .po-search-input::placeholder,
.pilarica-pda .po-line-input::placeholder,
.pilarica-pda input::placeholder {
    color: #5a6a7a;
    opacity: 1;
}

/* ===========================================================================
   Pedido EN PREPARACIÓN — alguien (otro operario) ya ha asignado al menos
   una línea de este SO a un palé abierto. Sirve de aviso visual al operario
   que entra a la vista de pedidos pendientes, para que NO empiece a preparar
   ese pedido en paralelo (riesgo: split de líneas en dos palés simultáneos
   por dos operarios).

   Lenguaje: NO usar rojo (alarma) ni amarillo (warning); usamos el azul Tentalo
   en saturación media — "actividad en curso", no "peligro". Patrón inspirado
   en Linear (cards "in progress" con left-border + halo sutil) y en el estado
   "active" de Stripe Dashboard (pulse de box-shadow sin alterar dimensiones).
   =========================================================================== */
.po-card.po-card-in-preparation {
    /* Conservamos el border-width = 1px del estado base para no provocar
       layout shift; sólo cambiamos el color del border a azul Tentalo sólido,
       más visible que el separator gris default. */
    border-color: #2469CE;
    animation: po-card-pulse 2s ease-in-out infinite;
}

/* Halo expandido que aparece/desaparece — simula un "ping" sin desplazar
   el contenido (box-shadow no toca el flujo del layout). El delta de spread
   (0 → 6px) es pequeño para no resultar agresivo en una lista densa de
   ~10 pedidos visibles a la vez en pantalla PDA. */
@keyframes po-card-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(36, 105, 206, 0.40); }
    50% { box-shadow: 0 0 0 6px rgba(36, 105, 206, 0); }
}

/* Accesibilidad — respetar prefers-reduced-motion (WCAG 2.3.3 AAA).
   Para usuarios con esa preferencia, mantenemos el border azul (señal
   estática) pero quitamos el pulse. */
@media (prefers-reduced-motion: reduce) {
    .po-card.po-card-in-preparation { animation: none; }
}

/* ===== Pedido CONTRAREEMBOLSO (COD) — badge "Contrareembolso" con parpadeo burdeos =====
   Réplica EXACTA del `.cod-badge` del Sales Tree Board: el parpadeo va en el BADGE, NO en el card.
   Así no compite con el parpadeo azul del card cuando el pedido está en preparación — ambas
   señales conviven (card azul "en preparación" + badge burdeos "contrareembolso"). */
.po-card-cod-badge {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    width: fit-content;
    margin: 2px 0 6px;
    padding: 4px 11px;
    border-radius: 999px;
    background: #8B2838;
    color: #FFFFFF;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.02em;
    animation: po-card-cod-pulse 2.4s ease-in-out infinite;
}
/* Anillo "respiro" burdeos (rgb 139,40,56) — mismo timing/forma que `cod-pulse` del board. */
@keyframes po-card-cod-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(139, 40, 56, 0.40); }
    70%  { box-shadow: 0 0 0 7px rgba(139, 40, 56, 0); }
    100% { box-shadow: 0 0 0 0 rgba(139, 40, 56, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .po-card-cod-badge { animation: none; }
}

/* Badge "Preparando: USER" — fila adicional dentro del card, debajo del
   meta row. Se renderiza sólo cuando isInPreparation = true; cuando no
   tenemos el User ID (PreparingUser vacío por algún edge case), el badge
   se reduce a "En preparación". Separador top sutil para no fusionarse
   con el meta row. */
.po-card-preparing-by {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(36, 105, 206, 0.10);
    color: #1e3a8a;
    border: 1px solid rgba(36, 105, 206, 0.30);
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

.po-card-preparing-by strong {
    font-weight: 700;
    /* User IDs son códigos cortos en mayúsculas (LPEREDA, JFERNANDEZ…); damos
       un leve tracking para mejorar lectura desde lejos en PDA con guantes. */
    letter-spacing: 0.3px;
}

.po-card-preparing-icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

/* ===========================================================================
   PDA Error Log (pantalla /pilarica/log-errores) — Refactor 2026-05-20 (Fase 2)
   Estilos específicos para entradas del log. Reutiliza tokens de `.po-card-*`
   añadiendo modifiers para origen del error (BC vs PDA) y estado de resolución.
   =========================================================================== */

/* Chip de origen del error: BC = rojo serio (bug / data corruption esperable),
   PDA = ámbar (HTTP / validación / red — menos crítico típicamente). Hereda
   estructura de `.po-status-chip` (ya definido para Scan Log) y solo cambia
   color de fondo / borde. */
.po-status-chip-error {
    background: #fee2e2;
    color: #991b1b;
    border: 1px solid #fca5a5;
}

.po-status-chip-warn {
    background: #fef3c7;
    color: #92400e;
    border: 1px solid #fcd34d;
}

/* Chip "Resuelto" — verde suave, contraste con el resto de meta. */
.po-resolved-chip {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    font-size: 0.75rem;
    font-weight: 600;
    background: #d1fae5;
    color: #065f46;
    border: 1px solid #6ee7b7;
    border-radius: 999px;
    margin-left: 6px;
}

/* Card cuando el error está marcado Resolved — opacidad reducida para que
   el operario distinga visualmente lo pendiente de lo cerrado. */
.po-card-resolved {
    opacity: 0.55;
    background: #f9fafb;
}

/* Texto del error — multi-línea, fuente monospace pequeña para que el operario
   o admin pueda copiar/leer el mensaje técnico de BC sin formato perdido. */
.po-error-text {
    margin-top: 8px;
    padding: 8px 10px;
    background: #f1f5f9;
    border-left: 3px solid #94a3b8;
    border-radius: 4px;
    font-family: ui-monospace, "SF Mono", Consolas, "Roboto Mono", monospace;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: #334155;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 12em;
    overflow-y: auto;
}

/* Variante PREVIEW (en la lista): truncado a 3 líneas con elipsis. El error
   completo se ve en el modal de detalle al tap-ear el card. */
.po-error-text-preview {
    max-height: 4em;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    /* Sin scroll vertical en la preview — el operario tapa para ver completo. */
}

/* === Modal de detalle del error === */
/* Hereda layout y backdrop de `.confirm-dialog-*` (coherencia con el resto
   de modales de la app). `.log-detail-dialog` solo ensancha un poco y permite
   altura mayor — los errores BC pueden ser largos (stack traces, listas
   consolidadas de múltiples SOs). */
.log-detail-dialog {
    max-width: 600px;
    width: 92vw;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
}

/* Bloque de metadatos del error (fecha, usuario, proceso, contexto). Lista
   compacta clave:valor. */
.log-detail-meta {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
    margin-bottom: 12px;
    padding: 10px 12px;
    background: #f8fafc;
    border-radius: 6px;
    font-size: 0.875rem;
    color: #334155;
}

.log-detail-meta strong {
    color: #1e293b;
    font-weight: 600;
    margin-right: 4px;
}

/* Texto completo del error en el modal — mismo estilo monospace que la
   preview pero sin truncar; scroll interno si pasa de cierto alto. */
.log-detail-error {
    flex: 1 1 auto;
    min-height: 6em;
    max-height: 50vh;
    overflow-y: auto;
    padding: 12px 14px;
    background: #f1f5f9;
    border-left: 3px solid #94a3b8;
    border-radius: 4px;
    font-family: ui-monospace, "SF Mono", Consolas, "Roboto Mono", monospace;
    font-size: 0.875rem;
    line-height: 1.45;
    color: #1e293b;
    white-space: pre-wrap;
    word-break: break-word;
    /* Permite selección manual del texto como fallback al botón Copiar. */
    user-select: text;
}

/* Feedback del botón Copiar (transitorio). Aparece bajo el bloque del error
   con animación de fade-in suave. */
.log-detail-copy-feedback {
    margin-top: 8px;
    padding: 6px 10px;
    background: #d1fae5;
    color: #065f46;
    border: 1px solid #6ee7b7;
    border-radius: 4px;
    font-size: 0.8125rem;
    font-weight: 600;
    animation: log-detail-copy-fade 0.2s ease-out;
}

@keyframes log-detail-copy-fade {
    from { opacity: 0; transform: translateY(-2px); }
    to { opacity: 1; transform: translateY(0); }
}
