/* ==========================================================================
   ACCESO — login y recuperar contraseña, en escritorio y en teléfono.

   La usan `security/_auth_layout.html.twig` (escritorio) y
   `mobile/security/_auth_layout.html.twig` (teléfono); el login extiende los dos. Y
   `security/_doble_factor_layout.html.twig`, el paso del doble factor (uno solo: en una
   ventana estrecha se queda la columna del formulario, sin visor).
   Sin Bootstrap a propósito: son dos campos y un botón.

   La pantalla tiene dos mitades y cada una habla su idioma:
   - EL VISOR (izquierda): el edificio de ejemplo de la landing montándose, el muro de
     fachada seleccionado en ámbar y «la traza» que lleva su 42,80 m² hasta la factura.
     Oscuro porque ES el visor (regla de la landing: lo oscuro sólo donde hay modelo), y
     con su tipografía (Saira en titulares y rótulos, Plex Mono en códigos y cifras), para
     que quien llega desde la web reconozca lo mismo que acaba de ver.
   - EL ACCESO (derecha): el programa. Nunito, blanco y los tokens de `custom.css`.

   ⚠️ El color de un elemento del modelo es su ESTADO, como en el visor real: ámbar = el
   muro que se sigue. No uses el ámbar para otra cosa en esta pantalla.

   ⚠️ Todo lo animado tiene su estado final escrito (fill-mode `both`/`forwards`): con
   `prefers-reduced-motion` las animaciones duran 0 y se ve directamente el final.
   ========================================================================== */

