/* Botones que cargan o guardan algo (boton-estado.js): la etiqueta se cruza con «cargando», «listo» o «error», el ancho la sigue y el botón puede sacudirse. */
.boton-estado {
    position: relative;
    overflow: visible;
    transition: width 0.35s cubic-bezier(0.23, 1, 0.32, 1), background-color 0.2s ease-out, color 0.2s ease-out, opacity 0.2s;
}

/* Recorta las etiquetas que entran y salen; los márgenes negativos lo estiran a lo alto del botón sin cambiarlo */
.be-contenido {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: -0.6rem 0;
    padding: 0.6rem 0;
    overflow: hidden;
    vertical-align: middle;
}

.be-etiqueta {
    display: inline-flex;
    flex: none;
    gap: 0.5rem;
    align-items: center;
    white-space: nowrap;
}

.be-entra {
    animation: be-entra 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}

.be-sale {
    position: absolute;
    animation: be-sale 0.2s cubic-bezier(0.23, 1, 0.32, 1) forwards;
    pointer-events: none;
}

@keyframes be-entra {
    from {
        opacity: 0;
        transform: translateY(8px);
        filter: blur(2px);
    }
}

@keyframes be-sale {
    to {
        opacity: 0;
        transform: translateY(-8px);
        filter: blur(2px);
    }
}

.be-icono {
    flex: none;
    width: 1em;
    height: 1em;
}

.be-cargando {
    animation: be-gira 0.7s linear infinite;
}

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

/* La palomita se dibuja */
.be-exito path {
    stroke-dasharray: 16;
    stroke-dashoffset: 16;
    animation: be-traza 0.3s 0.08s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}

@keyframes be-traza {
    to {
        stroke-dashoffset: 0;
    }
}

.boton-estado[data-estado="error"] {
    color: #fff;
    background: var(--peligro);
}

.be-sacude {
    animation: be-sacude 0.32s ease-out;
}

@keyframes be-sacude {
    20% { transform: translateX(-5px); }
    40% { transform: translateX(5px); }
    60% { transform: translateX(-3px); }
    80% { transform: translateX(3px); }
}

.be-particulas {
    position: absolute;
    z-index: 2;
    pointer-events: none;
}

/* Para los lectores de pantalla: anuncia el estado sin repetirlo en el nombre del botón */
.be-lector {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .boton-estado,
    .be-entra,
    .be-sale,
    .be-exito path,
    .be-sacude {
        animation: none;
        transition: none;
    }

    .be-exito path {
        stroke-dashoffset: 0;
    }
}
