El misterio de la rata — rama hp-exp en academia-arcana (2026-09-26)
~/nef/academia-arcana/ ahora es repo git. Dos experiencias, una por rama;
el servidor es el mismo para ambas según el checkout activo:
python3 -m http.server 8743 --directory ~/nef/academia-arcana # http://localhost:8743
main→ Academia Arcana (grimorio dominio público, ver 2026-07-19).hp-exp→ El misterio de la rata: MVP de una página inspirado en la escena de la Casa de los Gritos (Prisionero de Azkaban). Descubrir que Scabbers = Peter Pettigrew y que Sirius es inocente.
MECÁNICAS (hp-exp)
- 6 hotspots invisibles sobre ilustración SVG propia (viewBox 1200×800,
wrapper con
aspect-ratio: 3/2para que los % de los hotspots coincidan siempre con el dibujo). Pulsan, se iluminan al hover, se apagan al encontrar. - Modal-pergamino por pista; contador “Pistas: n/6” con barra.
- Panel lateral: pistas arrastrables (DnD escritorio, tap-dos-veces móvil);
pares con texto propio en
CONEXIONES(data.js), resto usa genérico. - 6/6 desbloquea “Revelar la verdad”: overlay con transformación rata→Pettigrew (crossfade CSS), línea de tiempo de la traición y “SIRIUS BLACK ES INOCENTE”.
- Progreso en localStorage clave
misterio-rata({encontradas, conexiones, revelado}). Botón “Reiniciar misterio” (confirm + borrado). - Modo pista: 30 s sin actividad → resalta un hotspot pendiente; también hay botón “Pista” manual. El timer se resetea con pointermove/keydown.
- Ding mágico con WebAudio (3 senos E6/B6/E7 en cascada, sin archivos).
DISEÑO
- Paleta: noche 0d1220, papel e3d3ae, sepia 4a3a26, oro c9982f, luna f0e6c8. Cinzel + EB Garamond (mismas fuentes que Arcana).
- Escena: personajes a contraluz (siluetas + rim-light sepia), luna llena con halo, haz de luz, puerta rota con luz cálida, textura de papel con feTurbulence sobre toda la escena. Sin imágenes con copyright: todo SVG.
- Mobile-first; panel pasa a columna derecha 320px sticky a ≥960px.
- prefers-reduced-motion respetado (revelación sin animación, estados finales).
RESTILO “MOMENTO” POTTERMORE (2026-09-26, ref: youtube FmBvjQj_qgw = Pottermore Book 6 Ch 9 Moment 1 walkthrough)
- Escena full-bleed:
.escena-marcoes fixed inset 0, SVG conpreserveAspectRatio="xMidYMid slice"(recorta, nunca letterbox). - POSICIÓN DE HOTSPOTS: con slice los % se desalinean según el ratio del viewport. Se calculan en JS: escala = max(w/1200, h/800), desp = centrado, px = vb*escala + desp. Recalcular en resize (posicionarHotspots).
- PARALLAX: SVG reagrupado en 3
<g class="capa" data-depth="0.3|0.6|1">(fondo / personajes / luz+polvo). pointermove → objetivo ±18px/±12px, lerp 0.07 en rAF (arranca solo al mover, se duerme al asentarse). La capa se traslada en unidades viewBox = px pantalla / escala. Cada pista tieneprofundidaden data.js y su hotspot hereda el offset de su capa (inline transform incluye el -50% de centrado). - Pared extendida a 640 y suelo subido a 540: solape de 100px para que el parallax nunca abra grietas entre capas.
- Ambiente: motas de polvo flotando (CSS, duraciones escalonadas), halo de
luna respirando, viñeta radial fija (
.escena-marco::after). - Chrome mínimo: cabecera flotante con degradado y pointer-events:none (botones con auto), progreso como 6 pips dorados (no barra), panel = cajón lateral (“Tablero”, translateX; hoja inferior translateY en móvil) con velo clicable. Pausa de animaciones también con body.panel-abierto.
- body overflow hidden + 100dvh: la app es un lienzo, no una página.
- PENDIENTE: zoom con doble clic (sello Pottermore) quedó fuera a propósito.
HANDOFF DE ARTE (2026-09-26 — spec acordada para subir fidelidad Pottermore)
- Lo que más falta para el estilo del walkthrough es la ILUSTRACIÓN real; el SVG actual es placeholder. El código ya hace todo lo demás.
- Nef entrega en
~/nef/academia-arcana/assets/:escena-fondo.webp→ paredes, ventana, luna, puerta rotaescena-media.webp→ suelo, mesa, 5 personajes + Scabbersescena-frente.webp→ haz de luz, polvo/bordes cercanos (opcional)
- REGLAS: lienzo completo 2400×1600 (2× del viewBox 1200×800) en las 3 capas, transparencia, NO recortar objeto por objeto, pintar clean plate detrás de los personajes (si no, el parallax abre agujeros), NO hornear viñeta / textura de papel / brillos de hotspot (van en código). Paleta actual o pasar swatches nuevos para retintar la UI.
- Opcionales: brillos pintados por hotspot (crossfade hover, ej.
brillo-rata.webp) y loop de ambiente ~30 s. - Al llegar el arte: sustituir capas SVG por imágenes apiladas (slice / parallax / hotspots quedan igual), reajustar las 6 coordenadas a la nueva composición y añadir el zoom con doble clic.
ESTADO AL CERRAR SESIÓN (2026-09-26)
- hp-exp commiteado: 856b24a (restilo + fixes). main intacta: c32ac30.
- Sirviendo con
python3 -m http.server 8743 --directory ~/nef/academia-arcana. - Smoke test: 34 asserts, todos en verde (stub en /tmp, se regenera fácil).
GOTCHA DEL ENTORNO DE TEST
- No hay playwright/jsdom instalados. Smoke test con mini-DOM stub en
/var/folders/.../T/opencode/test-misterio-rata.js(24 asserts, todos pasan). - En node, dos
eval()seguidos NO compartenconst(en el navegador dos<script>sí). Concatenar data.js + app.js en un solo eval para testear.
GOTCHA RESUELTO (2026-09-26, modal trabado)
backdrop-filter: blur()sobre la escena SVG (que ya usa feTurbulence) re-muestrea todo el fondo en cada frame → el modal se trababa al abrir. Fix: quitar backdrop-filter (fondo rgba .82 basta) + pausar conanimation-play-statelos hotspots y el botón revelar mientrasbody.modal-abierto/body.revelandoestán activos. Regla: nunca backdrop-filter encima de SVG con filtros.
GOTCHA RESUELTO (2026-09-26, modal que no se cierra — EL BUG REAL)
.modal-fondo { display: grid }pisaba la regla UA[hidden]{display:none}: el modal estaba visible DESDE LA CARGA (vacío) yhidden=trueno lo ocultaba. “Guardar pista” sí ejecutaba cerrarModal() pero nada cambiaba en pantalla. Fix:.modal-fondo[hidden], .revelar-fondo[hidden] { display:none !important }.- Lección SPAB: el smoke test pasaba porque el stub verificaba la PROPIEDAD
hidden, no el display computado. Añadida guardia estática: el test lee styles.css y exige la regla [hidden] para ambos contenedores (26 asserts). - Regla: si un contenedor se oculta con el atributo hidden, no declararle display sin una regla [hidden] explícita que lo proteja.
PENDIENTE SI SE RETOMA
- Verla en navegador real y ajustar posiciones de hotspots a ojo (las coords están calculadas sobre el viewBox, pero el pulso puede tapar la rata).
- Fuentes autoalojadas si se quiere 100% local-first (mismo pendiente que Arcana).