/*
 * T.N.S.V.T — Portal de la Creación (Sanctum v2)
 * Capa ADITIVA sobre el emblema del login (.gw-emblem, home.css).
 * Solo aplica cuando js/modules/creation-portal.js monta la cruz (.cp-active),
 * así que sin el JS el emblema original queda intacto.
 */

.gw-emblem.cp-active {
    /* El emblema original es pointer-events:none; solo la capa .cp-hit recibe toques. */
    isolation: isolate;
}

.cp-svg {
    position: absolute;
    width: 220px;
    height: 220px;
    overflow: visible;
    pointer-events: none;
    z-index: 2;
}

/* El núcleo dorado original queda como resplandor detrás de la cruz */
.gw-emblem.cp-active .gw-core {
    /* Más atenuado: antes el núcleo dorado (56px) tapaba la cruz (60px) y
       la cruz se leía como una mancha dorada, no como una cruz. */
    opacity: 0.32;
    transition: opacity 0.6s ease, transform 0.6s ease;
}
.gw-emblem.cp-charging .gw-core,
.gw-emblem.cp-open .gw-core {
    opacity: 0.5;
}

/* El emblema flota (gw-float, 6s infinito): el botón que lo activa se
   movía con él (objetivo móvil en movimiento) y Playwright no podía
   clickearlo ("element is not stable"). Al pasar el mouse o al enfocarlo
   con el teclado, la animación se pausa. */
.gw-emblem:hover,
.gw-emblem:focus-within {
    animation-play-state: paused;
}

/* ── Cruz ── */
.cp-cross-base {
    fill: rgb(var(--acc-p2) / 0.12);
}
.cp-cross-fill {
    fill: rgb(var(--acc-p4));
    filter: drop-shadow(0 0 10px rgb(var(--acc-p4)));
}
.cp-cross-outline {
    fill: none;
    stroke: var(--gold-bright-elev);
    stroke-width: 1.6;
    stroke-linejoin: round;
    filter: drop-shadow(0 0 6px rgb(var(--acc-p1) / 0.8));
    transition: filter 0.3s ease;
}
.cp-charging .cp-cross-outline,
.cp-open .cp-cross-outline {
    filter: drop-shadow(0 0 14px rgb(var(--acc-p4))) drop-shadow(0 0 30px rgb(var(--acc-p1) / 0.9));
}
.cp-cross {
    transform-box: fill-box;
    transform-origin: center;
    /* La cruz crece para que se lea POR ENCIMA del núcleo dorado. */
    transform: scale(1.25);
    transition: transform 0.2s ease;
}
.cp-charging .cp-cross {
    transform: scale(1.18);
}

