Academia Arcana — clon Pottermore con dominio público (2026-07-19)

Contexto: sitio interactivo tipo Pottermore construido en ~/nef/academia-arcana/ (vanilla HTML/CSS/JS, sin dependencias). Servir con python3 -m http.server 8743 --directory ~/nef/academia-arcana (ya registrado como academia-arcana en ~/.claude/launch.json).

PROYECTO: Academia Arcana
Ruta: ~/nef/academia-arcana/ (index.html, styles.css, app.js, data.js)

PREMISA
- Historia en 2ª persona, 7 capítulos, arco tipo "libro 1": huérfano →
  carta → mercado oculto → academia → misterio → guardián → cámara final.
- Todo dominio público: Merlín, Morgana (ciclo artúrico), Circe, Cerbero
  (mito griego), Baba Yaga (folclore eslavo), Nicolás Flamel (histórico),
  espejo encantado (cuento de hadas), acertijo de la esfinge.

MECÁNICAS
- Capítulos sellados: III y VI tienen acertijo (esfinge → "hombre";
  "cuanto más quitas..." → "agujero"); respuesta normalizada sin acentos.
- Capítulo IV = Ceremonia: quiz de 6 preguntas, 4 opciones barajadas,
  puntaje por casa, empate se resuelve al azar.
- Casas: Merlín/búho/sabiduría, Morgana/cuervo/ambición,
  Circe/loba/transformación, Baba Yaga/gato/astucia.
- Al elegir casa, el sitio entero se retiñe: `data-casa` en <html> +
  variable CSS `--casa`.
- Progreso en localStorage clave "academia-arcana"
  ({desbloqueado, resueltos, casa, comenzado}).

DISEÑO
- Paleta: hollín cálido #14100b, pergamino #e7d9bc, oro viejo #c9982f,
  lacre #8c2f26. Nada de azul-negro genérico ni gradientes AI.
- Tipos: Cinzel (display) + EB Garamond (cuerpo), Google Fonts.
- Firma visual: sello de lacre en portada. Los acertijos (cap III y VI) son
  PUERTAS DE MADERA con aldaba de bronce (SVG, rostro de guardián estilo
  Ravenclaw de Pottermore): "La aldaba pregunta" → respondes → la hoja gira
  sobre su gozne izquierdo (rotateY 3D) y revela el interior iluminado con el
  texto de éxito en oro. Respuesta incorrecta = temblor de la puerta.
- Capitular (drop cap) en color de casa.
- Responsive: índice lateral colapsa a fila de numerales romanos en móvil.
  prefers-reduced-motion respetado (sin giro ni temblor).

GOTCHA RESUELTO
- ALDABA_SVG debe declararse ANTES de `if(estado.comenzado) abrirGrimorio()`
  (top del archivo). Si el const queda debajo, TDZ: "Cannot access before
  initialization" al pintar el acertijo en carga. Consola no lo mostraba.

PENDIENTE SI SE RETOMA
- Fuentes autoalojadas si se quiere 100% local-first.
- Más acertijos / capítulos año 2 (el grimorio ya deja el gancho).