/* ─────────────────────────────────────────────────────────────
   Marketplace (nombre provisorio) — hoja de estilos
   Shell compartido (Fase 0.5): tokens, layout base, auth, botones,
   formularios, modal genérico, badges. Cada fase agrega sus propias
   secciones a partir de acá — sin sobre-diseñar por adelantado.
   ───────────────────────────────────────────────────────────── */

:root {
    --color-bg: #f6f8fb;
    --color-surface: #ffffff;
    --color-border: #e5e7eb;
    --color-text: #1f2933;
    --color-text-muted: #6b7280;
    /* Azul "azure" EXACTO de Tabler (antes #2563eb, más violáceo). El resto de
       tokens también se alinearon al tema para que la app se vea precisa, no
       "parecida". Ver SESSION_LOG (Sesión 44). */
    --color-primary: #066fd1;
    --color-primary-dark: #0b5cad;
    --color-primary-soft: rgba(6, 111, 209, 0.1);
    --color-success: #16a34a;
    --color-success-bg: #dcfce7;
    --color-warning: #d97706;
    --color-warning-bg: #fef3c7;
    --color-danger: #dc2626;
    --color-danger-bg: #fee2e2;
    --color-neutral-bg: #f1f5f9;
    --radius: 6px;
    --radius-sm: 4px;
    --shadow-sm: 0 1px 2px rgba(24, 36, 51, 0.04);
    --shadow-md: 0 2px 8px rgba(24, 36, 51, 0.08);
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-mono: "SF Mono", "Fira Code", Consolas, monospace;
}

/* ── Reset suave ──────────────────────────────────────────── */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.5;
    color: var(--color-text);
    background-color: var(--color-bg);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

code {
    font-family: var(--font-mono);
    font-size: 0.9em;
    background: var(--color-neutral-bg);
    padding: 1px 5px;
    border-radius: 3px;
}

/* ── Pantalla de autenticación ────────────────────────────── */
.auth-screen {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    min-height: 100vh;
}

/* CRÍTICO: el atributo `hidden` debe SIEMPRE poder ocultar un elemento.
   Varios componentes fijan display:flex/inline-flex (.modal-overlay, .btn,
   .loading-banner, .app-header), que gana por especificidad al `display:none`
   del user-agent para `[hidden]`. Esta regla global lo restablece — sin ella,
   ocultar un botón con `el.hidden = true` no tiene efecto (ej. "+ Tomar
   pedido", que debe verse solo para vendedores). */
[hidden] {
    display: none !important;
}

.auth-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    box-shadow: var(--shadow-md);
    padding: 2rem;
    width: 100%;
    max-width: 420px;
}

.auth-logo {
    font-size: 2.5rem;
    text-align: center;
    margin-bottom: 0.5rem;
}

.auth-card h2 {
    text-align: center;
    font-size: 1.4rem;
    color: var(--color-primary);
    margin-bottom: 0.25rem;
}

.auth-sub {
    text-align: center;
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin-bottom: 1.25rem;
}

.auth-warning {
    background: var(--color-warning-bg);
    color: var(--color-warning);
    padding: 0.75rem 1rem;
    border-radius: var(--radius);
    font-size: 0.82rem;
    margin-bottom: 1rem;
    line-height: 1.4;
}

.auth-msg {
    margin-top: 0.75rem;
    font-size: 0.85rem;
    min-height: 1.2em;
}

.auth-msg.error { color: var(--color-danger); }
.auth-msg.ok { color: var(--color-success); }

/* ── Paso del código de verificación ───────────────────────── */
/* Grande, monoespaciado y separado: se teclea mirando el correo, y confundir
   0/O o 1/l es lo que hace fallar el intento. */
.auth-code-input {
    font-family: var(--font-mono);
    font-size: 1.5rem;
    letter-spacing: 0.4em;
    text-align: center;
    padding: 0.7rem !important;
}

.auth-code-hint {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    margin-top: 0.4rem;
    line-height: 1.4;
}

.auth-code-hint a {
    color: var(--color-primary);
    cursor: pointer;
    font-weight: 600;
}

.auth-code-hint a:hover { text-decoration: underline; }

/* Durante la espera NO es un enlace: es texto. Un enlace deshabilitado igual
   invita a hacerle clic, y el clic que no hace nada se lee como app rota. */
.auth-resend-wait {
    color: var(--color-text-muted);
    font-weight: 600;
    cursor: default;
}

/* "Recordar este equipo" — solo en el desafío de 2FA. */
.auth-remember {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.7rem;
    font-weight: 400;
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
}

/* ── Verificación en dos pasos (Mi cuenta) ─────────────────── */
.tf-state {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    font-size: 0.88rem;
    margin-bottom: 0.3rem;
}

.tf-badge {
    background: var(--color-success-bg);
    color: var(--color-success);
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
}

.tf-badge.is-off {
    background: var(--color-neutral-bg);
    color: var(--color-text-muted);
}

.tf-devices {
    margin-top: 0.4rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.tf-device {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.55rem 0.7rem;
    font-size: 0.85rem;
}

.tf-device + .tf-device {
    border-top: 1px solid var(--color-border);
}

/* ── Los dos métodos: app autenticadora y correo ───────────── */
.tf-method {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.75rem 0.85rem;
    margin-top: 0.7rem;
}

.tf-method-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.25rem;
}

/* "Recomendada" — distinta del badge de estado: eso dice si está activa, esto
   dice cuál conviene. Si compartieran estilo se leerían como lo mismo. */
.tf-tag {
    border: 1px solid var(--color-primary);
    color: var(--color-primary);
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
}

/* Desactivar y regenerar van PLEGADOS: son la salida de emergencia, no lo que
   uno viene a hacer. Abiertos, cada método mostraría una caja de contraseña
   compitiendo con el botón que sí importa. */
.tf-details {
    margin-top: 0.6rem;
}

.tf-details > summary {
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.tf-warn {
    color: var(--color-warning, #b45309);
    font-size: 0.85rem;
    font-weight: 600;
}

.tf-backup-line {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 0.85rem;
    margin-top: 0.5rem;
}

/* ── Enrolar la app: QR + clave a mano ─────────────────────── */
.tf-enroll {
    margin-top: 0.8rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--color-border);
}

.tf-steps {
    margin: 0 0 0.7rem 1rem;
    padding: 0;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.tf-steps li {
    margin-bottom: 0.2rem;
}

.tf-enroll-body {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;      /* en el teléfono el QR se va arriba y la clave abajo */
    align-items: flex-start;
}

.tf-qr {
    width: 160px;
    height: 160px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    /* El QR se lee por CONTRASTE. En tema oscuro un SVG con fondo transparente
       queda negro sobre negro y la cámara no ve nada: el fondo blanco es
       funcional, no decorativo. */
    background: #fff;
    padding: 6px;
}

.tf-secret-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.tf-secret {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.9rem;
    letter-spacing: 0.08em;
    background: var(--color-neutral-bg);
    padding: 0.3rem 0.5rem;
    border-radius: var(--radius);
    word-break: break-all;
}

/* ── Link de invitación (se muestra UNA vez) ───────────────── */
.invite-link-box {
    border: 1px solid var(--color-primary);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
    margin-top: 0.8rem;
}

.invite-link-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0.5rem 0;
}

.invite-link {
    flex: 1;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.78rem;
    background: var(--color-neutral-bg);
    padding: 0.4rem 0.5rem;
    border-radius: var(--radius);
    /* El link es largo y lleva un token: tiene que verse ENTERO para poder
       comprobar que se copió bien. Cortado con puntos suspensivos, nadie sabe si
       lo que tiene en el portapapeles está completo. */
    word-break: break-all;
}

/* ── Códigos de respaldo ───────────────────────────────────── */
.tf-codes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 0.4rem;
    margin-top: 0.8rem;
}

.tf-codes code {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    background: var(--color-neutral-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.4rem 0.5rem;
    text-align: center;
    letter-spacing: 0.06em;
}

/* ── Respuesta al código: bien / mal ────────────────────────
   La señal va por TRES canales a la vez (sacudida + color + texto), nunca solo
   uno: quien no ve el color, lee el texto; quien tiene el movimiento reducido
   (mareos), igual ve el borde rojo y lee el mensaje. La animación REFUERZA, no
   informa sola. */
@keyframes auth-shake {
    10%, 90% { transform: translateX(-2px); }
    20%, 80% { transform: translateX(4px); }
    30%, 50%, 70% { transform: translateX(-7px); }
    40%, 60% { transform: translateX(7px); }
}

.auth-card.is-shake {
    animation: auth-shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}

.auth-code-input.is-error {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
}

.auth-code-input.is-ok {
    border-color: var(--color-success);
    box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.15);
    color: var(--color-success);
}

/* Confirmación al acertar: el visto se ve antes de entrar, para que el salto a
   la app no parezca un parpadeo sin explicación. */
.auth-ok {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.75rem;
    font-weight: 700;
    color: var(--color-success);
}

.auth-ok-check {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--color-success);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.9rem;
    animation: auth-pop 0.35s ease-out;
}

@keyframes auth-pop {
    0% { transform: scale(0.3); opacity: 0; }
    70% { transform: scale(1.15); }
    100% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .auth-card.is-shake { animation: none; }
    .auth-ok-check { animation: none; }
}

.auth-switch {
    text-align: center;
    font-size: 0.85rem;
    margin-top: 1rem;
    color: var(--color-text-muted);
}

.auth-switch a {
    color: var(--color-primary);
    cursor: pointer;
    font-weight: 600;
    text-decoration: none;
}

.auth-switch a:hover {
    text-decoration: underline;
}

/* ── Header con usuario ───────────────────────────────────── */
.app-header {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 1rem 1.5rem;
    box-shadow: var(--shadow-sm);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
}

.app-header h1 {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--color-primary);
}

.subtitle {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    margin-top: 2px;
}

.header-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.user-badge {
    font-size: 0.82rem;
    color: var(--color-text-muted);
    background: var(--color-neutral-bg);
    padding: 0.3rem 0.7rem;
    border-radius: 20px;
    font-weight: 600;
}

/* ── Navegación ───────────────────────────────────────────── */
.tabs {
    display: flex;
    gap: 0;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 0 1.5rem;
    overflow-x: auto;
}

.tab {
    background: none;
    border: none;
    border-bottom: 3px solid transparent;
    padding: 0.85rem 1.2rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: color 0.15s, border-color 0.15s;
}

.tab:hover {
    color: var(--color-text);
}

.tab-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/* ── Layout principal ─────────────────────────────────────── */
.app-main {
    flex: 1;
    padding: 1.5rem;
    max-width: 1400px;
    width: 100%;
    margin: 0 auto;
}

.panel {
    display: none;
    animation: fadeIn 0.2s ease;
}

.panel-active {
    display: block;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Formularios ──────────────────────────────────────────── */
form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-text);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="tel"],
select,
textarea {
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.9rem;
    font-family: var(--font);
    background: var(--color-surface);
    color: var(--color-text);
    transition: border-color 0.15s, box-shadow 0.15s;
}

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

textarea {
    resize: vertical;
}

/* ── Contraseñas: ojito para ver + medidor de seguridad ─────
   El ojito se inyecta por JS en TODO input[type=password] (ver
   enhancePasswordFields). El medidor solo donde la persona ELIGE una
   contraseña nueva (opt-in con data-strength). */
.pw-wrap {
    width: 100%;
}

/* Envuelve SOLO al input: es la referencia del ojito. Si el ojito se
   posicionara contra .pw-wrap (que además lleva el medidor), su height:100%
   abarcaría input+medidor y quedaría empujado abajo, fuera del campo. */
