/* ==========================================================================
   FX.CSS · efectos de las páginas internas (login, mapa, retos, admin)
   --------------------------------------------------------------------------
   Índice:
     1. Lupas de fondo
     2. Cara de Anonymous (NO TOCAR: dibujo y animaciones originales)
     3. Pantallas de Anonymous: cuenta atrás, game over y derrota (NO TOCAR)
     4. Mapa de pruebas
     5. Cajas y dígitos de la contraseña
     6. Vídeo de introducción
     7. Pantalla de victoria ("sistema restaurado"), estilo página de estado
   ========================================================================== */


/* ---------- 1. LUPAS DE FONDO ---------- */
.lupas { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.lupa {
  position: absolute;
  left: var(--x); top: var(--y);
  width: var(--s); height: var(--s);
  opacity: .38;
  transform: rotate(var(--r));
}
.lupa::before {                     /* lente */
  content: "";
  position: absolute; inset: 0;
  border-radius: 50%;
  border: calc(var(--s) * .07) solid #3c4250;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .1), 0 10px 30px rgba(0, 0, 0, .6);
  background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .18) 0 12%, rgba(255, 255, 255, .03) 30%, transparent 60%);
  backdrop-filter: brightness(1.5) contrast(1.1);
}
.lupa::after {                      /* mango */
  content: "";
  position: absolute;
  left: 50%; top: 96%;
  width: calc(var(--s) * .16); height: calc(var(--s) * .62);
  transform: translateX(-50%);
  border-radius: 0 0 calc(var(--s) * .08) calc(var(--s) * .08);
  background: linear-gradient(90deg, #1f232b, #4a3423 30%, #6b4a30 50%, #3b2a1c);
  box-shadow: 0 10px 20px rgba(0, 0, 0, .5);
}
@media (prefers-reduced-motion: no-preference) {
  .lupa { animation: flotar var(--d) ease-in-out infinite alternate; }
  .lupa:nth-child(2n) { animation-direction: alternate-reverse; }
}
@keyframes flotar {
  0%   { transform: translate(0, 0) rotate(var(--r)); }
  33%  { transform: translate(4vw, -3vh) rotate(calc(var(--r) + 12deg)); }
  66%  { transform: translate(-2vw, 4vh) rotate(calc(var(--r) - 8deg)); }
  100% { transform: translate(3vw, 2vh) rotate(calc(var(--r) + 4deg)); }
}
body.restaurada .lupas { display: none; }


/* ---------- 2. ANONYMOUS (NO TOCAR) ---------- */
.anon { display: block; width: 100%; height: auto; }
@media (prefers-reduced-motion: no-preference) {
  .anon .mandibula, .risa .mandibula { transform-box: fill-box; animation: reir .22s ease-in-out infinite alternate; }
  .risa { transform-box: fill-box; transform-origin: 50% 100%; animation: tembleque .5s ease-in-out infinite alternate; }
}
@keyframes reir { to { transform: translateY(9px); } }
@keyframes tembleque { from { transform: rotate(-5deg); } to { transform: rotate(5deg) scale(1.06); } }

/* Caras pequeñas que flotan por el fondo del mapa */
.caras { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.cara-flota { position: absolute; left: var(--x); top: var(--y); width: var(--s); opacity: .17; transform: rotate(var(--r));
  filter: drop-shadow(0 0 14px rgba(255, 46, 77, .55)); }
@media (prefers-reduced-motion: no-preference) { .cara-flota { animation: flotar var(--d) ease-in-out infinite alternate; } }
body.restaurada .caras { display: none; }


/* ---------- 3. PANTALLAS DE ANONYMOUS (NO TOCAR) ---------- */
.anon-pantalla, #gameover { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: #000; }
.anon-pantalla { background: rgba(0, 0, 0, .92); animation: aparece 2.8s forwards; }
.anon-pantalla .anon, #gameover .anon { width: min(62vw, 360px); filter: drop-shadow(0 0 40px rgba(255, 46, 77, .6)); }
@keyframes aparece { 0% { opacity: 0; transform: scale(.6); } 15% { opacity: 1; transform: scale(1); } 70% { opacity: 1; } 100% { opacity: 0; transform: scale(1.15); } }
#gameover { grid-template-rows: minmax(0, 1fr) auto; justify-items: center; padding: 1.5rem; }
#gameover .anon { align-self: center; }
/* Caja de diálogo estilo Undertale: la letra es JetBrains Mono (NO cambiar) */
.dialogo { width: min(780px, 100%); border: 4px solid #fff; background: #000; padding: 1.2rem 1.5rem; min-height: 9.5rem; margin-bottom: 1rem;
  font-family: "JetBrains Mono", "Courier New", monospace; font-size: clamp(1rem, 2.6vw, 1.5rem); line-height: 1.5; color: #fff;
  max-height: 42vh; overflow-y: auto; overflow-wrap: anywhere; }   /* el texto nunca se sale de la caja */
.dialogo a { color: #ff2e4d; }

/* Game over más teatral */
#gameover::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 40%, rgba(120, 0, 20, .45) 100%), repeating-linear-gradient(0deg, rgba(255, 255, 255, .03) 0 1px, transparent 1px 4px); }
#gameover .anon { width: min(70vw, 420px, 52vh); position: relative; }
@media (prefers-reduced-motion: no-preference) { #gameover .anon { animation: sacude .12s linear infinite alternate; } }
@keyframes sacude { from { transform: translate(-3px, 0); } to { transform: translate(3px, 2px); } }
.dialogo { position: relative; }

/* Escena de derrota: candado + cara llorando */
#derrota { position: fixed; inset: 0; z-index: 9999; display: grid; grid-template-rows: minmax(0, 1fr) auto; justify-items: center; padding: 1.5rem; background: #000;
  animation: fundido .5s; transition: opacity .9s; }
#derrota.sale { opacity: 0; }
#derrota.golpe { animation: golpe .4s; }
@keyframes fundido { from { opacity: 0; } }
@keyframes golpe { 20% { transform: translate(-10px, 6px); } 40% { transform: translate(9px, -6px); } 60% { transform: translate(-6px, 4px); } 80% { transform: translate(4px, -2px); } }
.escena-cara { position: relative; margin-bottom: 3rem; align-self: center; justify-self: center; width: min(64vw, 380px, 50vh);
  filter: drop-shadow(0 0 40px rgba(255, 46, 77, .5)); transition: opacity 1.6s, transform 1.6s; }
.escena-cara.se-va { opacity: 0; transform: translateY(60px) scale(.9); }
.escena-cara .anon { width: 100%; }
.candado { position: absolute; left: 50%; top: 56%; width: 48%; opacity: 0; transform: translate(-50%, -250%) rotate(-25deg);
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, .6)); }
.candado.cae { animation: candado-cae .6s cubic-bezier(.4, 1.5, .6, 1) forwards; }
@keyframes candado-cae { from { opacity: 1; transform: translate(-50%, -250%) rotate(-25deg); } to { opacity: 1; transform: translate(-50%, 0) rotate(0); } }


/* ---------- 4. MAPA DE PRUEBAS ---------- */
/* La ruta de puntos avanza despacio hacia delante */
.camino .ruta { stroke: color-mix(in srgb, var(--acento) 40%, transparent); animation: fluir 1.6s linear infinite; }
@keyframes fluir { to { stroke-dashoffset: -20; } }
/* Aro que late alrededor de la prueba disponible */
.nodo .pulso { fill: none; stroke: var(--acento); stroke-width: 2; transform-box: fill-box; transform-origin: center; animation: pulso 1.8s ease-out infinite; }
@keyframes pulso { from { transform: scale(1); opacity: .8; } to { transform: scale(1.45); opacity: 0; } }
/* Pruebas bloqueadas: borde rojo discontinuo con la cara de Anonymous dentro */
.nodo--bloqueado { opacity: 1; }
.nodo--bloqueado > circle { stroke: var(--alerta); stroke-dasharray: 8 6; fill: #0b0d12; }
.nodo--bloqueado text { fill: var(--alerta); font-size: 22px; }


/* ---------- 5. CAJAS Y DÍGITOS DE LA CONTRASEÑA ----------
   Panel como ventana de terminal: borde fino, sin brillo ni esquinas decorativas. */
body.averiada .panel, body.averiada .digito {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background-image: repeating-linear-gradient(0deg, rgba(255, 255, 255, .02) 0 1px, transparent 1px 4px);
}
.digito { border-style: solid !important; font-family: var(--font-title); }
.digito b { color: var(--alerta); min-width: 1ch; }              /* cifrado: rojo y cambiando */
.digito--abierto b { color: var(--acento); }                      /* descifrado: verde */
.digito--abierto { border-color: var(--acento) !important; }


/* ---------- 6. VÍDEO DE INTRODUCCIÓN ---------- */
.video-caja { background: #000; border: 1px solid var(--borde); aspect-ratio: 16 / 9; display: grid; place-items: center; }
.video-caja video { width: 100%; height: 100%; }


/* ---------- 7. VICTORIA: "CASO CERRADO" ----------
   Idea: la web vuelve y el expediente se archiva. Una hoja mecanografiada (misma
   letra de máquina que los documentos de la portada) con sello verde de "RESUELTO",
   una nota a mano y, al lado, el registro de tiempos como un ticket con puntos
   suspensivos. Las fichas de la contraseña están un pelín torcidas, como puestas a mano.
   Los colores vienen del tema body.restaurada (style.css). */
body.restaurada main > h1.glitch { display: block; font-size: clamp(2rem, 5vw, 3rem); margin: 2rem 0 .6rem; }
body.restaurada main > .antetitulo { margin-top: 1.2rem; }

/* Contraseña: 12 fichas de papel con la letra mecanografiada */
body.restaurada .digitos { grid-template-columns: repeat(auto-fit, minmax(46px, 1fr)); max-width: 760px; margin: .6rem 0 2.2rem; gap: .6rem; }
body.restaurada .digito { background: var(--panel); border: 1px solid var(--borde) !important; border-radius: 2px; padding: .4rem 0 .3rem; box-shadow: 1px 2px 0 rgba(60, 50, 30, .18); }
body.restaurada .digito:nth-child(odd)  { transform: rotate(-1.2deg); }
body.restaurada .digito:nth-child(even) { transform: rotate(.9deg) translateY(1px); }
body.restaurada .digito b { font-family: var(--font-maquina); font-weight: 400; color: var(--texto); }
body.restaurada .digito small { font-family: var(--font-maquina); }

.victoria { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 2rem; align-items: start; margin: 0 0 4rem; }
@media (max-width: 820px) { .victoria { grid-template-columns: 1fr; } }

/* Hoja del informe */
.informe {
  position: relative; padding: 2rem 2rem 2.2rem;
  background: var(--panel); color: var(--tinta);
  border: 1px solid var(--borde);
  font-family: var(--font-maquina);
  box-shadow: 2px 3px 0 rgba(60, 50, 30, .14), 0 18px 30px -18px rgba(60, 50, 30, .45);
  transform: rotate(-.6deg);
}
.informe-cab { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding-bottom: .5rem; margin-bottom: 1.4rem; border-bottom: 2px solid var(--tinta); font-size: .9rem; letter-spacing: .08em; }
.informe h2 { font-family: var(--font-maquina); font-weight: 400; font-size: clamp(1.5rem, 3.4vw, 2rem); margin: 0 0 .8rem; }
.informe p { color: var(--tinta); max-width: 46ch; margin: 0 0 1.4rem; font-size: 1.05rem; line-height: 1.55; }
.ficha { margin: 0 0 1.4rem; padding: 0; font-size: 1.02rem; }
.ficha div { display: flex; gap: .6rem; align-items: baseline; padding: .25rem 0; }
.ficha dt { color: var(--texto-suave); flex: none; }
.ficha dt::after { content: ":"; }
.ficha dd { margin: 0; font-weight: 700; }
.informe .nota-mano { font-family: var(--font-mano); font-size: 1.7rem; color: #2f4e8a; margin: 0 0 1.4rem; transform: rotate(-2deg); transform-origin: left; }
.informe .btn { font-family: var(--font-title); }
/* Sello verde de "RESUELTO", ligeramente girado y semitransparente como tinta real */
.sello-ok {
  position: absolute; top: 6.6rem; right: 1.4rem;
  padding: .2rem .7rem; border: 3px solid var(--acento); border-radius: 4px;
  color: var(--acento); font-family: var(--font-maquina); font-size: 1.5rem; letter-spacing: .12em; text-transform: uppercase;
  transform: rotate(8deg); opacity: .82; mix-blend-mode: multiply;
}
@media (max-width: 520px) { .sello-ok { position: static; display: inline-block; margin-bottom: 1rem; } }

/* Registro de tiempos: ticket con puntos suspensivos */
.registro { padding: 1.4rem 1.4rem 1.6rem; background: #fff; border: 1px solid var(--borde); font-family: var(--font-maquina); box-shadow: 1px 2px 0 rgba(60, 50, 30, .14); transform: rotate(.7deg); }
.registro h3 { font-family: var(--font-maquina); font-weight: 400; font-size: 1.1rem; letter-spacing: .1em; text-transform: uppercase; text-align: center; margin: 0 0 1rem; padding-bottom: .6rem; border-bottom: 2px dashed var(--borde); }
.tiempos { list-style: none; padding: 0; margin: 0; font-size: .98rem; }
.tiempos li { display: flex; align-items: baseline; gap: .4rem; padding: .18rem 0; color: var(--texto); }
.tiempos i { flex: 1; border-bottom: 2px dotted var(--borde); transform: translateY(-.2em); }
.tiempos b { font-weight: 400; font-variant-numeric: tabular-nums; }


/* ---------- 8. DERROTA: "CASO FALLIDO" ----------
   Tras las burlas del game over, la pantalla negra se convierte en el mismo informe de cierre que al ganar
   (papel, máquina de escribir, registro de tiempos), pero con el sello rojo de FRACASO y las pruebas que faltaron. */
#gameover.gameover--informe {
  display: block; overflow-y: auto; padding: 2.5rem 1rem 5rem; color: var(--texto); animation: fundido .7s;
  --fondo: #ece7da; --panel: #fbf8ef; --borde: #cdc4ae; --texto: #2a2620; --texto-suave: #6d6556; --acento: #2b7a4b; --alerta: #b3261e; --sobre-acento: #fff;
  background: radial-gradient(rgba(60, 50, 30, .13) 1px, transparent 1.4px) 0 0 / 22px 22px, #e6dfcd;
}
#gameover.gameover--informe::before { position: fixed; background: radial-gradient(ellipse at center, transparent 55%, rgba(140, 10, 20, .28) 100%); }
.fracaso-hoja { position: relative; width: min(1100px, 100%); margin: 0 auto; }
.fracaso-hoja .victoria { margin: 0; }
.fracaso-hoja .texto-alerta { color: var(--alerta); }
.sello-fracaso { border-color: var(--alerta); color: var(--alerta); font-size: 1.9rem; transform: rotate(-9deg); }
.tiempos li.falta { color: var(--alerta); }
.tiempos li.falta span { text-decoration: line-through; text-decoration-thickness: 2px; }
.tiempos li.falta b { font-style: italic; }
@media (prefers-reduced-motion: no-preference) {
  .sello-fracaso { animation: sello-golpe .45s cubic-bezier(.3, 1.6, .5, 1) .5s both; }
  .fracaso-hoja .informe { animation: hoja-cae .6s cubic-bezier(.2, 1.2, .4, 1) both; }
  .fracaso-hoja .registro { animation: hoja-cae .6s cubic-bezier(.2, 1.2, .4, 1) .15s both; }
}
@keyframes sello-golpe { from { opacity: 0; transform: rotate(-9deg) scale(2.6); } }
@keyframes hoja-cae { from { opacity: 0; transform: translateY(-40px) rotate(-3deg); } }
