/* =================================================================================================
   Componentes del tema (etapa 3 del plan de tema)

   Primero el puente hacia Bootstrap 5.3: sus componentes ya están escritos con variables propias,
   así que basta darles los tokens del panel y quedan del color del tema, en claro y en oscuro, sin
   reescribir sus reglas. Después vienen las piezas que el marcado de las vistas da por hechas
   —tarjeta, campo flotante, casilla, botones de la rejilla— que antes ponía el tema UBold.
   ================================================================================================= */

/* --- Puente hacia Bootstrap ------------------------------------------------------------------- */

:root {
    --bs-body-bg: var(--tema-fondo);
    --bs-body-color: var(--tema-texto);
    --bs-body-font-family: var(--tema-fuente);
    --bs-body-font-size: var(--tema-texto-md);
    --bs-border-color: var(--tema-borde);
    --bs-border-radius: var(--tema-radio-sm);
    --bs-border-radius-lg: var(--tema-radio-md);
    --bs-secondary-color: var(--tema-texto-tenue);
    --bs-emphasis-color: var(--tema-texto);
    --bs-link-color: var(--tema-acento);
    --bs-link-hover-color: var(--tema-acento-hover);
    --bs-primary: var(--tema-acento);
    --bs-success: var(--tema-correcto);
    --bs-danger: var(--tema-peligro);
    --bs-warning: var(--tema-aviso);
    --bs-info: var(--tema-info);
}

.text-muted {
    color: var(--tema-texto-tenue) !important;
}

/* --- Botones ------------------------------------------------------------------------------------ */

.btn {
    --bs-btn-padding-y: .5rem;
    --bs-btn-padding-x: 1rem;
    --bs-btn-font-size: var(--tema-texto-md);
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--tema-radio-sm);
    min-height: var(--tema-control-alto);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--tema-esp-2);
}

.btn:focus-visible {
    outline: 2px solid var(--tema-acento);
    outline-offset: 2px;
    box-shadow: none;
}

.btn-sm {
    --bs-btn-padding-y: .25rem;
    --bs-btn-padding-x: .5rem;
    --bs-btn-font-size: var(--tema-texto-sm);
    min-height: 32px;
}

.btn-primary {
    --bs-btn-bg: var(--tema-acento);
    --bs-btn-border-color: var(--tema-acento);
    --bs-btn-color: var(--tema-acento-texto);
    --bs-btn-hover-bg: var(--tema-acento-hover);
    --bs-btn-hover-border-color: var(--tema-acento-hover);
    --bs-btn-hover-color: var(--tema-acento-texto);
    --bs-btn-active-bg: var(--tema-acento-activo);
    --bs-btn-active-border-color: var(--tema-acento-activo);
    --bs-btn-active-color: var(--tema-acento-texto);
    --bs-btn-disabled-bg: var(--tema-acento);
    --bs-btn-disabled-border-color: var(--tema-acento);
    --bs-btn-disabled-color: var(--tema-acento-texto);
}

.btn-success {
    --bs-btn-bg: var(--tema-correcto);
    --bs-btn-border-color: var(--tema-correcto);
    --bs-btn-color: var(--tema-texto-inverso);
    --bs-btn-hover-bg: var(--tema-correcto);
    --bs-btn-hover-border-color: var(--tema-correcto);
    --bs-btn-hover-color: var(--tema-texto-inverso);
    --bs-btn-active-bg: var(--tema-correcto);
    --bs-btn-active-border-color: var(--tema-correcto);
    --bs-btn-disabled-bg: var(--tema-correcto);
    --bs-btn-disabled-border-color: var(--tema-correcto);
}

.btn-danger {
    --bs-btn-bg: var(--tema-peligro);
    --bs-btn-border-color: var(--tema-peligro);
    --bs-btn-color: var(--tema-texto-inverso);
    --bs-btn-hover-bg: var(--tema-peligro);
    --bs-btn-hover-border-color: var(--tema-peligro);
    --bs-btn-hover-color: var(--tema-texto-inverso);
    --bs-btn-active-bg: var(--tema-peligro);
    --bs-btn-active-border-color: var(--tema-peligro);
    --bs-btn-disabled-bg: var(--tema-peligro);
    --bs-btn-disabled-border-color: var(--tema-peligro);
}

/* Botón neutro: el de "Cancelar" y el de las acciones que no deciden nada. */
.btn-white, .btn-secondary, .btn-light {
    --bs-btn-bg: var(--tema-superficie);
    --bs-btn-border-color: var(--tema-borde-fuerte);
    --bs-btn-color: var(--tema-texto);
    --bs-btn-hover-bg: var(--tema-hundido);
    --bs-btn-hover-border-color: var(--tema-borde-fuerte);
    --bs-btn-hover-color: var(--tema-texto);
    --bs-btn-active-bg: var(--tema-hundido);
    --bs-btn-active-border-color: var(--tema-borde-fuerte);
    --bs-btn-active-color: var(--tema-texto);
}

/* --- Tarjeta ------------------------------------------------------------------------------------ */

