/* ==========================================================================
   Forma del login: micro-interazioni, stati e dark mode.

   Riguarda solo la colonna del form, non la scena di sfondo (quella vive in
   _login_corporate.css). Tre cose:
     1. passaggi animati fra gli step (credenziali -> 2FA -> OTP email)
     2. il codice a 6 cifre come sei caselle invece di un campo unico
     3. stati del bottone (attesa / fatto / errore) e dark mode

   Tutto degrada: senza JS il form resta usabile, e a moto ridotto le
   animazioni spariscono lasciando i cambi di stato istantanei.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Palette del form. Definita qui per intero in chiaro; il blocco scuro piu'
   sotto ridefinisce solo i token, mai le regole.
   -------------------------------------------------------------------------- */
.login_container {
    --lf-superficie: #ffffff;
    --lf-testo: #0f1b17;
    --lf-testo-tenue: #5d6b65;
    --lf-etichetta: #66746e;
    --lf-bordo: rgba(15, 40, 30, .14);
    --lf-campo: #fbfdfc;
    --lf-accento: #0b66dd;
    --lf-accento-morbido: rgba(11, 102, 221, .16);
    --lf-ok: #07a84c;
    --lf-ok-morbido: rgba(7, 168, 76, .16);
    --lf-errore: #d63a3a;
    --lf-errore-morbido: rgba(214, 58, 58, .14);
}

/* --------------------------------------------------------------------------
   1 - Passaggio fra gli step.

   .hidden resta display:none (lo usa il JS esistente). Qui si anima solo
   l'ingresso dello step che diventa visibile: il JS aggiunge .lf_entra.
   -------------------------------------------------------------------------- */
.login_inputs.lf_entra {
    animation: lfEntra .34s cubic-bezier(.22, .61, .36, 1) both;
}
@keyframes lfEntra {
    from { opacity: 0; transform: translateX(14px); }
    to   { opacity: 1; transform: none; }
}

/* Tornare indietro (Annulla) entra dal lato opposto: il movimento racconta
   la direzione, non e' decorazione. */
.login_inputs.lf_entra.lf_indietro {
    animation-name: lfEntraIndietro;
}
@keyframes lfEntraIndietro {
    from { opacity: 0; transform: translateX(-14px); }
    to   { opacity: 1; transform: none; }
}

/* Il form non deve saltare di altezza quando cambia lo step. */
.login_form { transition: none; }

/* --------------------------------------------------------------------------
   2 - Codice a 6 caselle.

   L'input vero resta nel DOM (il JS legge .value da li'), ma diventa
   invisibile e sovrapposto alle caselle: cosi' incolla, autofill e
   autocomplete="one-time-code" continuano a funzionare come prima.
   -------------------------------------------------------------------------- */
.lf_otp {
    position: relative;
    display: flex;
    gap: 10px;
    width: 100%;
}

.lf_otp input.totp_code_input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    z-index: 2;
    /* Il cursore resta utile: si clicca sulle caselle e si scrive. */
    cursor: text;
    /* Annulla lo stile del campo singolo: qui non si vede. */
    letter-spacing: normal !important;
    font-size: 1rem !important;
}

.lf_otp_cella {
    flex: 1;
    aspect-ratio: 1 / 1.18;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--lf-bordo);
    border-radius: 12px;
    background: var(--lf-campo);
    color: var(--lf-testo);
    font-size: 1.5rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    transition: border-color .18s, box-shadow .18s, background .18s, transform .18s;
}

/* La casella in scrittura: bordo acceso e un alone, come un campo a fuoco. */
.lf_otp_cella.attiva {
    border-color: var(--lf-accento);
    background: var(--lf-superficie);
    box-shadow: 0 0 0 3px var(--lf-accento-morbido);
}

/* Cifra gia' inserita: si posa con un piccolo scatto. */
.lf_otp_cella.piena {
    /* Bordo piu' marcato del riposo, derivato dal token: cosi' segue la
       palette del tema invece di imporre un colore fisso. */
    border-color: color-mix(in srgb, var(--lf-bordo) 100%, var(--lf-testo) 24%);
    animation: lfCifra .18s ease-out;
}
@keyframes lfCifra {
    from { transform: scale(.9); }
    to   { transform: none; }
}