.pw-field {
    position: relative;
}

/* Espacio a la derecha para que el texto no pase por debajo del ojito. */
.pw-field input {
    padding-right: 2.6rem;
}

.pw-eye {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    opacity: 0.55;
    /* El input hermano ya tiene su propio foco; este botón no debe taparlo. */
    border-radius: 0 var(--radius) var(--radius) 0;
}

.pw-eye:hover { opacity: 1; }

.pw-eye:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
    opacity: 1;
}

.pw-meter {
    margin-top: 0.4rem;
}

.pw-meter-track {
    height: 4px;
    border-radius: 999px;
    background: var(--color-neutral-bg);
    overflow: hidden;
}

.pw-meter-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    transition: width 0.2s ease, background-color 0.2s ease;
    background: var(--color-danger);
}

.pw-meter-text {
    margin-top: 0.25rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

/* Rojo → ámbar → verde. El color es la señal; el texto explica por qué. */
.pw-meter.is-s0 .pw-meter-fill { background: var(--color-danger); }
.pw-meter.is-s1 .pw-meter-fill { background: var(--color-danger); }
.pw-meter.is-s2 .pw-meter-fill { background: var(--color-warning); }
.pw-meter.is-s3 .pw-meter-fill { background: var(--color-success); }
.pw-meter.is-s4 .pw-meter-fill { background: var(--color-success); }

.pw-meter.is-s0 .pw-meter-text,
.pw-meter.is-s1 .pw-meter-text { color: var(--color-danger); }
.pw-meter.is-s2 .pw-meter-text { color: var(--color-warning); }
.pw-meter.is-s3 .pw-meter-text,
.pw-meter.is-s4 .pw-meter-text { color: var(--color-success); }

@media (prefers-reduced-motion: reduce) {
    .pw-meter-fill { transition: none; }
}

/* ── Checkboxes / radios: tamaño cómodo de clickear ────────── */
input[type="checkbox"],
input[type="radio"] {
    width: 16px;
    height: 16px;
    flex: none;
}

/* ── Botones ──────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.6rem 1.1rem;
    border: none;
    border-radius: var(--radius);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, opacity 0.15s;
}

.btn-primary {
    background: var(--color-primary);
    color: #fff;
}

.btn-primary:hover {
    background: var(--color-primary-dark);
}

.btn-secondary {
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
}

.btn-secondary:hover {
    background: var(--color-neutral-bg);
}

.btn-danger {
    background: var(--color-danger);
    color: #fff;
}

.btn-danger:hover {
    background: #b91c1c;
}

/* Colores semánticos de acción (convención del usuario): VERDE = aceptar/
   confirmar/positivo · ROJO = cancelar/destructivo · AZUL (primary) = lo demás. */
.btn-success {
    background: var(--color-success);
    color: #fff;
}
.btn-success:hover { background: #15803d; }

.btn-warning {
    background: var(--color-warning);
    color: #fff;
}
.btn-warning:hover { background: #b45309; }

/* "Cancelar"/descartar: rojo pero de contorno (no compite con el verde de la
   acción positiva ni con el rojo sólido de lo destructivo). */
.btn-danger-soft {
    background: var(--color-surface);
    color: var(--color-danger);
    border: 1px solid var(--color-danger);
}
.btn-danger-soft:hover { background: var(--color-danger-bg); }

.btn-sm {
    padding: 0.35rem 0.7rem;
    font-size: 0.8rem;
}

.btn-xs {
    padding: 0.25rem 0.55rem;
    font-size: 0.75rem;
}

.btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Cajas de estado ──────────────────────────────────────── */
.status-box {
    margin-top: 0.75rem;
    padding: 0.65rem 0.8rem;
    border-radius: var(--radius);
    font-size: 0.85rem;
}

.status-info {
    background: var(--color-neutral-bg);
    color: var(--color-text);
}

.status-success,
.status-ok {
    background: var(--color-success-bg);
    color: var(--color-success);
}

.status-warning {
    background: var(--color-warning-bg);
    color: var(--color-warning);
}

.status-error {
    background: var(--color-danger-bg);
    color: var(--color-danger);
}

/* ── Badges ───────────────────────────────────────────────── */
.badge {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 20px;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.badge-yes {
    background: var(--color-success-bg);
    color: var(--color-success);
}

.badge-no {
    background: var(--color-neutral-bg);
    color: var(--color-text-muted);
}

.badge-unknown,
.badge-warn {
    background: var(--color-warning-bg);
    color: var(--color-warning);
}
.badge-info {
    background: var(--color-primary-soft);
    color: var(--color-primary);
}
.badge-danger {
    background: rgba(220, 38, 38, 0.12);
    color: #dc2626;
}

/* Badge que ESCONDE información y la despliega al tocarlo (hoy: el motivo de la
   cancelación). Evita llenar el pedido de texto: el detalle está a un clic.
   Sin chevron ni ningún otro adorno: el destello ES el indicador. Convención del
   producto (se enseña a los vendedores): **lo que destella esconde información**.
   Por eso destella mientras está plegado y se queda quieto al abrirlo. */
.badge-reveal {
    border: none;
    font-family: inherit;
    cursor: pointer;
    /* .badge fija el resto (padding, radio, tipografía) — acá solo lo que un
       <button> no hereda. */
}

.badge-reveal:hover {
    filter: brightness(0.94);
}

@keyframes badge-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.45); }
    50%      { box-shadow: 0 0 0 5px rgba(220, 38, 38, 0); }
}

.badge-reveal.is-pulsing {
    animation: badge-pulse 1.9s ease-out infinite;
}

/* ── Autoguardado: chip vivo junto a "Guardar" ─────────────────────────
   El formulario se guarda solo mientras la persona escribe; este chip dice
   en qué va (sin guardar / guardando / guardado / error). Discreto a
   propósito: es tranquilidad, no una alarma. */
.autosave-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 0.8rem;
}
.autosave-status {
    font-size: 0.82rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--color-text-muted);
}
.autosave-status::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}
.autosave-status.is-dirty  { color: var(--color-text-muted); }
.autosave-status.is-saving { color: var(--color-warning); }
.autosave-status.is-saving::before { animation: autosave-blink 1s ease-in-out infinite; }
.autosave-status.is-saved  { color: var(--color-success); }
.autosave-status.is-blocked,
.autosave-status.is-error  { color: var(--color-danger); }

@keyframes autosave-blink {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
    .autosave-status.is-saving::before { animation: none; }
}

/* Encabezado de sección que despliega su contenido (hoy: "Historial del
   pedido"). Misma convención que los badges: destella mientras esconde algo, y
   se queda quieto cuando hay algo abierto. Clic = abrir/cerrar TODO. */
.section-reveal {
    display: inline-block;
    background: none;
    border: none;
    font-family: inherit;
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text);
    cursor: pointer;
    padding: 0.2rem 0.55rem;
    /* Aire arriba (lo separa de la caja de estado) y abajo: pegado al primer
       evento del historial se leía como si fuera parte de él. */
    margin: 1.4rem 0 0.85rem -0.55rem;
    border-radius: 10px;
}

.section-reveal:hover {
    background: var(--color-neutral-bg);
}

@keyframes section-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(6, 111, 209, 0.35); }
    50%      { box-shadow: 0 0 0 6px rgba(6, 111, 209, 0); }
}

.section-reveal.is-pulsing {
    animation: section-pulse 1.9s ease-out infinite;
}

/* Variante "inline" del encabezado colapsable: dentro de un toolbar-card (hoy los
   filtros de "Mis órdenes"), sin el margen del contexto del modal, con ícono +
   texto. Mismo destello que "Historial del pedido". */
.section-reveal.reveal-inline {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: 0.4rem;
    margin: 0.3rem 0 0.1rem;
    font-size: 0.95rem;
}
.section-reveal.reveal-inline .mp-icon { color: var(--color-text-muted); }

/* Título de un evento del historial: clic → despliega cuándo, quién y el detalle
   de cantidades. No destella (siete títulos parpadeando sería una feria): el que
   avisa es el encabezado de la sección. */
.tl-event {
    background: none;
    border: none;
    padding: 0;
    font-family: inherit;
    font-size: inherit;
    font-weight: 700;
    color: var(--color-text);
    text-align: left;
    cursor: pointer;
}

.tl-event:hover {
    color: var(--color-primary);
}

/* La Ficha del establecimiento se abre SOBRE otros modales (ej. desde "Tomar
   pedido", para revisar o corregir los datos del cliente sin perder el pedido a
   medio armar). Vive en el contenedor `#modals`, que va antes en el DOM que los
   modales creados al vuelo: con el z-index por defecto quedaría DEBAJO de ellos. */
#ficha-overlay {
    z-index: 1100;
}

/* ── Progreso de lectura (toda la app) ─────────────────────── */
/* La barra de scroll nativa se ve tosca y le roba ancho al contenido. Se esconde
   —el scroll sigue funcionando igual: rueda, trackpad, teclado, barra espaciadora—
   y su información ("cuánto queda por leer") la da una barra fina que se llena al
   bajar: en la PÁGINA, fija arriba de todo; en cada MODAL, bajo su encabezado.
   Ojo: solo se esconde el scroll VERTICAL de la página y de los modales. Los
   contenedores con scroll horizontal (ej. la tabla de productos angosta)
   conservan su barra: ahí el desplazamiento lateral no se adivina. */
html,
.modal-body {
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* Edge viejo */
}

html::-webkit-scrollbar,
.modal-body::-webkit-scrollbar {
    width: 0;
    height: 0;
}

.scroll-progress {
    flex: 0 0 auto;
    height: 3px;
    background: var(--color-border);
}

.scroll-progress > span {
    display: block;
    height: 100%;
    width: 0;
    background: var(--color-primary);
    transition: width 0.08s linear;
}

/* La de la página va fija arriba de todo (sobre el encabezado), sin fondo: en un
   documento corto no debe verse ni una línea gris de más. */
#page-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1200;
    background: transparent;
}

@media (prefers-reduced-motion: reduce) {
    .scroll-progress > span { transition: none; }
}

/* ── Sub-pestañas dentro de un panel (Órdenes / Seguimientos) ─ */
.subtabs {
    display: flex;
    flex-wrap: wrap;   /* en móvil, 3 sub-pestañas con contadores no caben en una fila → 2ª fila (antes desbordaban) */
    gap: 0.25rem;
    border-bottom: 1px solid var(--color-border);
    margin-top: 0.75rem;
}

.subtab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 0.45rem 0.75rem;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--color-text-muted);
    cursor: pointer;
    white-space: nowrap;   /* la etiqueta no se parte en dos líneas al envolver */
}

.subtab:hover {
    color: var(--color-text);
}

.subtab.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/* ── Fila de filtros ──────────────────────────────────────── */
/* Los controles conservan el contenedor de la app (borde, radio, padding y
   tipografía vienen del estilo base de input/select): acá solo se corrige el
   ancho —los campos de formulario son `width:100%` y apilaban un control por
   fila— y se les fija un ALTO común.
   El alto hace falta porque `<input>` y `<select>` NO miden lo mismo con el
   mismo padding: Chrome le reserva al select un alto de línea mayor (2px de
   diferencia), y ni `align-items:stretch` ni `line-height` lo emparejan. Con
   `box-sizing:border-box`, fijar la altura los deja idénticos. */
.filter-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0.75rem 0 0.5rem;
}

.filter-row .filter-select,
.filter-row .btn {
    height: 2.4rem;
}

