/* ============================================================
   AUTENTICACIÓN — Tema neumórfico compartido
   login.php · recuperar.php · restablecer.php

   Todo el tema sale de estas 3 variables: cambia --base y ajusta
   --sh-d (base -8% luz) y --sh-l (base +8% luz).
   ============================================================ */
:root {
    --base: #272c36;
    --sh-d: #1b1f27;
    /* sombra dura (abajo-derecha) */
    --sh-l: #333a49;
    /* luz (arriba-izquierda)      */

    --txt: #dbe2f0;
    --muted: #8b94a8;
    --accent: #26acef;
    --accent-d: #1489cc;
    --led: #5fd8ff;
    --ok: #4ce09a;
    --bad: #ff7d6d;
    --warn: #ffc978;

    --r: 13px;
    /* ancho del robot: manda sobre el resto del layout vertical */
    --bw: clamp(130px, 42vw, 186px);
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display", "Segoe UI", system-ui, Roboto, sans-serif;

    /* recetas neumórficas reutilizables */
    --raise: 7px 7px 14px var(--sh-d), -7px -7px 14px var(--sh-l);
    --raise-sm: 4px 4px 8px var(--sh-d), -4px -4px 8px var(--sh-l);
    --sink: inset 5px 5px 10px var(--sh-d), inset -5px -5px 10px var(--sh-l);
    --sink-sm: inset 3px 3px 6px var(--sh-d), inset -3px -3px 6px var(--sh-l);
}

* {
    box-sizing: border-box
}

html {
    height: 100%
}

body {
    margin: 0;
    min-height: 100%;
    overflow-x: hidden;
    font-family: var(--font);
    color: var(--txt);
    background: var(--base);
    display: grid;
    justify-items: center;
    align-items: center;
    align-items: safe center;
    /* el hueco de arriba lo pide el robot, que asoma 0.656 de su ancho */
    padding: calc(var(--bw) * .656 + 16px) clamp(20px, 6vw, 26px) 30px;
    -webkit-font-smoothing: antialiased;
}

.stage {
    position: relative;
    z-index: 1;
    width: min(392px, 100%);
    /* sin esto, el ancho mínimo del contenido (la fila de dígitos)
       ensancha la tarjeta y la saca de la pantalla en móvil */
    min-width: 0
}

.stage > .card { min-width: 0 }

/* ============================================================
   FONDO DE TALLER
   La escena va en bajo contraste y un charco del color base se
   posa detrás de la tarjeta, para no perder del todo el relieve.
   ============================================================ */
.workshop {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    color: #9fb0cc
}

.workshop svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: .5
}

.workshop::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse clamp(230px, 70vw, 520px) clamp(220px, 50vh, 500px) at 50% 47%,
            var(--base) 34%, rgba(39, 44, 54, .88) 58%, rgba(39, 44, 54, 0) 84%);
}

/* lámpara colgante que se mece */
.lamp {
    transform-box: view-box;
    transform-origin: 352px 0;
    animation: sway 6.5s ease-in-out infinite alternate
}

@keyframes sway {
    from { transform: rotate(-2.4deg) }
    to   { transform: rotate(2.4deg) }
}

.lamp-glow {
    animation: flicker 5.4s ease-in-out infinite
}

@keyframes flicker {
    0%, 100% { opacity: 1 }
    42% { opacity: .72 }
    45% { opacity: 1 }
    62% { opacity: .85 }
}

/* chispas de soldadura */
.spark {
    animation: spark 2.6s ease-out infinite
}

@keyframes spark {
    0%   { transform: translate(0, 0) scale(1); opacity: 0 }
    8%   { opacity: 1 }
    100% { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0 }
}

.weld {
    animation: weld 2.6s ease-out infinite
}

@keyframes weld {
    0%, 100% { opacity: 0 }
    5%  { opacity: 1 }
    34% { opacity: .12 }
}

/* engranajes de utilería */
.wheel {
    transform-box: fill-box;
    transform-origin: 50% 50%
}

@keyframes spin  { to { transform: rotate(360deg) } }
@keyframes spinr { to { transform: rotate(-360deg) } }

.w1 { animation: spin 38s linear infinite }
.w2 { animation: spinr 24s linear infinite }

