PTENES
MÓDULO 3.1

🖱️ Marco, cursor y zoom

La capa de animación que transforma una captura estática en un recorrido guiado profesional: el marco de navegador, el cursor que apunta a la bounding box real, el clic con ripple, el zoom en el resultado y el house style dark premium ámbar.

7
Temas
30
Minutos
Avanzado
Nivel
Lectura
Tipo
canvas 1920×1080 · #appwin 🔒 localhost:8000 captura dentro de la ventana en (WIN_L, SHOT_T) objetivo (.hlbox) power3.inOut canvasX = WIN_L + sx · canvasY = SHOT_T + sy · punta = objetivo − (6,3)
1

🪟 El marco del navegador

Una ventana persistente rodea cada captura de pantalla; es lo que le da el aspecto de "navegador" y disimula que el contenido es una captura.

💡Concepto principal

La ventana #appwin vive en la bg-layer con data-layout-ignore: borde, radio, sombra grande, barra de título con 3 puntos (rojo/amarillo/verde) y una píldora de URL monoespaciada con candado + window.urlLabel. Las capturas de pantalla (1 clip por escena) quedan dentro de ella, en (WIN_L, SHOT_T) con tamaño VW×VH.

steps.json — bloque window
"window": {
  "top": 96,           // WIN_T — topo da janela no canvas
  "titleH": 52,        // altura da barra de título
  "urlLabel": "localhost:8000"
}
// derivados no build-demo.mjs:
WIN_L  = (1920 - VW) / 2     // centraliza horizontal
SHOT_T = WIN_T + TITLE_H     // topo do screenshot
✓HACER
  • ✓Marcar el marco con data-layout-ignore
  • ✓Usar la urlLabel real de la app capturada
  • ✓Mantener la ventana persistente (no recrearla en cada escena)
✗NO HACER
  • ✗Dibujar la captura de pantalla fuera del área de la ventana
  • ✗Cargar el sitio en vivo dentro del marco (el renderizado es determinista)
  • ✗Animar el marco como si fuera una escena
2

➡️ El cursor animado y el recorrido hasta el objetivo

Un único cursor global se desliza por la línea de tiempo principal y cae justo en el centro de la bounding box real del control.

💡Mapeo de coordenadas

La captura se ejecuta en un viewport fijo (p. ej., 1280×800) — toda bbox viene en este espacio. Un punto (sx, sy) del screenshot se convierte canvasX = WIN_L + sx, canvasY = SHOT_T + sy. El objetivo del cursor es el centro de la bbox mapeada.

tween del cursor (concepto)
// hotspot na ponta da seta ≈ (6,3) num SVG de 42px
const HOT = { x: 6, y: 3 };
// a PONTA cai no centro do alvo, não o canto
tl.to("#cursor", {
  x: alvoX - HOT.x,
  y: alvoY - HOT.y,
  duration: 0.7,
  ease: "power3.inOut"
}, s.start + 0.35);   // deixa a cena aparecer antes
📊
Por qué apuntar al bbox real

La bounding box viene de getBoundingClientRect() en la captura, no a partir de una estimación "a ojo". Eso es exactamente lo que hace que el cursor parezca profesional: cae justo en el píxel del botón o campo.

🧭
Cursor global
timeline principal
📍
Hotspot al final
(6,3)
📦
bbox real
getBoundingClientRect
〰️
power3.inOut
easing curvo
3

👆 El clic y el efecto visual

Cuando el cursor «hace clic», un pulso en el propio cursor y un ripple ámbar comunican la acción al espectador.

~start + 0.35scursor parte

El cursor sale de la posición anterior hacia el objetivo, dejando que la escena aparezca primero.

~start + 1.05sllega al objetivo

La punta aterriza en el centro de la bbox; el resaltado ya está pulsando alrededor del control.

~start + 1.15shaz clic

El cursor hace scale:.82 en yoyo (pulse) y el #ripple (el círculo ámbar) se expande y desaparece en el centro del objetivo.

⚡
Consejo práctico

Pasos solo de lectura (sin click:true) no activan el ripple — ideal para la pantalla inicial (intro:true), donde solo presentas la app sin interactuar.

4