.card-box {
    padding: var(--tema-esp-5);
    margin-bottom: var(--tema-esp-5);
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde);
    border-radius: var(--tema-radio-md);
}

.header-title {
    margin: 0 0 var(--tema-esp-1);
    color: var(--tema-texto);
    font-size: var(--tema-texto-xl);
    font-weight: 600;
}

.card-box > p.text-muted {
    margin-bottom: var(--tema-esp-4);
}

/*
 * Las tarjetas de una fila del tablero, todas de la misma altura.
 *
 * No tienen el mismo contenido: «Timbres restantes» no lleva el RFC al pie que sí llevan «Emitidos»
 * y «Cancelados», y sin esto se queda 37 px más baja que sus vecinas y la fila se ve desalineada.
 *
 * SE ESTIRA LA TARJETA DENTRO DE SU COLUMNA, y no con `height: 100%`, que es lo primero que se
 * intenta: la columna ya mide lo que la tarjeta más alta MÁS su margen inferior, así que un 100 %
 * se pasa justo ese margen —medido en el navegador: 24 px de desborde por tarjeta— y se come el
 * aire que separa de la fila siguiente. Con la columna en flexible y la tarjeta creciendo, las tres
 * quedan a la altura de la más alta y el margen se respeta.
 *
 * La cifra NO se centra en el hueco que sobra, a propósito: como las tres empiezan con su título,
 * dejarla donde está mantiene los tres números a la misma altura, que es lo que se mira al leer la
 * fila de un vistazo.
 */
.fila-tarjetas > [class*="col-"] {
    display: flex;
    flex-direction: column;
}

    .fila-tarjetas .card-box {
        flex: 1;
    }

/* --- Interruptores de preferencia ---------------------------------------------------------------
 *
 * Las casillas que guardan al tocarlas, sin botón: los dos correos de «Mi perfil» y la venta en
 * línea de «Datos de distribuidor». La maquinaria es `utils.Interruptores`.
 *
 * Vivían en el <style> de Perfil.cshtml y se llamaban `interruptor-correo` y `nota-correo`. El
 * 2026-10-08 la venta en línea se mudó a la otra pantalla, y una regla que usan dos pantallas no
 * puede quedarse dentro de una —ni llamarse «correo» cuando ya no todas lo son—.
 */
.interruptor-preferencia {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 4px 0 0 0;
    cursor: pointer;
}

    .interruptor-preferencia input {
        width: 18px;
        height: 18px;
        margin: 0;
        accent-color: var(--tema-acento);
        cursor: pointer;
    }

.nota-preferencia {
    margin-top: 6px !important;
}

/* --- Cuenta de cobro del distribuidor -----------------------------------------------------------
 *
 * La tarjeta de la cuenta conectada de Stripe (plan-stripe-connect-distribuidores.md, K-1). Los
 * botones se envuelven en pantalla angosta en vez de desbordar: son tres y sus textos son largos.
 */
.cuenta-stripe .estado-cuenta {
    margin-bottom: var(--tema-esp-3);
}

.cuenta-stripe .acciones-cuenta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tema-esp-2);
}

/* --- Formularios -------------------------------------------------------------------------------- */

.form-control, .form-select {
    min-height: var(--tema-control-alto);
    background-color: var(--tema-superficie);
    border-color: var(--tema-borde-fuerte);
    border-radius: var(--tema-radio-sm);
    color: var(--tema-texto);
    font-size: var(--tema-texto-md);
}

.form-control:focus, .form-select:focus {
    border-color: var(--tema-acento);
    box-shadow: 0 0 0 3px var(--tema-acento-suave);
    color: var(--tema-texto);
}

.form-control::placeholder {
    color: var(--tema-texto-tenue);
}

label, .control-label {
    color: var(--tema-texto-tenue);
    font-size: var(--tema-texto-sm);
    font-weight: 500;
}

/*
 * Campo con su etiqueta arriba (etapa 4 del plan de tema).
 *
 * Hasta la etapa 3 la etiqueta flotaba dentro del campo y subía al escribir, que es bonito y tiene
 * dos problemas: en español los rótulos son largos y se cortaban, y mientras se escribe la etiqueta
 * compite con el texto. Ahora la etiqueta va encima y el campo es una caja con borde, que además
 * deja lugar para el mensaje de error debajo.
 *
 * El marcado no cambió: sigue siendo input + `.control-label` + `.bar`, en ese orden, en los 29
 * lugares que ya lo traían. La etiqueta sube con `order`, y la barra de foco —que ya no hace falta—
 * se esconde. El nombre `campo-flotante` se queda porque es el que conocen las vistas.
 */
.campo-flotante {
    display: flex;
    flex-direction: column;
    gap: var(--tema-esp-1);
    margin-bottom: var(--tema-esp-4);
}