/* ============================================================
   ROBOT
   ============================================================ */
.bot {
    position: absolute;
    left: 50%;
    top: calc(var(--bw) * -.656);
    width: var(--bw);
    transform: translateX(-50%);
    z-index: 3;
    pointer-events: none
}

.bot svg {
    width: 100%;
    height: auto;
    overflow: visible;
    animation: bob 4.4s ease-in-out infinite
}

@keyframes bob {
    0%, 100% { transform: translateY(0) }
    50% { transform: translateY(-6px) }
}

/* halo de luz detrás: despega al robot del fondo */
.bot::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 44%;
    z-index: -1;
    width: calc(var(--bw) * 1.4);
    height: calc(var(--bw) * 1.24);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(120, 190, 255, .17), rgba(120, 190, 255, .05) 55%, transparent 72%);
}

/* carcasa clara sobre fondo oscuro: la sombra solo separa, no esculpe */
.neu {
    filter: drop-shadow(2px 3px 5px rgba(0, 0, 0, .5))
}

/* el cuerpo entero gira un poco hacia donde mira */
.rig {
    transform-box: view-box;
    transform-origin: 120px 172px;
    transition: transform .4s cubic-bezier(.3, 1.05, .4, 1)
}

.bot__eyes {
    transform-origin: 120px 80px;
    animation: blink 6.5s infinite
}

@keyframes blink {
    0%, 95%, 100% { transform: scaleY(1) }
    97% { transform: scaleY(.06) }
}

.bot__pupils {
    transition: transform .34s cubic-bezier(.34, 1.15, .4, 1)
}

.eye {
    fill: var(--led);
    filter: url(#soft);
    transition: fill .3s
}

.pupil { fill: #0a1420 }

.eye-happy {
    stroke: var(--ok);
    stroke-width: 5;
    stroke-linecap: round;
    fill: none;
    opacity: 0;
    transition: opacity .25s
}

.antenna-ball {
    fill: var(--led);
    transition: fill .3s
}

.antenna-halo {
    fill: var(--led);
    opacity: .22;
    transform-origin: 120px 9px;
    animation: pulse 2.6s ease-in-out infinite
}

@keyframes pulse {
    0%, 100% { transform: scale(1); opacity: .2 }
    50% { transform: scale(2); opacity: 0 }
}

.grille {
    stroke: #8b99b3;
    stroke-width: 2.2;
    stroke-linecap: round
}

.hand { transition: transform .42s cubic-bezier(.34, 1.3, .5, 1) }
.hand--l { transform-origin: 80px 164px }
.hand--r { transform-origin: 160px 164px }

/* manos tapando el visor (foco en contraseña) */
.bot.is-shy .hand--l { transform: translate(19px, -85px) rotate(-10deg) }
.bot.is-shy .hand--r { transform: translate(-19px, -85px) rotate(10deg) }
.bot.is-shy .bot__eyes { opacity: .3 }

.bot.is-happy .eye,
.bot.is-happy .pupil { opacity: 0 }
.bot.is-happy .eye-happy { opacity: 1 }
.bot.is-happy .antenna-ball,
.bot.is-happy .antenna-halo { fill: var(--ok) }
.bot.is-happy svg { animation: cheer .5s ease-in-out 2 }

@keyframes cheer {
    0%, 100% { transform: translateY(0) rotate(0) }
    30% { transform: translateY(-11px) rotate(-4deg) }
    65% { transform: translateY(-4px) rotate(4deg) }
}

.bot.is-alert .eye { fill: var(--bad) }
.bot.is-alert .antenna-ball { fill: var(--bad) }
.bot.is-alert svg { animation: nope .42s ease-in-out }

@keyframes nope {
    0%, 100% { transform: translateX(0) }
    25% { transform: translateX(-8px) }
    75% { transform: translateX(8px) }
}

/* asiente cada vez que cae un dígito del código */
.bot.is-nod svg { animation: nod .34s ease-out }

@keyframes nod {
    0%, 100% { transform: translateY(0) }
    45% { transform: translateY(5px) }
}

/* ============================================================
   TARJETA — mismo color que el fondo, solo sombras
   ============================================================ */
.card {
    position: relative;
    z-index: 2;
    border-radius: 20px;
    padding: clamp(28px, 7.5vw, 34px) clamp(16px, 5.5vw, 22px) 18px;
    background: var(--base);
    box-shadow: 13px 13px 26px var(--sh-d), -13px -13px 26px var(--sh-l);
}

.card.shake {
    animation: shake .42s cubic-bezier(.36, .07, .19, .97)
}

@keyframes shake {
    10%, 90% { transform: translateX(-2px) }
    20%, 80% { transform: translateX(4px) }
    30%, 50%, 70% { transform: translateX(-6px) }
    40%, 60% { transform: translateX(6px) }
}

/* ============================================================
   MARCA
   ============================================================ */
.brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    margin: 0 0 18px
}

.mark {
    display: block;
    width: clamp(76px, 24vw, 98px);
    height: auto;
    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .45))
}