/* Ojo con la especificidad: el estilo base apunta a `input[type="search"]`
   (0,1,1), que le gana a una clase suelta (0,1,0) — con `.filter-select` a secas,
   el `width:100%` del formulario seguía ganando y el campo se comía la fila
   entera. `.filter-row .filter-select` (0,2,0) sí manda. */
.filter-row .filter-select {
    margin: 0;
    width: auto;
    min-width: 190px;
    max-width: 100%;
    flex: 0 1 auto;
}

/* Buscador con sugerencias (cliente o RUT). El <datalist> nativo se ve feo y el
   navegador lo posiciona a su antojo: esta lista es de la casa, cae bajo el
   campo y usa el contenedor de la app.

   El componente es reutilizable (lo usan "Mis órdenes" y "Tomar pedido"): acá
   solo se posiciona. El ANCHO depende del contexto — en la fila de filtros crece
   y se queda con el espacio sobrante (es el control más usado y los nombres de
   cliente son largos); dentro de un modal ocupa el ancho completo, como cualquier
   campo de formulario. */
.combo {
    position: relative;
}

.filter-row .combo {
    flex: 1 1 260px;
    min-width: 240px;
    max-width: 460px;
}

/* Dentro del combo, el campo ocupa todo el ancho disponible (el min-width de
   190px es para los controles sueltos de la fila, no para este). */
.filter-row .combo .filter-select {
    width: 100%;
    min-width: 0;
}

.filter-row select.filter-select {
    flex: 0 0 auto;
}

/* `fixed`, no `absolute`: dentro de un modal el cuerpo tiene `overflow:auto` y
   RECORTA cualquier hijo posicionado — la lista salía cortada a una línea. Fija
   escapa del recorte; su posición la calcula el JS desde el campo
   (`positionComboList`) y se recalcula al hacer scroll o redimensionar. */
.combo-list {
    position: fixed;
    /* Más ancha que el campo si hace falta: con el ancho del input, el RUT
       quedaba cortado ("Almacén Don Pepe · …") y era justo lo que hay que ver
       para elegir. */
    width: max-content;
    max-width: min(380px, 90vw);
    z-index: 1150;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    max-height: 260px;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.combo-option {
    padding: 0.45rem 0.6rem;
    border-radius: 6px;
    font-size: 0.85rem;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.combo-option:hover,
.combo-option.is-active {
    background: var(--color-neutral-bg);
}

.combo-empty {
    padding: 0.45rem 0.6rem;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

/* En móvil ya se apilan igual (no caben en una fila): que ocupen el ancho
   completo en vez de quedar angostos con un hueco al lado. */
@media (max-width: 480px) {
    .filter-row .combo,
    .filter-row .filter-select,
    .filter-row .btn {
        width: 100%;
        min-width: 0;
    }
}

/* ⭐ Seguir una orden: marca personal, se fija en "Mis seguimientos". */
.follow-star {
    background: none;
    border: none;
    padding: 0 0.15rem;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    color: var(--color-text-muted);
}

.follow-star:hover {
    color: var(--color-warning);
}

.follow-star.is-on {
    color: var(--color-warning);
}

/* ── Etiquetas personalizadas del cliente ──────────────────── */
/* La ETAPA es un .badge (embudo, fijo); las ETIQUETAS son chips libres que el
   vendedor crea. Color por etiqueta, pintado inline desde TAG_COLORS. */
.tag-chip {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 20px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}
.tag-add {
    border: none;
    background: none;
    cursor: pointer;
    line-height: 0;
    padding: 0 0.1rem;
    display: inline-flex;
    align-items: center;
    opacity: 0.75;
}
.tag-add:hover { opacity: 1; }

/* Modal de etiquetas: cada fila es una etiqueta (toggle) + eliminar. */
.tag-manage-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}
.tag-toggle {
    flex: 1;
    text-align: left;
    border: 1px solid;
    border-radius: 20px;
    padding: 0.25rem 0.65rem;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    background: transparent;
}
.tag-toggle:not(.is-on) { opacity: 0.7; }
.tag-toggle:hover { opacity: 1; }
.tag-del {
    border: none;
    background: none;
    cursor: pointer;
    opacity: 0.45;
    font-size: 0.9rem;
    line-height: 1;
}
.tag-del:hover { opacity: 1; }
.tag-swatch {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
}
.tag-swatch.is-sel { outline: 2px solid var(--color-text-muted); outline-offset: 1px; }

/* ── Buscar prospectos: hero de búsqueda + tarjetas de resultado ── */
.search-hero {
    margin-top: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    box-shadow: var(--shadow-sm);
}
.search-hero .search-row {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
    flex-wrap: wrap;
}
.search-hero .search-grow { flex: 1; min-width: 220px; }
.search-hero .search-row > div:not(.search-grow) { flex: 1; min-width: 110px; }
.search-hero label {
    display: block;
    font-weight: 600;
    font-size: 0.85rem;
    margin-bottom: 0.3rem;
}
.search-hero input,
.search-hero select { margin: 0; }
.search-advanced summary {
    cursor: pointer;
    color: var(--color-text-muted);
    font-size: 0.85rem;
    list-style: none;
}
.search-advanced summary::-webkit-details-marker { display: none; }

.search-results-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
    min-height: 1.2rem;
}
.search-results-head p { margin: 0; }
.search-results {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 0.5rem;
}
.search-result { cursor: pointer; }
.search-result-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.search-result-badges {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.search-result-meta {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
}
.search-reason { margin-top: 0.45rem; line-height: 1.4; }
.result-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.12rem 0.55rem;
    border-radius: 20px;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--color-neutral-bg);
    color: var(--color-text-muted);
    white-space: nowrap;
}
.search-empty {
    text-align: center;
    padding: 2.75rem 1rem;
    color: var(--color-text);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}
.search-empty-icon { font-size: 2.5rem; margin-bottom: 0.5rem; }
.search-empty p { margin: 0.25rem 0; }

/* ── Líneas de la orden (tabla de productos) ───────────────── */
.order-lines {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.order-lines th {
    text-align: left;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-text-muted);
    font-weight: 700;
    padding: 0 0.4rem 0.35rem;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.order-lines td {
    padding: 0.5rem 0.4rem;
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
}

.order-lines .num {
    text-align: right;
    white-space: nowrap;
}

/* La línea que no llegó: atenuada (ya no es plata) pero legible — es
   justamente la que el vendedor tiene que ver. */
.order-lines .line-lost td {
    opacity: 0.55;
}

/* Fila del catálogo: se toca para elegir el producto en el pedido. */
.order-lines .catalog-row {
    cursor: pointer;
}

.order-lines .catalog-row:hover td {
    background: var(--color-neutral-bg);
}

/* Aparición del panel desplegado: un fundido corto, sin rebote. */
@keyframes reveal-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.reveal-panel {
    animation: reveal-in 0.18s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    .badge-reveal.is-pulsing,
    .section-reveal.is-pulsing { animation: none; }
    .btn.is-loading { animation: none; }
    .reveal-panel { animation: none; }
}

/* Contenedor liviano para agrupar sub-secciones dentro de un panel
   (ej. "Generar con IA", "Semáforo" en los perfiles de prospección). */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
}
.card h3 {
    margin: 0 0 0.4rem;
}

/* El dropdown de autocompletado de Google Places debe quedar por encima
   del modal de alta manual. */
.pac-container {
    z-index: 100000 !important;
}

/* Rueda de carga + banner prominente (para acciones con IA que tardan). */
@keyframes mp-spin {
    to { transform: rotate(360deg); }
}
.spinner {
    display: inline-block;
    width: 1.5rem;
    height: 1.5rem;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: mp-spin 0.7s linear infinite;
    flex: none;
}

/* Botón en carga: parpadea para indicarle a cualquiera (no informático) que está
   trabajando. El texto cambia a "Cargando…" y queda deshabilitado mientras consulta. */
@keyframes mp-btn-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
.btn.is-loading {
    animation: mp-btn-pulse 1s ease-in-out infinite;
    cursor: wait;
}
.loading-banner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
    padding: 1rem 1.25rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--color-primary);
    background: var(--color-primary-soft);
    border: 1px solid rgba(6, 111, 209, 0.25);
    border-radius: var(--radius);
}
/* `display:flex` de arriba le gana al atributo `hidden` del navegador; esta
   regla más específica restablece que `hidden` vuelva a ocultar el banner
   (si no, se quedaría "pegado" al terminar la acción). */
.loading-banner[hidden] {
    display: none;
}

/* Dos campos lado a lado (ej. latitud/longitud). */
.form-row {
    display: flex;
    gap: 0.5rem;
}
.form-row > div {
    flex: 1;
}

/* Mapa de Google en "Buscar prospectos". Grande y navegable: es el centro de la
   pantalla (arrastrar el pin, ver la cartera, soltar puntos). */
.map-canvas {
    width: 100%;
    height: 400px;               /* chico por defecto; el ⛶ lo agranda */
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
}

/* Barra de controles del mapa (toggle cartera, agregar punto, buscar en esta zona). */
.map-toolbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
}
.map-toolbar .map-toolbar-spacer { flex: 1; }
/* "Mis clientes" es una pestaña (.subtab); en la barra va sin el margen de la
   barra de sub-pestañas. */
.map-toolbar .subtab { margin: 0; }
/* El botón "Buscar en esta zona" aparece al mover el pin. */
#map-search-here { transition: opacity 0.15s; }

/* "Agregar punto de venta": misma pestaña que "Mis clientes" (.subtab) pero
   PARPADEA para avisar que es un botón/acción. Al activarlo (modo agregar) deja de
   parpadear y queda como pestaña activa. */
@keyframes map-cta-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}
.subtab.map-cta {
    color: var(--color-primary);
    animation: map-cta-pulse 1.4s ease-in-out infinite;
}
.subtab.map-cta.is-active {
    animation: none;
    border-bottom-color: var(--color-primary);
}
@media (prefers-reduced-motion: reduce) {
    .subtab.map-cta { animation: none; }
}

/* InfoWindow del mapa más compacto: Google reserva mucho aire arriba (header de
   ~48px + 17px de padding). Achicamos el header y el botón de cierre — el ícono ×
   (span 24×24) trae margin:12px pensado para 48px, así que lo recentramos con
   flex, si no queda descolgado. */
.gm-style-iw-ch { padding-top: 0 !important; }
.gm-style-iw button.gm-ui-hover-effect {
    width: 30px !important;
    height: 30px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
}
.gm-style-iw button.gm-ui-hover-effect > span { margin: 0 !important; }

/* Segundo tamaño del mapa (agrandado). El control ⛶ lo alterna. */
.map-canvas.map-big {
    height: 60vh;
    min-height: 460px;
}