/* ---------- Fuentes de la landing, autoalojadas (OFL, licencias al lado) ---------- */
@font-face {
    font-family: 'Saira Variable';
    font-style: normal;
    font-display: swap;
    font-weight: 100 900;
    font-stretch: 50% 125%;
    src: url('../vendor/fonts/acceso/saira-latin-wdth-normal.woff2') format('woff2-variations');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-display: swap;
    font-weight: 500;
    src: url('../vendor/fonts/acceso/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens (los de `custom.css`, más los del visor de la landing) ---------- */
:root {
    --dp: #4e73df;
    --dp-dark: #224abe;
    --dp-soft: #eef2ff;
    --ink: #2b3648;
    --ink-2: #4a5568;
    --texto-2: #5a6478;
    --muted: #96a0b1;
    --line: #edf0f6;
    --line-2: #dfe5f0;
    --bg-soft: #f6f8fc;
    --dang: #e74a3b;
    --dang-texto: #b8362a;
    --dang-soft: #fdecea;
    --ambar: #f6c23e;
    --ambar-texto: #8a6710;
    --r: 16px;
    --r-sm: 11px;

    --visor-texto: #e8edfb;
    --visor-tenue: #93a1c2;
    --visor-linea: rgba(148, 176, 255, .18);
    --visor-fondo:
        radial-gradient(55% 45% at 62% 55%, rgba(78, 115, 223, .30), transparent 72%),
        radial-gradient(70% 55% at 0% 0%, rgba(78, 115, 223, .22), transparent 62%),
        linear-gradient(162deg, #17327a 0%, #0f1f4d 46%, #0a1433 100%);

    --f-display: 'Saira Variable', 'Nunito', Arial, sans-serif;
    --f-cuerpo: 'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --f-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --ease-out: cubic-bezier(.22, 1, .36, 1);
}

.acceso-pagina {
    margin: 0;
    min-height: 100vh;
    font-family: var(--f-cuerpo);
    color: var(--ink);
    background: #fff;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.acceso-pagina *,
.acceso-pagina *::before,
.acceso-pagina *::after {
    box-sizing: border-box;
}

/* ==========================================================================
   ESCRITORIO — dos columnas: visor a la izquierda, acceso a la derecha.
   En el DOM va primero el formulario (lector de pantalla y tabulador llegan antes a
   lo que se viene a hacer); la rejilla lo coloca a la derecha.
   ========================================================================== */
.acceso {
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(440px, 1fr);
}

.acceso > .visor { grid-column: 1; grid-row: 1; }
.acceso > .acceso-lado { grid-column: 2; grid-row: 1; }

@media (max-width: 991.98px) {
    .acceso { grid-template-columns: minmax(0, 1fr); }
    .acceso > .visor { display: none; }
    .acceso > .acceso-lado { grid-column: 1; }
}

/* ==========================================================================
   EL VISOR
   ========================================================================== */
.visor {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: clamp(24px, 4vh, 42px) clamp(32px, 4.4vw, 68px) clamp(22px, 3.2vh, 34px);
    color: var(--visor-texto);
    background: var(--visor-fondo);
}

.visor-cabecera {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.visor-logo {
    display: block;
    height: clamp(46px, 6.6vh, 64px);
    width: auto;
}

/* El rótulo de maqueta, como en la landing: lo que se ve no es un proyecto real. */
.visor-maqueta {
    font-family: var(--f-display);
    font-weight: 600;
    font-stretch: 112%;
    font-size: .64rem;
    letter-spacing: .07em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--visor-tenue);
    border: 1px solid var(--visor-linea);
    border-radius: 6px;
    padding: .42rem .62rem .38rem;
}

.visor-titular {
    margin: clamp(16px, 3.4vh, 46px) 0 0;
    max-width: 16em;
    font-family: var(--f-display);
    font-weight: 650;
    font-stretch: 74%;
    font-size: clamp(2rem, min(3.15vw, 5.6vh), 3.4rem);
    line-height: .98;
    letter-spacing: -.005em;
    color: #fff;
    animation: acceso-sube .8s var(--ease-out) .05s both;
}

.visor-titular span { display: block; }
.visor-titular span + span { color: #9db6ff; }

.visor-escena-marco {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(6px, 1.8vh, 22px) 0;
}

/* Donde se entienden las unidades de contenedor, la escena ocupa todo el hueco que
   dejan el titular y la traza (el marco no aporta alto propio: lo reparte el flex). */
@supports (width: 1cqh) {
    .visor-escena-marco {
        flex: 1 1 0;
        min-height: 210px;
        container-type: size;
    }
}

/* ---------- La escena: edificio + ficha del elemento ----------
   El alto manda (se ajusta a la pantalla) y el ancho sale de la proporción del
   viewBox (527×396): así la ficha, colocada en % sobre el dibujo, cae siempre en el
   mismo punto de la guía. */
.escena {
    position: relative;
    width: min(100%, calc(clamp(190px, 33vh, 430px) * 1.3308));
    aspect-ratio: 527 / 396;
    transform: translate3d(calc(var(--px, 0) * 9px), calc(var(--py, 0) * 6px), 0);
    transition: transform .7s var(--ease-out);
}

@supports (width: 1cqh) {
    .visor-escena-marco > .escena { width: min(100cqw, 100cqh * 1.3308, 660px); }
}

.escena .edificio {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.edificio .suelo {
    fill: none;
    stroke: rgba(148, 176, 255, .2);
    stroke-width: 1px;
    vector-effect: non-scaling-stroke;
    animation: acceso-aparece 1.2s ease .05s both;
}

/* El modelo se mueve un poco más que el suelo: profundidad al pasar el ratón. */
.edificio .modelo {
    transform: translate(calc(var(--px, 0) * 4px), calc(var(--py, 0) * 3px));
    transition: transform .7s var(--ease-out);
}

/* Colores del visor de la landing (`ModeloIso.css`): cada cara se sombrea sola según
   hacia dónde mira, y el estado sólo cambia el color base (--c) y su opacidad (--a). */
.edificio .el {
    --c: 125 155 255;
    --a: .1;
    --trazo: rgb(157 182 255 / .5);
    --grosor: .8px;
    animation: acceso-el-cae .55s var(--ease-out) backwards;
    animation-delay: calc(var(--d) * 70ms + .2s);
}

.edificio .cara {
    fill: rgb(var(--c) / var(--a));
    stroke: var(--trazo);
    stroke-width: var(--grosor);
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.edificio .cara--techo { fill: rgb(var(--c) / calc(var(--a) * 1.4)); }
.edificio .cara--lado { fill: rgb(var(--c) / calc(var(--a) * .65)); }

.edificio .cara--hueco {
    fill: rgb(190 210 255 / .16);
    stroke: rgb(190 210 255 / .45);
}

.edificio .el--fondo {
    --a: .05;
    --trazo: rgb(157 182 255 / .2);
}

/* El muro que se sigue: se selecciona cuando el edificio ya está montado y luego
   respira, sin dejar de ser ámbar. */
.edificio .is-traza .cara {
    animation:
        acceso-muro-elegido .5s ease 1.7s both,
        acceso-muro-respira 3.6s ease-in-out 2.3s infinite;
}

/* La guía hasta la ficha: sale del muro, se dibuja y acaba en un punto. */
.edificio .guia-linea {
    fill: none;
    stroke: rgba(246, 194, 62, .85);
    stroke-width: 1;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: acceso-traza-guia .55s var(--ease-out) 2.05s forwards;
}

.edificio .guia-origen,
.edificio .guia-fin {
    fill: var(--ambar);
    animation: acceso-aparece .3s ease 1.95s both;
}

.edificio .guia-fin { animation-delay: 2.5s; }

.edificio .guia-onda {
    fill: none;
    stroke: var(--ambar);
    stroke-width: 1;
    transform-box: fill-box;
    transform-origin: center;
    opacity: 0;
    animation: acceso-onda 2.8s ease-out 2.4s infinite;
}

/* La ficha del elemento, como el inspector del visor: clase, GlobalId y la cantidad
   que viaja. Su borde derecho cae en el final de la guía (--qx/--qy, del SVG). */
.visor-ficha {
    position: absolute;
    right: calc(100% - var(--qx) + 8px);
    top: var(--qy);
    width: max-content;
    max-width: 224px;
    padding: .62rem .78rem .66rem;
    border-radius: 10px;
    background: rgba(12, 22, 54, .82);
    border: 1px solid rgba(246, 194, 62, .42);
    box-shadow: 0 12px 32px rgba(4, 10, 30, .45);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    font-size: .74rem;
    line-height: 1.35;
    color: var(--visor-texto);
    animation: acceso-ficha .5s var(--ease-out) 2.45s both;
}

.ficha-titulo { display: block; white-space: nowrap; }
.ficha-clase { font-family: var(--f-mono); font-weight: 500; color: var(--ambar); }
.ficha-nombre { color: #c9d3ee; }

.ficha-guid {
    display: block;
    margin: .22rem 0 .5rem;
    font-family: var(--f-mono);
    font-size: .64rem;
    color: var(--visor-tenue);
}

.ficha-medida {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1.1rem;
    padding-top: .45rem;
    border-top: 1px solid rgba(148, 176, 255, .16);
}

.ficha-medida span {
    font-family: var(--f-mono);
    font-size: .64rem;
    color: var(--visor-tenue);
}

.ficha-medida strong {
    font-family: var(--f-mono);
    font-weight: 500;
    font-size: .9rem;
    color: #fff;
}

/* ---------- La traza: el mismo dato, parada a parada ----------
   El raíl se llena de izquierda a derecha y cada nodo se enciende cuando el relleno
   llega a él (raíl lineal de 1,9 s; nodos cada 0,475 s, que es 1,9 / 4). Luego, cada
   pocos segundos, un destello lo recorre otra vez. */
.traza-marco {
    position: relative;
    margin-top: clamp(4px, 1vh, 12px);
}

.traza {
    position: relative;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    margin: 0;
    padding: 0;
    list-style: none;
}

.traza::before,
.traza::after,
.traza-marco::after {
    content: "";
    position: absolute;
    top: 6px;
    left: 10%;
    right: 10%;
    height: 2px;
    border-radius: 2px;
}

.traza::before { background: rgba(148, 176, 255, .16); }

.traza::after {
    background: linear-gradient(90deg, rgba(246, 194, 62, .35), var(--ambar));
    transform-origin: left center;
    transform: scaleX(0);
    animation: acceso-rail 1.9s linear 2.75s forwards;
}

.traza-marco::after {
    z-index: 2;
    background: linear-gradient(90deg, transparent, rgba(255, 246, 214, .95), transparent) no-repeat;
    background-size: 18% 100%;
    background-position: -30% 0;
    animation: acceso-destello 6.5s ease-in-out 5.4s infinite;
}

.traza li {
    position: relative;
    min-width: 0;
    padding: 22px 4px 0;
    text-align: center;
}

.traza li::before {
    content: "";
    position: absolute;
    z-index: 1;
    top: 1px;
    left: 50%;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    border-radius: 50%;
    background: #0f1f4d;
    border: 2px solid rgba(148, 176, 255, .42);
    animation: acceso-nodo .35s ease calc(2.75s + var(--i) * .475s) forwards;
}

.traza-parada {
    display: block;
    font-family: var(--f-display);
    font-weight: 600;
    font-stretch: 112%;
    font-size: .64rem;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: #c9d3ee;
}

.traza-ref {
    display: block;
    margin-top: .32rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--f-mono);
    font-size: .66rem;
    color: var(--visor-tenue);
}

.traza-dato {
    display: block;
    margin-top: .12rem;
    white-space: nowrap;
    font-family: var(--f-mono);
    font-weight: 500;
    font-size: .82rem;
    color: #fff;
    opacity: .3;
    animation: acceso-dato .35s ease calc(2.8s + var(--i) * .475s) forwards;
}

/* ---------- Lo que incluye: la lista de siempre, en dos columnas ---------- */
.brand-features {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .4rem 1.6rem;
    margin: clamp(14px, 2.4vh, 26px) 0 0;
    padding: clamp(12px, 2vh, 20px) 0 0;
    border-top: 1px solid rgba(148, 176, 255, .14);
    list-style: none;
    animation: acceso-aparece .8s ease .5s both;
}

.brand-features li {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    font-size: .79rem;
    line-height: 1.3;
    color: rgba(232, 237, 251, .8);
}

.brand-features i {
    flex: 0 0 1.1rem;
    margin-top: .12rem;
    text-align: center;
    font-size: .76rem;
    color: #9db6ff;
}

/* En una pantalla baja la lista no cabe sin empujar el visor (y con él, el pie del
   formulario): se queda la traza, que es lo que cuenta el producto. */
@media (max-height: 740px) {
    .brand-features { display: none; }
}

/* ==========================================================================
   EL ACCESO
   ========================================================================== */
.acceso-lado {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: 24px clamp(28px, 4.6vw, 76px) 22px;
    background:
        radial-gradient(42% 34% at 92% 4%, rgba(78, 115, 223, .07), transparent 70%),
        #fff;
}

.acceso-cuerpo {
    flex: 1 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 64px 0 36px;
}

.acceso-tarjeta {
    width: 100%;
    max-width: 396px;
}

/* Portátiles de 768 px de alto (los más comunes en una oficina pequeña): el formulario
   entero sin desplazar. */
@media (max-height: 720px) {
    .acceso-cuerpo { padding: 60px 0 16px; }
    .acceso-lado .login-sub { margin-bottom: 1.3rem; }
    .acceso-lado .input-wrap { margin-bottom: .95rem; }
    .acceso-lado .acceso-nota { margin-top: 1.1rem; padding-top: .9rem; }
}

/* Entrada escalonada, corta: el visor es el que se mueve, esto sólo aparece. */
.acceso-tarjeta > * { animation: acceso-sube .6s var(--ease-out) both; }
.acceso-tarjeta > :nth-child(2) { animation-delay: .05s; }
.acceso-tarjeta > :nth-child(3) { animation-delay: .1s; }
.acceso-tarjeta > :nth-child(4) { animation-delay: .15s; }
.acceso-tarjeta > :nth-child(5) { animation-delay: .2s; }
.acceso-tarjeta > :nth-child(n+6) { animation-delay: .25s; }

/* Sin el visor (ventana estrecha) el logotipo va encima del formulario. */
.acceso-logo-compacto {
    display: none;
    height: 72px;
    width: auto;
    margin: 0 0 28px;
}

@media (max-width: 991.98px) {
    .acceso-logo-compacto { display: block; }
}

.acceso-saludo {
    margin: 0 0 .3rem;
    font-size: .95rem;
    font-weight: 700;
    color: var(--dp-dark);
}

.login-heading {
    margin: 0 0 .5rem;
    font-family: var(--f-cuerpo);
    font-weight: 800;
    font-size: clamp(1.75rem, 2.3vw, 2.1rem);
    line-height: 1.12;
    letter-spacing: -.02em;
    color: var(--ink);
}

.login-sub {
    margin: 0 0 1.9rem;
    font-size: .95rem;
    line-height: 1.5;
    color: var(--texto-2);
}

/* ---------- Campos ---------- */
.field-label {
    display: block;
    margin: 0 0 .45rem;
    font-size: .84rem;
    font-weight: 700;
    color: var(--ink);
}

.input-wrap {
    position: relative;
    margin-bottom: 1.15rem;
}

.input-wrap .field-icon {
    position: absolute;
    z-index: 1;
    left: 16px;
    top: 26px;
    transform: translateY(-50%);
    font-size: .92rem;
    color: var(--muted);
    pointer-events: none;
    transition: color .18s;
}

.input-wrap:focus-within .field-icon { color: var(--dp); }

.login-input {
    display: block;
    width: 100%;
    height: 52px;
    margin: 0;
    padding: 0 1rem 0 2.85rem;
    border: 1.5px solid var(--line-2);
    border-radius: var(--r-sm);
    background: var(--bg-soft);
    font-family: inherit;
    font-size: 1rem;
    color: var(--ink);
    transition: border-color .18s, box-shadow .18s, background-color .18s;
}

.login-input::placeholder { color: #a3adbd; }
.login-input:hover { border-color: #cbd4e4; }

.login-input:focus {
    outline: none;
    border-color: var(--dp);
    background: #fff;
    box-shadow: 0 0 0 4px rgba(78, 115, 223, .14);
}

/* El autorrelleno del navegador pinta su propio fondo: se tapa con una sombra interior
   y se conserva el anillo de foco. */
.login-input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px #f1f4ff inset;
    -webkit-text-fill-color: var(--ink);
}

.login-input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px #fff inset, 0 0 0 4px rgba(78, 115, 223, .14);
}

.login-input[aria-invalid="true"] {
    border-color: rgba(231, 74, 59, .55);
    background: #fffafa;
}

.login-input--con-boton { padding-right: 3.3rem; }

.toggle-pass {
    position: absolute;
    right: 6px;
    top: 26px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: color .15s, background-color .15s;
}

.toggle-pass:hover,
.toggle-pass[aria-pressed="true"] {
    color: var(--dp);
    background: rgba(78, 115, 223, .08);
}

.toggle-pass:focus-visible {
    outline: 2px solid var(--dp);
    outline-offset: 1px;
}

.acceso-mayus {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: -.55rem 0 1rem;
    font-size: .8rem;
    font-weight: 700;
    color: var(--ambar-texto);
}

.acceso-mayus[hidden] { display: none; }
.acceso-mayus i { color: var(--ambar); }

/* ---------- Recordarme (interruptor) y enlace de recuperación ---------- */
.login-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin: .25rem 0 1.5rem;
}

.remember {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    font-size: .88rem;
    font-weight: 600;
    color: var(--ink-2);
    cursor: pointer;
    user-select: none;
}

.remember input {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    flex: 0 0 auto;
    width: 34px;
    height: 20px;
    margin: 0;
    border-radius: 999px;
    background: #d4dae6;
    cursor: pointer;
    transition: background-color .2s;
}

.remember input::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .25);
    transition: transform .22s var(--ease-out);
}

.remember input:checked { background: var(--dp); }
.remember input:checked::after { transform: translateX(14px); }

.remember input:focus-visible {
    outline: 2px solid var(--dp);
    outline-offset: 2px;
}

.link-soft {
    font-size: .88rem;
    font-weight: 700;
    color: var(--dp-dark);
    text-decoration: none;
}

.link-soft:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ---------- Botón principal ---------- */
.btn-login {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    width: 100%;
    height: 54px;
    border: 0;
    border-radius: var(--r-sm);
    background: linear-gradient(135deg, #4e73df 0%, #3a60d6 48%, #224abe 100%);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 10px 24px rgba(34, 74, 190, .28);
    font-family: var(--f-cuerpo);
    font-weight: 800;
    font-size: 1rem;
    letter-spacing: .01em;
    color: #fff;
    text-decoration: none;
    cursor: pointer;
    transition: transform .15s, box-shadow .2s;
}

.btn-login::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .22) 50%, transparent 70%);
    transform: translateX(-120%);
    transition: transform .8s var(--ease-out);
}

.btn-login:hover {
    transform: translateY(-1px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 14px 30px rgba(34, 74, 190, .36);
}

.btn-login:hover::before { transform: translateX(120%); }
.btn-login:active { transform: translateY(0); }

.btn-login:focus-visible {
    outline: 3px solid rgba(78, 115, 223, .45);
    outline-offset: 2px;
}

.btn-login .btn-flecha { transition: transform .22s var(--ease-out); }
.btn-login:hover .btn-flecha { transform: translateX(3px); }

.btn-login .btn-girando {
    display: none;
    width: 18px;
    height: 18px;
    border: 2.5px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: acceso-gira .7s linear infinite;
}

.btn-login.is-enviando { pointer-events: none; }
.btn-login.is-enviando .btn-flecha { display: none; }
.btn-login.is-enviando .btn-girando { display: inline-block; }

.btn-ghost {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    width: 100%;
    margin-top: .9rem;
    padding: .75rem 1rem;
    border-radius: var(--r-sm);
    font-size: .9rem;
    font-weight: 700;
    color: var(--texto-2);
    text-decoration: none;
    transition: color .15s, background-color .15s;
}

.btn-ghost:hover {
    color: var(--dp-dark);
    background: rgba(78, 115, 223, .06);
}

/* ---------- Avisos ---------- */
.login-alert {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    margin-bottom: 1.4rem;
    padding: .8rem 1rem;
    border-radius: var(--r-sm);
    font-size: .9rem;
    line-height: 1.45;
}

.login-alert > i { margin-top: .18rem; }

.login-alert.err {
    background: var(--dang-soft);
    border: 1px solid rgba(231, 74, 59, .18);
    color: var(--dang-texto);
    animation: acceso-sacude .45s ease .35s both;
}

.login-alert.info {
    background: var(--dp-soft);
    color: var(--dp-dark);
}

.field-error {
    margin: -.7rem 0 1rem;
    font-size: .82rem;
    color: var(--dang-texto);
}

.field-error ul { margin: 0; padding-left: 1.1rem; }

.field-hint {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    margin: -.5rem 0 1.4rem;
    font-size: .82rem;
    line-height: 1.45;
    color: var(--texto-2);
}

.field-hint i { margin-top: .15rem; }

.auth-state { text-align: center; }

.auth-state .state-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 76px;
    height: 76px;
    margin-bottom: 1.3rem;
    border-radius: 20px;
    background: var(--dp-soft);
    color: var(--dp);
    font-size: 1.8rem;
}

/* Quién más entra por aquí: los portales comparten puerta con el equipo. */
.acceso-nota {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    margin: 1.6rem 0 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
    font-size: .83rem;
    line-height: 1.5;
    color: var(--texto-2);
}

.acceso-nota i {
    margin-top: .22rem;
    color: var(--dp);
}

/* ---------- Pie legal ---------- */
.acceso-pie {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .35rem 1rem;
    font-size: .76rem;
    color: var(--texto-2);
    text-align: center;
}

.acceso-pie a {
    color: var(--texto-2);
    text-decoration: none;
}

.acceso-pie a:hover {
    color: var(--dp-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.acceso-copy {
    flex: 1 0 100%;
    margin-top: .2rem;
    color: #7c879b;
}

/* ---------- Idioma: detrás del formulario en el DOM, arriba a la derecha en pantalla ---------- */
.acceso-idioma {
    position: absolute;
    top: 22px;
    right: clamp(28px, 4.6vw, 76px);
    margin: 0;
}

.acceso-idioma-grupo {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--bg-soft);
}

.acceso-idioma button {
    padding: .45rem .62rem;
    border: 0;
    border-radius: 7px;
    background: transparent;
    font-family: var(--f-cuerpo);
    font-weight: 800;
    font-size: .72rem;
    letter-spacing: .05em;
    color: var(--texto-2);
    cursor: pointer;
    transition: color .15s, background-color .15s;
}

.acceso-idioma button:hover { color: var(--dp-dark); }

.acceso-idioma button[aria-current="true"] {
    background: #fff;
    color: var(--dp-dark);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .1);
}

.acceso-idioma button:focus-visible {
    outline: 2px solid var(--dp);
    outline-offset: 1px;
}

/* ---------- Doble factor: verificar, darlo de alta y los códigos de recuperación ----------
   `security/_doble_factor_layout.html.twig` y sus tres hijas, sobre el mismo esqueleto. */
.login-alert.ok {
    background: #e8f6ef;
    border: 1px solid rgba(28, 200, 138, .22);
    color: #157347;
}

/* El código se lee y se teclea en grupos: monoespaciada y con aire entre cifras. */
.login-input--codigo {
    font-family: var(--f-mono);
    font-size: 1.12rem;
    font-weight: 500;
    letter-spacing: .28em;
}

.acceso-qr {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    margin: 0 0 1.5rem;
    padding: 1rem;
    border: 1px solid var(--line-2);
    border-radius: var(--r);
    background: var(--bg-soft);
}

.acceso-qr img {
    flex: 0 0 auto;
    display: block;
    width: 160px;
    height: 160px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: #fff;
}

.acceso-qr p {
    margin: 0;
    font-size: .82rem;
    line-height: 1.45;
    color: var(--texto-2);
}

.acceso-clave {
    display: block;
    margin-top: .5rem;
    font-family: var(--f-mono);
    font-size: .9rem;
    font-weight: 500;
    line-height: 1.6;
    color: var(--ink);
    user-select: all;
}

@media (max-width: 479.98px) {
    .acceso-qr { flex-direction: column; text-align: center; }
}

.acceso-codigos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .5rem;
    margin: 0 0 1.5rem;
    padding: 1rem;
    border: 1px dashed var(--line-2);
    border-radius: var(--r);
    background: var(--bg-soft);
    list-style: none;
}

.acceso-codigos code {
    display: block;
    padding: .5rem .6rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: #fff;
    font-family: var(--f-mono);
    font-size: .92rem;
    font-weight: 500;
    letter-spacing: .04em;
    text-align: center;
    color: var(--ink);
}

.btn-peligro {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    height: 50px;
    border: 1.5px solid rgba(231, 74, 59, .35);
    border-radius: var(--r-sm);
    background: #fff;
    font-family: var(--f-cuerpo);
    font-weight: 800;
    font-size: .95rem;
    color: var(--dang-texto);
    cursor: pointer;
    transition: background-color .15s, border-color .15s;
}

.btn-peligro:hover {
    background: var(--dang-soft);
    border-color: rgba(231, 74, 59, .55);
}

.btn-peligro:focus-visible {
    outline: 3px solid rgba(231, 74, 59, .35);
    outline-offset: 2px;
}

.btn-ghost + .btn-ghost { margin-top: .2rem; }

/* ==========================================================================
   ALTA (/alta) — `alta/_layout.html.twig`. El formulario es largo: el visor se queda
   fijo a la izquierda mientras la columna del formulario se desplaza. Aquí SÍ hay
   Bootstrap (los formularios salen del tema `bootstrap_5_layout`), y esta sección viste
   sus campos como los del login. Todo va bajo `.acceso-pagina--alta`: con más
   especificidad que Bootstrap y sin tocar el login, que no lo carga.
   ========================================================================== */
/* ⚠️ Dentro del media query: fuera de él, esta regla va después de la de pantalla
   estrecha y la pisaba (en el teléfono quedaban dos columnas con el visor oculto). */
@media (min-width: 992px) {
    .acceso--alta { grid-template-columns: minmax(0, 1fr) minmax(540px, 1.15fr); }

    .acceso--alta > .visor {
        position: sticky;
        top: 0;
        align-self: start;
        height: 100vh;
        min-height: 0;
    }
}

.acceso-pagina--alta .acceso-cuerpo {
    align-items: flex-start;
    padding: 72px 0 40px;
}

.acceso-tarjeta--alta { max-width: 640px; }

/* Los tres pasos del alta: un recorrido de verdad, de ahí los números. */
.alta-pasos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem 0;
    margin: 0 0 1.6rem;
    padding: 0;
    list-style: none;
}