.wordmark {
    margin: 0;
    text-align: center;
    line-height: 1.15
}

.wordmark strong {
    display: block;
    font-size: clamp(17px, 4.8vw, 20px);
    font-weight: 700;
    letter-spacing: 3.4px;
    color: var(--txt);
    text-shadow: 1.5px 1.5px 3px var(--sh-d), -1.5px -1.5px 3px var(--sh-l)
}

.wordmark span {
    display: block;
    margin-top: 4px;
    font-size: clamp(9.5px, 2.8vw, 10.5px);
    letter-spacing: 1.7px;
    text-transform: uppercase;
    color: var(--muted)
}

/* mientras trabaja, el logo se enciende */
.card.working .mark {
    animation: markpulse 1.05s ease-in-out infinite
}

@keyframes markpulse {
    0%, 100% { filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .45)) }
    50% { filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .45)) drop-shadow(0 0 12px rgba(38, 172, 239, .75)) brightness(1.18) }
}

/* ============================================================
   TÍTULOS
   ============================================================ */
.head {
    text-align: center;
    margin: 0 0 16px
}

.head h1 {
    margin: 0;
    font-size: clamp(15.5px, 4.2vw, 17px);
    font-weight: 700;
    letter-spacing: .2px;
    color: var(--txt)
}

.head p {
    margin: 5px 0 0;
    font-size: 12.4px;
    line-height: 1.45;
    color: var(--muted)
}

/* ============================================================
   CAMPOS — hundidos
   ============================================================ */
.field {
    position: relative;
    margin-bottom: 10px
}

.field input {
    width: 100%;
    height: 52px;
    padding: 19px 14px 7px;
    border: 0;
    border-radius: var(--r);
    background: var(--base);
    color: var(--txt);
    font-size: 15px;
    font-family: inherit;
    outline: none;
    box-shadow: var(--sink);
    transition: box-shadow .28s ease, color .2s;
}

.field input:focus {
    box-shadow: var(--sink), 0 0 0 2px rgba(38, 172, 239, .5)
}

.field label {
    position: absolute;
    left: 15px;
    top: 17px;
    color: var(--muted);
    font-size: 15px;
    pointer-events: none;
    transition: transform .18s ease, font-size .18s ease, color .18s ease;
    transform-origin: left top;
}

.field input:focus + label,
.field input:not(:placeholder-shown) + label {
    transform: translateY(-10px);
    font-size: 10.5px;
    letter-spacing: .4px
}

.field input:focus + label { color: #7cc6f2 }

.field.invalid input {
    box-shadow: var(--sink), 0 0 0 2px rgba(255, 125, 109, .55)
}

.field input[type=password] {
    padding-right: 50px;
    letter-spacing: .14em
}

.field.has-peek input { padding-right: 50px }

/* autocompletado del navegador: mantener el relieve hundido */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--txt);
    -webkit-box-shadow: var(--sink), 0 0 0 1000px var(--base) inset;
    caret-color: var(--txt);
    transition: background-color 9999s ease-in-out 0s;
}

.peek {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--base);
    color: var(--muted);
    cursor: pointer;
    box-shadow: var(--sink-sm);
    transition: box-shadow .18s, color .2s;
}

.peek:hover { color: var(--txt) }
.peek.on { color: var(--accent) }

/* ============================================================
   FILA DE OPCIONES / ENLACES
   ============================================================ */