.campo-flotante input,
.campo-flotante textarea,
.campo-flotante select {
    display: block;
    width: 100%;
    min-height: var(--tema-control-alto);
    padding: var(--tema-esp-2) var(--tema-esp-3);
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde-fuerte);
    border-radius: var(--tema-radio-sm);
    box-shadow: none;
    color: var(--tema-texto);
    font-family: inherit;
    font-size: var(--tema-texto-md);
}

.campo-flotante input:focus,
.campo-flotante textarea:focus,
.campo-flotante select:focus {
    border-color: var(--tema-acento);
    box-shadow: 0 0 0 3px var(--tema-acento-suave);
}

/* La etiqueta arriba, venga antes o después del campo en el marcado. */
.campo-flotante .control-label {
    position: static;
    order: -1;
    color: var(--tema-texto-tenue);
    font-size: var(--tema-texto-sm);
    font-weight: 600;
}

.campo-flotante .bar {
    display: none;
}

.campo-flotante textarea {
    resize: none;
}

.campo-flotante input:focus,
.campo-flotante textarea:focus,
.campo-flotante select:focus {
    outline: none;
}

/* El mensaje de validación, debajo del campo y en rojo. */
.campo-flotante .k-invalid-msg {
    order: 1;
}

/* Casilla con etiqueta al lado; el cuadro es de 18 px pero el área de toque llega a 40. */
.checkbox {
    position: relative;
    display: inline-flex;
    align-items: center;
    min-height: var(--tema-control-alto);
}

.checkbox input[type="checkbox"] {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--tema-acento);
}

.checkbox label {
    margin: 0 0 0 var(--tema-esp-2);
    color: var(--tema-texto);
    font-size: var(--tema-texto-md);
    font-weight: 400;
    cursor: pointer;
}

/* El mensaje de validación de Kendo, que las vistas colocan a mano. */
.k-invalid-msg {
    display: block;
    color: var(--tema-peligro);
    font-size: var(--tema-texto-xs);
}

/* --- Avisos y pastillas -------------------------------------------------------------------------- */

.alert {
    border-radius: var(--tema-radio-md);
    border-width: 1px;
}

.alert-success {
    background-color: var(--tema-correcto-suave);
    border-color: var(--tema-correcto);
    color: var(--tema-texto);
}

.alert-danger {
    background-color: var(--tema-peligro-suave);
    border-color: var(--tema-peligro);
    color: var(--tema-texto);
}

.badge {
    border-radius: var(--tema-radio-sm);
    font-weight: 500;
}

.text-bg-primary {
    background-color: var(--tema-acento) !important;
    color: var(--tema-acento-texto) !important;
}

/* --- Modales ------------------------------------------------------------------------------------- */

.modal-content {
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde);
    border-radius: var(--tema-radio-lg);
    box-shadow: var(--tema-sombra-modal);
}

.modal-header, .modal-footer {
    border-color: var(--tema-borde);
}

.modal-title {
    font-size: var(--tema-texto-xl);
    font-weight: 600;
}

/*
 * En teléfono el modal ocupa la pantalla: capturar un cliente o abonar timbres no cabe en una caja.
 * El contenido fluye y el pie se queda pegado abajo, para que "Guardar" esté siempre a la vista sin
 * tener que llegar al final del formulario (etapa 4 del plan de tema).
 */
@media (max-width: 575.98px) {
    .modal-dialog {
        max-width: none;
        margin: 0;
    }

    .modal-content {
        min-height: 100vh;
        border: 0;
        border-radius: 0;
    }

    .modal-footer {
        position: sticky;
        bottom: 0;
        z-index: 2;
        background-color: var(--tema-superficie);
    }
}

/* --- Avisos de sweetalert2 ----------------------------------------------------------------------- */

/*
 * El complemento trae sus colores fijos —fondo blanco, título gris, botón azul— y no mira el tema:
 * en modo oscuro el aviso salía blanco sobre la pantalla oscura. Los pinta `utils.Notifications` en
 * sus confirmaciones y la compra en línea al terminar («¡Listo!», con el folio).
 *
 * SE LE GANA EN ESPECIFICIDAD, NO EN ORDEN. `sweetalert2.all.min.js` trae su hoja dentro y la
 * inyecta —otra vez, igualita a la que ya cargó el <link>— al final del <head>, o sea después de
 * esta: a igualdad de especificidad ganaría él. Por eso cada regla cuelga de `:root`, que suma una
 * clase y con eso basta.
 *
 * LAS TAPAS DEL ICONO DE ÉXITO NO SE TOCAN A PROPÓSITO. El complemento lee el fondo YA CALCULADO
 * del aviso y se lo copia en línea a `.swal2-success-fix` y a los dos arcos, que son las piezas que
 * ocultan la animación del anillo. Al darle a `.swal2-popup` el color del tema, esas tres lo siguen
 * solas; una regla aquí solo se pelearía con un estilo en línea y habría que ponerle `!important`.
 *
 * Solo está lo que estos avisos pintan. Las entradas (`swal2-input`, `swal2-validationerror`) no se
 * tocan porque ninguna de las cuatro llamadas del panel las usa; el día que alguna las use, van
 * aquí con los mismos tokens que `.k-textbox`.
 */