/* Control propio en la esquina del mapa (estilo del ⛶ de Google) → agrandar/achicar. */
.map-size-ctrl {
    background: #fff;
    border-radius: 2px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    cursor: pointer;
    margin: 10px;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.map-size-ctrl:hover { background: #f5f5f5; }

/* ── Modales (overlay/card/header/body/footer) ─────────────
   Genérico: cualquier modal usa este mismo esqueleto de clases,
   abierto/cerrado con openModal(id)/closeModal(id) (app.js) — no un
   par de funciones open/close por cada modal. ────────────────── */
.modal-overlay {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 2rem 1rem;
    overflow-y: auto;
}

.modal-card {
    background: #fff;
    border-radius: 12px;
    max-width: 600px;
    width: 100%;
    display: flex;
    flex-direction: column;
    max-height: 90vh;
}

/* El <form> dentro de .modal-card debe heredar el flex chain para que
   modal-body y modal-footer se estructuren bien (scroll, footer fijo). */
.modal-card > form {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.modal-lg {
    max-width: 850px;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--color-border);
}

.modal-header h2 {
    margin: 0;
    font-size: 1.25rem;
}

.modal-close {
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
    color: var(--color-text-muted);
    padding: 0;
    line-height: 1;
}

.modal-close:hover {
    color: var(--color-text);
}

.modal-body {
    padding: 1.5rem;
    overflow-y: auto;
}

.modal-body label {
    display: block;
    margin-top: 0.75rem;
}

.modal-body input:not([type="checkbox"]):not([type="radio"]),
.modal-body select,
.modal-body textarea {
    margin-top: 0.25rem;
}

.modal-footer {
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--color-border);
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

/* ── Panel general (superadmin) ───────────────────────────── */
.overview-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
    margin: 1rem 0 1.5rem;
}

.stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
}

.stat-value {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.1;
}

.stat-label {
    margin-top: 0.25rem;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.stat-sub {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.overview-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
}

.overview-cols h3 {
    margin-bottom: 0.75rem;
}

/* Selector de estado compacto (tabla de Empresas / global admin). */
.status-select {
    width: auto;
    padding: 0.2rem 0.4rem;
    font-size: 0.8rem;
    margin: 0;
}

/* Barra de filtros de las vistas globales (Clientes / Órdenes). */
.admin-filters {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 1rem;
}

.admin-filters select,
.admin-filters input {
    width: auto;
    max-width: 240px;
    padding: 0.35rem 0.5rem;
    font-size: 0.85rem;
    margin: 0;
}

/* ── Órdenes: tarjeta clicable + zona de peligro ──────────── */
.order-card { transition: box-shadow 0.12s, border-color 0.12s; }
.order-card:hover {
    border-color: var(--color-primary);
    box-shadow: 0 2px 10px rgba(6, 111, 209, 0.10);
}

/* ── Ficha del establecimiento (cliente): hero + relaciones ── */
/* La ficha habla el mismo idioma que "Mis clientes"/"Mis órdenes": lo que
   importa (identidad, relación, compra) arriba; los datos editables, plegados. */
.ficha-hero {
    background: var(--color-neutral-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.85rem 1rem;
    margin-bottom: 1.2rem;
}
.ficha-hero-clickable { cursor: pointer; transition: border-color 0.12s, box-shadow 0.12s; }
.ficha-hero-clickable:hover {
    border-color: var(--color-primary);
    box-shadow: 0 2px 10px rgba(6, 111, 209, 0.10);
}
.ficha-hero-hint {
    margin-top: 0.3rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--color-primary);
}
/* Encabezado de la ficha: "← Volver" (cuando aplica) + nombre + rótulo de vista. */
.ficha-header-left {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    flex-wrap: wrap;
}
/* Listas de giros / direcciones de despacho en "Datos del cliente". */
.ficha-list-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.1rem;
    border-bottom: 1px solid var(--color-border);
    flex-wrap: wrap;
    font-size: 0.9rem;
}
.ficha-list-actions {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-shrink: 0;
}
.ficha-link-btn {
    background: none;
    border: none;
    padding: 0;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-primary);
    cursor: pointer;
    white-space: nowrap;
}
.ficha-link-btn:hover { text-decoration: underline; }
.ficha-link-danger { color: var(--color-danger); }
.ficha-add-row {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.7rem;
    flex-wrap: wrap;
}
.ficha-add-row input {
    flex: 1;
    min-width: 200px;
    margin: 0;
}
/* Rótulo de la sub-pantalla de datos, junto al nombre en el encabezado. */
.ficha-title-tag {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--color-primary);
    background: rgba(6, 111, 209, 0.12);
    border-radius: 20px;
    padding: 0.12rem 0.6rem;
    vertical-align: middle;
    margin-left: 0.5rem;
}
.ficha-hero-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.ficha-chip {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--color-text-muted);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 20px;
    padding: 0.12rem 0.55rem;
    white-space: nowrap;
}
.ficha-chip-manual { color: #7c3aed; border-color: #ddd6fe; background: #f5f3ff; }
.ficha-tags {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
}
.ficha-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}
.ficha-wa {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: #25D366;
    color: #fff;
    border: none;
    border-radius: 8px;
    padding: 0.35rem 0.7rem;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}
.ficha-wa.is-off { opacity: 0.55; }
.ficha-section { margin-bottom: 1.4rem; }
.ficha-h3 { font-size: 0.98rem; margin: 0 0 0.6rem; }
.ficha-rel-card {
    margin-bottom: 0.6rem;
    cursor: pointer;
    padding: 0.8rem 0.9rem;
}
.ficha-rel-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.ficha-rel-badges {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.ficha-rel-foot { margin-top: 0.4rem; }
/* "Mis clientes": pie de tarjeta con recencia (izq.) + WhatsApp (der.). */
.mc-card-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.4rem;
    flex-wrap: wrap;
}
.mc-wa {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: #25D366;
    color: #fff;
    border: none;
    border-radius: var(--radius);
    padding: 0.28rem 0.6rem;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
}
.mc-wa.is-off { opacity: 0.5; }

/* ── FASE 1 — Tarjeta de "Mis clientes" por LOCAL ─────────────────────────
   Jerarquía: nombre+comuna · etapa/estrella · HÉROE del recontacto (coloreado
   por urgencia) · proveedor+motivo+actividad · plata discreta+acciones. Todo
   con flex-wrap y sin anchos fijos → no desborda en 360–375px (móvil primero). */
.mc-card .mc-foot-actions { display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }
/* Píldora HÉROE del recontacto: es lo primero que el vendedor busca ("¿a quién
   vuelvo hoy?"), por eso ocupa su propia línea y se colorea por urgencia. */
.mc-hero-recontact {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.55rem;
    padding: 0.3rem 0.6rem;
    border-radius: var(--radius);
    font-size: 0.85rem;
    font-weight: 700;
    line-height: 1.2;
}
.mc-hero-recontact .mp-icon { width: 1rem; height: 1rem; flex-shrink: 0; }
.mc-hero-recontact.is-overdue { background: var(--color-danger-bg); color: var(--color-danger); }
.mc-hero-recontact.is-soon    { background: var(--color-warning-bg); color: var(--color-warning); }
.mc-hero-recontact.is-later   { background: var(--color-primary-soft); color: var(--color-text-muted); }
.mc-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.55rem;
    margin-top: 0.5rem;
    font-size: 0.83rem;
    color: var(--color-text-muted);
}
.mc-prov-chip {
    display: inline-block;
    max-width: 100%;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-text);
    font-weight: 600;
    font-size: 0.78rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.mc-prov-chip.mc-prov-none { background: transparent; color: var(--color-text-muted); font-weight: 500; font-style: italic; }
/* Punto liberado (búsqueda): acento verde + contexto comercial derivado. */
.search-result.is-released { border-left: 3px solid var(--color-success); }
.released-summary { margin-top: 0.45rem; font-size: 0.82rem; color: var(--color-success); line-height: 1.4; }
.mc-motivo::before { content: "· "; }
.mc-act::before { content: "· "; }
/* Etiqueta "Proveedor" junto al nombre de la empresa: deja claro que es el
   proveedor (vende), no el cliente. El cliente es el LOCAL (dueño de la ficha). */
.ficha-rel-role {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #7c3aed;
    background: #f5f3ff;
    border: 1px solid #ddd6fe;
    border-radius: 20px;
    padding: 0.06rem 0.5rem;
    margin-left: 0.4rem;
    vertical-align: middle;
}
.ficha-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.6rem;
    margin: 0.5rem 0 1.2rem;
}
.ficha-stats .stat-card { padding: 0.7rem 0.8rem; }
.ficha-stats .stat-value { font-size: 1.2rem; }
@media (max-width: 520px) {
    .ficha-stats { grid-template-columns: 1fr; }
}

.danger-zone { border-color: var(--color-danger); }
.danger-zone h3 { color: var(--color-danger); }
.danger-note {
    font-size: 0.85rem;
    color: var(--color-text-muted);
    line-height: 1.55;
    margin-bottom: 0.9rem;
}
.danger-note strong { color: var(--color-danger); }

/* ── "Tomar pedido": listas de cliente/empresa ─────────────── */
.take-list {
    max-height: 220px;
    overflow-y: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-top: 0.25rem;
}

.take-row {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    border-bottom: 1px solid var(--color-border);
    padding: 0.5rem 0.65rem;
    cursor: pointer;
}

.take-row:last-child { border-bottom: none; }
.take-row:hover { background: var(--color-neutral-bg); }

.take-selected {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.65rem;
    background: var(--color-neutral-bg);
    border-radius: var(--radius);
    margin-top: 0.25rem;
}

/* ── Notificaciones (campana + badge + bandeja) ───────────── */
.notif-wrap { position: relative; }

.notif-bell {
    position: relative;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.25rem;
    line-height: 1;
    padding: 0.25rem;
}

.notif-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--color-danger);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

.notif-dropdown {
    position: absolute;
    right: 0;
    top: 2.25rem;
    width: 340px;
    max-width: 90vw;
    max-height: 420px;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 200;
}

.notif-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--color-border);
}

.notif-head a { color: var(--color-primary); cursor: pointer; font-size: 0.8rem; }

.notif-item {
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;
}

.notif-item:hover { background: var(--color-neutral-bg); }
.notif-unread { background: #eff5ff; }

/* ── Banner de impersonación ("Ingresar como…") ───────────── */
.impersonation-banner {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.5rem 1rem;
    background: var(--color-warning-bg);
    color: var(--color-warning);
    border-bottom: 1px solid var(--color-warning);
    font-size: 0.9rem;
    font-weight: 600;
}

.impersonation-banner .btn {
    background: var(--color-warning);
    color: #fff;
    border-color: var(--color-warning);
}

/* ── Footer ───────────────────────────────────────────────── */
.app-footer {
    text-align: center;
    padding: 1.25rem;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

/* ── Responsive ───────────────────────────────────────────── */
@media (max-width: 700px) {
    .app-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .modal-overlay {
        padding: 0;
    }

    .modal-card {
        max-height: 100vh;
        border-radius: 0;
    }

    .overview-cols {
        grid-template-columns: 1fr;
    }
}

/* ── Medidor de completitud del perfil (anillo + chips) ──────
   Analizador compacto y guiado para los perfiles (vendedor y empresa):
   un anillo de progreso, chips por dimensión con ✓/~/○, y una tarjeta
   de análisis IA con preguntas guía. Portado del prototipo prueba-api-v2
   al sistema de diseño del marketplace. */
.perfil-meter {
    display: flex;
    gap: 0.9rem;
    align-items: flex-start;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-neutral-bg);
}
.pm-ring {
    flex: none;
    width: 56px;
    height: 56px;
    position: relative;
}
.pm-ring svg { transform: rotate(-90deg); }
.pm-ring .pm-fondo { stroke: var(--color-border); }
.pm-ring .pm-barra { transition: stroke-dashoffset 0.5s ease, stroke 0.3s; }
.pm-pct {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 0.8rem;
    font-weight: 800;
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
}
.pm-check { flex: 1; min-width: 0; }
.pm-check-title {
    font-size: 0.8rem;
    font-weight: 700;
    display: block;
    margin-bottom: 0.35rem;
}
.pm-check-title span {
    font-weight: 400;
    color: var(--color-text-muted);
    font-size: 0.72rem;
}
.pm-lista { display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; }
.pm-tag {
    font-size: 0.72rem;
    padding: 0.14rem 0.55rem;
    border-radius: 11px;
    font-weight: 600;
    border: 1px solid transparent;
    white-space: nowrap;
}
.pm-tag.completo { background: var(--color-success-bg); color: var(--color-success); }
.pm-tag.parcial { background: var(--color-warning-bg); color: var(--color-warning); }
.pm-tag.falta {
    background: var(--color-surface);
    color: var(--color-text-muted);
    border-color: var(--color-border);
}
.pm-resumen {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    margin-top: 0.35rem;
}

/* Tarjeta de análisis IA con preguntas guía. */
.pm-ai-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-top: 0.75rem;
}
.pm-ai-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--color-border);
}
.pm-ai-score {
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 50%;
    background: var(--color-surface);
    display: grid;
    place-items: center;
    font-size: 1.05rem;
    font-weight: 800;
    border: 3px solid currentColor;
    font-variant-numeric: tabular-nums;
}
.pm-ai-head-text b { font-size: 0.85rem; }
.pm-ai-head-text div {
    font-size: 0.78rem;
    color: var(--color-text-muted);
    margin-top: 0.1rem;
}
.pm-ai-chips {
    padding: 0.6rem 0.9rem 0.25rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.45rem;
}
.pm-questions { padding: 0.45rem 0.9rem 0.85rem; }
.pm-questions-title {
    font-size: 0.8rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}