.row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 12px 3px 15px;
    font-size: 12.5px
}

.check {
    display: flex;
    align-items: center;
    gap: 9px;
    color: var(--muted);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none
}

.check input {
    position: absolute;
    opacity: 0;
    pointer-events: none
}

.box {
    width: 20px;
    height: 20px;
    border-radius: 6px;
    background: var(--base);
    box-shadow: var(--sink-sm);
    display: grid;
    place-items: center;
    transition: box-shadow .22s, color .22s;
    color: var(--accent)
}

.box svg {
    opacity: 0;
    transform: scale(.4);
    transition: .22s
}

.check input:checked + .box { box-shadow: var(--raise-sm) }
.check input:checked + .box svg { opacity: 1; transform: scale(1) }

.link {
    color: #63bdf0;
    text-decoration: none;
    font-weight: 500
}

.link:hover { text-decoration: underline }

.links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    flex-wrap: wrap;
    margin-top: 14px;
    font-size: 12.5px
}

.links a {
    display: inline-flex;
    align-items: center;
    gap: 6px
}

/* ============================================================
   BOTÓN + PUERTA
   ============================================================ */
.btn {
    position: relative;
    width: 100%;
    height: 52px;
    border: 0;
    border-radius: var(--r);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px 0 20px;
    font-family: inherit;
    font-size: 15.5px;
    font-weight: 600;
    color: #fff;
    background: linear-gradient(145deg, #4cbcf2, #1489cc);
    box-shadow: 5px 5px 11px var(--sh-d), -5px -5px 11px var(--sh-l);
    transition: box-shadow .2s, filter .2s;
}

.btn:hover { filter: brightness(1.05) }

.btn:active {
    box-shadow: inset 4px 4px 9px rgba(0, 0, 0, .45), inset -4px -4px 9px rgba(255, 255, 255, .16)
}

.btn:disabled { cursor: default }

.btn.dooropen {
    box-shadow: 5px 5px 18px rgba(255, 196, 110, .26), -5px -5px 11px var(--sh-l)
}

/* botón centrado, sin puerta (recuperar / restablecer) */
.btn--plain {
    justify-content: center;
    gap: 10px;
    padding: 0 18px
}

.btn .spin {
    width: 19px;
    height: 19px;
    border-radius: 50%;
    border: 2.4px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    display: none;
    animation: spin .7s linear infinite
}

.btn.loading .spin { display: block }
.btn.loading .btn-ic { display: none }

.dooric {
    position: relative;
    width: 27px;
    height: 35px;
    perspective: 300px
}

/* marco: hueco tallado en el botón */
.dooric__frame {
    position: absolute;
    inset: 0;
    border-radius: 4px;
    background: #1a2540;
    box-shadow: inset 3px 3px 5px rgba(0, 0, 0, .65), inset -2px -2px 4px rgba(255, 255, 255, .14)
}

.dooric__glow {
    position: absolute;
    inset: 2.5px;
    border-radius: 2.5px;
    opacity: 0;
    background: linear-gradient(180deg, #fff4d2, #ffcd78);
    transition: opacity .3s ease .06s
}

.btn.dooropen .dooric__glow { opacity: .95 }

/* bisagra a la DERECHA: la hoja se repliega hacia ese lado y deja
   el hueco a la izquierda, que es por donde llega el muñequito */
.dooric__panel {
    position: absolute;
    inset: 0;
    border-radius: 4px;
    transform-origin: right center;
    transform: rotateY(0deg);
    background: linear-gradient(35deg, #dbe7ff, #8fb3f2 55%, #5f8ad8);
    box-shadow: -2px 2px 4px rgba(0, 0, 0, .45), inset 1px -1px 2px rgba(255, 255, 255, .5);
    transition: transform .42s cubic-bezier(.28, .9, .32, 1.05);
    backface-visibility: hidden;
}

/* manubrio en el lado libre, opuesto a la bisagra */
.dooric__panel::after {
    content: "";
    position: absolute;
    left: 3.5px;
    top: 50%;
    width: 3.5px;
    height: 3.5px;
    border-radius: 50%;
    background: rgba(25, 38, 66, .8);
    transform: translateY(-50%)
}

.btn.dooropen .dooric__panel { transform: rotateY(-72deg) }

/* el muñequito */
.dooric__person {
    position: absolute;
    left: -26px;
    bottom: 4px;
    width: 11px;
    height: 24px;
    color: rgba(255, 255, 255, .95);
    transform-origin: bottom center;
    transition: transform .52s linear, opacity .3s ease, color .3s ease;
}

.btn.dooropen .dooric__person { color: #1d2942 }

/* 1) camina hasta el umbral */
.btn.out .dooric__person { transform: translateX(26px) }

/* 2) se aleja hacia dentro: encoge y sube hacia el punto de fuga */
.btn.inside .dooric__person {
    transform: translate(31px, -5px) scale(.42);
    transition: transform .6s cubic-bezier(.35, 0, .7, .55), opacity .3s ease, color .3s ease;
}

.btn.entered .dooric__person { opacity: 0 }
.btn.reset .dooric__person { transition: none }

.dooric__person span {
    position: absolute;
    background: currentColor;
    border-radius: 3px
}

.p-head { width: 7px; height: 7px; left: 1.8px; top: 0; border-radius: 50% }
.p-body { width: 2.8px; height: 9.5px; left: 4px; top: 7px }
.p-arm  { width: 2.3px; height: 8px; left: 4.2px; top: 8px; transform-origin: top center }
.p-arm--back  { opacity: .5; transform: rotate(22deg) }
.p-arm--front { transform: rotate(-22deg) }
.p-leg  { width: 2.4px; height: 4.8px; left: 4.2px; top: 16.5px; transform-origin: top center }
.p-leg--back { opacity: .5 }
.p-shin { width: 2.4px; height: 5.2px; left: 0; top: 4.4px; transform-origin: top center }

.btn.walking .p-leg--front,
.btn.walking .p-arm--back { animation: thighF .46s linear infinite }

.btn.walking .p-leg--back,
.btn.walking .p-arm--front { animation: thighB .46s linear infinite }

.btn.walking .p-leg--front .p-shin { animation: shinF .46s linear infinite }
.btn.walking .p-leg--back .p-shin  { animation: shinB .46s linear infinite }

@keyframes thighF {
    0% { transform: rotate(26deg) }
    50% { transform: rotate(-24deg) }
    100% { transform: rotate(26deg) }
}

@keyframes thighB {
    0% { transform: rotate(-24deg) }
    50% { transform: rotate(26deg) }
    100% { transform: rotate(-24deg) }
}

@keyframes shinF {
    0% { transform: rotate(0) }
    30% { transform: rotate(6deg) }
    60% { transform: rotate(42deg) }
    100% { transform: rotate(0) }
}

@keyframes shinB {
    0% { transform: rotate(40deg) }
    40% { transform: rotate(4deg) }
    70% { transform: rotate(10deg) }
    100% { transform: rotate(40deg) }
}

@keyframes spin { to { transform: rotate(360deg) } }

/* ============================================================
   ESTADO
   ============================================================ */
.status {
    min-height: 16px;
    margin: 8px 0 0;
    text-align: center;
    font-size: 12px;
    color: var(--muted);
    opacity: 0;
    transition: opacity .25s
}

.status.show { opacity: 1 }
.status.err { color: var(--bad) }
.status.ok  { color: var(--ok) }

/* ============================================================
   AVISOS (toast)
   ============================================================ */
.toasts {
    position: fixed;
    top: 16px;
    right: 16px;
    left: 16px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
    pointer-events: none
}

.toast {
    --tone: var(--led);
    position: relative;
    overflow: hidden;
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 11px;
    width: min(344px, 100%);
    padding: 13px 14px 14px 17px;
    border-radius: 14px;
    background: var(--base);
    box-shadow: var(--raise), 0 0 0 1px rgba(255, 255, 255, .04);
    animation: toastIn .34s cubic-bezier(.25, 1.1, .4, 1);
}

/* filo de color: lo que hace que el aviso se vea de un vistazo */
.toast::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--tone)
}

/* barra que drena mientras el aviso está en pantalla */
.toast::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 100%;
    background: var(--tone);
    opacity: .4;
    transform-origin: left center;
    animation: toastBar var(--dur, 5000ms) linear forwards
}

@keyframes toastBar {
    from { transform: scaleX(1) }
    to   { transform: scaleX(0) }
}

.toast.out { animation: toastOut .3s ease forwards }

@keyframes toastIn {
    from { opacity: 0; transform: translateX(24px) scale(.96) }
    to   { opacity: 1; transform: none }
}

@keyframes toastOut {
    to { opacity: 0; transform: translateX(24px) scale(.96) }
}

.toast .ic {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--base);
    box-shadow: var(--sink-sm)
}