:root .swal2-popup {
    background: var(--tema-superficie);
    border: 1px solid var(--tema-borde);
    border-radius: var(--tema-radio-lg);
    box-shadow: var(--tema-sombra-modal);
}

:root .swal2-popup .swal2-title {
    color: var(--tema-texto);
}

:root .swal2-popup .swal2-content {
    color: var(--tema-texto-tenue);
}

:root .swal2-popup .swal2-footer {
    border-top-color: var(--tema-borde);
    color: var(--tema-texto-tenue);
}

:root .swal2-popup .swal2-close {
    color: var(--tema-texto-tenue);
}

    :root .swal2-popup .swal2-close:hover {
        color: var(--tema-peligro);
    }

/* Los botones, como los del resto del panel: el que decide en el acento, el de cancelar neutro —los
   mismos tokens que `.btn-primary` y `.btn-white`—. Se pueden escribir aquí porque `Notifications`
   dejó de mandar `confirmButtonColor` y `cancelButtonColor`, que el complemento ponía EN LÍNEA y
   contra eso no hay hoja que valga. */
:root .swal2-popup .swal2-styled.swal2-confirm {
    background-color: var(--tema-acento);
    color: var(--tema-acento-texto);
}

:root .swal2-popup .swal2-styled.swal2-cancel {
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde-fuerte);
    color: var(--tema-texto);
}

/* El foco del complemento es un halo blanco; sobre fondo oscuro se ve como un recuadro suelto. Se
   cambia por el del panel, el mismo del buscador y de los campos de Kendo. */
:root .swal2-popup .swal2-styled:focus {
    box-shadow: 0 0 0 3px var(--tema-acento-suave);
}

/* Los iconos, con los colores semánticos del tema. El anillo del de éxito va en el tono suave, que
   es el que hace de «el mismo color al 30 %» sin tener que calcular una transparencia. */
:root .swal2-icon.swal2-success {
    border-color: var(--tema-correcto);
}

    :root .swal2-icon.swal2-success .swal2-success-ring {
        border-color: var(--tema-correcto-suave);
    }

    :root .swal2-icon.swal2-success [class^=swal2-success-line] {
        background-color: var(--tema-correcto);
    }

:root .swal2-icon.swal2-error {
    border-color: var(--tema-peligro);
}

    :root .swal2-icon.swal2-error [class^=swal2-x-mark-line] {
        background-color: var(--tema-peligro);
    }

:root .swal2-icon.swal2-warning {
    border-color: var(--tema-aviso);
    color: var(--tema-aviso);
}

:root .swal2-icon.swal2-info {
    border-color: var(--tema-info);
    color: var(--tema-info);
}

/* --- Pestañas -------------------------------------------------------------------------------------- */

.nav-tabs {
    border-bottom: 1px solid var(--tema-borde);
    gap: var(--tema-esp-2);
}

.nav-tabs .nav-link {
    min-height: var(--tema-control-alto);
    padding: var(--tema-esp-2) var(--tema-esp-4);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--tema-texto-tenue);
    font-weight: 500;
}

.nav-tabs .nav-link:hover {
    border-bottom-color: var(--tema-borde-fuerte);
    color: var(--tema-texto);
    text-decoration: none;
}

.nav-tabs .nav-link.active {
    background: none;
    border-bottom-color: var(--tema-acento);
    color: var(--tema-acento);
}

/* --- Menús desplegables ---------------------------------------------------------------------------- */

.dropdown-menu {
    --bs-dropdown-bg: var(--tema-superficie);
    --bs-dropdown-color: var(--tema-texto);
    --bs-dropdown-border-color: var(--tema-borde);
    --bs-dropdown-border-radius: var(--tema-radio-md);
    --bs-dropdown-link-color: var(--tema-texto);
    --bs-dropdown-link-hover-bg: var(--tema-hundido);
    --bs-dropdown-link-hover-color: var(--tema-texto);
    box-shadow: var(--tema-sombra-menu);
}

/* =================================================================================================
   Compatibilidad con el marcado que dejó el tema anterior.

   Son clases que las 46 vistas todavía traen. Se sostienen aquí, con los tokens del tema, hasta que
   las etapas 4 y 5 reescriban pantalla por pantalla; entonces esta sección se va completa.
   ================================================================================================= */

/* Botones chicos de la rejilla: `btn label label-success` y sus hermanos. Bajos a propósito: son
   los que mandan la altura del renglón, y el sistema visual pide 40 px. */
.btn.label {
    min-height: 28px;
    padding: var(--tema-esp-1) var(--tema-esp-2);
    border: 0;
    border-radius: var(--tema-radio-sm);
    color: #FFFFFF;
    font-size: var(--tema-texto-sm);
    font-weight: 500;
}

.btn.label:hover {
    color: #FFFFFF;
    filter: brightness(1.08);
}

.label-success { background-color: var(--tema-correcto); }
.label-info    { background-color: var(--tema-info); }
.label-danger  { background-color: var(--tema-peligro); }
.label-warning { background-color: var(--tema-aviso); }
.label-muted   { background-color: var(--tema-borde-fuerte); color: var(--tema-texto); }