.alta-paso {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .84rem;
    font-weight: 700;
    color: var(--texto-2);
}

.alta-paso + .alta-paso::before {
    content: "";
    width: 28px;
    height: 1.5px;
    margin: 0 .75rem;
    border-radius: 2px;
    background: var(--line-2);
}

.alta-paso-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1.5px solid var(--line-2);
    border-radius: 50%;
    font-size: .76rem;
    color: var(--texto-2);
    background: #fff;
}

.alta-paso.is-activo { color: var(--ink); }

.alta-paso.is-activo .alta-paso-num {
    border-color: var(--dp);
    background: var(--dp);
    color: #fff;
    box-shadow: 0 0 0 4px rgba(78, 115, 223, .14);
}

.alta-paso.is-hecho .alta-paso-num {
    border-color: #1cc88a;
    background: #1cc88a;
    color: #fff;
}

.alta-paso.is-hecho + .alta-paso::before { background: #1cc88a; }

/* Secciones del formulario: rótulo y filete hasta el final de la línea. */
.alta-seccion {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: 2.1rem 0 1rem;
    font-size: .74rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--dp-dark);
}

.alta-seccion::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

.alta-nota {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    margin: .6rem 0 0;
    font-size: .83rem;
    line-height: 1.45;
    color: var(--texto-2);
}

