/* App de staff de Fiweex Loyalty.

   La abre un empleado en el celular, parado en el mostrador, con un cliente
   enfrente esperando. Todo está dimensionado para eso: botones de 56px, textos
   grandes, contraste alto y cero dependencias externas.

   El lenguaje visual es el del panel de Loyalty (fx_loyalty_tablero.css):
   superficies blancas sobre un fondo apenas gris, borde tenue, doble sombra y
   el violeta #6D5BF7 como único color de marca. Los valores están repetidos
   acá y no importados: aquellos cuelgan de #fx-loyalty-page y viven dentro del
   panel con mdi_shell.css cargado, y esta pantalla se abre suelta desde un
   link, sin nada de eso alrededor. Es el mismo criterio que ya se aplicó con
   .fxp-* y .fxd-*.

   Prefijo .fxs-* para no chocar con .fxlc-* (la tarjeta), .fxp-* (la landing)
   ni .fxd-* (el panel). */

:root {
    --fxs-fondo: #FAFAFC;
    --fxs-panel: #FFFFFF;
    --fxs-borde: #E9E9EF;

    --fxs-tinta: #18181B;
    --fxs-tinta-media: #52525B;
    --fxs-tinta-suave: #71717A;

    /* Violeta de marca, el mismo --fxd-marca del panel. */
    --fxs-marca: #6D5BF7;
    --fxs-marca-fuerte: #5B48E0;
    --fxs-marca-suave: #F1EEFE;

    --fxs-ok: #16A34A;
    --fxs-error: #DC2626;
    --fxs-premio: #B45309;
    --fxs-premio-fondo: #FEF3C7;

    /* Doble sombra, igual que .fxd-panel: una corta que despega la superficie
       del fondo y otra larga y difusa que la apoya. Con una sola, o se ve un
       borde duro o no se ve nada. */
    --fxs-sombra: 0 1px 2px rgba(24, 24, 27, .05),
                  0 12px 28px -14px rgba(24, 24, 27, .16);
}

.fxs-body {
    margin: 0;
    padding: 0 0 env(safe-area-inset-bottom);
    /* Velo violeta arriba, fijo (no se mueve con el scroll): es lo mismo que
       separa un panel de datos de una app con la que da gusto trabajar, y
       sobre blanco no cuesta nada de legibilidad. */
    background:
        radial-gradient(1100px 520px at 50% -12%, rgba(109, 91, 247, .12), transparent 62%),
        var(--fxs-fondo);
    background-attachment: fixed;
    color: var(--fxs-tinta);
    font-family: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    -webkit-font-smoothing: antialiased;
    /* Sin selección de texto: el empleado toca botones, no lee. Evita el menú
       de copiar al mantener apretado. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.fxs-body *, .fxs-body *::before, .fxs-body *::after { box-sizing: border-box; }

/* Toda la app se muestra y se esconde con el atributo hidden. Cualquier regla
   nuestra con display (flex, block) le gana al display:none del navegador, así
   que el elemento "oculto" sigue en pantalla: es lo que tapaba el visor de la
   cámara con el cartel de "Prender cámara". */
.fxs-body [hidden] { display: none !important; }

.fxs-wrap {
    width: 100%;
    max-width: 480px;
    margin: 0 auto;
    padding: 12px 14px 28px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.fxs-centrado { min-height: 100svh; justify-content: center; }

/* --- Cabecera ---
   Pegada arriba: en la pantalla de la tarjeta el empleado scrollea hasta los
   botones, y "Salir" es lo que cierra el turno cuando le pasa el celular a un
   compañero. Con blur atrás para que el contenido que pasa por debajo no se
   confunda con el texto de la cabecera. */
.fxs-top {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: -12px -14px 0;
    padding: 12px 14px;
    background: rgba(250, 250, 252, .88);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--fxs-borde);
}
.fxs-marca { display: flex; align-items: center; gap: 10px; min-width: 0; }
.fxs-negocio-col { display: flex; flex-direction: column; min-width: 0; }

/* Logo chico del negocio, junto al nombre. Redondeado y con un borde tenue:
   funciona igual de bien con un isotipo cuadrado que con uno circular, sin
   que el propio marco compita con el logo. */
.fxs-logo-mini {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    object-fit: cover;
    background: #fff;
    border: 1px solid var(--fxs-borde);
}

.fxs-negocio {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fxs-empleado { font-size: 12px; color: var(--fxs-tinta-suave); }
/* Sin empleado logueado el renglón no reserva alto: la cabecera del login
   queda con el nombre del negocio solo y centrado verticalmente. */
.fxs-empleado:empty { display: none; }

.fxs-salir {
    flex: 0 0 auto;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    color: var(--fxs-tinta-media);
    background: #fff;
    border: 1px solid var(--fxs-borde);
    border-radius: 999px;
    padding: 7px 15px;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}
.fxs-salir:active { background: var(--fxs-fondo); color: var(--fxs-tinta); }

/* --- Paneles --- */
.fxs-panel {
    background: var(--fxs-panel);
    border: 1px solid var(--fxs-borde);
    border-radius: 14px;
    padding: 18px;
    box-shadow: var(--fxs-sombra);
}

/* El panel de login es la primera pantalla que ve el empleado y, con el logo
   del negocio arriba, la que más tiene que sentirse "de este local" y no
   "una herramienta genérica". Un poco más de aire y la franja de marca arriba
   alcanzan para eso sin tocar el resto de los paneles. */
.fxs-panel-login {
    position: relative;
    padding-top: 24px;
    text-align: center;
    overflow: hidden;
}
.fxs-panel-login::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--fxs-marca), #957AFB);
}
.fxs-panel-login .fxs-titulo,
.fxs-panel-login .fxs-sub { text-align: center; }
.fxs-panel-login form { text-align: left; }