.btn.label-muted:hover, .btn.label.disabled {
    color: var(--tema-texto);
}

/* Pastillas de la barra de suplantación y del pie. */
span.label {
    display: inline-block;
    padding: 2px var(--tema-esp-2);
    border-radius: var(--tema-radio-sm);
    color: #FFFFFF;
    font-size: var(--tema-texto-xs);
    font-weight: 600;
}

.full-width { width: 100%; }
.font-13    { font-size: var(--tema-texto-sm); }
.font-14    { font-size: var(--tema-texto-md); }

.m-0    { margin: 0 !important; }
.m-b-0  { margin-bottom: 0 !important; }
.m-b-10 { margin-bottom: 10px !important; }
.m-b-30 { margin-bottom: 30px !important; }
.m-t-0  { margin-top: 0 !important; }
.m-t-5  { margin-top: 5px !important; }
.m-t-10 { margin-top: 10px !important; }
.m-t-30 { margin-top: 30px !important; }
.m-l-10 { margin-left: 10px !important; }
.p-t-0  { padding-top: 0 !important; }

/* --- Asistente de compra (jquery.steps) ---------------------------------------------------------- */

/*
 * El complemento trae su propia hoja con azules fijos. Aquí solo se le cambian los colores por los
 * tokens; la estructura y el comportamiento siguen siendo suyos. La compra en línea es la única
 * pantalla que lo usa.
 */
.wizard > .steps a,
.wizard > .steps a:hover {
    border-radius: var(--tema-radio-sm);
}

.wizard > .steps .current a,
.wizard > .steps .current a:hover {
    background-color: var(--tema-acento);
    color: var(--tema-acento-texto);
}

.wizard > .steps .done a,
.wizard > .steps .done a:hover {
    background-color: var(--tema-acento-suave);
    color: var(--tema-acento);
}

.wizard > .steps .disabled a,
.wizard > .steps .disabled a:hover {
    background-color: var(--tema-hundido);
    color: var(--tema-texto-tenue);
}

.wizard > .content {
    background-color: var(--tema-hundido);
    border-radius: var(--tema-radio-md);
}

.wizard > .actions a,
.wizard > .actions a:hover {
    background-color: var(--tema-acento);
    border-radius: var(--tema-radio-sm);
    color: var(--tema-acento-texto);
}

.wizard > .actions .disabled a,
.wizard > .actions .disabled a:hover {
    background-color: var(--tema-hundido);
    color: var(--tema-texto-tenue);
}

/* Campos sueltos de Kendo: los que el marcado marca con `k-textbox` y no van en un campo flotante.
   Sin esto el navegador los pinta con su propio gris de modo oscuro. */
.k-textbox,
textarea.k-textbox {
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde-fuerte);
    border-radius: var(--tema-radio-sm);
    color: var(--tema-texto);
}

.k-textbox:focus {
    border-color: var(--tema-acento);
    box-shadow: 0 0 0 3px var(--tema-acento-suave);
    outline: none;
}

/* `btn-purple` venía del tema anterior y lo usan el cambio de PAC y el paso anterior del asistente
   de compra. Sin una regla propia salía blanco sobre blanco. Se le da el tono informativo del tema
   hasta que la etapa 5 revise esos botones. */
.btn-purple {
    --bs-btn-bg: var(--tema-info);
    --bs-btn-border-color: var(--tema-info);
    --bs-btn-color: var(--tema-texto-inverso);
    --bs-btn-hover-bg: var(--tema-info);
    --bs-btn-hover-border-color: var(--tema-info);
    --bs-btn-hover-color: var(--tema-texto-inverso);
    --bs-btn-disabled-bg: var(--tema-info);
    --bs-btn-disabled-border-color: var(--tema-info);
    --bs-btn-disabled-color: var(--tema-texto-inverso);
    background-color: var(--tema-info);
    border-color: var(--tema-info);
    color: var(--tema-texto-inverso);
}

/* `text-dark` en estas vistas quiere decir "el color de texto normal", no "negro": con el modo
   oscuro, negro sobre negro no se lee. Igual `text-light`, que se usa sobre fondos de color. */
.text-dark {
    color: var(--tema-texto) !important;
}

.text-light {
    color: #FFFFFF !important;
}

/* `bg-white` en el dashboard quiere decir "la superficie de la tarjeta". En modo oscuro, blanco
   literal deja el texto ilegible. */
.bg-white {
    background-color: var(--tema-superficie) !important;
}

/* Las utilidades de color de texto de Bootstrap se calculan de variables `-rgb` que no se pueden
   escribir con nuestros tokens; se reescriben directo para que sigan al tema. */
.text-primary { color: var(--tema-acento) !important; }
.text-success { color: var(--tema-correcto) !important; }
.text-danger  { color: var(--tema-peligro) !important; }
.text-warning { color: var(--tema-aviso) !important; }
.text-info    { color: var(--tema-info) !important; }