.alta-nota i { margin-top: .18rem; color: var(--dp); }
.alta-nota--en-linea { margin: 0; align-items: center; }
.alta-nota--en-linea i { margin-top: 0; }

.alta-acciones {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.25rem;
    margin-top: 1.8rem;
}

.alta-aviso-simulado {
    padding: 1rem 1.1rem;
    border: 1px solid #f3dca0;
    border-radius: var(--r-sm);
    background: #fdf5df;
    font-size: .9rem;
    color: var(--ambar-texto);
}

/* El botón del alta: el de entrar del login, con su ancho natural. */
.acceso-pagina--alta .btn-alta {
    position: relative;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    height: 54px;
    padding: 0 1.6rem;
    border: 0;
    border-radius: var(--r-sm);
    background: linear-gradient(135deg, #4e73df 0%, #3a60d6 48%, #224abe 100%);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 10px 24px rgba(34, 74, 190, .28);
    font-family: var(--f-cuerpo);
    font-weight: 800;
    font-size: 1rem;
    color: #fff;
    text-decoration: none;
    transition: transform .15s, box-shadow .2s;
}

.acceso-pagina--alta .btn-alta:hover {
    transform: translateY(-1px);
    color: #fff;
    background: linear-gradient(135deg, #4e73df 0%, #3a60d6 48%, #224abe 100%);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 14px 30px rgba(34, 74, 190, .36);
}

.acceso-pagina--alta .btn-alta:focus-visible {
    outline: 3px solid rgba(78, 115, 223, .45);
    outline-offset: 2px;
}

.acceso-pagina--alta .btn-alta i { transition: transform .22s var(--ease-out); }
.acceso-pagina--alta .btn-alta:hover i { transform: translateX(3px); }

/* Campos de Bootstrap con la piel de los del login. El tema mete cada campo en un
   `div.mb-3` y la fila ya trae su separación (`g-3`): sin esto el aire salía doble. */
.acceso-pagina--alta .row > * > .mb-3 { margin-bottom: 0 !important; }
.acceso-pagina--alta form > .mb-3,
.acceso-pagina--alta .mt-4 > .mb-3 { margin-bottom: 0 !important; }
/* Campos de Bootstrap con la piel de los del login. */
.acceso-pagina--alta .form-label {
    margin-bottom: .45rem;
    font-size: .84rem;
    font-weight: 700;
    color: var(--ink);
}

.acceso-pagina--alta .form-control,
.acceso-pagina--alta .form-select {
    min-height: 50px;
    padding: .7rem .95rem;
    border: 1.5px solid var(--line-2);
    border-radius: var(--r-sm);
    background-color: var(--bg-soft);
    font-family: inherit;
    font-size: 1rem;
    color: var(--ink);
    transition: border-color .18s, box-shadow .18s, background-color .18s;
}

.acceso-pagina--alta .form-select { padding-right: 2.4rem; }

.acceso-pagina--alta .form-control:hover,
.acceso-pagina--alta .form-select:hover { border-color: #cbd4e4; }

.acceso-pagina--alta .form-control:focus,
.acceso-pagina--alta .form-select:focus {
    border-color: var(--dp);
    background-color: #fff;
    box-shadow: 0 0 0 4px rgba(78, 115, 223, .14);
}

.acceso-pagina--alta .form-control.is-invalid,
.acceso-pagina--alta .form-select.is-invalid {
    border-color: rgba(231, 74, 59, .6);
    background-color: #fffafa;
}

.acceso-pagina--alta .invalid-feedback { font-size: .82rem; color: var(--dang-texto); }
.acceso-pagina--alta .form-text { font-size: .8rem; color: var(--texto-2); }

.acceso-pagina--alta .form-check { padding-left: 1.9rem; }

.acceso-pagina--alta .form-check-input {
    width: 1.2em;
    height: 1.2em;
    margin-top: .18em;
    margin-left: -1.9rem;
    border: 1.5px solid #c3cbdb;
    border-radius: 6px;
}

.acceso-pagina--alta .form-check-input:checked {
    border-color: var(--dp);
    background-color: var(--dp);
}

.acceso-pagina--alta .form-check-input:focus {
    border-color: var(--dp);
    box-shadow: 0 0 0 4px rgba(78, 115, 223, .14);
}

.acceso-pagina--alta .form-check-label {
    font-size: .9rem;
    line-height: 1.5;
    color: var(--ink-2);
}

.acceso-pagina--alta .form-check-label a {
    font-weight: 700;
    color: var(--dp-dark);
    text-decoration: none;
}

.acceso-pagina--alta .form-check-label a:hover { text-decoration: underline; }

/* Resúmenes (pago y estado): etiqueta tenue, valor en tinta. */
.acceso-pagina--alta dl.row { margin-top: .25rem; }
.acceso-pagina--alta dt { font-size: .84rem; font-weight: 700; color: var(--texto-2); }
.acceso-pagina--alta dd { color: var(--ink); }
.acceso-pagina--alta .alert { border-radius: var(--r-sm); }

@media (max-width: 991.98px) {
    .acceso-pagina--alta .acceso-cuerpo { padding-top: 64px; }
}

@media (max-width: 575.98px) {
    .acceso-pagina--alta .acceso-lado { padding-left: 18px; padding-right: 18px; }
    .alta-paso-nombre { font-size: .78rem; }
    .alta-paso + .alta-paso::before { width: 16px; margin: 0 .45rem; }
    .acceso-pagina--alta .btn-alta { width: 100%; }
}

/* ==========================================================================
   TELÉFONO — el visor arriba en pequeño y una hoja blanca que sube desde abajo.
   ========================================================================== */
.acceso-pagina--movil {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
    background: #0f1f4d;
}

.movil-visor {
    position: relative;
    overflow: hidden;
    padding: calc(env(safe-area-inset-top, 0px) + 16px) 20px 34px;
    color: var(--visor-texto);
    background: var(--visor-fondo);
}

.movil-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}

.movil-logo {
    display: block;
    height: 46px;
    width: auto;
}

.movil-visor .visor-maqueta { font-size: .56rem; }

.movil-titular {
    margin: 14px 0 0;
    max-width: 13em;
    font-family: var(--f-display);
    font-weight: 650;
    font-stretch: 76%;
    font-size: 1.48rem;
    line-height: 1;
    color: #fff;
    animation: acceso-sube .8s var(--ease-out) .05s both;
}

.movil-titular span { display: block; }
.movil-titular span + span { color: #9db6ff; }

.movil-escena-marco {
    width: min(100%, 300px);
    margin: -4px -8px 0 auto;
}

/* Teléfonos bajos: el edificio cede sitio para que «Entrar» quede a la vista. */
@media (max-height: 700px) {
    .movil-escena-marco { width: min(100%, 236px); }
}

/* En el teléfono la ficha es mínima: la clase y la cantidad. */
.movil-escena-marco .visor-ficha {
    padding: .4rem .55rem .45rem;
    font-size: .64rem;
}

.movil-escena-marco .ficha-nombre,
.movil-escena-marco .ficha-guid,
.movil-escena-marco .ficha-medida span { display: none; }

.movil-escena-marco .ficha-medida {
    margin-top: .2rem;
    padding-top: .25rem;
}

.movil-escena-marco .ficha-medida strong { font-size: .78rem; }

.movil-hoja {
    position: relative;
    z-index: 1;
    flex: 1 0 auto;
    margin-top: -26px;
    padding: 28px 22px calc(env(safe-area-inset-bottom, 0px) + 22px);
    border-radius: 26px 26px 0 0;
    background: #fff;
    box-shadow: 0 -12px 30px rgba(4, 10, 30, .25);
}

.movil-hoja .acceso-tarjeta {
    max-width: 440px;
    margin: 0 auto;
}

/* El dedo manda: objetivos táctiles algo más grandes que en escritorio. */
.movil-hoja .login-input { height: 54px; }
.movil-hoja .input-wrap .field-icon,
.movil-hoja .toggle-pass { top: 27px; }
.movil-hoja .login-heading { font-size: 1.6rem; }
.movil-hoja .login-sub { margin-bottom: 1.5rem; font-size: .92rem; }

.movil-hoja .acceso-pie {
    margin-top: 1.6rem;
    padding-top: 1.2rem;
    border-top: 1px solid var(--line);
}

.movil-hoja .acceso-idioma {
    position: static;
    display: flex;
    justify-content: center;
    margin-top: 1.1rem;
}

/* ==========================================================================
   ANIMACIONES
   ========================================================================== */
@keyframes acceso-sube {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

@keyframes acceso-aparece {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes acceso-el-cae {
    from { opacity: 0; transform: translateY(-16px); }
    to { opacity: 1; transform: none; }
}

@keyframes acceso-muro-elegido {
    from { fill: rgb(125 155 255 / .14); stroke: rgb(157 182 255 / .5); stroke-width: .8px; }
    to { fill: rgb(246 194 62 / .5); stroke: #f6c23e; stroke-width: 1.6px; }
}

@keyframes acceso-muro-respira {
    0%, 100% { fill: rgb(246 194 62 / .5); stroke: #f6c23e; stroke-width: 1.6px; }
    50% { fill: rgb(246 194 62 / .64); stroke: #ffd666; stroke-width: 1.6px; }
}

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

@keyframes acceso-onda {
    0% { opacity: .9; transform: scale(1); }
    70%, 100% { opacity: 0; transform: scale(4.2); }
}

@keyframes acceso-ficha {
    from { opacity: 0; transform: translate(8px, -50%); }
    to { opacity: 1; transform: translate(0, -50%); }
}

@keyframes acceso-rail {
    to { transform: scaleX(1); }
}

@keyframes acceso-nodo {
    to {
        background: var(--ambar);
        border-color: var(--ambar);
        box-shadow: 0 0 0 4px rgba(246, 194, 62, .16), 0 0 14px rgba(246, 194, 62, .55);
    }
}

@keyframes acceso-dato {
    to { opacity: 1; color: #ffe08a; }
}

@keyframes acceso-destello {
    0% { background-position: -30% 0; }
    40%, 100% { background-position: 130% 0; }
}

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

@keyframes acceso-sacude {
    0%, 100% { transform: none; }
    20% { transform: translateX(-6px); }
    40% { transform: translateX(5px); }
    60% { transform: translateX(-3px); }
    80% { transform: translateX(2px); }
}

/* Sin movimiento: cada animación salta a su estado final, que está escrito. */
@media (prefers-reduced-motion: reduce) {
    .acceso-pagina *,
    .acceso-pagina *::before,
    .acceso-pagina *::after {
        animation-duration: .001ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }

    .escena,
    .edificio .modelo { transform: none !important; }
}