.fxs-logo-login {
    display: block;
    width: 64px;
    height: 64px;
    margin: 0 auto 14px;
    border-radius: 16px;
    object-fit: cover;
    background: #fff;
    border: 1px solid var(--fxs-borde);
    box-shadow: 0 8px 20px -12px rgba(24, 24, 27, .35);
}

.fxs-titulo {
    margin: 0 0 4px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--fxs-tinta);
}
.fxs-sub { margin: 0 0 16px; font-size: 14px; color: var(--fxs-tinta-suave); }

.fxs-label {
    display: block;
    margin: 14px 0 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fxs-tinta-media);
}
.fxs-label:first-of-type { margin-top: 0; }

.fxs-input {
    width: 100%;
    /* 16px exactos: con menos, Safari en iPhone hace zoom al enfocar y la app
       queda descuadrada en plena atención al cliente. */
    font-size: 16px;
    font-family: inherit;
    color: var(--fxs-tinta);
    background: #fff;
    border: 1px solid var(--fxs-borde);
    border-radius: 10px;
    padding: 13px 14px;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.fxs-input::placeholder { color: #A1A1AA; }
.fxs-input:focus {
    border-color: var(--fxs-marca);
    box-shadow: 0 0 0 3px rgba(109, 91, 247, .18);
}

/* El código se dicta en voz alta y se tipea: monoespaciado y espaciado para
   que el empleado no confunda caracteres al leerlo de vuelta. */
.fxs-codigo {
    font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 22px;
    letter-spacing: .18em;
    text-align: center;
    text-transform: uppercase;
}

/* --- Botones --- */
.fxs-btn {
    position: relative;
    width: 100%;
    /* 56px: se toca con el pulgar, de parado, a veces con una sola mano. */
    min-height: 56px;
    margin-top: 16px;
    font-size: 17px;
    font-weight: 600;
    font-family: inherit;
    color: #fff;
    background: var(--fxs-marca);
    border: 0;
    border-radius: 12px;
    cursor: pointer;
    box-shadow: 0 8px 20px -12px rgba(109, 91, 247, .8);
    transition: background .15s, transform .12s ease, box-shadow .12s ease, opacity .15s;
}
.fxs-btn:active {
    background: var(--fxs-marca-fuerte);
    transform: scale(.99);
    box-shadow: 0 4px 12px -10px rgba(109, 91, 247, .8);
}
.fxs-btn:disabled { opacity: .5; cursor: default; box-shadow: none; transform: none; }

.fxs-btn-grande { min-height: 64px; font-size: 19px; font-weight: 700; }

/* Entregar el premio es la acción con costo real del módulo: ámbar plena para
   que no se confunda con "Sellar", que es la de todos los días. */
.fxs-btn-premio {
    background: #F59E0B;
    color: #1F2937;
    box-shadow: 0 8px 20px -12px rgba(245, 158, 11, .9);
}
.fxs-btn-premio:active { background: #D97706; }

.fxs-btn.is-cargando .fxs-btn-txt { visibility: hidden; }
.fxs-btn.is-cargando .fxs-spinner { display: block; }

.fxs-spinner {
    display: none;
    position: absolute;
    top: 50%; left: 50%;
    width: 22px; height: 22px;
    margin: -11px 0 0 -11px;
    border: 2px solid rgba(255, 255, 255, .4);
    border-top-color: #fff;
    border-radius: 50%;
    animation: fxs-girar .7s linear infinite;
}
@keyframes fxs-girar { to { transform: rotate(360deg); } }

.fxs-deshacer {
    padding: 0;
    font-family: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}
/* Secundario de Fiweex Loyalty: mismo lavado de marca que .fxd-btn--marca-suave
   del tablero, no el link chico de antes. Con el cliente enfrente el empleado
   necesita un botón que se toque seguro, no un texto que hay que apuntar. */
.fxs-volver {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-height: 48px;
    margin-bottom: 12px;
    padding: 0 20px;
    font-family: inherit;
    font-size: 16px;
    font-weight: 700;
    color: var(--fxs-marca);
    background: var(--fxs-marca-suave);
    border: 0;
    border-radius: 12px;
    cursor: pointer;
    transition: background .15s, color .15s;
}
.fxs-volver:active {
    background: #E6E1FD;
    color: var(--fxs-marca-fuerte);
}
.fxs-deshacer {
    display: block;
    width: 100%;
    margin-top: 14px;
    padding: 10px;
    font-size: 14px;
    font-weight: 600;
    color: var(--fxs-error);
    text-decoration: underline;
}

/* --- Cámara ---
   El visor sigue siendo negro aunque la app sea clara: es video, y un marco
   claro alrededor de una imagen oscura hace que la pupila se cierre y el QR se
   lea peor. Sobre blanco, además, la caja negra es lo primero que encuentra el
   ojo al abrir la pantalla, que es exactamente lo que hay que tocar. */
.fxs-camara-caja {
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    background: #18181B;
    /* Cuadrada: es la forma en que la gente apunta a un QR, y evita que el
       visor cambie de alto cuando la librería arranca. */
    aspect-ratio: 1 / 1;
}
.fxs-camara { width: 100%; height: 100%; }
.fxs-camara video { width: 100% !important; height: 100% !important; object-fit: cover; }

.fxs-camara-off {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px;
    text-align: center;
    background: var(--fxs-marca-suave);
}
.fxs-camara-off p { margin: 0; font-size: 14px; color: var(--fxs-tinta-media); }
.fxs-camara-off .fxs-btn { width: auto; padding: 0 24px; min-height: 48px; }

/* Alternativa a la cámara, siempre visible. Separada por una línea para que se
   lea como el otro camino y no como un paso más del de arriba. */
.fxs-manual {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--fxs-borde);
    font-size: 14px;
    color: var(--fxs-tinta-suave);
}
.fxs-manual-lbl {
    display: block;
    margin-bottom: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--fxs-tinta-media);
}
.fxs-manual form { display: flex; flex-direction: column; gap: 10px; }

/* --- Historial del empleado ---
   La versión de mostrador del registro de sellos del panel
   (fx_loyalty_sellos.php): las mismas filas y el mismo vocabulario visual —la
   posición del ciclo a la derecha, la fila anulada apagada y tachada, el botón
   de anular en rojo lavado—, pero como lista y no como tabla. Cinco columnas no
   entran en un celular sostenido con una mano, y de todas formas acá no se
   filtra ni se exporta: se mira lo último y, si hace falta, se corrige. */
.fxs-historial { padding: 16px 14px; }

.fxs-hist-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}
.fxs-hist-titulo {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.3;
    /* El nombre del empleado va adentro del título, así que puede ser largo:
       que use dos renglones antes que empujar a "Actualizar" fuera del panel. */
    min-width: 0;
}
.fxs-hist-refrescar {
    flex: 0 0 auto;
    padding: 7px 13px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--fxs-marca);
    background: var(--fxs-marca-suave);
    border: 0;
    border-radius: 999px;
    cursor: pointer;
}
.fxs-hist-refrescar:active { background: #E6E1FD; color: var(--fxs-marca-fuerte); }
.fxs-hist-refrescar:disabled { opacity: .5; cursor: default; }

.fxs-hist-vacio {
    margin: 0;
    font-size: 14px;
    line-height: 1.45;
    color: var(--fxs-tinta-suave);
}

.fxs-hist-lista { margin: 0; padding: 0; list-style: none; }

/* Separadas por una línea y no por tarjetas: son renglones de un mismo
   registro, y un borde completo por sello convertía la lista en una pila de
   cajas que compite con el panel del escáner de arriba. */
.fxs-hist-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 0;
    border-top: 1px solid var(--fxs-borde);
}
.fxs-hist-item:first-child { border-top: 0; padding-top: 0; }