/* =================================================================================================
   Piezas de las pantallas críticas (etapa 4 del plan de tema)
   ================================================================================================= */

/*
 * Pastilla de estado. El sistema visual pide que un estado se lea, no que se adivine por el color
 * del renglón: por eso lleva texto siempre, y el color solo acompaña.
 */
.pastilla {
    display: inline-flex;
    align-items: center;
    gap: var(--tema-esp-1);
    padding: 2px var(--tema-esp-2);
    border-radius: 999px;
    font-size: var(--tema-texto-xs);
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}

.pastilla .punto {
    width: 6px;
    height: 6px;
    border-radius: 999px;
    background: currentColor;
}

.pastilla-ok      { background: var(--tema-correcto-suave); color: var(--tema-correcto); }
.pastilla-baja    { background: var(--tema-peligro-suave); color: var(--tema-peligro); }
.pastilla-aviso   { background: var(--tema-aviso-suave); color: var(--tema-aviso); }
.pastilla-marca   { background: var(--tema-acento-suave); color: var(--tema-acento); }
.pastilla-neutra  { background: var(--tema-superficie-alt); color: var(--tema-texto-tenue); border: 1px solid var(--tema-borde); }

/* Un dato con su rótulo encima: en las tarjetas de teléfono y en el abono. */
.dato {
    display: grid;
    gap: 1px;
}

.dato .rot {
    color: var(--tema-texto-tenue);
    font-size: var(--tema-texto-xs);
    letter-spacing: .04em;
    text-transform: uppercase;
}

.dato .val {
    font-family: var(--tema-fuente-mono);
    font-size: var(--tema-texto-md);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    /* Un correo largo parte donde toque antes que encimarse con el dato de al lado. */
    overflow-wrap: anywhere;
}

/* El dato que no es una cifra —un correo, un teléfono— no necesita la monoespaciada ni el peso. */
.dato .val.texto {
    font-family: inherit;
    font-weight: 400;
}

/* Aviso en línea, del ancho de su caja: el de "varias bolsas" y sus hermanos. */
.aviso-linea {
    display: flex;
    align-items: flex-start;
    gap: var(--tema-esp-2);
    padding: var(--tema-esp-2) var(--tema-esp-3);
    border-radius: var(--tema-radio-sm);
    background: var(--tema-aviso-suave);
    color: var(--tema-aviso);
    font-size: var(--tema-texto-sm);
}

/*
 * Botones de acción de un renglón o de una tarjeta. En escritorio miden 32 px y en teléfono 40,
 * que es el área táctil mínima del sistema visual: eran de 26 y costaba atinarles con el dedo.
 */
.btn.label {
    min-width: 32px;
    min-height: 32px;
}

@media (max-width: 991.98px) {
    .btn.label {
        min-width: 40px;
        min-height: 40px;
        font-size: var(--tema-texto-md);
    }
}

/* --- Abono de timbres --------------------------------------------------------------------------- */

/* Una tarjeta por bolsa: los mismos datos que la tabla de antes, con el rótulo una sola vez. */
.bolsa-abono {
    padding: var(--tema-esp-3);
    margin-bottom: var(--tema-esp-3);
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde);
    border-radius: var(--tema-radio-md);
}

.bolsa-abono .cabecera-bolsa {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tema-esp-2);
    margin-bottom: var(--tema-esp-3);
}

.bolsa-abono .medidas {
    display: grid;
    gap: var(--tema-esp-3);
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
    align-items: end;
}

.bolsa-abono .campo-flotante .control-label {
    font-weight: 500;
}

/* Los paquetes de la bolsa (plan-paquetes-timbres.md, P5): un botón por paquete y «Personalizado».
   Se acomodan en varias líneas en vez de desbordar la tarjeta en el teléfono. */
.bolsa-abono .paquetes-bolsa {
    margin-bottom: var(--tema-esp-2);
}

/* Botones cuadrados, pensados para el dedo: una rejilla que en el teléfono deja tres por renglón y en
   escritorio los que quepan. Cada uno dice nombre, cantidad —grande— y precio. Los mismos en el abono
   y en el paso 1 de la compra en línea (P6). */
.bolsa-abono .paquetes-bolsa.k-button-group,
.paquetes-compra.k-button-group {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: var(--tema-esp-2);
    width: 100%;
}

.bolsa-abono .paquetes-bolsa.k-button-group > .k-button,
.paquetes-compra.k-button-group > .k-button {
    aspect-ratio: 1 / 1;
    min-height: 96px;
    max-height: 140px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: var(--tema-esp-2);
    margin: 0;
    border-radius: var(--tema-radio-md);
    white-space: normal;
    text-align: center;
    line-height: 1.15;
    touch-action: manipulation;
}

