Día del Maestro para Alejandra — Caso de Estudio

Un regalo digital single-view para una maestra de primaria. Una caja de crayolas 3D vibrando al centro de un cielo estrellado; al tocarla cae con confeti y revela cuatro crayolas que esconden mensajes dedicados, personalizados con los gustos de Alejandra. Construido sin frameworks, pensado para móvil, desplegado en Firebase Hosting.

HTML5CSS3Vanilla JavaScriptBootstrap 5.3Canvas-ConfettiCSS 3D TransformsFirebase Hosting

Demo Interactiva

La página original funcionando, embebida. Toca la cajita de crayolas: cae con confeti, aparecen cuatro crayolas y cada una tiene mensajes dedicados para Ale.

🖍️ Día del Maestro para Ale — demo interactiva

1. Descripción General

Cliente: Alejandra, maestra de primaria. Encargo personal para el Día del Maestro (México, 15 de mayo de 2026).

Problema: El detalle tradicional (flores, tarjeta, regalo material) no reflejaba lo que se quería transmitir: un mensaje único, íntimo y memorable que se sintiera hecho a la medida de la persona, no un regalo genérico.

Propuesta de solución: Una página web de un solo render que es en sí misma el regalo y la experiencia. Sin menús ni navegación, solo una interacción guiada: tocar la caja de crayolas y descubrir, con confeti y flores, mensajes que aluden a los gustos personales de Ale.

Resultado: Una experiencia completa en ~3 gestos (derribar la caja → ver el mensaje de regaño juguetón → elegir una crayola y leer su mensaje dedicado). Cero dependencias de frameworks, carga instantánea, prioridad móvil.

Anécdota: La base de este detalle se reutilizó de un proyecto personal anterior: la página del Día de la Primavera para Melissa (marzo de 2026). Comparando con mi detalle de primavera compartido con amigos, adapté el mismo patrón de single-view interactivo para esta experiencia del Día del Maestro.

2. Arquitectura

Visión General

Arquitectura estática pura. No hay backend, base de datos ni build tooling: tres archivos servidos tal cual por Firebase Hosting. Toda la lógica corre en el navegador como una pequeña máquina de estados manipulada por clases CSS.

┌─ Navegador (Firebase Hosting) ────────────────────────────┐
│  index.html  ──▶  style.css (3D box, crayons, states)      │
│        │               │                                    │
│        └──▶ script.js (máquina de estados)                  │
│                                                                │
│  [idle] → tocar caja ─▶ [fallen] ▸ confeti + lluvia de flores │
│                              └─▶ [spilled] crayolas visibles   │
│                                        └─ tocar crayola ─▶ modal
│                                                              │
│  (Bootstrap bundle + canvas-confetti desde CDN)              │
└────────────────────────────────────────────────────────────┘

Flujo de Interacción

1. Carga → fondo estrellado generado por JS, caja vibra (clase .vibrate)
2. Click/tap en caja → .fallen (rota -90° y se desplaza), confetti + flores
3. Título cambia a "¡Nooo! ¿Por qué las tiraste? 😱" (3s)
4. scene.gained .spilled → 4 crayolas visibles en posiciones rotadas
5. Título → "Venga, hay que recogerlas... ¡toma una! 🖍️"
6. Click/tap en crayola → modal Bootstrap con mensaje aleatorio de su array

Separación de Responsabilidades

CapaTecnologíaResponsabilidad
Escena & UIHTML5 + CSS3Caja 3D (transforms preserve-3d), crayolas, títulos, decoración
LógicaVanilla JavaScriptMáquina de estados, estrellas, flores, mensajes aleatorios por color
ModalBootstrap 5.3 (CDN)Presentación del mensaje dedicado con color de fondo dinámico
EfectosCanvas-Confetti (CDN)Explosión de confeti al derribar la caja

3. Tecnologías y Justificación

Estructura y Estilos

  • HTML5 + CSS3 (zero framework): Todo el modelado de la caja 3D se hace con CSS Transforms (`preserve-3d`, `rotateX/Y`, `translateZ`) y keyframes (`vibrate`, `twinkle`, `rise-up`, `galaxy-float`). Para un único render estático, un framework añadiría peso sin ventaja; CSS puro ofrece animaciones de GPU y carga instantánea.
  • Google Fonts (Fredoka + Nunito): Tipografías redondeadas y cálidas que refuerzan el tono infantil y afectivo del regalo.

Interacción

  • Vanilla JavaScript: Máquina de estados simple con un flag `hasFallen` y clases `.fallen` / `.spilled`. Sin estado global ni librerías; el `setTimeout` encadena las frases y el despliegue de crayolas.
  • Bootstrap 5.3 (solo modal): Componente modal accesible out-of-the-box, cargado puntual desde CDN para no re-implementar comportamiento de diálogo y close con `data-bs-dismiss`.
  • Canvas-Confetti: Librería ligera, única dependencia visual. Dispara una ráfaga de confeti con `origin` aleatorio al derribar la caja.