.toast .bd { flex: 1; min-width: 0 }

/* display:block es obligatorio: son <span> y en línea el título
   y el mensaje quedaban pegados ("¡Listo!Se ha enviado…") */
.toast .tt {
    display: block;
    font-size: 12.8px;
    font-weight: 700;
    color: var(--txt);
    margin-bottom: 3px
}

.toast .ms {
    display: block;
    font-size: 12px;
    line-height: 1.45;
    color: var(--muted);
    overflow-wrap: break-word
}

.toast .cl {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    display: grid;
    place-items: center
}

.toast .cl:hover { color: var(--txt) }

.toast--danger  { --tone: var(--bad) }
.toast--success { --tone: var(--ok) }
.toast--info    { --tone: var(--led) }
.toast--warning { --tone: var(--warn) }

.toast .ic { color: var(--tone) }

/* ============================================================
   PASOS (restablecer)
   ============================================================ */
.steps {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 0 0 18px
}

.steps .dot {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 12.5px;
    font-weight: 700;
    background: var(--base);
    color: var(--muted);
    box-shadow: var(--sink-sm);
    transition: box-shadow .3s, color .3s
}

.steps .dot.active { color: var(--led); box-shadow: var(--raise-sm) }
.steps .dot.done   { color: var(--ok);  box-shadow: var(--raise-sm) }