/* Kendo pone el contenido en un span; se estira para que las tres líneas se acomoden. */
.bolsa-abono .paquetes-bolsa.k-button-group > .k-button > .k-button-text,
.paquetes-compra.k-button-group > .k-button > .k-button-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.bolsa-abono .paquetes-bolsa .paq-nombre,
.paquetes-compra .paq-nombre {
    font-size: var(--tema-texto-xs);
    letter-spacing: .02em;
    opacity: .8;
    overflow-wrap: anywhere;
}

.bolsa-abono .paquetes-bolsa .paq-cantidad,
.paquetes-compra .paq-cantidad {
    font-family: var(--tema-fuente-mono);
    font-size: 22px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.bolsa-abono .paquetes-bolsa .paq-precio,
.paquetes-compra .paq-precio {
    font-size: var(--tema-texto-sm);
    font-variant-numeric: tabular-nums;
}

/* «Personalizado» no es una cifra: su segunda línea va en texto normal. */
.bolsa-abono .paquetes-bolsa .paq-personalizado .paq-cantidad,
.paquetes-compra .paq-personalizado .paq-cantidad {
    font-family: inherit;
    font-size: var(--tema-texto-md);
}

.bolsa-abono .cabecera-bolsa .actuales {
    margin-left: auto;
    font-size: var(--tema-texto-sm);
    color: var(--tema-texto-tenue);
    font-variant-numeric: tabular-nums;
}

.bolsa-abono .captura-personalizada[hidden] {
    display: none;
}

/* En el paso 1 de la compra, un poco de aire entre el rótulo y los botones. */
.paquetes-compra.k-button-group {
    margin-top: var(--tema-esp-1);
}

/* El paso 1 esconde el precio por timbre con un paquete: el paquete ya dice su precio. */
#compraStep1View .fila-precio[hidden] {
    display: none;
}

/* Las formas de pago del paso 2 (2026-10-05). Mismo trato que los paquetes del paso 1 —botones de
   alternancia, el componente de Kendo, el mismo radio y la misma separación— porque es la misma
   pregunta: elegir una de pocas opciones. Antes era una lista desplegable.

   NO SON CUADRADOS como los paquetes, y es a propósito: un paquete enseña tres datos —nombre,
   cantidad y precio— y necesita el alto; una forma de pago es una línea de texto, y un cuadro de
   96 px con la palabra «PayPal» en medio se ve vacío. Van anchos y bajos.

   `auto-fit` y no `auto-fill`: son dos o tres, y las pistas vacías que dejaría `auto-fill` las
   apretarían contra la izquierda en lugar de repartir el ancho. Los paquetes sí usan `auto-fill`,
   que es lo que mantiene el cuadrado cuando hay pocos. */
.formas-pago.k-button-group {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--tema-esp-2);
    width: 100%;
    margin-top: var(--tema-esp-1);
}

.formas-pago.k-button-group > .k-button {
    min-height: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--tema-esp-2) var(--tema-esp-3);
    margin: 0;
    border-radius: var(--tema-radio-md);
    white-space: normal;
    text-align: center;
    line-height: 1.2;
    touch-action: manipulation;
}

/* Kendo mete el contenido del botón en un span propio, así que la columna —icono arriba, nombre
   debajo— se arma ahí dentro y no en el botón. Es lo mismo que hacen los paquetes del paso 1. */
.formas-pago.k-button-group > .k-button > .k-button-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--tema-esp-1);
}

.formas-pago .fp-nombre {
    font-size: var(--tema-texto-md);
    font-weight: 500;
    overflow-wrap: anywhere;
}

/* Icono arriba y nombre debajo, como las tres líneas de un paquete. El icono va a medida fija y no
   a la del texto: es el ancla de la columna, y con `1.15em` se vería distinto en cada botón según lo
   que ocupe el nombre. */
.formas-pago .k-button .ico {
    width: 20px;
    height: 20px;
}

.bolsa-abono .detalle-paquete {
    margin-bottom: var(--tema-esp-3);
    font-size: var(--tema-texto-sm);
    color: var(--tema-texto-tenue);
}

.bolsa-abono .detalle-paquete:empty {
    display: none;
}

/* El total del abono, siempre a la vista: es la cifra que el usuario está confirmando. */
.total-abono {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: flex-end;
    gap: var(--tema-esp-2) var(--tema-esp-5);
    padding: var(--tema-esp-3) var(--tema-esp-4);
    background-color: var(--tema-acento-suave);
    border-radius: var(--tema-radio-md);
    color: var(--tema-acento);
    font-weight: 600;
}

.total-abono .cifra {
    font-family: var(--tema-fuente-mono);
    font-size: 22px;
    font-variant-numeric: tabular-nums;
}

.total-abono .detalle {
    font-weight: 400;
}

/* En teléfono las medidas van en dos columnas y arrancan arriba: con `end` los rótulos quedaban
   a distintas alturas y la tarjeta se veía desordenada. */
