O que Página de Destino com Paralaxe faz?
Transforme um vídeo curto em uma landing page cinematográfica de tela única, onde o gesto de rolagem do usuário avança o vídeo quadro a quadro enquanto cinco cenas de texto dramáticas aparecem e desaparecem. O documento nunca rola de fato — a entrada de roda/touch/teclado é interceptada em JavaScript e convertida em progresso virtual de quadro.
Esta skill codifica os padrões comprovados na referência incluída em ../../examples/parasites/ (as landings github / lion / hope — três páginas funcionais construídas com esta mesma skill). Trate essa pasta como a verdade absoluta se algo aqui estiver ambíguo.
Onde esta skill se encaixa na pirâmide YUV.AI
parallax-landing-page está no nível médio da pirâmide de skills YUV.AI, ao lado de yuv-design-system, yuv-decks, yuv-viral-video e video-to-landing-page. O orquestrador de nível superior yuv-pilot roteia para cá sempre que um clipe de vídeo de 5–15s precisa se tornar uma landing page de rolagem única.
Esta skill traz sua própria linguagem visual (Anton + Caveat + Inter, paleta de acentos ouro/âmbar/accent/creme) — ela NÃO chama o yuv-design-system. Os dois sistemas coexistem: yuv-design-system é dono da paleta da marca em superfícies web/app/deck, parallax-landing-page é dono da estética cinematográfica de rolagem especificamente. Para landings de paralaxe YUV.AI, você pode OPCIONALMENTE adicionar uma marca d'água da fênix + a URL canônica do Linktree na área do rodapé como um fio condutor da marca — veja yuv-design-system/assets/ para o arquivo da marca d'água. NÃO troque a pilha de fontes Anton/Caveat pela paleta Neon do sistema de design — isso perderia a aparência característica.
O que você está construindo
Cada landing é uma viewport fixa com:
- Um canvas preenchendo a tela, desenhando um quadro por vez (cover-fit, DPR ≤ 2)
- 5 cenas de texto posicionadas absolutamente (kicker + headline Anton maiúscula + linha manuscrita Caveat), cada uma com sua própria janela de progresso de rolagem
- Uma navegação fixa com
PARALLAX // showcasee links para landings irmãs - Um carregador que pré-carrega todos os quadros antes de permitir a interação
- Uma sobreposição de vinheta + granulado de filme
- Uma dica de rolagem no final que desaparece quando o usuário começa a rolar
- Um contador de quadros no canto inferior direito (ex.
073 / 145) - Uma cena final que é a seção CTA — nenhuma seção
.endseparada abaixo
Peso total em q:v 2: aproximadamente 120–220 KB por quadro × número de quadros. Um clipe de 6s a 24 fps = 145 quadros ≈ 25 MB. Um clipe de 10s = 241 quadros ≈ 53 MB.
Local de salvamento
Padrão: ~/Documents/yuv-projects/landings/<slug>/ — sempre salve landings autônomas aqui para que você possa encontrá-las novamente. Substitua apenas se o usuário escolher explicitamente um local diferente OU se o Modo B (integrar no showcase examples/parasites/ existente) for selecionado.
mkdir -p ~/Documents/yuv-projects/landings
cd ~/Documents/yuv-projects/landings
# A skill cria <slug>/ aqui conforme extrai quadros e constrói o HTML.
Caminho final (Modo A — autônomo): ~/Documents/yuv-projects/landings/<slug>/.
Caminho final (Modo B — integrar): o diretório de showcase existente que o usuário escolheu.
Informe o caminho final ao usuário no final de cada construção.
Fluxo de trabalho
Há quatro fases. Não pule fases — cada uma alimenta a próxima.
Fase 1 — Descoberta
Confirme com o usuário:
- Caminho do vídeo — onde o MP4 de origem está.
- Slug — nome curto de pasta/arquivo (ex.
hope,marcus,desk). Uma palavra, minúscula, sem espaços. Isso se torna tanto o nome da pasta de quadros (<slug>/) quanto o nome do arquivo HTML (<slug>.html). - Tema / tópico — sobre o que é esta landing? Um lançamento de produto? Um momento pessoal? Um encontro com a vida selvagem? Você precisa disso para escrever o texto.
- Modo de projeto — autônomo (pasta nova) ou integrar no showcase de parasitas existente em
examples/parasites/(topo deste repositório). Se o usuário disser "adicione ao showcase", eles querem o Modo B abaixo. - Cor de acento — para o destaque do script/CTA:
gold(#f5b042),amber(#ff8a3d),accent(rosa #ff4d6d),cream(#f5e9d4), ou algo novo (adicione a:rootno style.css e escreva uma nova regra.script.<nome>).
Se o usuário não especificou alguns desses, proponha padrões e siga em frente — não pare em perguntas que eles podem responder quando virem o resultado.
Fase 2 — Extrair quadros
Execute o script de extração incluído. Ele analisa o vídeo com ffprobe e extrai cada quadro na resolução nativa com -q:v 2 (JPEG quase sem perdas), nomeando-os frame-001.jpg até frame-NNN.jpg (3 dígitos com zeros à esquerda).
python <skill>/scripts/extract_frames.py <video_path> <output_folder>
Exemplo:
python C:/Users/User/.claude/skills/parallax-landing-page/scripts/extract_frames.py \
C:/Users/User/Documents/parasites/hope/hope.mp4 \
C:/Users/User/Documents/parasites/hope
O script imprime um bloco de metadados JSON para stdout. Capture-o — você precisa de frame_count e suggested_scroll_budget para o HTML.
Por que -q:v 2: ezgif e ferramentas similares re-comprimem agressivamente (~55 KB/quadro). O ffmpeg nativo em q:v 2 dá ~120–220 KB/quadro nas mesmas dimensões — visivelmente mais nítido. Não reduza a escala; nunca aumente a escala (infla arquivos sem adicionar detalhes).
Por que a fórmula do orçamento de rolagem (≈26 px por quadro): mantém constante a sensação tátil de "pixels de rolagem por quadro avançado" em diferentes durações de clipe. 145 quadros → ~4200, 241 quadros → ~6300, 90 quadros → ~2500 (mínimo). O script calcula isso para você e limita a [2500, 8000].
Fase 3 — Criar a página
Leia o template em <skill>/assets/landing-page-template.html. É um arquivo funcional completo com marcadores {{PLACEHOLDER}} e comentários <!-- TODO: --> ao lado das partes criativas. Escreva um novo arquivo em <target>/<slug>.html com tudo substituído.
Checklist de substituição (cada placeholder deve ser substituído):
| Placeholder | O que colocar | Exemplo |
|---|---|---|
{{PAGE_TITLE}} | Título HTML <title> | Hope — O Coração Mais Rápido do Negev |
{{PAGE_DESCRIPTION}} | Meta descrição, uma frase | Um momento com Hope, a chita do Midbarium. |
{{SLUG}} | Nome da pasta (sem caminho, sem barra) | hope |
{{FRAME_COUNT}} | Número inteiro de quadros | 241 |
{{FRAME_COUNTER_TEXT}} | 001 / NNN com largura correspondente | 001 / 241 |
{{SCROLL_BUDGET}} | Inteiro do JSON do extrator | 6300 |
{{PREVIEW_FRAME_MID}} | Quadro do meio com zeros à esquerda | 121 |
{{PREVIEW_FRAME_END}} | Último quadro com zeros à esquerda | 241 |
{{LOADER_TITLE}} | Uma palavra, maiúscula | HOPE |
{{LOADER_SCRIPT}} | Linha manuscrita terminando em … | convocando o corredor… |
{{NAV_LINKS_HTML}} | Bloco completo de tags <a> para navegação | veja abaixo |
{{SCENE_N_*}} | Kicker, headline, linha manuscrita para cada uma das 5 cenas | veja guia de copy |
{{SCROLL_HINT_TEXT}} | Prompt de 2–4 palavras em maiúsculas | ROLE PARA CORRER |
{{CTA_BUTTONS_HTML}} | 2–4 tags <a class="cta"> | veja abaixo |
{{ACCENT_CLASS}} | Sufixo de cor de acento para .script.X e .cta.X | amber |
Leia references/copy-guide.md para os padrões cinematográficos de copy (formulação do kicker, comprimento da headline, tom da linha manuscrita). A copy é onde esta skill se destaca — copy genérica afundará uma animação linda.
Fase 4 — Conectar assets
Se a pasta de destino já tiver style.css e parallax.js (integração em showcase), não faça nada — eles são compartilhados. Caso contrário, copie ambos de <skill>/assets/ para a pasta de destino:
cp <skill>/assets/style.css <target>/style.css
cp <skill>/assets/parallax.js <target>/parallax.js
Se estiver integrando em um showcase existente, também siga os passos em references/showcase-integration.md — adicione um card ao index.html, adicione um link a cada barra de navegação das landings existentes e adicione o CTA em cadeia na cena final da landing anterior.
Informe ao usuário como visualizar:
Abra
<target>/<slug>.htmlviapython -m http.server 8000a partir da pasta pai (nãofile://— o Chromium pode contaminar o canvas com origens de imagem locais).
Contrato de arquivos
<target>/
├── <slug>/ # pasta de quadros
│ ├── <slug>.mp4 # o vídeo fonte (preservado)
│ ├── frame-001.jpg
│ ├── frame-002.jpg
│ └── … frame-NNN.jpg
├── <slug>.html # a landing page
├── style.css # compartilhado (cópia se autônomo)
├── parallax.js # compartilhado (cópia se autônomo)
└── index.html # o hub (apenas se autônomo ou integração)
O nome da pasta de quadros e o nome do arquivo HTML DEVEM compartilhar o mesmo slug — a opção folder na chamada new ParallaxPage({folder: '<slug>', ...}) da página é o caminho literal da pasta.
A API ParallaxPage (já está em parallax.js, não redefina)
new ParallaxPage({
folder: '<slug>', // pasta contendo frame-001.jpg, etc.
frameCount: 145, // inteiro
prefix: 'frame-', // sempre 'frame-' para esta skill
scrollBudget: 4200, // pixels de entrada acumulados para passagem completa
// opcional: padWidth (padrão 3), ext (padrão 'jpg')
})
A classe anexa automaticamente body.scrub-page (que trava a rolagem via CSS), pré-carrega todos os quadros, executa uma lerp orientada por RAF (fator 0.22) em direção ao quadro alvo derivado da rolagem e faz a transição de cenas cujos intervalos data-start/data-end incluem o progresso atual.
Restrições rígidas (os não-negociáveis)
Estas estão incorporadas na referência e quebram a experiência se violadas:
- 5 cenas, janelas de progresso fixas:
0.00–0.20,0.22–0.40,0.42–0.60,0.62–0.80,0.82–1.00. A lacuna de 0.02 entre as cenas é intencional — é um momento de "apenas a imagem, sem texto" entre os momentos. O herói (cena 1) e a final (cena 5) usamdata-fade="0.30"edata-fade="0.18"respectivamente para que durem mais nas bordas; as cenas do meio usam o padrão 0.25. - Nenhuma seção
.endabaixo do scrub. A cena final contém os CTAs. A página inteira é uma viewport fixa. - Anton + Caveat + Inter — Anton maiúscula para tudo em negrito, Caveat para acentos manuscritos (ouro/âmbar/creme), Inter para qualquer texto de corpo principal. Nunca substitua, nunca adicione uma quarta fonte.
- Branco off-white
#f5f1ea, nunca#fff— já está no CSS comovar(--text). - Nomes de quadros são
frame-NNN.jpgcom zeros à esquerda para a largura do total (3 dígitos é o padrão, pois clipes < 1000 quadros; o JS calcula automaticamente a largura do contador a partir do total). - O slug é o nome da pasta E o nome base do arquivo HTML —
hope/,hope.html. Sem exceções; as etapas de integração assumem isso.
Onde procurar quando você travar
- O showcase de referência incluído neste repositório:
examples/parasites/— github.html, lion.html, hope.html, style.css, parallax.js, index.html. Se sua saída divergir visivelmente desses, você se desviou; releia. references/copy-guide.md— como escrever as 5 cenas para que elas realmente pareçam cinematográficas.references/showcase-integration.md— edições exatas necessárias ao adicionar a um hub existente.assets/landing-page-template.html— a estrutura canônica com placeholders.assets/hub-template.html— usado apenas ao criar um showcase totalmente novo (3 cards do zero).
Dois exemplos reais de invocação
Autônomo: usuário tem um clipe único desk.mp4 e quer uma landing page.
- Pergunte slug + tema. Execute o extrator em
desk.mp4→./desk/frame-NNN.jpg. - Copie
style.css+parallax.jspara a raiz do projeto. - Crie
desk.htmla partir do template. Nav tem apenas um link: ele mesmo. - Pronto. Informe ao usuário para servir com
python -m http.server.
Adição em showcase: usuário adiciona hope.mp4 à pasta de parasitas existente.
- Slug =
hope. Extraia →hope/frame-NNN.jpg. (Reutilize style.css + parallax.js existentes.) - Crie
hope.htmla partir do template. - Execute a integração do showcase: adicione um terceiro card a
index.html, acrescente um linkHopeà barra de navegação emgithub.htmlelion.html, encadeie a cena final da landing anterior com um CTAPróximo: Hope →. - Se estiver introduzindo uma nova cor de acento, adicione-a a
:roote adicione regras.script.X+.cta.Xemstyle.css.