.fxs-hist-fila { display: flex; align-items: flex-start; gap: 10px; }
.fxs-hist-datos { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }

.fxs-hist-cliente {
    font-size: 15px;
    font-weight: 600;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fxs-hist-meta { font-size: 13px; color: var(--fxs-tinta-suave); }

/* Cuál del ciclo fue este sello. Monoespaciado y en pastilla: es el dato que se
   barre de arriba abajo cuando el empleado busca el que puso mal. */
.fxs-hist-pos {
    flex: 0 0 auto;
    padding: 3px 9px;
    font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 13px;
    font-weight: 600;
    color: var(--fxs-tinta-media);
    background: var(--fxs-fondo);
    border: 1px solid var(--fxs-borde);
    border-radius: 999px;
    white-space: nowrap;
}

/* El sello anulado sigue en la lista —es lo que el empleado viene a verificar
   cuando se corrigió—, pero apagado: ya no cuenta para nadie. */
.fxs-hist-item.is-anulado .fxs-hist-cliente {
    color: var(--fxs-tinta-suave);
    text-decoration: line-through;
}
.fxs-hist-item.is-anulado .fxs-hist-pos {
    color: #A1A1AA;
    text-decoration: line-through;
}
.fxs-hist-baja {
    font-size: 13px;
    line-height: 1.4;
    color: var(--fxs-error);
}

.fxs-hist-nota { font-size: 13px; color: var(--fxs-tinta-suave); }

/* Alineado a la derecha y del alto de un botón real (44px de área táctil): es
   una acción destructiva, así que no se pone en el camino del pulgar que baja
   leyendo, pero tampoco puede errarse. */
.fxs-hist-anular {
    align-self: flex-end;
    min-height: 44px;
    padding: 0 18px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    color: var(--fxs-error);
    background: #FEF2F2;
    border: 0;
    border-radius: 10px;
    cursor: pointer;
    transition: background .15s;
}
.fxs-hist-anular:active { background: #FEE2E2; }
.fxs-hist-anular:disabled { opacity: .5; cursor: default; }

/* Salida a la pantalla completa. Ancho entero y separado por la misma línea que
   las filas: es el último renglón de la lista —"y hay más"—, no un botón que
   compita con los del escáner de arriba. */
.fxs-hist-todos {
    display: block;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--fxs-borde);
    font-size: 14px;
    font-weight: 600;
    color: var(--fxs-marca);
    text-align: center;
    text-decoration: none;
}
.fxs-hist-todos:active { color: var(--fxs-marca-fuerte); }

/* --- Historial completo (/loyalty_staff_sellos) ---
   La pantalla propia: mismo orden de lectura que fx_loyalty_sellos.php del
   panel —encabezado, números, lista, pie con el paginado— en el ancho de un
   celular. Reusa .fxs-hist-* de arriba: la fila es la misma, y que el sello se
   lea igual en los dos lados es justamente lo que hace que la pantalla completa
   se sienta "lo mismo, pero todo". */
a.fxs-volver { text-decoration: none; }

.fxs-hist-encabezado h1 {
    margin: 0 0 4px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
}
.fxs-hist-encabezado p {
    margin: 0;
    font-size: 14px;
    line-height: 1.45;
    color: var(--fxs-tinta-suave);
}

/* Tres en fila y no una tarjeta cada uno: son el contexto de la lista, no el
   contenido de la pantalla. Con grid de tres columnas iguales entran en 480px
   sin que el número más largo desacomode a los otros. */
.fxs-kpis {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}
.fxs-kpi {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 10px;
    background: var(--fxs-panel);
    border: 1px solid var(--fxs-borde);
    border-radius: 12px;
    box-shadow: var(--fxs-sombra);
}
.fxs-kpi-valor { font-size: 22px; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; }
.fxs-kpi-label { font-size: 12px; line-height: 1.3; color: var(--fxs-tinta-suave); }
/* El color solo en los dos que lo necesitan: "hoy" es lo que el empleado viene
   mirando y los anulados son la excepción. Pintar los tres los volvería un
   semáforo sin significado. */
.fxs-kpi.es-hoy .fxs-kpi-valor { color: var(--fxs-marca); }
.fxs-kpi.es-anulado .fxs-kpi-valor { color: var(--fxs-error); }

/* Pie de la lista, adentro del panel: el conteo y el paginador describen a esta
   lista y sueltos abajo se leen como otro bloque. */
.fxs-hist-pie {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--fxs-borde);
}
.fxs-hist-conteo {
    margin: 0;
    font-size: 13px;
    color: var(--fxs-tinta-suave);
    text-align: center;
}
.fxs-hist-conteo b { color: var(--fxs-tinta-media); font-weight: 700; }