.steps .bar {
    width: 54px;
    height: 5px;
    border-radius: 99px;
    background: var(--base);
    box-shadow: var(--sink-sm);
    overflow: hidden;
    position: relative
}

.steps .bar::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 0;
    border-radius: 99px;
    background: linear-gradient(90deg, var(--accent), var(--led));
    transition: width .5s ease
}

.steps .bar.done::after { width: 100% }

/* ============================================================
   CÓDIGO DE 6 DÍGITOS + CANDADO
   La animación de la clave: cada dígito enciende un pin del
   candado; al sexto, el arco salta y se abre.
   ============================================================ */
.lockwrap {
    display: flex;
    justify-content: center;
    margin: 2px 0 14px
}

.lock {
    width: clamp(84px, 26vw, 100px);
    height: auto;
    overflow: visible
}

.lock .body {
    fill: var(--base);
    /* un filo tenue: sin él, el cuerpo del candado se pierde contra la tarjeta */
    stroke: rgba(255, 255, 255, .06);
    stroke-width: 1.4;
    filter: drop-shadow(3px 3px 6px var(--sh-d)) drop-shadow(-3px -3px 6px var(--sh-l));
    transform-box: view-box;
    transform-origin: 60px 80px
}

.lock .shackle {
    fill: none;
    stroke: #8792a8;
    stroke-width: 11;
    stroke-linecap: round;
    transform-box: view-box;
    transform-origin: 84px 56px;
    transition: transform .55s cubic-bezier(.3, 1.5, .45, 1), stroke .4s;
}

.lock.open .shackle {
    transform: rotate(-26deg) translateY(-3px);
    stroke: var(--ok)
}

.lock .keyhole {
    fill: #1c2130;
    transition: fill .4s
}