.pm-question { margin-bottom: 0.6rem; }
.pm-question label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--color-primary);
    margin-bottom: 0.25rem;
}
.pm-question input { width: 100%; }
.pm-complete-note {
    padding: 0.75rem 0.9rem;
    text-align: center;
    font-size: 0.82rem;
    color: var(--color-success);
    font-weight: 600;
}

/* ── Cuenta y seguridad (perfil del vendedor) ────────────────
   Rejilla de estado (usuario, sesión, cifrado, último acceso) + nota. */
.sec-grid {
    background: rgba(6, 111, 209, 0.05);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.5rem 0.9rem;
    margin-bottom: 0.75rem;
}
.sec-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.88rem;
}
.sec-row:last-child { border-bottom: none; }
.sec-row .k { color: var(--color-text-muted); }
.sec-row .v { font-weight: 700; text-align: right; word-break: break-word; }
.sec-row .v.ok { color: var(--color-success); }
.sec-note {
    font-size: 0.8rem;
    color: var(--color-text-muted);
    line-height: 1.5;
    margin-bottom: 0.9rem;
}
.sec-note strong { color: var(--color-text); }

/* ── Placa de versión (solo superadmin, en el Panel general) ──
   Fondo oscuro con la versión en dorado — solo el superadmin ve qué versión
   corre de verdad en producción. */
.version-badge {
    background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
    border: 1px solid #334155;
    border-radius: var(--radius);
    padding: 0.9rem 1.2rem;
    margin-bottom: 1.25rem;
    text-align: right;
    box-shadow: var(--shadow-md);
}
.version-badge-num {
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: 0.01em;
    color: #facc15;
    font-variant-numeric: tabular-nums;
}
.version-badge-credit {
    margin-top: 0.15rem;
    font-size: 0.9rem;
    color: #e2e8f0;
}
.version-badge-credit strong { color: #ffffff; font-weight: 700; }
.version-badge-email {
    margin-top: 0.1rem;
    font-size: 0.8rem;
    color: #94a3b8;
}
.version-badge-quote {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
    border-top: 1px solid #334155;
    font-style: italic;
    font-size: 0.88rem;
    color: #facc15;
}

/* ── Acordeón de productos por categoría (catálogo) ──────────── */
.cat-accordion {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin-bottom: 0.5rem;
    overflow: hidden;
}
.cat-accordion > summary {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.9rem;
    cursor: pointer;
    font-weight: 600;
    background: var(--color-neutral-bg);
    list-style: none;
    user-select: none;
}
.cat-accordion > summary::-webkit-details-marker { display: none; }
.cat-accordion > summary::before {
    content: "▸";
    color: var(--color-text-muted);
    transition: transform 0.15s;
}
.cat-accordion[open] > summary::before { transform: rotate(90deg); }
.cat-accordion .cat-count {
    margin-left: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 20px;
    padding: 0.05rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-text-muted);
}
.cat-accordion-body { overflow-x: auto; }
.cat-accordion > summary > span:first-child { font-weight: 600; }
/* Categoría hoja (sin subcategorías): fila simple, no colapsable. */
.cat-leaf {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.9rem;
    border-bottom: 1px solid var(--color-border);
}
.cat-leaf:last-child { border-bottom: none; }
.cat-leaf > span:first-child { flex: 1; }
/* Acciones (superadmin) dentro del summary/hoja, alineadas a la derecha. */
.cat-actions {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
    margin-left: 0.5rem;
}

/* ═══════════════════════════════════════════════════════════════
   FASE 2 — Layout HORIZONTAL Tabler (menú ARRIBA, contenido fluido)
   Va SIN capa y al final: gana a @layer tabler donde haga falta. Solo
   estilos de shell; el contenido de los paneles no se toca. El menú reusa
   la clase .tab (switchTab no cambia): en horizontal quedan pestañas con
   subrayado activo (el look base de .tab, style.css:503-523). Se eligió el
   layout horizontal + fluido para darle TODO EL ANCHO al contenido (no hay
   sidebar que reste 15rem). Ver SESSION_LOG (Sesión 41).

   OJO (regla que se repite) — el reset propio `* { margin:0; padding:0 }`
   (sin capa, style.css:31-37) PISA todos los márgenes/paddings de Tabler
   (sin-capa gana a @layer tabler). Por eso acá se fija el padding de las
   barras y de los items de forma explícita, sin capa.
   ═══════════════════════════════════════════════════════════════ */

/* El contenedor raíz es el .page de Tabler, en columna y a todo el ancho.
   Neutralizamos el "boxed theme" de .page (max-width/borde/fondo). */
#app-wrap.page {
    flex: 1;
    max-width: none;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    display: flex;
    flex-direction: column;
}

/* ── Barra superior: marca + acciones ──────────────────────────── */
.app-topbar {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    min-height: auto;
    padding: 0;
}
.app-topbar > .container-fluid {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.55rem 1.5rem;
}
.app-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-text);
    white-space: nowrap;
}
.app-brand-mark { color: var(--color-primary); }
/* Empuja las acciones a la derecha (la marca y el subtítulo vacío quedan a la
   izquierda). */
.app-topbar .header-right { margin-left: auto; }

/* ── Barra del menú horizontal ─────────────────────────────────── */
.app-menubar {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
    min-height: auto;
    padding: 0;
}
.app-menubar > .container-fluid { padding: 0 1.5rem; }
.app-menubar .navbar-nav { gap: 0.15rem; }
.app-menubar .nav-item { display: flex; }
/* Los items reusan .tab (base: pestaña horizontal con subrayado activo). El
   -1px pega el subrayado activo al borde inferior de la barra. */
.app-menubar .tab {
    border-radius: 0;
    margin-bottom: -1px;
}

/* page-body sin el margen vertical propio de Tabler: el padding lo pone
   .app-main. */
.page-body { margin-top: 0; margin-bottom: 0; }

/* Contenido a todo el ancho (fluid): sin el cap de 1400px de .app-main. */
.app-main { max-width: none; }

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 767.98px) {
    /* La barra de menú colapsa (hamburguesa en la barra superior). Al expandir,
       los items se apilan a lo ancho; le damos aire y que ocupen la fila. */
    .app-menubar > .container-fluid { padding: 0 1rem; }
    .app-menubar .navbar-nav { gap: 0; padding: 0.25rem 0; }
    .app-menubar .nav-item { width: 100%; }
    .app-menubar .tab { width: 100%; margin-bottom: 0; }
}

/* ═══════════════════════════════════════════════════════════════
   FASE 3 — Contenido del VENDEDOR (lenguaje visual)
   Pulido de las pantallas del vendedor con estilo Tabler, reusando los
   tokens :root y las clases propias que ya existen (.stat-card, .card,
   .badge, .status-*). Clases NUEVAS y reutilizables (sin capa, sin chocar
   con Tabler ni con lo existente). Solo presentación: no toca datos/lógica.
   Ver SESSION_LOG (Sesión 42). Empezó por "Inicio" (piloto).
   ═══════════════════════════════════════════════════════════════ */

/* Grilla de métricas (mismas tarjetas .stat-card que el Panel general del
   superadmin → app cohesiva). El acento de color da lectura rápida al vendedor. */
.metric-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1rem;
    margin-top: 1.25rem;
}
.stat-card { transition: box-shadow 0.12s, border-color 0.12s; }
/* El acento de color de la métrica del vendedor migró del borde-izq. grueso al
   avatar de ícono teñido (.stat-icon, sección FASE 3.5) — el patrón de Tabler. */
.stat-value.is-success { color: var(--color-success); }
.stat-value.is-warning { color: var(--color-warning); }

/* Encabezado de sección: título + acción a la derecha, espaciado consistente. */
.section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 2rem 0 0.85rem;
}
.section-head h3 { margin: 0; font-size: 1.05rem; }
.section-head .section-sub { margin: 0.15rem 0 0; width: 100%; }

/* Embudo del pipeline como chips (de un vistazo, no una línea de texto). */
.pipeline-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.9rem; }
.pipe-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    padding: 0.3rem 0.75rem;
    background: var(--color-neutral-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--color-text-muted);
    white-space: nowrap;
}
.pipe-chip-n { font-weight: 700; color: var(--color-text); font-size: 0.92rem; }
.pipe-chip.pipe-muted { opacity: 0.75; }

/* Estado vacío reutilizable (icono + mensaje, en vez de un texto suelto). */
.empty-state {
    text-align: center;
    padding: 1.75rem 1rem;
    color: var(--color-text-muted);
    background: var(--color-neutral-bg);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
    font-size: 0.9rem;
}
.empty-state .empty-emoji { font-size: 1.6rem; display: block; margin-bottom: 0.4rem; }
.empty-state-action { margin-top: 0.75rem; }

/* Tarjeta clicable (abre modal/ficha): mismo hover que .order-card, genérico. */
.card--clickable { cursor: pointer; transition: box-shadow 0.12s, border-color 0.12s; }
.card--clickable:hover { border-color: var(--color-primary); box-shadow: var(--shadow-md); }
/* Separación entre tarjetas apiladas de una lista (antes iba en style inline). */
.order-card { margin-bottom: 0.6rem; }

/* Estructura de item de lista (orden, cliente, prospecto): 3 zonas, sin styles
   inline. Cabecera (identidad + badges) · meta (números clave) · pie (contexto +
   acción rápida). Mobile-first: todo con gap explícito (el reset mata los defaults). */
.list-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.75rem; flex-wrap: wrap; }
.list-card-identity { min-width: 0; }
.list-card-identity .name { font-weight: 700; }
.list-card-identity .sub { color: var(--color-text-muted); font-size: 0.85rem; }
.list-card-badges { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.list-card-meta { margin-top: 0.5rem; color: var(--color-text-muted); font-size: 0.85rem; display: flex; gap: 0.35rem 0.75rem; flex-wrap: wrap; }
.list-card-foot { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-top: 0.6rem; flex-wrap: wrap; }

/* Fila de KPIs compacta (Buscar prospectos): derivada de datos ya en el cliente. */
.kpi-row { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 0.85rem 0; }
.kpi { flex: 1 1 140px; }

/* Punto-semáforo de afinidad, alineado al color del marcador del mapa. */
.status-dot { display: inline-block; width: 0.6rem; height: 0.6rem; border-radius: 50%; flex: none; }
.dot-success { background: var(--color-success); }
.dot-muted { background: var(--color-text-muted); }
.dot-warning { background: var(--color-warning); }

/* Mini medidor horizontal (fit_score del prospecto). */
.mini-meter { height: 6px; border-radius: 999px; background: var(--color-neutral-bg); overflow: hidden; }
.mini-meter > span { display: block; height: 100%; border-radius: 999px; background: var(--color-primary); }

/* Toolbar de filtros/subtabs envuelta como card (agrupa el bloque de controles). */
.toolbar-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.75rem; display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1rem; }