/* Anterior / Siguiente y no la tira de números del panel: son dos objetivos
   grandes en los extremos, que es donde caen los pulgares. */
.fxs-pag {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
}
.fxs-pag-btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    padding: 0 14px;
    font-size: 15px;
    font-weight: 600;
    color: var(--fxs-marca);
    background: var(--fxs-marca-suave);
    border-radius: 10px;
    text-decoration: none;
}
.fxs-pag-btn:active { background: #E6E1FD; color: var(--fxs-marca-fuerte); }
/* El extremo se muestra apagado y no desaparece: sin él los dos botones se
   corren de lugar al llegar a la primera o la última página, y el pulgar
   aprende una posición que después cambia. */
.fxs-pag-btn.is-off {
    color: #A1A1AA;
    background: var(--fxs-fondo);
    cursor: default;
}
.fxs-pag-info { font-size: 13px; font-weight: 600; color: var(--fxs-tinta-media); }

/* --- Tarjeta encontrada --- */
.fxs-programa {
    margin: 0 0 2px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--fxs-marca);
}
.fxs-cliente {
    margin: 0 0 14px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
}

.fxs-progreso { display: flex; flex-direction: column; gap: 8px; }
.fxs-contador { font-size: 32px; font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.fxs-barra { height: 10px; border-radius: 999px; background: #EFEFF4; overflow: hidden; }
.fxs-barra-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    /* El violeta de marca al lila, el mismo degradado que la franja del login
       y que la marca usa en la landing y el onboarding. */
    background: linear-gradient(90deg, var(--fxs-marca), #957AFB);
    transition: width .35s ease;
}
.fxs-barra-fill.is-completa { background: linear-gradient(90deg, var(--fxs-ok), #22C55E); }
.fxs-premio { font-size: 14px; color: var(--fxs-tinta-suave); }

.fxs-acciones { display: flex; flex-direction: column; }

/* --- Recompensas intermedias ---
   Una fila por intermedia del programa, en el orden de los sellos. La que se
   puede entregar lleva el ámbar del premio y su botón; las demás son un dato
   en tinta suave, para que de un vistazo resalte solo lo que hay que hacer. */
.fxs-intermedias {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.fxs-intermedias[hidden] { display: none; }
.fxs-inter {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px 8px 12px;
    border: 1px solid var(--fxs-borde);
    border-radius: 10px;
    font-size: 14px;
    line-height: 1.35;
    color: var(--fxs-tinta-suave);
}
.fxs-inter-txt { flex: 1; min-width: 0; }
.fxs-inter-tit { display: block; font-weight: 600; color: var(--fxs-tinta); overflow-wrap: anywhere; }
.fxs-inter-sub { display: block; font-size: 12px; }
.fxs-inter.is-disponible {
    border-color: transparent;
    background: var(--fxs-premio-fondo);
}
.fxs-inter.is-disponible .fxs-inter-tit,
.fxs-inter.is-disponible .fxs-inter-sub { color: var(--fxs-premio); }
.fxs-inter.is-canjeada .fxs-inter-tit { color: var(--fxs-tinta-suave); text-decoration: line-through; }
.fxs-inter-btn {
    flex: none;
    min-height: 40px;
    padding: 0 14px;
    font-size: 14px;
    font-weight: 700;
    font-family: inherit;
    color: #1F2937;
    background: #F59E0B;
    border: 0;
    border-radius: 10px;
    cursor: pointer;
}
.fxs-inter-btn:active { background: #D97706; }
.fxs-inter-btn:disabled { opacity: .5; cursor: default; }

/* Popup de pendientes: una casilla por intermedia, del alto de un dedo. */
.fxs-pend-lista { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.fxs-pend-item {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 48px;
    padding: 0 12px;
    border: 1px solid var(--fxs-borde);
    border-radius: 10px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
}
.fxs-pend-item input { width: 22px; height: 22px; flex: none; accent-color: #F59E0B; }
.fxs-pend-nota { margin-top: 12px; font-size: 13px; }

/* --- Fecha límite de la tarjeta ---
   Un dato, no un aviso: va en tinta suave y sin fondo de color, para que el
   amarillo del aviso de abajo siga significando "leé esto antes de actuar". La
   etiqueta y la fecha se separan solas con el gap. */
.fxs-vence {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    margin: 12px 0 0;
    padding: 8px 12px;
    border: 1px solid var(--fxs-borde);
    border-radius: 10px;
    font-size: 13px;
    line-height: 1.4;
}
.fxs-vence[hidden] { display: none; }
.fxs-vence-lbl { color: var(--fxs-tinta-suave); }
/* La fecha es lo que el empleado le lee al cliente: pesa más que su etiqueta. */
.fxs-vence-fecha { font-weight: 700; color: var(--fxs-tinta); white-space: nowrap; }

/* Con la tarjeta completa y plazo de canje corriendo, esta fecha deja de ser
   un dato de fondo y pasa a ser lo que hay que decirle al cliente antes de que
   se vaya del mostrador. */
.fxs-vence.is-canje {
    border-color: transparent;
    background: var(--fxs-premio-fondo);
}
.fxs-vence.is-canje .fxs-vence-lbl,
.fxs-vence.is-canje .fxs-vence-fecha { color: var(--fxs-premio); }

.fxs-aviso-linea {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--fxs-premio-fondo);
    color: var(--fxs-premio);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.4;
}

/* --- Mensajes --- */
.fxs-error {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-radius: 10px;
    background: #FEF2F2;
    font-size: 14px;
    line-height: 1.4;
    color: var(--fxs-error);
}

.fxs-aviso { text-align: center; }
.fxs-aviso h1 { margin: 0 0 8px; font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
.fxs-aviso p { margin: 0; color: var(--fxs-tinta-suave); }

/* El resultado se lee de reojo, con el cliente enfrente: va grande, fijo abajo
   y por encima de todo. Siempre en color pleno, incluso ahora que el fondo es
   claro: es el único elemento que tiene que leerse sin mirar. */
.fxs-toast {
    position: fixed;
    left: 50%;
    bottom: calc(20px + env(safe-area-inset-bottom));
    transform: translateX(-50%);
    z-index: 60;
    width: min(440px, calc(100vw - 28px));
    padding: 16px 18px;
    border-radius: 12px;
    font-size: 16px;
    font-weight: 600;
    text-align: center;
    color: #fff;
    background: var(--fxs-tinta);
    box-shadow: 0 12px 32px -10px rgba(24, 24, 27, .45);
}
.fxs-toast.is-ok     { background: var(--fxs-ok); }
.fxs-toast.is-error  { background: #B91C1C; }
.fxs-toast.is-premio { background: #F59E0B; color: #1F2937; }

/* --- Confirmación ---
   Reemplaza al window.confirm del navegador. El diálogo del sistema sale
   pegado al borde de arriba, con tipografía chica y botones del tamaño de un
   link: con el celular en una mano y el cliente enfrente se acepta sin leer.
   Este ocupa el ancho de la app y sus botones son los mismos que el resto. */
.fxs-modal {
    position: fixed;
    inset: 0;
    z-index: 70;   /* sobre el toast, que es 60 */
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 14px;
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
    background: rgba(24, 24, 27, .45);
}
/* Como el resto de la app, se muestra y se esconde con [hidden]: la regla de
   display de arriba le ganaría al display:none del navegador. */
.fxs-modal[hidden] { display: none; }

.fxs-modal-caja {
    width: min(440px, 100%);
    background: var(--fxs-panel);
    border: 1px solid var(--fxs-borde);
    border-radius: 16px;
    padding: 20px;
    box-shadow: 0 18px 44px -12px rgba(24, 24, 27, .3);
    /* Entra desde abajo, que es de donde viene el pulgar. */
    animation: fxs-subir .18s ease-out;
}
@keyframes fxs-subir {
    from { transform: translateY(14px); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .fxs-modal-caja { animation: none; }
}

.fxs-modal-titulo {
    margin: 0 0 6px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.25;
}
.fxs-modal-texto {
    margin: 0;
    font-size: 15px;
    line-height: 1.45;
    color: var(--fxs-tinta-suave);
}

/* El botón de confirmar toma el color de lo que está por pasar: entregar un
   premio es ámbar como el premio, anular es rojo. Sin variante, el violeta de
   siempre. */
.fxs-modal .fxs-btn.is-premio { background: #F59E0B; color: #1F2937; }
.fxs-modal .fxs-btn.is-premio:active { background: #D97706; }
.fxs-modal .fxs-btn.is-peligro { background: #DC2626; box-shadow: none; }
.fxs-modal .fxs-btn.is-peligro:active { background: #B91C1C; }

/* El campo del dato del staff, debajo del texto del diálogo. */
.fxs-modal-input { margin-top: 14px; }

.fxs-modal-cancelar {
    width: 100%;
    min-height: 48px;
    margin-top: 8px;
    font-size: 16px;
    font-weight: 600;
    font-family: inherit;
    color: var(--fxs-tinta-media);
    background: none;
    border: 0;
    border-radius: 12px;
    cursor: pointer;
}
.fxs-modal-cancelar:active { background: var(--fxs-fondo); }

/* --- Sello aplicado ---
   Mismo diálogo de abajo que la confirmación, pero centrado y con la marca
   verde arriba: no pregunta nada, avisa. El empleado lo mira de reojo mientras
   le devuelve el celular al cliente, así que lo que tiene que reconocer sin
   leer es el tilde. */
/* Centrado vertical, a diferencia de la confirmación, que sale de abajo al
   alcance del pulgar. Acá no hay una decisión que tomar con una mano: es un
   cartel para mirar, y en el medio de la pantalla es donde cae la vista cuando
   el empleado vuelve del cliente al celular. */
.fxs-modal-exito { align-items: center; }
.fxs-modal-exito .fxs-modal-caja { text-align: center; }

.fxs-exito-marca {
    width: 56px;
    height: 56px;
    margin: 0 auto 12px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 30px;
    line-height: 1;
    color: #fff;
    background: var(--fxs-ok);
}

/* --- Firma de Fiweex ---
   Al pie, en las tres pantallas. La app de staff se abre desde un link pelado
   que alguien pasó por WhatsApp, sin el panel alrededor: esto es lo único que
   dice de qué producto es. Discreta a propósito -es una herramienta de trabajo
   del local, no una publicidad-, pero siempre presente.

   El PNG original es oscuro y el fondo acá es claro, así que va sin invertir:
   brightness(0) lo lleva a negro puro y la opacidad hace el resto. Mismo
   criterio que .fxlc-powered.is-oscuro en la tarjeta del cliente. */
.fxs-pie {
    display: flex;
    justify-content: center;
    margin-top: 4px;
    padding-top: 4px;
}
.fxs-powered {
    height: 30px;
    width: auto;
    max-width: 200px;
    opacity: .45;
    filter: brightness(0);
}