.lock.open .keyhole { fill: #1b3b31 }

.lock .pin {
    fill: #3c4351;
    transition: fill .3s;
    transform-box: fill-box;
    transform-origin: 50% 50%
}

.lock .pin.on {
    fill: var(--led);
    animation: pinPop .38s cubic-bezier(.3, 1.5, .5, 1)
}

.lock.open .pin.on { fill: var(--ok) }

@keyframes pinPop {
    0%   { transform: scale(.5) }
    55%  { transform: scale(1.45) }
    100% { transform: scale(1) }
}

.lock.open .body {
    animation: lockJump .5s cubic-bezier(.3, 1.4, .5, 1)
}

@keyframes lockJump {
    0%, 100% { transform: translateY(0) }
    40% { transform: translateY(-5px) }
}

.code {
    display: flex;
    justify-content: center;
    gap: clamp(5px, 2vw, 9px);
    margin: 0 0 8px
}

.code input {
    /* casillas elásticas: se encogen antes que desbordar la tarjeta */
    flex: 1 1 0;
    min-width: 0;
    max-width: 46px;
    height: clamp(50px, 15vw, 58px);
    padding: 0;
    border: 0;
    border-radius: var(--r);
    background: var(--base);
    color: var(--txt);
    font-family: inherit;
    font-size: clamp(19px, 5.6vw, 23px);
    font-weight: 700;
    text-align: center;
    outline: none;
    box-shadow: var(--sink);
    transition: box-shadow .28s ease, color .25s ease;
}

.code input:focus {
    box-shadow: var(--sink), 0 0 0 2px rgba(38, 172, 239, .5)
}

.code input.filled {
    color: var(--led);
    box-shadow: var(--raise-sm);
    animation: digitPop .36s cubic-bezier(.3, 1.5, .45, 1)
}

@keyframes digitPop {
    0%   { transform: scale(.84) translateY(3px) }
    55%  { transform: scale(1.09) translateY(-3px) }
    100% { transform: scale(1) translateY(0) }
}

.code input.error {
    box-shadow: var(--sink), 0 0 0 2px rgba(255, 125, 109, .6);
    animation: digitNo .36s ease
}

@keyframes digitNo {
    0%, 100% { transform: translateX(0) }
    30% { transform: translateX(-4px) }
    70% { transform: translateX(4px) }
}

.code-hint {
    text-align: center;
    font-size: 11.6px;
    letter-spacing: .3px;
    color: var(--muted);
    margin: 0 0 16px;
    transition: color .3s
}

.code-hint.done { color: var(--ok) }

/* ============================================================
   FUERZA DE CONTRASEÑA
   ============================================================ */
.strength {
    height: 8px;
    border-radius: 99px;
    background: var(--base);
    box-shadow: var(--sink-sm);
    overflow: hidden;
    margin: 2px 3px 7px
}

.strength i {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 99px;
    background: var(--bad);
    transition: width .4s cubic-bezier(.3, 1, .4, 1), background .4s
}

.strength-txt {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin: 0 4px 12px;
    font-size: 11.4px;
    color: var(--muted)
}

.strength-txt b {
    font-weight: 600;
    transition: color .3s
}

.match {
    margin: -4px 4px 10px;
    font-size: 11.4px;
    min-height: 15px;
    color: var(--muted);
    transition: color .25s
}

.match.ok  { color: var(--ok) }
.match.bad { color: var(--bad) }

/* ============================================================
   CONFIRMACIÓN DE ENVÍO
   El sello: el sobre entra, el distintivo cae encima y el
   visto se dibuja. Es el ancla visual de la pantalla.
   ============================================================ */
.bigic {
    width: 88px;
    height: 88px;
    margin: 2px auto 18px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--base);
    box-shadow: var(--raise);
    color: var(--ok);
    position: relative
}

.bigic::after {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    border: 2px solid currentColor;
    opacity: 0;
    animation: ping 2.6s ease-out infinite
}

@keyframes ping {
    0%   { transform: scale(.9); opacity: .5 }
    70%  { transform: scale(1.18); opacity: 0 }
    100% { opacity: 0 }
}

.seal {
    width: 46px;
    height: auto;
    overflow: visible;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round
}

.seal .env {
    transform-box: fill-box;
    transform-origin: 50% 50%;
    animation: sealIn .5s cubic-bezier(.3, 1.3, .5, 1) both
}

.seal .badge {
    fill: var(--base);
    transform-box: fill-box;
    transform-origin: 50% 50%;
    animation: sealIn .42s .34s cubic-bezier(.3, 1.6, .5, 1) both
}

.seal .tick {
    stroke-width: 2.4;
    stroke-dasharray: 15;
    stroke-dashoffset: 15;
    animation: sealTick .38s .56s ease-out forwards
}