/* Cursore lampeggiante nella casella attiva e vuota. */
.lf_otp_cella.attiva:empty::after {
    content: '';
    width: 2px;
    height: 1.4rem;
    background: var(--lf-accento);
    border-radius: 1px;
    animation: lfCursore 1.05s steps(2, start) infinite;
}
@keyframes lfCursore {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0; }
}

/* Codice rifiutato: le caselle tremano e si arrossano. */
.lf_otp.errore .lf_otp_cella {
    border-color: var(--lf-errore);
    background: var(--lf-errore-morbido);
}
.lf_otp.errore {
    animation: lfScossa .4s cubic-bezier(.36, .07, .19, .97) both;
}
@keyframes lfScossa {
    10%, 90% { transform: translateX(-2px); }
    20%, 80% { transform: translateX(4px); }
    30%, 50%, 70% { transform: translateX(-7px); }
    40%, 60% { transform: translateX(7px); }
}

/* Codice accettato: verde, prima del redirect. */
.lf_otp.ok .lf_otp_cella {
    border-color: var(--lf-ok);
    background: var(--lf-ok-morbido);
}

/* --------------------------------------------------------------------------
   3 - Stati del bottone.

   Tre stati oltre al riposo: attesa (richiesta in volo), fatto (successo,
   subito prima del redirect), errore. Il JS mette/toglie le classi.
   -------------------------------------------------------------------------- */
.login_button.login {
    position: relative;
    overflow: hidden;
}

.login_button.login[disabled] {
    cursor: progress;
    opacity: .92;
}

/* Attesa: l'icona diventa un anello che gira. */
.login_button.login.lf_attesa .fa-solid {
    animation: lfGira .7s linear infinite;
}
@keyframes lfGira {
    to { transform: rotate(360deg); }
}

/* Fatto: verde pieno, un attimo prima di cambiare pagina. */
.login_button.login.lf_fatto {
    background: var(--lf-ok) !important;
    box-shadow: 0 8px 22px var(--lf-ok-morbido) !important;
    transform: none !important;
}

/* Errore: rosso e scossa, coerente con le caselle OTP. */
.login_button.login.lf_errore {
    background: var(--lf-errore) !important;
    animation: lfScossa .4s cubic-bezier(.36, .07, .19, .97) both;
}

/* Il bottone non deve sollevarsi mentre e' occupato. */
.login_button.login.lf_attesa:hover,
.login_button.login.lf_fatto:hover,
.login_button.login.lf_errore:hover {
    transform: none;
}

/* --------------------------------------------------------------------------
   4 - Messaggi di errore e informativi: entrano invece di apparire.
   -------------------------------------------------------------------------- */