/* Badge suave (segmento del prospecto, etiquetas): sin uppercase agresivo. */
.badge-soft { text-transform: none; letter-spacing: 0; font-weight: 600; background: var(--color-neutral-bg); color: var(--color-text-muted); }

/* Bloque de alerta (Zona peligrosa, avisos fuertes). */
.alert-danger { background: var(--color-danger-bg); border: 1px solid var(--color-danger); border-radius: var(--radius); padding: 0.8rem 1rem; color: var(--color-danger); }

/* Datagrid clave/valor reutilizable (lecturas rápidas: seguridad, datos). */
.data-grid { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.9rem; font-size: 0.88rem; }
.data-grid .k { color: var(--color-text-muted); }
.data-grid .v.ok { color: var(--color-success); }

/* Zona peligrosa (eliminar cuenta): acento rojo para separarla claramente. */
.danger-zone { border-color: var(--color-danger); border-left: 3px solid var(--color-danger); }

/* Hilo de notas de la orden (vendedor↔empresa) como burbujas de chat: las tuyas
   a la derecha (azul suave), las del otro lado a la izquierda. */
.note-thread { display: flex; flex-direction: column; gap: 0.1rem; }
.note-item { max-width: 85%; margin-bottom: 0.5rem; padding: 0.5rem 0.7rem; border-radius: 12px; background: var(--color-neutral-bg); }
.note-item.note-mine { margin-left: auto; background: #eff5ff; }
.note-meta { font-size: 0.72rem; color: var(--color-text-muted); margin-bottom: 0.2rem; }
.note-body { white-space: pre-wrap; word-break: break-word; }

/* ═══════════════════════════════════════════════════════════════
   FASE 3.5 — Fidelidad Tabler (vendedor): íconos de línea, subheaders,
   avatares de métrica y micro-ajustes al detalle del tema. Solo
   presentación. Íconos: Tabler Icons (MIT), embebidos como SVG inline
   (sin CDN ni fuente, funcionan offline). Ver THIRD_PARTY_LICENSES.md.
   ═══════════════════════════════════════════════════════════════ */

/* Ícono de línea inline: hereda color (currentColor) y se dimensiona por
   font-size salvo que el contexto fije un tamaño. El reset propio no lo toca
   (no tiene margin/padding). */
.mp-icon {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    stroke-width: 2;
    vertical-align: -0.2em;
}

/* Botón con ícono + texto: separa ambos (los botones de un solo hijo no cambian). */
.btn { gap: 0.4rem; }
.btn .mp-icon { width: 1.05em; height: 1.05em; }

/* Etiqueta "subheader" de Tabler: minúscula, versalita y con tracking. Es la
   firma visual de las tarjetas de métrica del tema. */
.subheader {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    line-height: 1.2;
}

/* Menú por rol: ícono de línea + etiqueta alineados. */
.app-menubar .tab { display: inline-flex; align-items: center; gap: 0.45rem; }
.app-menubar .tab .mp-icon { width: 18px; height: 18px; opacity: 0.9; }

/* Tarjeta de métrica estilo Tabler: fila [subheader | avatar de ícono], valor
   grande debajo. El avatar teñido es el semáforo de lectura rápida (reemplaza
   al borde-izquierdo grueso). */
.stat-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.stat-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius);
    flex: none;
}
.stat-icon .mp-icon { width: 1.2rem; height: 1.2rem; }
.stat-icon.accent-success { background: var(--color-success-bg); color: var(--color-success); }
.stat-icon.accent-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.stat-icon.accent-primary { background: var(--color-primary-soft); color: var(--color-primary); }
.stat-icon.accent-muted { background: var(--color-neutral-bg); color: var(--color-text-muted); }

/* En la métrica del vendedor el valor va con aire arriba (tras la cabecera). */
.metric-grid .stat-card { box-shadow: var(--shadow-sm); }
.metric-grid .stat-value { margin-top: 0.55rem; font-size: 1.9rem; }

/* Encabezado de sección con ícono de línea (en vez del emoji). */
.section-head h3 { display: inline-flex; align-items: center; gap: 0.5rem; }
.section-head h3 .mp-icon { width: 1.15rem; height: 1.15rem; color: var(--color-text-muted); }

/* "Salir" dentro del menú: oculto en desktop, se muestra en móvil. La
   especificidad iguala a `.app-menubar .nav-item` (que lo pone en flex) y gana
   por ir después en el archivo. */
.app-menubar .nav-item-mobile-logout { display: none; }

/* En móvil el badge de usuario (correo · rol) es redundante — ese dato vive en
   "Mi cuenta" — y roba espacio. Y "Salir" pasa AL MENÚ (más alcanzable con el
   pulgar), así que se quita de la barra superior para no duplicarlo. */
@media (max-width: 767.98px) {
    .user-badge { display: none; }
    #logout-btn { display: none; }
    .app-menubar .nav-item-mobile-logout { display: flex; }

    /* La marca "◆ Portal Vendedor Freelancer" se esconde en móvil para darle el
       ancho a la app: así la hamburguesa y las acciones (Tomar pedido / PDV /
       campana) caben en UNA sola barra (antes el título ocupaba la primera fila
       y las acciones bajaban a una segunda). Se oculta VISUALMENTE pero el <h1>
       queda para lectores de pantalla (no display:none → no se pierde el h1). */
    .app-brand {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }
    /* Con la marca fuera de flujo, apretamos padding/gap para que la hamburguesa
       (izquierda) y las acciones (derecha) entren holgadas en una fila. */
    .app-topbar > .container-fluid { padding: 0.5rem 0.75rem; gap: 0.5rem; }
    .app-topbar .header-right { gap: 0.4rem; }
}

/* ═══════════════════════════════════════════════════════════════
   FASE 3.5 — Móvil primero (el vendedor vive en terreno con el teléfono).
   En ≤640px: modales a PANTALLA COMPLETA (máximo espacio, sin franjas) y la
   tabla de productos del pedido se APILA (sin scroll horizontal, que escondía
   justo el total y la comisión). Solo presentación.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
    .modal-overlay { padding: 0; align-items: stretch; }
    .modal-card {
        max-width: none;
        width: 100%;
        height: 100vh;
        height: 100dvh;   /* respeta la barra del navegador móvil */
        max-height: none;
        border-radius: 0;
    }
    .modal-header { padding: 0.85rem 1rem; }
    /* El cuerpo crece y hace scroll; encabezado y pie quedan fijos. */
    .modal-body { padding: 1rem; flex: 1 1 auto; min-height: 0; }
    .modal-footer { padding: 0.75rem 1rem; }
    /* Acciones grandes y fáciles de tocar en terreno (ocupan el ancho). */
    .modal-footer .btn { flex: 1 1 auto; }

    /* Tabla de productos del pedido → tarjetas apiladas. Cada producto es un
       bloque con su etiqueta a la izquierda. Solo la del detalle
       (.order-lines-detail), no el catálogo de "Tomar pedido". */
    .order-lines-detail thead { display: none; }
    .order-lines-detail,
    .order-lines-detail tbody,
    .order-lines-detail tr,
    .order-lines-detail td { display: block; width: 100%; }
    .order-lines-detail tr {
        border: 1px solid var(--color-border);
        border-radius: var(--radius);
        padding: 0.55rem 0.75rem;
        margin-bottom: 0.6rem;
    }
    .order-lines-detail td { border: none; padding: 0.12rem 0; }
    .order-lines-detail td.num {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        text-align: right;
    }
    .order-lines-detail td.num::before {
        content: attr(data-label);
        color: var(--color-text-muted);
        font-weight: 600;
        text-align: left;
        margin-right: 1rem;
    }
    /* La línea no entregada se atenúa como bloque (no celda a celda). */
    .order-lines-detail .line-lost { opacity: 0.6; }
    .order-lines-detail .line-lost td { opacity: 1; }
}

/* ═══════════════════════════════════════════════════════════════
   FASE 3.5 — Móvil primero (2): objetivos táctiles, apilado y notch.
   Salió de una auditoría por pantalla (ver SESSION_LOG). Todo presentación.
   Los objetivos táctiles apuntan a ~40px sin agrandar el glifo. Selectores
   que no existan quedan inertes (no rompen nada).
   ═══════════════════════════════════════════════════════════════ */

/* Red de seguridad: un desborde puntual no arrastra el scroll de toda la página.
   Va en body (no en html/.page*): no toca el scroll vertical ni los position:fixed. */
body { overflow-x: hidden; }

/* Botón "quitar del carrito" (Tomar pedido): control real y accesible, área cómoda. */
.cart-remove {
    border: none;
    background: none;
    color: var(--color-danger);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    min-height: 40px;
    margin-left: 0.25rem;
}

/* "← Volver" del auth: área táctil sin separar de más los links inline. */
.auth-switch a { display: inline-block; padding: 0.35rem 0.5rem; margin: -0.2rem 0; }

/* iOS hace zoom al enfocar un input < 16px (la base es 0.9rem = 14.4px). Subirlo
   a 16px en móvil lo evita (y sube el alto del control de paso). */
@media (max-width: 767.98px) {
    input[type="text"], input[type="email"], input[type="password"],
    input[type="number"], input[type="search"], input[type="tel"],
    select, textarea { font-size: 16px; }
}