Despliegue

  • Firebase Hosting: Hospedaje estático gratuito con SSL y CDN global. Encaja perfecto con una página sin backend; el deploy es copiar los tres archivos.

4. Capturas de Pantalla

Próximamente: capturas de la escena inicial con la caja vibrando, el vuelco con confeti y flores, y el modal con mensaje dedicado. Mientras tanto puedes usar la demo interactiva de arriba.

Escena inicial — caja vibrando bajo cielo estrellado
Vuelco — confeti + lluvia de flores
Modal — mensaje dedicado según la crayola

5. Problemas Encontrados

Mensajes aleatorios por color

Problema: Cada crayola debía mostrar distintos mensajes sin repetirse y pensados por tema (azul = admiración, verde = dulces de guayaba, rojo = vocación, amarillo = piña). Un solo `data-message` estático hacía la experiencia pobre.

Solución aplicada: Cuatro arrays en JS (`messagesblue`, `messagesgreen`, `messagesred`, `messagesyellow`), uno por crayola. Al hacer click se elige un mensaje aleatorio del array correspondiente, con el `data-message` como fallback.

Interacción antes del vuelco

Problema: Las crayolas existen desde el inicio (opacity 0), pero no debían ser clickeables mientras la caja no hubiera caído.

Solución aplicada: Guarda en el handler: `if (!scene.classList.contains('spilled')) return;`. La bandera de estado se controla con la clase `.spilled`, así lógica y CSS hablan el mismo lenguaje.

Mobile-first y activación táctil

Problema: El regalo es principalmente para abrir en teléfono; en táctil no hay `hover` para dar feedback, y taps no siempre disparan `click` de inmediato.

Solución aplicada: `touchstart`/`touchend` con una clase `.active-touch` para feedback de prensa, y CSS `touch-action: manipulation` para eliminar el delay de 300ms del doble-tap de zoom.

Modal con color de fondo dinámico

Problema: Bootstrap modal incluía estilos claros que chocaban con el fondo oscuro y no reflejaban el color de la crayola.

Solución aplicada: Sobrescritura `.custom-modal` (border radius, sombra, color blanco) y `modalContent.style.backgroundColor = color` setea el color de la crayola en tiempo de ejecución.

6. Decisiones Técnicas Clave

Vanilla HTML/CSS/JS vs framework (React/Svelte)

Alternativas consideradas: React, Svelte o un bundler (Vite) para la mini-página.

Decisión: Archivos estáticos sin build tooling. Para un solo render con animaciones CSS, un framework añade tiempos de build, bundle y complejidad sin beneficio. El resultado es cargar inmediatay una única responsabilidad de mantenimiento.

Caja 3D con CSS Transforms vs canvas/WebGL

Alternativas consideradas: Three.js / WebGL, o animar con canvas 2D.

Decisión: CSS `preserve-3d` con seis caras. Para un objeto cúbico simple, CSS da profundidad 3D sin librerías ni overhead; el navegador acelera por GPU y funciona en móvil. WebGL quedaba sobredimensionado para una caja de crayolas.

Bootstrap modal vs modal custom

Alternativas consideradas: Implementar un diálogo propio con JS/CSS puro.

Decisión: Bootstrap modal desde CDN. Entrega focus trap, cierre con Esc, y semántica accesible sin escribirlo a mano. Trayendo ya el CSS de Bootstrap, la sobrescritura `.custom-modal` es mínima. El trade-off (una dependencia más) es aceptable.

7. Aprendizajes

  • Cero framework cuando el scope lo permite. Para una experiencia de un solo render, HTML/CSS/JS puro es la opción más simple, rápida y mantenible. El instinto de "meter un framework" no siempre es la respuesta; el scope mínimo justifica tolering cero infraestructura.
  • El contenido personalizado es el verdadero "regalo". La tecnología (3D, confeti, modal) es el envoltorio; lo que conecta emocionalmente son los mensajes escritos a la medida (Jane Austen, dulces de guayaba, piña). El detalle no está en el stack sino en lo que se dice.
  • Máquina de estados con clases CSS. Coordinar animaciones con entradas de usuario es más fácil cuando los estados (`.fallen`, `.spilled`) viven como clases: el CSS renderiza el estado y el JS lo alterna, sin desincronizar lógica y presentación.
  • El móvil es el primer ciudadano. `touchstart`/`touchend`, `touch-action: manipulation` y probar en pantalla real desde el inicio son lo que separa una demo de escritorio de un regalo que realmente se abre en un teléfono.

8. Documentación Técnica del Proyecto

Repositorio de la página original, desplegada en su propio proyecto Firebase (prideandcrayons). El README incluye el motivo del encargo, los detalles especiales para Ale y las tecnologías.

Demo interactivaAbre la página en su propia pestaña para jugar a pantalla completa