.form_row_error:not(.hidden),
.form_row_info:not(.hidden) {
    animation: lfMessaggio .26s ease-out both;
}
@keyframes lfMessaggio {
    from { opacity: 0; transform: translateY(-5px); }
    to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   5 - Accessibilita': il fuoco da tastiera deve vedersi sempre.

   :focus-visible colpisce solo la navigazione da tastiera, quindi il mouse
   non si porta dietro aloni indesiderati.
   -------------------------------------------------------------------------- */
.login_form a:focus-visible,
.login_form button:focus-visible,
.login_form input:focus-visible {
    outline: 2px solid var(--lf-accento);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Quando il campo nascosto dell'OTP prende fuoco, l'anello va sulle caselle
   (il campo e' invisibile: un outline su di lui non si vedrebbe). */
.lf_otp input.totp_code_input:focus-visible { outline: none; }
.lf_otp:focus-within .lf_otp_cella.attiva {
    outline: 2px solid var(--lf-accento);
    outline-offset: 2px;
}

/* Testo riservato ai lettori di schermo. */
.lf_sr {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   6 - Dark mode.

   Segue il tema di sistema. Si ridefiniscono solo i token: le regole sopra
   restano identiche. Il tema "vetro" ha gia' un suo trattamento chiaro su
   fondo scuro, quindi lo si lascia fuori.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
    body:not([data-tema="corporate"]) .login_container {
        --lf-superficie: #121a18;
        --lf-testo: #e8f0ec;
        --lf-testo-tenue: #9aaaa3;
        --lf-etichetta: #8b9c95;
        --lf-bordo: rgba(255, 255, 255, .14);
        --lf-campo: #18211f;
        --lf-accento: #4da3ff;
        --lf-accento-morbido: rgba(77, 163, 255, .22);
        --lf-ok: #2bd97a;
        --lf-ok-morbido: rgba(43, 217, 122, .18);
        --lf-errore: #ff6b6b;
        --lf-errore-morbido: rgba(255, 107, 107, .18);
    }

    body:not([data-tema="corporate"]) .login_container,
    body:not([data-tema="corporate"]) .login_form {
        background-color: var(--lf-superficie);
    }
    body:not([data-tema="corporate"]) .login_form h1 { color: var(--lf-testo); }
    body:not([data-tema="corporate"]) .login_form h5,
    body:not([data-tema="corporate"]) .totp_step,
    body:not([data-tema="corporate"]) #forgotPasswordLink { color: var(--lf-testo-tenue); }
    body:not([data-tema="corporate"]) .login_form label { color: var(--lf-etichetta); }

    body:not([data-tema="corporate"]) .login_form input {
        background-color: var(--lf-campo);
        border-color: var(--lf-bordo);
        color: var(--lf-testo);
    }
    body:not([data-tema="corporate"]) .login_form input::placeholder {
        color: var(--lf-etichetta);
        opacity: .75;
    }
    body:not([data-tema="corporate"]) .login_button.secondary {
        background-color: rgba(255, 255, 255, .06);
        border-color: var(--lf-bordo);
        color: var(--lf-testo);
    }
    body:not([data-tema="corporate"]) .password_toggle { color: var(--lf-etichetta); }

    /* Il QR resta su fondo bianco: e' un codice, va letto dalla fotocamera. */
    body:not([data-tema="corporate"]) .totp_qr_box {
        background: #fff;
        border-color: var(--lf-bordo);
    }

    /* Il divisore "oppure" e' un <span> con opacita' fissa nel template:
       su fondo scuro sparisce. Qui si riporta a un grigio leggibile. */
    body:not([data-tema="corporate"]) #googleSsoContainer > span {
        color: var(--lf-testo-tenue);
        opacity: 1;
    }

    /* Il bottone Nextcloud ha colori propri (disattivato, stile Google):
       al buio resterebbe una macchia chiara. */
    body:not([data-tema="corporate"]) .nextcloud-sso-btn {
        background: rgba(255, 255, 255, .07);
        border-color: var(--lf-bordo);
        color: var(--lf-etichetta);
    }

    body:not([data-tema="corporate"]) .form_row_error {
        background: rgba(214, 58, 58, .14);
        border-color: rgba(255, 107, 107, .38);
        color: #ffb4b4;
    }
    body:not([data-tema="corporate"]) .form_row_info {
        background: rgba(7, 168, 76, .14);
        border-color: rgba(43, 217, 122, .34);
        color: #9ae7bd;
    }
}

/* --------------------------------------------------------------------------
   7 - Moto ridotto: si tolgono i movimenti, restano i colori.

   Gli stati (errore rosso, successo verde, casella attiva) sopravvivono:
   e' l'informazione, non l'effetto.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .login_inputs.lf_entra,
    .lf_otp.errore,
    .login_button.login.lf_errore,
    .lf_otp_cella.piena,
    .form_row_error:not(.hidden),
    .form_row_info:not(.hidden) {
        animation: none;
    }
    .lf_otp_cella.attiva:empty::after { animation: none; }
    .login_button.login.lf_attesa .fa-solid { animation: none; }
    .lf_otp_cella { transition: none; }
}

/* --------------------------------------------------------------------------
   8 - Schermi stretti: le caselle restano leggibili senza uscire dal bordo.
   -------------------------------------------------------------------------- */
@media (max-width: 420px) {
    .lf_otp { gap: 6px; }
    .lf_otp_cella { font-size: 1.2rem; border-radius: 9px; }
}