🔍 Zoom y resaltado en la región activa

El resaltado dirige la mirada al control; el zoom hace un push-in cinematográfico en el momento del resultado.

🟨
.hlbox (destaque)

Rectángulo solo con box-shadow (anillo ámbar + glow) en el bbox mapeado con ~6px de margen. Aparece con back.out y pulsa el glow unas veces: enfoca sin cubrir nada.

🔎
zoom: true

En el paso del resultado, el <img> recibe scale 1 → 1.12 a lo largo de la narración, con transformOrigin en el centro del objetivo (p. ej., el panel de resultados).

steps.json — paso con zoom
{
  "shot": "04-result.png",
  "target": { "x": 668, "y": 128, "w": 484, "h": 324 },
  "zoom": true,
  "caption": "O resultado aparece pronto para baixar.",
  "narration": "E pronto: o resultado já está disponível."
}
📊
Ritmo recomendado

El último paso de contenido suele ser el resultado con zoom:true — un ligero «¡ta-dá!» que cierra el arco del walkthrough antes de la CTA.

5

🎨 Estilo visual premium oscuro ámbar

Una paleta cerrada de 6 colores con el ámbar como único acento dominante: la identidad visual de todos los videos.

#0D1321
fondo (--bg)
#1D2D44
panel (--bg2)
#3E5C76
borde (--bg3)
#F0EBD8
texto (--fg)
#FFC300
ámbar (--accent)
#2EC4B6
código (--code)
⚡
Regla del acento único

UN acento dominante: el ámbar. Aparece en el ripple del clic, en el anillo del resaltado, en el glow de fondo y en el CTA. El fondo es idéntico en todas las escenas: nunca es plano.

📊
Composición de video (no es web)

Capa de fondo persistente con data-layout-ignore: resplandor radial ámbar que respira, texto fantasma gigante que se desplaza, cuadrícula de líneas finas y grano. Escala grande: titular de 64–172px, elementos decorativos con 12–25% de opacidad.

6

🔤 Las fuentes incrustadas

Sora, Inter y JetBrains Mono como .woff2 locales — nunca CDN, porque el render es offline y determinista.

Aa
Sora 700–800

Títulos y titulares (geométrica, impacto).

Aa
Inter 400–600

Cuerpo y captions (alta legibilidad).

Aa
JetBrains Mono

Píldora de URL, valores y código.

🚨
Nunca Google Fonts vía CDN

El entorno de renderizado puede no tener internet. Las fuentes externas pueden fallar y alterar el aspecto visual. Las fuentes vienen de assets/fonts/ (subset latin cubre PT-BR); el build-demo.mjs inyecta el fonts.css reescribiendo las rutas.

🅰️
Sora
títulos
📝
Inter
cuerpo
⌨️
JetBrains
mono
📦
.woff2 local
offline-safe
7

⏱️ Sincronizar el tiempo de cada paso con la narración

El cursor responde a la narración: llega al objetivo antes de la explicación y hace clic en el momento adecuado, con un ritmo definido por LEAD/TAIL/FADE.

💡Ritmo recomendado

LEAD 0.5s — la escena aparece antes de que empiece la voz.

TAIL 0.7s — pausa después de que termina el audio.

FADE 0.4s — transición entre escenas.

El cursor llega al objetivo ~0.7s antes de la explicación principal; el clic ocurre cerca de start + 1.15s.

⚡
Mantén 5–8 pasos

Además, el video cansa y la captura y edición se convierten en un trabajo pesado. 5–8 pasos + CTA ≈ 35–50s — el tamaño ideal para un walkthrough.

🎯 Lo que aprendiste

  • ✓El marco #appwin rodea el shot y le da el aspecto de navegador
  • ✓El cursor global apunta al bbox real con el hotspot en la punta y easing curvo
  • ✓El clic activa pulse + ripple ámbar; el zoom hace un push-in sobre el resultado
  • ✓Paleta dark premium ámbar y fuentes locales Sora/Inter/JetBrains
  • ✓La sincronización LEAD/TAIL/FADE ajusta la animación a la narración

Próximo: Módulo 3.2 — cómo generar la narración local con Kokoro y montar todo con el build-demo.mjs.