@media (max-width: 640px) {
    /* Objetivos táctiles: botones compactos y el ✕ de todos los modales. */
    .btn-sm, .btn-xs { min-height: 40px; padding-top: 0.5rem; padding-bottom: 0.5rem; }
    .modal-close { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }

    /* Sub-pestañas y controles de la tarjeta (estrella/etiquetas): blanco >= 40px
       sin agrandar el ícono. .subtab conserva su subrayado (margin-bottom:-1px). */
    .subtab { min-height: 40px; display: inline-flex; align-items: center; }
    .follow-star, .tag-add { min-width: 40px; min-height: 40px; display: inline-flex; align-items: center; justify-content: center; padding: 0; }

    /* WhatsApp de la tarjeta de cliente (el gesto de calle con el pulgar). */
    .mc-wa { min-height: 40px; padding: 0.5rem 0.9rem; font-size: 0.82rem; }

    /* Ficha: acciones-enlace de las listas (giros/direcciones), con "Quitar"
       (destructiva) separada de "Marcar principal". */
    #ficha-body .ficha-link-btn { min-height: 40px; padding: 0.4rem 0.5rem; display: inline-flex; align-items: center; }
    #ficha-body .ficha-list-actions { gap: 1rem; }

    /* Empresas disponibles: el botón de afinidad IA a ancho completo (scopeado
       para no afectar las toolbars de Inicio/Mis órdenes). */
    .panel[data-panel="companies-feed"] .toolbar-card .btn { width: 100%; min-height: 44px; }

    /* Tomar pedido: si el nombre del cliente/empresa es largo, los botones bajan. */
    .take-selected { flex-wrap: wrap; row-gap: 0.4rem; }

    /* Auth: inputs y botón principal con alto táctil (no son .modal-* ni btn-sm). */
    .auth-card input[type="text"], .auth-card input[type="email"],
    .auth-card input[type="password"], .auth-card input[type="tel"],
    .auth-card #auth-btn { min-height: 44px; }

    /* Notch / home indicator (iPhone) en el modal a pantalla completa. env() vale
       0 sin viewport-fit=cover / en no-notch, así que max() no cambia nada ahí. */
    .modal-header { padding-top: max(0.85rem, env(safe-area-inset-top)); }
    .modal-footer { padding-bottom: max(0.75rem, env(safe-area-inset-bottom)); }

    /* Catálogo de "Tomar pedido" → tarjetas apiladas (igual que el detalle de la
       orden), AISLADO por la clase extra .order-lines-catalog: `.order-lines-catalog td`
       (0,0,1,1) gana a `.order-lines td` y NO toca la tabla del detalle. */
    .order-lines-catalog thead { display: none; }
    .order-lines-catalog,
    .order-lines-catalog tbody,
    .order-lines-catalog tr,
    .order-lines-catalog td { display: block; width: 100%; }
    .order-lines-catalog tr {
        border: 1px solid var(--color-border);
        border-radius: var(--radius);
        padding: 0.55rem 0.75rem;
        margin-bottom: 0.6rem;
    }
    .order-lines-catalog td { border: none; padding: 0.12rem 0; }
    .order-lines-catalog td.num { display: flex; justify-content: space-between; align-items: baseline; text-align: right; }
    .order-lines-catalog td.num::before {
        content: attr(data-label);
        color: var(--color-text-muted);
        font-weight: 600;
        text-align: left;
        margin-right: 1rem;
    }
}

@media (max-width: 480px) {
    /* Fila de filtros: alto táctil (hoy 2.4rem = 38.4px). */
    .filter-row .filter-select, .filter-row .btn { height: 2.6rem; }

    /* Buscar prospectos: apilar la fila de búsqueda y sus CTAs a ancho completo. */
    .search-hero .search-row { flex-direction: column; align-items: stretch; gap: 0.5rem; }
    .search-hero .search-row > .search-grow,
    .search-hero .search-row > .btn,
    .search-hero .search-row > div { width: 100%; min-width: 0; }
    .search-hero .search-row > .btn { min-height: 44px; }

    /* Barra del mapa: el CTA "Buscar en esta zona" a ancho completo. */
    .map-toolbar .map-toolbar-spacer { display: none; }
    #map-search-here { width: 100%; min-height: 44px; font-size: 0.85rem; }
    .map-toolbar .subtab { padding: 0.55rem 0.75rem; }
}

/* ═══════════════════════════════════════════════════════════════
   Confirmación flotante de "pedido registrado" (check verde + folio).
   Tarjeta COMPACTA centrada — NO usa .modal-card, así en móvil NO va a
   pantalla completa. Igual de bien en móvil y desktop. Solo presentación.
   ═══════════════════════════════════════════════════════════════ */
