
Persiana
GratisCristal y luz · WebGL
La pieza
Un fondo de vídeo en bucle a pantalla completa: un haz de luz ámbar cae desde un claro entre nubes de tormenta, con motas de polvo en suspensión, sobre un mar oscuro de oleaje lento y con un barco diminuto en el horizonte. Es un vídeo generado con IA (Higgsfield) con cámara fija; el final se funde con el principio durante un segundo, así que el bucle no deja costura. Incluye MP4 de 1080p, WebM, una versión de 720p para móvil y el póster. La demo añade un velo para que se lea el texto, un titular mínimo en grotesca sin cursivas, una píldora de interfaz con pausa y progreso, y se detiene fuera de pantalla y con movimiento reducido (entonces muestra el póster). El prompt enseña a usarlo de fondo en cualquier web: atributos del vídeo, póster, móvil, velo y accesibilidad. Encaja en portadas de hoteles de costa, marcas náuticas, cine, fotografía, bodegas o cualquier hero cinematográfico.
Encaja bien en webs de
Antes de copiar
Cambia lo que quieras y copia: el prompt sale ya con el nombre, los colores y los textos de tu cliente. Lo que dejes en blanco se queda como en la demo.
Gratis y entero
Qué trae el prompt, por apartados
Tokens estimados para español (≈3,6 caracteres por token): sirven para orientarte, no son exactos.
# Recrea en un único archivo HTML: Haz de luz
Un fondo a pantalla completa: un haz de luz ámbar que cae entre nubes de tormenta sobre un mar oscuro, con un barco diminuto en el horizonte. Calma, escala y un punto de asombro.
Eres un desarrollador front-end creativo senior. Genera un único `index.html` autocontenido que reproduzca exactamente la pieza descrita: mismo layout, textos, colores y comportamiento. HTML, CSS y JS en un solo archivo, sin build, sin frameworks y sin librerías. Todos los valores numéricos de este documento son definitivos: úsalos tal cual. Responde solo con el archivo completo.
## Qué es
- **El fondo es un vídeo en bucle ya generado** (9,1 s, 24 fps, 1920×1080 y 1280×720). No lo generes tú: cárgalo desde las URL de la sección «Recursos». Muestra, con cámara fija, un haz de luz ámbar que cae desde un claro entre nubes de tormenta, motas de polvo en suspensión y un mar oscuro con oleaje, con un barco diminuto en el horizonte. **El bucle está cerrado**: el final se funde con el principio durante 1 s, así que el atributo `loop` no deja costura.
- **Encima**, un velo oscuro para legibilidad, un titular mínimo y una píldora de interfaz con progreso y botón de pausa.
- **Degradación**: sin vídeo se ve el póster; con `prefers-reduced-motion` el vídeo ni se descarga y se queda el póster.
## Recursos (vídeo y póster)
```js
const ASSETS = 'https://motionframe.app/assets/haz-de-luz';
```
| Archivo | Uso | Peso aprox. |
|---|---|---|
| `https://motionframe.app/assets/haz-de-luz/loop.webm` | VP9 1920×1080, primera opción en escritorio | 1,6 MB |
| `https://motionframe.app/assets/haz-de-luz/loop.mp4` | H.264 1920×1080, respaldo | 5,5 MB |
| `https://motionframe.app/assets/haz-de-luz/loop-720.mp4` | H.264 1280×720 para pantallas de ≤ 760 px de ancho | 1,7 MB |
| `https://motionframe.app/assets/haz-de-luz/poster.webp` | primer fotograma, 1920 px | 33 KB |
Si el vídeo vive en otro dominio y solo lo reproduces con `<video>` no hace falta CORS. Si prefieres alojarlo tú, copia los cuatro archivos a una carpeta pública y cambia solo `ASSETS`.
## Tokens de diseño
```css
:root{
--fondo:#060504; --tinta:#fff8ee; --tinta-2:rgba(255,248,238,.72); --linea:rgba(255,248,238,.2);
--acento:#ffb23e;
--sans:"Inter Tight", system-ui, sans-serif;
--curva:cubic-bezier(.16,.84,.24,1);
--gutter:clamp(18px, 4vw, 56px);
}
```
- Fuente de Google: `Inter Tight` 500/600/700, sin cursivas, con `display=swap`. Una sola familia para todo.
- Un único color vivo (`--acento`); el resto es negro, blanco y el ámbar y el negro del propio vídeo.
## Estructura y contenido
`main.escena` a sangre (`height:100svh`, `overflow:hidden`, `isolation:isolate`, fondo `var(--fondo)`). Dentro, apilados con `position:absolute; inset:0; width:100%; height:100%; object-fit:cover`:
1. `img` póster (`alt=""`, `aria-hidden="true"`), visible desde el inicio.
2. `video` con `muted loop playsinline preload="none" aria-hidden="true" disablepictureinpicture`. Empieza con opacidad 0 y pasa a 1 en 1,2 s cuando dispara `loadeddata`, de modo que el póster nunca parpadea.
3. Un `::after` de la escena (z-index 2, `pointer-events:none`) que hace de velo:
```css
.escena::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
background:
radial-gradient(90% 55% at 50% 38%, rgba(6,5,4,.5), transparent 75%),
linear-gradient(180deg, rgba(6,5,4,.55) 0%, rgba(6,5,4,.12) 38%, transparent 62%, rgba(6,5,4,.62) 100%)}
```
Encima (z-index 3):
- **Titular** centrado, `top: clamp(88px, 22svh, 220px)`: `h1` «Luz en plena <span>tormenta</span>» en Inter Tight 600, `font-size: clamp(46px, 8.2vw, 132px)`, `line-height:.94`, `letter-spacing:-.045em`, `text-wrap:balance`, `text-shadow:0 2px 44px rgba(6,5,4,.55)`. El `<span>` va en `var(--acento)`.
- **Píldora** centrada abajo (margen inferior `max(26px, env(safe-area-inset-bottom))`): `display:inline-flex; gap:14px; padding:8px 8px 8px 18px; border-radius:999px; border:1px solid var(--linea); background:rgba(14,10,6,.42); backdrop-filter:blur(10px)`, texto 13 px peso 500 en `--tinta-2`. Contiene, en orden: un punto de 7 px en `--acento` con `box-shadow:0 0 12px var(--acento)` que late (opacidad 1 → .35, 2,4 s), el texto «Haz de luz», una barra de progreso de 72×1 px (relleno `--acento`, `transform:scaleX(currentTime/duration)`) y un botón redondo de 34 px con iconos SVG de pausa y reproducir.
- Entrada: el titular y la píldora suben 18 px desde opacidad 0 y blur 8 px en 1,4 s con `--curva`; la píldora con retardo de 0,5 s.
## Código clave
```js
(() => {
const ASSETS = 'https://motionframe.app/assets/haz-de-luz';
const escena = document.getElementById('escena');
const video = document.getElementById('video');
const poster = document.getElementById('poster');
const pausaBtn = document.getElementById('pausa');
const pildora = document.getElementById('pildora');
const barraProg = document.getElementById('progreso');
const aviso = document.getElementById('aviso'); // <p class="oculto" aria-live="polite">
const reducido = matchMedia('(prefers-reduced-motion: reduce)');
const movil = innerWidth <= 760;
poster.src = `${ASSETS}/poster.webp`;
let visible = true, pausadoUsuario = reducido.matches, cargado = false;
function cargarVideo() {
if (cargado || reducido.matches) return; // movimiento reducido: solo el póster
cargado = true;
const fuentes = movil
? [['loop-720.mp4', 'video/mp4']]
: [['loop.webm', 'video/webm; codecs=vp9'], ['loop.mp4', 'video/mp4']];
for (const [f, tipo] of fuentes) {
const s = document.createElement('source'); s.src = `${ASSETS}/${f}`; s.type = tipo; video.appendChild(s);
}
video.preload = 'auto';
video.load();
}
function sincronizar() {
const debe = visible && !document.hidden && !pausadoUsuario;
if (debe) { cargarVideo(); if (video.paused && video.readyState >= 2) video.play().catch(() => {}); }
else if (!video.paused) video.pause();
}
function marcar() {
pausaBtn.setAttribute('aria-pressed', String(pausadoUsuario));
pausaBtn.setAttribute('aria-label', pausadoUsuario ? 'Reproducir el fondo' : 'Pausar el fondo');
pildora.dataset.pausa = String(pausadoUsuario);
aviso.textContent = pausadoUsuario ? 'Fondo en pausa' : 'Fondo en reproducción';
}
pausaBtn.addEventListener('click', () => { pausadoUsuario = !pausadoUsuario; if (!pausadoUsuario) cargarVideo(); marcar(); sincronizar(); });
new IntersectionObserver((es) => { visible = es[0].isIntersecting; sincronizar(); }, { threshold: 0.01 }).observe(escena);
document.addEventListener('visibilitychange', sincronizar);
reducido.addEventListener('change', () => { pausadoUsuario = reducido.matches; marcar(); sincronizar(); });
video.addEventListener('loadeddata', () => { video.classList.add('listo'); sincronizar(); });
(function tic() {
if (video.duration) barraProg.style.transform = `scaleX(${(video.currentTime / video.duration).toFixed(4)})`;
requestAnimationFrame(tic);
})();
marcar();
if (!reducido.matches) cargarVideo();
})();
```
## Interacción
- **Pausa**: el botón detiene el vídeo y el latido del punto; al pulsarlo otra vez vuelve a reproducir. Cambia su `aria-label` entre «Pausar el fondo» y «Reproducir el fondo» y muestra el icono contrario.
- Sin ratón ni scroll: el fondo es contemplativo.
## Cómo usarlo de fondo en cualquier web
1. **Contenedor**: una `section` con `position:relative; overflow:hidden; isolation:isolate; min-height:80svh` (o `100svh`). Nunca `100vh` a secas.
2. **Vídeo**: `<video muted loop playsinline preload="none" aria-hidden="true" disablepictureinpicture>` con `position:absolute; inset:0; width:100%; height:100%; object-fit:cover`. `muted` y `playsinline` son obligatorios para que arranque en iOS y Chrome. Nunca pongas `controls` ni `autoplay` si vas a gestionar la reproducción por script.
3. **Póster**: una `img` idéntica debajo del vídeo (o el atributo `poster`), de modo que siempre hay imagen antes de que el vídeo cargue y cuando no carga.
4. **Móvil**: en ≤ 760 px de ancho carga solo `https://motionframe.app/assets/haz-de-luz/loop-720.mp4` (1,7 MB). En escritorio, WebM primero y MP4 de respaldo con dos `<source>`.
5. **Velo**: una capa `::after` con degradados oscuros como la de arriba, siempre. El texto va encima con `position:relative; z-index:3`. Si el texto va a la izquierda, añade `linear-gradient(90deg, rgba(6,5,4,.6), transparent 55%)`.
6. **Pausa fuera de pantalla**: `IntersectionObserver` con umbral 0,01 que llama a `video.pause()` al salir y a `video.play()` al volver; también con `document.hidden`.
7. **Movimiento reducido**: con `prefers-reduced-motion: reduce` no descargues ni reproduzcas el vídeo (`preload="none"` y no añadas los `<source>`); queda el póster. Escucha el cambio de la preferencia en caliente.
8. **Botón de pausa**: el movimiento dura más de 5 s, así que ofrece siempre un botón visible (WCAG 2.2.2).
## Adaptación a móvil y tablet
- **≤ 760 px**: el progreso mide 44 px y el titular baja a `top: clamp(72px, 18svh, 150px)`. La píldora sigue centrada.
- `object-fit: cover` recorta los lados en vertical; la parte importante del encuadre (el haz de luz y el barco) queda en el centro.
- Sin scroll horizontal de 360 a 1920 px.
## Accesibilidad y movimiento reducido
- Con `prefers-reduced-motion: reduce`: el vídeo no arranca ni se descarga, se ve el póster, sin animaciones de entrada ni latido; el botón muestra «reproducir».
- `img`, `video` y la barra de progreso llevan `aria-hidden="true"`.
- Botón real con `type="button"`, foco visible (`outline:2px solid var(--acento)`), controlable con teclado.
- Contraste: texto `#fff8ee` sobre el cielo casi negro con velo (> 12:1).
## Rendimiento
- `preload="none"` hasta que la escena es visible; solo se descarga una fuente.
- Pausa del vídeo fuera de pantalla y con la pestaña oculta.
- Peso: HTML ≈ 8 KB; vídeo 1,6 MB (WebM) o 5,5 MB (MP4) en escritorio y 1,7 MB en móvil.
## Personalización
- **Color de acento**: `#ffb23e` en `:root`. Debe ser vivo y claro (luminancia > 45 %) para leerse sobre las nubes oscuras.
- **Texto**: `Luz en plena` y `tormenta` (2–5 palabras en total) y `Haz de luz`. Para dejar solo el fondo, borra `header.titular` y la píldora.
- **Virar el color**: `filter: hue-rotate(-12deg) saturate(.9)` sobre el `<video>` y el póster cambia el ámbar a rojos o dorados fríos sin tocar el archivo.
- **Más calma**: `video.playbackRate = 0.75` en `loadeddata`.
- **Alojamiento propio**: descarga los cuatro archivos y cambia solo `ASSETS`.
## Comprobación final
1. La escena llena la pantalla sin bordes en 1440×900, 390×844 y 1920×1080 y el vídeo vuelve a empezar sin salto visible.
2. Sin errores en consola; en la pestaña de red se pide un solo vídeo.
3. El texto se lee con claridad sobre las nubes y la píldora no tapa el haz de luz.
4. El botón de pausa detiene el vídeo y cambia su etiqueta accesible.
5. Con movimiento reducido solo se ve el póster y no se descarga el vídeo.
6. Al hacer scroll fuera de la escena o cambiar de pestaña, el vídeo se pausa.
7. En móvil se descarga `loop-720.mp4` y no hay scroll horizontal.Prueba en frío
Aún sin publicar para esta pieza
En la prueba en frío pegamos el prompt en Claude Sonnet 5.5, sin ayuda ni contexto, y comparamos lo que genera con la demo. Cuando esté hecha, aquí verás la captura, el veredicto y la fecha.
Paso a paso
Personaliza
Copia el Completo o el Lite
Pega e itera
Publica
Licencia en claro
Todas las piezas incluyen licencia de uso comercial. Usa el resultado tal cual en tus productos, encargos freelance o webs de clientes, sin atribución.
Puedes
No puedes
Es la misma licencia para lo gratis y lo Pro. La tienes entera en licencia de uso.
Preguntas frecuentes
Versión 1.0 · publicada el 01-10-2026