@media (max-width: 575.98px) {
    .bolsa-abono .medidas {
        align-items: start;
    }

    /* Tres por renglón, a todo lo ancho, y botones del pie que se alcanzan con el pulgar. */
    .bolsa-abono .paquetes-bolsa.k-button-group,
    .paquetes-compra.k-button-group {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .bolsa-abono .paquetes-bolsa.k-button-group > .k-button,
    .paquetes-compra.k-button-group > .k-button {
        min-height: 88px;
    }

    /*
     * El pie del abono lleva tres botones desde que el enlace de pago se mudó aquí
     * (plan-enlace-compra.md, E4), y tres botones de pulgar no caben en 375 px: se salían de la
     * pantalla y el primero quedaba cortado por la izquierda. En el teléfono el enlace se lleva su
     * propio renglón, completo, y debajo quedan Cancelar y Abonar a mitades como antes.
     */
    .modal-abonos .modal-footer {
        flex-wrap: wrap;
    }

    .modal-abonos .modal-footer > .btn {
        flex: 1 1 0;
        min-height: 48px;
    }

    .modal-abonos .modal-footer > .btn.btn-enlace-pago {
        flex: 1 0 100%;
        margin-right: 0;
    }
}

/* =================================================================================================
   Iconos (etapa 5 del plan de tema)

   Un sprite propio de Lucide con los 43 iconos que el panel usa, en `tema/iconos-2.svg`. Sustituye a
   las nueve familias de fuentes de iconos del tema anterior —4.4 MB— y hereda color y tamaño del
   texto, porque los trazos van con `currentColor`.
   ================================================================================================= */

.ico {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -.2em;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* El del menú lateral y el del logotipo, que piden una medida fija y no la del texto. */
#sidebar-menu li a .ico,
.logo .ico {
    width: 20px;
    height: 20px;
}

/* El único icono que gira: el de "cargando". */
.ico.gira {
    animation: gira-icono 1s linear infinite;
}

@keyframes gira-icono {
    to { transform: rotate(360deg); }
}

/* =================================================================================================
   Barra de herramientas de un catálogo

   El encabezado con la acción principal, la búsqueda, el segmentado de estado y el contador de lo
   que se está viendo. La usan el catálogo de clientes del distribuidor y el del administrador, con
   el mismo marcado: si una crece, crecen las dos.
   ================================================================================================= */

.encabezado-pantalla {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--tema-esp-3);
    margin-bottom: var(--tema-esp-4);
}

.barra-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tema-esp-2) var(--tema-esp-4);
    padding-bottom: var(--tema-esp-3);
    margin-bottom: var(--tema-esp-3);
    border-bottom: 1px solid var(--tema-borde);
}

/* La búsqueda: el icono dentro de la caja y el campo sin borde propio. */
.barra-filtros .buscador {
    display: flex;
    align-items: center;
    gap: var(--tema-esp-2);
    flex: 1 1 260px;
    max-width: 380px;
    min-height: var(--tema-control-alto);
    padding: 0 var(--tema-esp-3);
    background-color: var(--tema-superficie);
    border: 1px solid var(--tema-borde-fuerte);
    border-radius: var(--tema-radio-sm);
    color: var(--tema-texto-tenue);
}

    .barra-filtros .buscador:focus-within {
        border-color: var(--tema-acento);
        box-shadow: 0 0 0 3px var(--tema-acento-suave);
    }

    .barra-filtros .buscador input {
        flex: 1;
        min-width: 0;
        background: none;
        border: 0;
        color: var(--tema-texto);
        font-size: var(--tema-texto-md);
    }

        .barra-filtros .buscador input:focus {
            outline: none;
        }

/* Segmentado de estado: dos opciones, la elegida en el color del acento. */
.grupo-estado {
    display: inline-flex;
    padding: 3px;
    background-color: var(--tema-hundido);
    border-radius: 999px;
}

    .grupo-estado .btn-estado {
        min-height: 32px;
        padding: 4px var(--tema-esp-4);
        background: none;
        border: 0;
        border-radius: 999px;
        color: var(--tema-texto-tenue);
        font-size: var(--tema-texto-md);
        font-weight: 500;
        cursor: pointer;
    }

        .grupo-estado .btn-estado[aria-pressed="true"] {
            background-color: var(--tema-acento);
            color: var(--tema-acento-texto);
        }

        .grupo-estado .btn-estado:focus-visible {
            outline: 2px solid var(--tema-acento);
            outline-offset: 2px;
        }

/* Cuántos se ven de cuántos, y cuántos quedan fuera del filtro. */
.contador-filtro {
    margin-left: auto !important;
    font-size: var(--tema-texto-sm);
}

/* El aviso de lista vacía dice por qué está vacía; el texto lo pone la pantalla. */
.sin-resultados {
    padding: var(--tema-esp-5) 0;
    text-align: center;
}

/* La «X» de cerrar de Bootstrap (`btn-close`) es un ícono negro. En modo oscuro se aclara con el
   mismo filtro que usa Bootstrap con data-bs-theme="dark", que aquí no se usa: el tema lo manda
   `data-tema`. Sin esto, la del panel lateral del historial de compras y la de los avisos del
   dashboard quedaban negras sobre negro (2026-10-18). */
:root[data-tema="oscuro"] .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-tema="claro"]) .btn-close {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}