.confirm-overlay {
    position: fixed;
    inset: 0;
    background: rgba(24, 36, 51, 0.45);
    z-index: 1200;   /* sobre cualquier modal (1000–1100) */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    padding-bottom: max(1rem, env(safe-area-inset-bottom));
    animation: confirm-fade 0.15s ease;
}
.confirm-pop {
    background: var(--color-surface);
    border-radius: 14px;
    box-shadow: var(--shadow-md);
    padding: 1.75rem 1.5rem 1.25rem;
    max-width: 360px;
    width: 100%;
    text-align: center;
    animation: confirm-pop-in 0.22s cubic-bezier(0.2, 0.8, 0.3, 1.2);
}
.confirm-check {
    width: 4rem;
    height: 4rem;
    margin: 0 auto 0.75rem;
    border-radius: 50%;
    background: var(--color-success-bg);
    color: var(--color-success);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.confirm-check .mp-icon { width: 2.4rem; height: 2.4rem; stroke-width: 2.2; }
/* Tonos del ícono según el resultado (verde éxito por defecto). */
.confirm-check.tone-danger { background: var(--color-danger-bg); color: var(--color-danger); }
.confirm-check.tone-primary { background: var(--color-primary-soft); color: var(--color-primary); }

/* ═══════════════════════════════════════════════════════════════
   Calendario propio con el estilo del tema (Tabler). El campo (.mp-datefield)
   es un botón que abre el calendario (.mp-datepicker), en vez del date picker
   nativo (que no se puede restilar por CSS). Solo presentación.
   ═══════════════════════════════════════════════════════════════ */
.mp-datefield-wrap { display: block; width: 100%; }
.mp-datefield {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: var(--font);
    font-size: 0.9rem;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.mp-datefield:hover { border-color: var(--color-primary); }
.mp-datefield:focus-visible { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-soft); }
.mp-datefield .mp-icon { color: var(--color-text-muted); flex: none; width: 1.05rem; height: 1.05rem; }
.mp-datefield-text.is-empty { color: var(--color-text-muted); }

.mp-datepicker {
    position: fixed;
    z-index: 1300;   /* sobre modales (1000-1100) y confirmaciones (1200) */
    width: 17rem;
    max-width: calc(100vw - 1rem);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    padding: 0.6rem;
    user-select: none;
}
.mp-dp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.35rem; }
.mp-dp-title { font-weight: 700; font-size: 0.95rem; text-transform: capitalize; }
.mp-dp-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: none;
    background: none;
    border-radius: var(--radius);
    color: var(--color-text-muted);
    cursor: pointer;
}
.mp-dp-nav:hover { background: var(--color-neutral-bg); color: var(--color-text); }
.mp-dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mp-dp-wd { text-align: center; font-size: 0.68rem; font-weight: 600; color: var(--color-text-muted); padding: 0.2rem 0; text-transform: uppercase; }
.mp-dp-day {
    aspect-ratio: 1 / 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
}
.mp-dp-day:hover { background: var(--color-neutral-bg); }
.mp-dp-day.is-other { color: var(--color-text-muted); opacity: 0.55; }
.mp-dp-day.is-today { color: var(--color-primary); font-weight: 700; box-shadow: inset 0 0 0 1px var(--color-primary); }
.mp-dp-day.is-selected,
.mp-dp-day.is-selected.is-today { background: var(--color-primary); color: #fff; font-weight: 700; box-shadow: none; }
.mp-dp-day.is-selected:hover { background: var(--color-primary-dark); }
.mp-dp-foot { display: flex; justify-content: space-between; margin-top: 0.5rem; }
.mp-dp-foot button {
    background: none;
    border: none;
    color: var(--color-primary);
    font-family: var(--font);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0.25rem 0.45rem;
    border-radius: var(--radius);
}
.mp-dp-foot button:hover { background: var(--color-neutral-bg); }

/* Móvil: calendario a lo ancho, días más grandes para el pulgar. */
@media (max-width: 480px) {
    .mp-datepicker { width: calc(100vw - 1rem); }
    .mp-dp-day { font-size: 0.95rem; }
}
.confirm-pop h3 { margin: 0 0 0.15rem; font-size: 1.15rem; }
.confirm-folio { font-size: 1.7rem; font-weight: 800; line-height: 1.1; margin: 0.1rem 0; }
.confirm-sub { color: var(--color-text-muted); font-size: 0.9rem; margin: 0.2rem 0 0.35rem; }
.confirm-total { font-size: 0.95rem; margin: 0 0 1.1rem; }
.confirm-actions { display: flex; gap: 0.5rem; }
.confirm-actions .btn { flex: 1; min-height: 44px; }

@keyframes confirm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes confirm-pop-in {
    from { opacity: 0; transform: scale(0.92) translateY(10px); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .confirm-overlay, .confirm-pop { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════
   MOTOR DE MISIONES — presentación (sin capa; padding/margin explícitos
   por el reset propio *{margin:0;padding:0}). Móvil primero: tarjetas
   claras, botones táctiles, sin scroll horizontal. Los modales heredan el
   fullscreen ≤640px de .modal-overlay/.modal-card (FASE 3.5).
   ═══════════════════════════════════════════════════════════════ */

/* Sub-pestañas del panel de misiones */
.subtab-row { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
.subtab {
    border: 1px solid var(--color-border); background: var(--color-surface);
    color: var(--color-text-muted); border-radius: var(--radius);
    padding: 0.45rem 0.85rem; font-size: 0.9rem; font-weight: 600;
    cursor: pointer; min-height: 40px;
}
.subtab-active { background: var(--color-primary-soft, #e8f2fd); color: var(--color-primary); border-color: var(--color-primary); }

/* Ledger de créditos */
.mission-ledger { display: flex; flex-direction: column; gap: 0.4rem; }
.ledger-row {
    display: flex; justify-content: space-between; align-items: center; gap: 0.6rem;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); padding: 0.6rem 0.8rem;
}
.ledger-amt { font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Condiciones de una participación */
.mission-conditions { display: flex; flex-direction: column; gap: 0.3rem; margin: 0.5rem 0; }
.mission-cond { display: flex; align-items: center; gap: 0.45rem; font-size: 0.9rem; color: var(--color-text-muted); }
.mission-cond.is-met { color: var(--color-success, #16a34a); }
.mission-cond .mp-icon { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; }
.mission-cond span:nth-child(2) { color: var(--color-text); font-weight: 600; }
.mission-cond-list { margin: 0.3rem 0 0.6rem 1.1rem; }
.mission-cond-list li { margin: 0.15rem 0; }

/* Envíos + evidencia */
.mission-subs { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.6rem; }
.mission-sub { background: var(--color-bg, #f8fafc); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.6rem 0.75rem; }
.mission-sub-head { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.25rem; }
.mission-files { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.35rem; }
.mission-ai-flags { margin-top: 0.3rem; font-size: 0.85rem; color: var(--color-warning, #b45309); background: #fffbeb; border-radius: 6px; padding: 0.3rem 0.5rem; }

/* Participaciones (empresa) */
.mission-participation { margin-bottom: 0.75rem; }
.mission-part-actions, .mission-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }
.mission-actions { margin-bottom: 1rem; }

/* Tira de créditos del vendedor */
.mission-credit-strip {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
    gap: 0.5rem; margin: 0.6rem 0 1rem;
}
.mission-credit-strip > div {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: var(--radius); padding: 0.55rem 0.7rem; text-align: center;
}
.mission-credit-strip strong { display: block; font-size: 1.2rem; margin-top: 0.15rem; font-variant-numeric: tabular-nums; }
.mission-credit-strip .is-success { color: var(--color-success, #16a34a); }
.mission-subhead { font-weight: 700; margin: 0.9rem 0 0.5rem; color: var(--color-text); }
.mission-vendor-card { margin-bottom: 0.7rem; }
.mission-corr { margin-top: 0.4rem; background: #fffbeb; border: 1px solid #fde68a; color: #92400e; border-radius: var(--radius); padding: 0.45rem 0.6rem; font-size: 0.88rem; }

/* Creador de misiones */
.mission-ai-box { background: var(--color-primary-soft, #eef5ff); border: 1px solid var(--color-primary); border-radius: var(--radius); padding: 0.7rem 0.8rem; margin-bottom: 1rem; }
.mission-ai-box textarea { width: 100%; margin: 0.3rem 0; }
.mission-missing { margin-top: 0.3rem; color: var(--color-warning, #b45309); font-size: 0.85rem; }
.field-label { display: block; font-weight: 600; font-size: 0.88rem; margin: 0.7rem 0 0.25rem; }
.mc-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; }
.mc-check { display: flex; align-items: center; gap: 0.5rem; margin: 0.5rem 0; font-size: 0.92rem; min-height: 40px; }
.mc-check input { width: auto; }
.mc-evidence-row, .mc-product-row { display: flex; gap: 0.4rem; align-items: center; margin: 0.3rem 0; flex-wrap: wrap; }
.mc-est-picker { background: var(--color-bg, #f8fafc); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 0.6rem; }
.mc-est-option { padding: 0.45rem 0.55rem; border-radius: 6px; cursor: pointer; min-height: 40px; }
.mc-est-option:hover { background: var(--color-primary-soft, #e8f2fd); }
#mission-creator-body input[type="text"], #mission-creator-body input[type="number"],
#mission-creator-body input[type="datetime-local"], #mission-creator-body select,
#mission-creator-body textarea { width: 100%; }

@media (max-width: 640px) {
    .mc-grid2 { grid-template-columns: 1fr; }
    .mission-part-actions .btn, .mission-actions .btn { flex: 1 1 auto; }
}

/* ══════════════════════════════════════════════════════════════
   LIQUIDACIÓN DE COMISIONES Y MISIONES (Boleta de Honorarios SII)
   ══════════════════════════════════════════════════════════════
   Va al FINAL del archivo a propósito: el orden ES la cascada (style.css va sin
   capa y dentro de él gana lo último). Todo declara su padding/margin explícito
   porque el reset propio `*{margin:0;padding:0}` pisa lo de Tabler.

   Los montos usan `tabular-nums` para que las columnas de plata alineen. El
   redondeo tiene un solo dueño en el servidor: acá solo se muestra. */

/* ── Card "Saldo disponible" (Inicio del vendedor) ───────────── */
.balance-card {
    border-left: 3px solid var(--color-success);
    margin-bottom: 1rem;
    padding: 1rem 1.1rem;
}
.balance-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.balance-value {
    font-size: 2rem; font-weight: 700; line-height: 1.15; margin-top: 0.15rem;
    color: var(--color-success); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.balance-unit { font-size: 0.85rem; font-weight: 600; color: var(--color-text-muted); margin-left: 0.4rem; }
.balance-split {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.6rem 1.2rem; margin-top: 0.8rem;
}
.balance-split strong { display: block; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.balance-split-muted { border-top: 1px solid var(--color-border); padding-top: 0.7rem; margin-top: 0.8rem; }
.balance-split-muted strong { font-size: 0.95rem; font-weight: 600; }
.balance-actions { margin-top: 0.9rem; }
.balance-blockers { margin-top: 0.8rem; }
.balance-blockers div { margin: 0.1rem 0; }

/* La plata en curso NO desaparece: se ve moviéndose entre estados. */
.bal-flow { margin-top: 0.8rem; border-top: 1px solid var(--color-border); padding-top: 0.7rem; }
.bal-flow-row {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
    padding: 0.35rem 0; font-size: 0.88rem;
}
.bal-flow-code { font-weight: 600; font-variant-numeric: tabular-nums; }
.bal-flow-amt, .bal-flow-net { font-variant-numeric: tabular-nums; }
.bal-flow-net { color: var(--color-success); font-weight: 600; }

/* ── Sección de "Mi cuenta" ──────────────────────────────────── */
.settle-card { margin-bottom: 1rem; padding: 1rem 1.1rem; }
.settle-card h3 { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.15rem; }
.settle-metrics { margin-top: 0.8rem; }
.settle-toolbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.9rem;
    padding: 0.7rem 0.85rem; margin: 0.7rem 0;
}
.settle-all { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; min-height: 40px; }
.settle-all input { width: auto; }
.settle-total { margin-left: auto; text-align: right; }
.settle-total strong { display: block; font-size: 1.25rem; font-variant-numeric: tabular-nums; }

/* ── Tabla de ingresos / de líneas ───────────────────────────── */
.table-scroll { overflow-x: auto; }
.settle-lines { width: 100%; border-collapse: collapse; font-size: 0.88rem; margin-top: 0.3rem; }
.settle-lines th, .settle-lines td { padding: 0.45rem 0.5rem; text-align: left; border-bottom: 1px solid var(--color-border); }
.settle-lines th { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--color-text-muted); }
.settle-lines td.num, .settle-lines th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.settle-pick { width: 2.2rem; }
.settle-pick input { width: auto; }
.linklike {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--color-primary); font: inherit; text-align: left; text-decoration: underline;
}
.linklike:hover { opacity: 0.8; }

/* ── Modal: la instrucción de emisión ────────────────────────── */
.settle-status-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-bottom: 0.8rem; }
.settle-step { font-size: 0.9rem; color: var(--color-text-muted); }
.settle-step.is-yours { color: var(--color-warning); font-weight: 600; }
.settle-emit {
    background: var(--color-primary-soft, #eef5ff);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius);
    padding: 0.85rem 0.9rem; margin-bottom: 0.9rem;
}
.settle-emit-lead { font-size: 0.95rem; line-height: 1.5; margin-bottom: 0.7rem; }
.settle-emit-warn { color: var(--color-danger); font-weight: 600; }
.settle-amounts { margin-top: 0.2rem; }
.settle-amounts .stat-value { font-variant-numeric: tabular-nums; white-space: nowrap; }
.settle-receiver, .settle-doc, .settle-payment { margin: 0.9rem 0; }

/* El detalle que se pega en el SII: monoespaciado, seleccionable, con su botón
   de copiar (el texto va en data-* — nunca un literal JS dentro de un onclick). */
.settle-detail-box {
    border: 1px dashed var(--color-border); border-radius: var(--radius);
    padding: 0.8rem 0.85rem; margin: 0.9rem 0;
}
.settle-detail {
    background: var(--color-neutral-bg, #f8fafc); border-radius: 6px;
    padding: 0.6rem 0.7rem; margin: 0.5rem 0; font-size: 0.85rem;
    white-space: pre-wrap; word-break: break-word;
    font-family: ui-monospace, Menlo, Consolas, monospace;
}
.settle-detail-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.settle-issues { margin: 0.35rem 0 0 1.1rem; }
.settle-issues li { margin: 0.15rem 0; }
.settle-ok {
    background: color-mix(in srgb, var(--color-success) 10%, transparent);
    border: 1px solid var(--color-success); border-radius: var(--radius);
    padding: 0.55rem 0.7rem; margin: 0.8rem 0; font-size: 0.88rem; color: var(--color-success);
}

/* ── Formularios de subida / pago / checklist ────────────────── */
.settle-upload { border-top: 1px solid var(--color-border); margin-top: 1rem; padding-top: 0.9rem; }
.settle-upload h4 { margin-bottom: 0.2rem; }
.settle-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.6rem 0.9rem; margin: 0.6rem 0; }
.settle-fields label { display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 0.2rem; }
.settle-fields input, .settle-fields select { width: 100%; }
.settle-upload-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.settle-checklist {
    background: var(--color-neutral-bg, #f8fafc); border: 1px solid var(--color-border);
    border-radius: var(--radius); padding: 0.75rem 0.85rem; margin: 0.9rem 0;
}
.settle-checklist h4 { margin-bottom: 0.4rem; }
.settle-check { display: flex; align-items: flex-start; gap: 0.55rem; margin: 0.35rem 0; font-size: 0.9rem; min-height: 40px; }
.settle-check input { width: auto; margin-top: 0.15rem; }
.settle-timeline { margin-top: 0.4rem; }

/* ── Móvil primero: el vendedor vive en terreno con el teléfono ─ */
@media (max-width: 640px) {
    .balance-value { font-size: 1.7rem; }
    .balance-head { align-items: center; }
    .balance-split { grid-template-columns: 1fr 1fr; }
    .balance-actions .btn { width: 100%; min-height: 44px; }
    .settle-toolbar { flex-direction: column; align-items: stretch; }
    .settle-total { margin-left: 0; text-align: left; }
    .settle-toolbar .btn { width: 100%; min-height: 44px; }
    .settle-fields { grid-template-columns: 1fr; }
    .settle-detail-actions .btn { flex: 1 1 auto; min-height: 40px; }
    .bal-flow-row { flex-direction: column; align-items: flex-start; gap: 0.15rem; }

    /* La tabla se APILA en tarjetas: sin esto el scroll horizontal esconde justo
       la columna del monto, que es la que importa. Clase aislada (.settle-lines)
       para no contaminar las tablas del pedido. */
    .table-scroll { overflow-x: visible; }
    .settle-lines thead { display: none; }
    .settle-lines,
    .settle-lines tbody,
    .settle-lines tr,
    .settle-lines td { display: block; width: 100%; }
    .settle-lines tr {
        border: 1px solid var(--color-border); border-radius: var(--radius);
        padding: 0.55rem 0.75rem; margin-bottom: 0.6rem;
    }
    .settle-lines td { border: none; padding: 0.12rem 0; }
    .settle-lines td[data-label] {
        display: flex; justify-content: space-between; align-items: baseline; text-align: right;
    }
    .settle-lines td[data-label]::before {
        content: attr(data-label);
        color: var(--color-text-muted); font-weight: 600;
        text-align: left; margin-right: 1rem;
    }
    .settle-lines td.settle-pick { display: block; text-align: left; }
    .settle-lines td.settle-pick input { min-width: 22px; min-height: 22px; }
}

/* ══════════════════════════════════════════════════════════════
   PRUEBA DE CONEXIÓN (Configuración → API)
   ══════════════════════════════════════════════════════════════
   El semáforo por integración. Antes, configurar una key era a ciegas: se
   guardaba y no había forma de saber si servía hasta que la feature fallaba
   (o peor, hasta que NO fallaba de forma visible — el mapa se veía gris y
   nadie sabía por qué).

   El punto de color lleva SIEMPRE su palabra al lado ("PASSED"/"NO PASSED"):
   el color solo no le sirve a quien no distingue rojo de verde, y tampoco a
   un lector de pantalla. */

.conn-test {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin: 0.35rem 0 0.9rem;
}

.conn-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: 0 0 auto;
    margin-top: 0.55rem;
    background: var(--color-border, #e5e7eb);
}
.conn-dot[data-state="passed"]  { background: var(--color-success, #2fb344); }
.conn-dot[data-state="failed"]  { background: var(--color-danger,  #d63939); }
.conn-dot[data-state="testing"] {
    background: var(--color-primary, #066fd1);
    animation: conn-pulse 1s ease-in-out infinite;
}

@keyframes conn-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
    .conn-dot[data-state="testing"] { animation: none; }
}

.conn-msg {
    margin: 0.4rem 0 0;
    flex: 1 1 260px;
    min-width: 0;          /* deja que el texto largo corte en vez de desbordar */
    line-height: 1.45;
}

.conn-verdict { letter-spacing: 0.02em; }
.conn-passed  { color: var(--color-success, #2fb344); }
.conn-failed  { color: var(--color-danger,  #d63939); }

/* El detalle (la pista accionable) va debajo y más chico: el veredicto tiene
   que leerse de un vistazo, el porqué se lee después. */
.conn-detail {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.85em;
    opacity: 0.85;
}

/* Móvil: el botón a todo el ancho y el resultado abajo — en 375px, botón y
   mensaje en la misma línea dejan el mensaje en una columna de 3 palabras. */
@media (max-width: 640px) {
    .conn-test > .btn { width: 100%; }
    .conn-dot { margin-top: 0.35rem; }
    .conn-msg { flex-basis: 100%; }
}