@keyframes sealIn {
    from { opacity: 0; transform: scale(.55) }
    to   { opacity: 1; transform: none }
}

@keyframes sealTick {
    to { stroke-dashoffset: 0 }
}

/* el correo al que se envió: un dato, no un adorno */
.emailchip {
    display: flex;
    justify-content: center;
    margin: 0 0 16px
}

.emailchip span {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    max-width: 100%;
    padding: 11px 16px;
    border-radius: 12px;
    background: var(--base);
    box-shadow: var(--sink-sm);
    font-size: 13.4px;
    font-weight: 600;
    letter-spacing: .2px;
    color: #7cc6f2;
    overflow-wrap: anywhere
}

.emailchip svg { flex: 0 0 auto; color: var(--muted) }

/* los dos datos que el usuario necesita saber después de enviar */
.facts {
    display: grid;
    gap: 9px;
    margin: 0 0 18px;
    padding: 13px 15px;
    border-radius: 14px;
    background: var(--base);
    box-shadow: var(--sink-sm)
}

.fact {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0;
    font-size: 12.1px;
    line-height: 1.45;
    color: var(--muted);
    text-align: left
}

.fact svg {
    flex: 0 0 auto;
    margin-top: 1px;
    color: var(--accent);
    opacity: .85
}

/* el texto va en su propio hijo: suelto, cada <b> se volvería
   un ítem flex y la frase se partiría en columnas */
.fact span { flex: 1; min-width: 0 }

.fact b { color: var(--txt); font-weight: 600 }

/* ============================================================
   CAJAS DE APOYO
   ============================================================ */
.note {
    border-radius: 14px;
    padding: 13px 14px;
    background: var(--base);
    box-shadow: var(--sink-sm);
    font-size: 12.2px;
    line-height: 1.5;
    color: var(--muted);
    text-align: center
}

.note + .note { margin-top: 10px }

.note strong { color: var(--txt); font-weight: 600 }

.note--danger { color: #ffb3aa }

.note code {
    display: inline-block;
    margin-top: 6px;
    padding: 6px 14px;
    border-radius: 9px;
    background: var(--base);
    box-shadow: var(--raise-sm);
    font-family: ui-monospace, Consolas, monospace;
    font-size: 17px;
    letter-spacing: 5px;
    color: var(--led)
}

.foot {
    margin: 14px 0 0;
    text-align: center;
    font-size: 10.6px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: rgba(139, 148, 168, .65)
}

/* ============================================================
   RESPONSIVE
   El ancho lo resuelven los clamp(); aquí se ataca la altura,
   que es lo que de verdad se queda corto.
   ============================================================ */
@media (max-width: 380px) {
    .row {
        flex-wrap: wrap;
        gap: 8px 0;
        justify-content: flex-start
    }
    .row .link { margin-left: auto }
    .code { gap: 5px }
}

/* portátiles pequeños y móvil en horizontal */
@media (max-height: 760px) {
    :root { --bw: clamp(104px, 20vh, 150px) }

    body { padding-bottom: 20px }

    .card {
        padding-top: clamp(22px, 4vh, 28px);
        padding-bottom: 14px;
        border-radius: 18px
    }

    .brand { margin-bottom: 12px }
    .head { margin-bottom: 12px }
    .field { margin-bottom: 8px }
    .field input, .btn { height: 46px }
    .field input { padding: 16px 13px 6px }
    .field label { top: 14px }
    .peek { width: 30px; height: 30px }
    .row { margin: 10px 3px 12px }
    .status { min-height: 14px; margin: 6px 0 0 }
    .lock { width: clamp(70px, 16vh, 86px) }
    .code input { height: clamp(44px, 12vh, 52px) }
}

@media (max-height: 560px) {
    :root { --bw: clamp(88px, 17vh, 120px) }

    .wordmark span, .head p { display: none }
    .field input, .btn { height: 42px }
    .field input { padding: 14px 12px 5px }
    .field label { top: 12px }
    .lockwrap { display: none }
}

/* la sombra necesita aire para no quedar cortada contra el borde */
@media (max-width: 430px) {
    .card {
        box-shadow: 10px 10px 20px var(--sh-d), -10px -10px 20px var(--sh-l)
    }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .05ms !important
    }
}