/* ── Rayos ── */
.cp-rays {
    transform-box: fill-box;
    transform-origin: center;
    opacity: 0;
    transform: scale(0.3) rotate(-20deg);
    transition: opacity 1.4s cubic-bezier(0.2, 0.8, 0.2, 1), transform 1.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.cp-rays line {
    stroke: rgb(var(--acc-p3) / 0.55);
}
.cp-open .cp-rays {
    opacity: 1;
    transform: none;
}
.cp-open .cp-rays line {
    animation: cp-ray 3s ease-in-out infinite;
}
@keyframes cp-ray {
    50% {
        opacity: 0.35;
    }
}

/* ── Capa táctil ── */
.cp-hit {
    position: absolute;
    width: 120px;
    height: 140px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    pointer-events: auto;
    z-index: 3;
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}
.cp-hit:focus-visible {
    outline: 2px solid var(--gold-bright-elev);
    outline-offset: 4px;
}

/* ── Textos ── */
.cp-hint {
    margin: -6px 0 6px;
    text-align: center;
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    color: var(--on-surface-dim-elev, #b8b8cc);
    animation: cp-hint 2.4s ease-in-out infinite;
}
.cp-open ~ .cp-hint {
    animation: none;
}
@keyframes cp-hint {
    50% {
        opacity: 0.45;
    }
}
.cp-verse {
    min-height: 1.5em;
    margin: 0 0 10px;
    text-align: center;
    font-family: var(--font-display-elev, 'Cinzel', serif);
    font-size: 1rem;
    font-weight: 600;
    color: rgb(var(--acc-p4));
    text-shadow: 0 0 18px rgb(var(--acc-p1) / 0.7);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.8s ease, transform 0.8s ease;
}
.cp-verse.is-visible {
    opacity: 1;
    transform: none;
}

/* ── Destello ── */
.cp-flash {
    position: fixed;
    inset: 0;
    z-index: 60;
    pointer-events: none;
    background: radial-gradient(
        circle at var(--fx, 50%) var(--fy, 30%),
        #fff 0,
        rgb(var(--acc-p3) / 0.6) 18%,
        transparent 60%
    );
    animation: cp-flash 1.1s ease forwards;
}
@keyframes cp-flash {
    0% {
        opacity: 0;
    }
    15% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cp-rays,
    .cp-verse,
    .cp-cross {
        transition: none;
    }
    .cp-open .cp-rays line,
    .cp-hint {
        animation: none;
    }
}

/* ═══ Casillas OTP del 2FA (js/modules/otp-boxes.js) ═══ */
.otp-real-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0 0 0 0) !important;
    border: 0 !important;
    opacity: 0 !important;
}
.otp-boxes {
    display: flex;
    justify-content: center;
    gap: 0.45rem;
    margin-top: 0.35rem;
}
.otp-boxes .otp-box {
    padding: 0 !important;
    line-height: 3.3rem;
    box-sizing: border-box;
    -webkit-text-fill-color: currentColor;
    width: 2.75rem;
    height: 3.3rem;
    min-width: 0;
    flex: 0 1 2.75rem;
    text-align: center;
    font-size: 1.35rem;
    font-weight: 700;
    border-radius: 0.65rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    color: var(--on-surface-elev, #e9def6);
    outline: none;
    transition: border-color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease, background-color 0.25s ease;
}
.otp-box:focus {
    border-color: var(--gold-bright-elev);
    box-shadow: 0 0 18px rgb(var(--acc-p1) / 0.45);
    transform: translateY(-2px);
}
.otp-box.is-filled {
    border-color: rgb(var(--acc-p1) / 0.55);
    background: rgb(var(--acc-p2) / 0.1);
}
.otp-boxes.is-error {
    animation: otp-shake 0.4s;
}
.otp-boxes.is-error .otp-box {
    border-color: rgba(248, 113, 113, 0.7);
}
@keyframes otp-shake {
    20%,
    60% {
        transform: translateX(-6px);
    }
    40%,
    80% {
        transform: translateX(6px);
    }
}
@media (prefers-reduced-motion: reduce) {
    .otp-boxes.is-error {
        animation: none;
    }
}

/* ═══ Sello "Acceso concedido" (creation-portal.js → mountSeal) ═══ */
.cp-seal {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    background: radial-gradient(circle at 50% 45%, rgb(var(--acc-s7) / 0.85), rgba(5, 3, 8, 0.92) 70%);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: var(--on-surface-elev, #e9def6);
    text-align: center;
    animation: cp-seal-in 0.35s ease both;
}
.cp-seal svg {
    overflow: visible;
    width: 5.5rem;
    height: 5.5rem;
}
.cp-seal-ring,
.cp-seal-check {
    fill: none;
    stroke: var(--gold-bright-elev);
    stroke-linecap: round;
    stroke-linejoin: round;
    filter: drop-shadow(0 0 10px rgb(var(--acc-p1) / 0.8));
}
.cp-seal-ring {
    stroke-width: 2.5;
    stroke-dasharray: 160;
    stroke-dashoffset: 160;
    animation: cp-seal-draw 0.5s ease forwards;
}
.cp-seal-check {
    stroke: rgb(var(--acc-p4));
    stroke-width: 3;
    stroke-dasharray: 40;
    stroke-dashoffset: 40;
    animation: cp-seal-draw 0.35s 0.35s ease forwards;
}
.cp-seal strong {
    font-family: var(--font-display-elev, 'Cinzel', serif);
    font-size: 1.35rem;
    letter-spacing: 0.08em;
    color: rgb(var(--acc-p4));
    text-shadow: 0 0 18px rgb(var(--acc-p1) / 0.6);
}
.cp-seal span {
    font-size: 0.85rem;
    color: var(--on-surface-dim-elev, #b8b8cc);
}
.cp-seal.is-static,
.cp-seal.is-static .cp-seal-ring,
.cp-seal.is-static .cp-seal-check {
    animation: none;
    stroke-dashoffset: 0;
}
@keyframes cp-seal-in {
    from {
        opacity: 0;
    }
}
@keyframes cp-seal-draw {
    to {
        stroke-dashoffset: 0;
    }
}

/* ═══ Velo del Portal ══════════════════════════════════════════════════════
   `templates/public/login.html.twig` pone `cp-veil` en el <body>: la página
   arranca "apagada" y solo quedan visibles la cruz (.gw-emblem), los dos
   títulos (.gw-kicker/.gw-title), el versículo (.verse) y la pista (.cp-hint).
   creation-portal.js cambia `cp-veil` por `cp-open` al tocar la cruz.

   Reglas de oro de este bloque:
   1. Se usa opacity/visibility/transform/filter — NUNCA display:none — para
      que el layout no cambie ni un píxel: la cruz tiene que quedar EXACTAMENTE
      en la misma posición antes y después de abrir.
   2. Las transiciones se declaran SOLO en `body.cp-open`, así el estado
      inicial no anima nada (evita el parpadeo del primer frame).
   3. El escalonado va por custom property (--cp-delay) en cada región.
   ═════════════════════════════════════════════════════════════════════════ */

body.cp-veil .gw-topbar,
body.cp-veil .stats-strip,
body.cp-veil .login-section,
body.cp-veil .gw-modules,
body.cp-veil .gw-bottomnav {
    opacity: 0;
    visibility: hidden;
    transform: translateY(18px);
    pointer-events: none;
    transition: none;
}

/* Lo que está "detrás del velo" también se disuelve, no solo se desvanece. */
body.cp-veil .stats-strip,
body.cp-veil .login-section {
    filter: blur(12px);
    -webkit-filter: blur(12px);
}

body.cp-open .gw-topbar,
body.cp-open .stats-strip,
body.cp-open .login-section,
body.cp-open .gw-modules,
body.cp-open .gw-bottomnav {
    transition:
        opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1) var(--cp-delay, 0ms),
        transform 0.55s cubic-bezier(0.16, 1, 0.3, 1) var(--cp-delay, 0ms),
        filter 0.55s ease var(--cp-delay, 0ms),
        visibility 0s linear var(--cp-delay, 0ms);
}

/* Escalonado: topbar → stats → login → grilla → bottom nav. */
body.cp-open .gw-topbar {
    --cp-delay: 0ms;
}
body.cp-open .stats-strip {
    --cp-delay: 70ms;
}
body.cp-open .login-section {
    --cp-delay: 140ms;
}
body.cp-open .gw-modules {
    --cp-delay: 210ms;
}
body.cp-open .gw-bottomnav {
    --cp-delay: 280ms;
}

/* La entrada escalonada de la grilla (.gw-fade, home.css) arranca en
   `opacity: 0` y corre al cargar: con el velo encima se consumiría invisible.
   Se congela mientras el velo está puesto y arranca recién al abrir. */
body.cp-veil .gw-fade {
    animation-play-state: paused;
}
body.cp-open .gw-fade {
    animation-play-state: running;
}

/* Con prefers-reduced-motion: sin desplazamiento, sin blur, sin escalonado. */
@media (prefers-reduced-motion: reduce) {
    body.cp-veil .gw-topbar,
    body.cp-veil .stats-strip,
    body.cp-veil .login-section,
    body.cp-veil .gw-modules,
    body.cp-veil .gw-bottomnav {
        transform: none;
        filter: none;
        -webkit-filter: none;
    }
    body.cp-open .gw-topbar,
    body.cp-open .stats-strip,
    body.cp-open .login-section,
    body.cp-open .gw-modules,
    body.cp-open .gw-bottomnav {
        transition: none;
        --cp-delay: 0ms;
    }
    body.cp-veil .gw-fade {
        animation-play-state: running;
    }
}
