Três a seis vídeos curtos em grade de três colunas. Cada card é uma capa 16:9 com o título, a duração e o rótulo de episódio dentro da imagem, e um anel de play no canto. No clique, um <dialog> nativo cobre a tela e entrega um <video> com os controles do navegador.
O que ela resolve: publicar vários vídeos curtos — corte de live, comentário de mercado, aula de dez minutos — numa página que não é sobre vídeo. A pessoa precisa escolher um entre vários, e para escolher precisa saber quanto tempo cada um custa e onde ele está na série. É por isso que a duração é dado obrigatório e não enfeite.
Quando usar
- Série de conteúdo em vídeo que ganha item novo toda semana: comentário de mercado, cortes de live, respostas rápidas.
- Trilha de aulas curtas de educação financeira, onde a ordem importa e cada aula tem duração diferente.
- Quando existem três a seis vídeos publicados e todos merecem estar visíveis ao mesmo tempo. Com um vídeo só, é o
midia/showreel-expansivel; com vinte, a página precisa de busca e paginação, que esta peça não tem. - Quando cada vídeo é autossuficiente: nada fora dele explica o que ele diz.
Quando não usar
- Um vídeo só —
midia/showreel-expansivel. Ele éitens [1,1], a capa é a peça gráfica da dobra e a coreografia dele cresce do lugar exato daquela capa. Repetir aquilo seis vezes seria seis coreografias a manter iguais. - Vídeo como superfície da primeira dobra —
hero/video-fundo. Ali o vídeo é textura, toca em laço, sem som, e ninguém escolhe nada. - Depoimento em vídeo —
prova/depoimento-video. Lá o conteúdo é a fala de uma pessoa, e a citação tem de estar legível sem clique, porque quem não ouve também precisa receber a prova. Aqui o conteúdo só existe no vídeo; não há transcrição na dobra, e por isso a peça não serve para prova social. - Faixa de fotos ou cases cujo destino é outra página —
midia/galeria-scroll-horizontal. Ver a comparação abaixo: é o irmão de que este componente mais precisa se distinguir. - Card com texto, foto, tags e CTA no detalhe —
overlay/card-expansivel-fullscreen. O detalhe dele é conteúdo escrito, carregado nosdata-*do próprio card. Ele não toca vídeo. - Vinte vídeos, ou uma videoteca. Grade de seis é um índice curado. Videoteca pede filtro, busca e paginação, e nada disso está aqui.
Por que não é o galeria-scroll-horizontal com uma thumb de vídeo
A pergunta é justa, porque as duas peças são cards de mídia numa dobra. Ela se responde com quatro diferenças que não são de aparência.
midia/faixa-videos |
midia/galeria-scroll-horizontal |
|
|---|---|---|
| Onde está o conteúdo | no vídeo, nesta página | em outra página, do outro lado do clique |
| Elemento do card | <button> + aria-haspopup="dialog" |
<a href> |
| Duração | obrigatória, em <time> e lida por leitor de tela |
não existe |
| Ordem | é informação — <ol>, episódio e data |
explicitamente fora de ordem (capitulos-navegaveis) |
| Forma | grade de 3 colunas, tudo visível | trilho que sangra, com scroll-snap |
| Gesto de play | anel de play, sempre visível | não existe |
O que decide não é a thumb: é o destino. Um card cujo conteúdo está do outro lado do clique é uma âncora, e uma âncora promete navegação — Enter navega, o meio do mouse abre em outra aba, o histórico ganha uma entrada. Um card cujo conteúdo abre aqui é um botão, e o que ele precisa entregar é o contrato de sobreposição: foco preso, Esc, foco de volta no card que abriu, página inerte. Trocar o <a> do irmão por um <button> já não seria uma variação dele — seria mudar o elemento, o aria, o teclado e o que acontece ao fechar.
Somam-se dois requisitos que uma galeria de fotos não tem e nunca vai ter. Duração: sem ela, uma lista de vídeos é uma lista de compromissos de tamanho desconhecido, e "8 min" muda a decisão de quem tem cinco minutos. Ordem de episódio: capitulos-navegaveis no irmão significa, na letra do vocabulário, "frentes que a pessoa pode querer acessar FORA de ordem" — o oposto de uma série, onde o episódio 12 é o mais novo e é por ele que se começa. Daí <ol> e não <ul>.
E há a diferença de forma que vem do uso: grade, não trilho. Um trilho esconde metade da lista fora da tela, e índice do qual não se vê o fim não é índice. Quem chega numa faixa de vídeos quer varrer a lista com o olho e escolher; quem chega num trilho de cases quer ser conduzido.
Padrão editorial
| Slot | Regra |
|---|---|
| Olho | 2 a 3 palavras. Diz a cadência da série, não o assunto: toda quinta, aulas curtas. É a informação que o card não tem espaço para repetir seis vezes |
| Título | 3 a 6 palavras. O nome da série, com uma palavra em <em> |
| Apoio | 1 a 2 frases. A segunda é o lugar da ressalva de natureza do conteúdo — comentário, não recomendação |
| Título do vídeo | 6 a 12 palavras, por item. Informa o que muda, nunca promete resultado |
| Duração | 4 a 9 caracteres, por item. A duração real, no formato 8 min |
| Rótulo de série | 8 a 20 caracteres, por item. Episódio, data, ou os dois: Ep. 12 · 28 ago |
| Alt da capa | por item, no atributo alt do <img>. Descreve a cena, não o vídeo |
Itens: 3 a 6. Três e seis fecham a fileira; quatro e cinco deixam a última incompleta — o que num índice que cresce toda semana lê como "tem mais vindo", e não como erro de montagem.
O título informa, não promete. O que muda na renda fixa com a Selic em queda serve. Como dobrar seu patrimônio não serve, e não é questão de gosto: é o §4 do briefing e a razão pela qual esta biblioteca não escreve superlativo de mercado.
O título vai dentro da capa, e é isso que limita o tamanho. Acima de 12 palavras ele vira três linhas e a legenda come metade da imagem. Não há corte de linha no CSS de propósito — título truncado no meio de uma palavra é pior que título de três linhas —, então o teto é da copy.
A duração é a informação que decide o clique. Ela não pode ser arredondada para ficar bonita, e não pode ficar velha quando o arquivo é trocado. Duração que não bate com o vídeo é enfeite que mente, e derruba a confiança nas outras cinco.
O rótulo de série tem a mesma forma em todos os cards. Se um traz episódio e o outro só a data, o rótulo deixa de ordenar e passa a ser decoração.
Todos os títulos escritos juntos, na mesma sessão. A legenda é o único texto do card, e comprimentos muito diferentes fazem a linha de base dançar entre um card e o vizinho.
Especificação dos assets
Capas e vídeos não atravessam (§11 do contrato): o preview usa os placeholders de showroom/demo/, e o que segue é a especificação do asset real.
| Asset | Especificação |
|---|---|
| Capa | 16:9, 1600×900 ou maior, WebP ou JPEG. Uma por vídeo. É um quadro do próprio vídeo — e de preferência não o primeiro, que costuma ser preto ou vinheta |
| Vídeo | mp4 com H.264, 1920×1080. Um webm adicional é bem-vindo e não obrigatório. Áudio normalizado entre os episódios: seis vídeos com volumes diferentes obrigam a mexer no controle a cada clique |
| Legenda | um .vtt por vídeo, em data-fvid-vtt. Não é opcional onde há fala |
Peso alvo: capa abaixo de 90 KB. Seis capas são o peso real desta dobra, e são a única coisa que ela baixa antes de alguém clicar.
Composição / enquadramento: o texto do card cobre a faixa inferior da capa e o anel de play ocupa o canto superior direito (46 px). Medido na coluna de 348 px: a capa tem 197 px de altura e a legenda ocupa os 100 px de baixo — metade —, dos quais só os 44% inferiores são véu opaco; o resto é a máscara em degradê apagando. Na prática: o terço de cima da capa é o único espaço limpo, e é onde tem de estar o que interessa no quadro — rosto, gesto, o gráfico de que o vídeo fala. Nada essencial na metade de baixo.
O que a capa não pode ter:
- texto queimado na imagem — título, duração, nome de episódio, "assista agora". O card já escreve tudo isso por cima, e o resultado é texto sobre texto;
- botão de play desenhado no quadro — o componente desenha o dele, e dois play no mesmo card é um deles que não funciona;
- tarja preta em cima ou embaixo (vídeo 4:3 exportado em moldura 16:9): o
object-fit:coveramplia a tarja em vez de removê-la; - logo de instituição real, marca de terceiro, rosto sem autorização de uso de imagem — nada disso atravessa, mesmo que o original tenha.
Como usar
<link rel="stylesheet" href="componentes/midia/faixa-videos/estilo.css">
<script src="componentes/midia/faixa-videos/script.js"></script>
Cole a <section> inteira — o <dialog> vem dentro dela, como último filho, e é assim que tem de ficar. Duas razões, e as duas foram medidas: é fora do .wrap e fora de todo [data-rv], então nenhum ancestral com filter o alcança; e é filho da própria seção, o que deixa o script achá-lo a partir da raiz — é isso que permite duas faixas de vídeo na mesma página, cada uma com o seu reprodutor.
O <dialog> leva três classes, nesta ordem: class="dialog-casca fvid-dialog sec-deep".
dialog-cascaé a primitiva do core (base.css, já na lista de dependências): zera padding, borda, fundo e os limites de tamanho que o navegador dá de graça ao<dialog>, e pinta o::backdrop.fvid-dialogé a forma desta peça: o palco de tela cheia, odisplayde[open]e o grau do véu.sec-deepé escopo de tom no markup — a exceção nomeada do §3. Sem ele o diálogo cai nocolor: CanvasTextdo navegador e a legenda do palco fica preta sobre fundo escuro.
Depois, por card: troque a capa e o alt, escreva título, rótulo e duração (o texto e o datetime), e aponte data-fvid-src para o arquivo do vídeo. data-fvid-vtt para a legenda.
Ganchos
| Gancho | Papel |
|---|---|
[data-fvid] |
a <section>. O script parte daqui, sempre |
[data-fvid-card] |
cada <button> de capa |
data-fvid-src |
no card — endereço do vídeo daquele item. Ausente: o diálogo abre com o poster e nada toca |
data-fvid-vtt |
no card — endereço do .vtt daquele item. Opcional no markup, obrigatório onde há fala |
[data-fvid-dialog] |
o <dialog> da seção |
[data-fvid-palco] |
a caixa que entra em cena. Recebe .is-entrando |
[data-fvid-video] |
o <video> compartilhado |
[data-fvid-fechar] |
o botão de fechar |
--fvid-min |
largura mínima da coluna. 320px — é ela que decide 3, 2 ou 1 coluna |
--fvid-gap |
vão da grade |
--fvid-tempo |
duração das transições de interação. .55s |
--fvid-play-size |
diâmetro do anel de play. 46px, 40px no mobile |
--fvid-entrada |
duração da entrada do palco. .5s |
--fvid-veil-mix |
grau do véu do ::backdrop. 88% — mais escuro que os 78% da casa, e de propósito |
--fvid-cromo |
altura que a legenda do palco e os respiros comem acima do quadro. 108px, 92px no mobile |
.is-entrando |
dispara a entrada do palco |
Os slots .fvid-palco-serie e .fvid-palco-titulo não são gancho de autoria: nascem vazios e o script os escreve com o rótulo e o título do card que abriu. Escrever neles à mão é trabalho perdido no primeiro clique.
Variações
- Duas colunas —
--fvid-min: 460pxno.fvid. Capa maior, legenda com mais ar; bom para quatro vídeos em vez de seis. Acima de520pxa grade cai para uma coluna no notebook, o que não é o que se quer. - Sem reprodutor — troque cada
<button class="fvid-card">por um<a class="fvid-card">apontando para a página daquele vídeo, apague o<dialog>e não cole oscript.js. A peça vira índice que leva a uma página por vídeo. É a forma certa quando cada vídeo tem transcrição, comentários ou material de apoio — e é o único caminho com piso sem JavaScript. - Grão sobre a capa — um
<span class="grain" aria-hidden="true"></span>dentro do.fvid-card, antes da.fvid-legenda. - Em dobra clara —
.sec-paperna seção; o<dialog>mantém o.sec-deep. O card não muda. - Player externo —
<iframe>no lugar do<video>, e o script escrevendo nosrcdo frame. Perde-se a pausa ao fechar e o controle depreload, e a CSP do site precisa liberar o frame. - Vertical 9:16 —
.fvid--verticalna seção (o markup está nopreview-extra.html). Para cortes no formato do celular: reels, corte de live, depoimento gravado em pé. A capa e o quadro do diálogo viram 9:16 pelos dois parafusos de proporção,--fvid-pwe--fvid-ph— que nasceram nesta variação: antes o 16:9 estava cravado em três regras. A coluna mínima cai para 220px, e a grade acomoda quatro por fileira (medido: 255×451 a 1440px); no celular, duas colunas (167×295), nunca uma — uma capa 9:16 na largura do celular mede 620px. O palco do diálogo já sabia lidar, porque a conta de largura usa a razão: a 1440×900 o quadro sai com 446×792. Teto editorial do título cai para 8 palavras. Referência: os cortes de motion do portfólio do Dudes Becker. Experimental.
Gotchas
-
displaysó em.fvid-dialog[open]. O<dialog>nascedisplay:nonena folha do agente do usuário, e qualquer regra de autor comdisplayvence essa —.fvid-dialog{display:grid}deixaria o reprodutor visível o tempo todo, com a página rolando por baixo. É a armadilha do §6.5 na versão do elemento nativo. -
removeAttribute('src'), nuncasrc=''. String vazia resolve contra a URL da página: o navegador tenta carregar o próprio HTML como mídia e escreve um erro de mídia no console. Semsrce sem<source>, a especificação manda oload()ir paraNETWORK_EMPTYe abortar, sem evento de erro — que é o que se quer. -
pause()para o som e não para o download. Com o diálogo fechado e osrcainda no elemento, o navegador segue puxando o arquivo. São megabytes de alguém sem nada na tela para justificá-los. Por isso o fechamento remove osrce chamaload(). -
O
<track>é criado de novo a cada abertura, não reaproveitado. Trocar osrcde um<track>já analisado não faz o navegador reler as cues: o vídeo seguinte apareceria com as falas do anterior. E ele é inserido antes de osrcdo vídeo ser escrito, porque é durante a seleção de recurso que odefaulté honrado. -
Legenda não funciona por
file://, e não é bug seu. Medido: com o preview aberto por duplo-clique, o.vtté recusado com "'file:' URLs are treated as unique security origins" — o<track>é buscado com CORS, e cada arquivo local é uma origem opaca. O<video>toca, a legenda não aparece, e o console acusa. Servido por HTTP, que é como o site roda no ar, funciona. Conferir legenda pede servidor. -
block-size:autona capa não é redundante, e a falta dele foi medida. O markup declarawidth="1600" height="900"no<img>para a caixa já estar reservada antes de a imagem existir — e o atributoheightvira uma altura definida de 900px. Com altura definida,aspect-rationão tem o que resolver e é ignorado em silêncio: a capa saía 348×900 em vez de 348×196, e o card com 902px de altura. Quem apagar a linha do CSS reabre o buraco; quem apagar os atributos do markup perde a reserva de caixa. -
<time datetime="PT8M">não é lido por leitor de tela. É crença comum que o atributo seja anunciado; não é — o que se lê é o texto do<time>. Daí o<span class="fvid-dur-rot visually-hidden">Duração</span>na frente: sem ele o card se anuncia como "… 8 min", e "8 min" solto no meio de um botão não diz de que são os oito minutos. Odatetimefica para máquina, e tem de ser atualizado junto com o texto. -
O
play()tem guard desrc, e o guard não é firula. Chamarplay()num<video>sem mídia rejeita a promessa comNotSupportedError. Capturar e descartar essa rejeição seria pior que não chamar: esconderia do log um erro que continuaria acontecendo. Ocatchfica de pé para a rejeição legítima — política de autoplay muda por navegador e por configuração. -
play()depois do clique não éautoplay. A peça não tem um único<video autoplay>, e opreload="none"garante que antes do clique não há um byte de mídia na página. O que acontece no clique é a pessoa pedindo o vídeo. -
O botão de fechar é o primeiro elemento do diálogo no DOM, e é por isso que recebe o foco. O
<dialog>foca o primeiro focável quando abre; se o<video>viesse antes, ele ganharia o foco, porque<video controls>é focável. A alternativa seriaautofocus, que rende aviso de console no showroom servido porfile://(MANUAL §8) — quatro já existem, e um quinto seria ruído. O CSS tira o botão do fluxo e o põe no canto. -
--fvid-cromoé a única medida que precisa de calibragem à mão, e ela tem folga de propósito. É ela que faz o palco caber em tela baixa: a largura é capada para que a altura 16:9 dela mais o cromo caibam na janela. O cromo medido é 58 px no desktop e 72 px no celular; o declarado é 108 px e 92 px. A folga é o que absorve uma legenda de duas linhas — título longo, fonte de tema mais larga — sem que o quadro encoste na borda de baixo. O preço é um vídeo alguns pixels menor em janela baixa, e é o lado certo para errar. Quem apertar o número ganha vídeo e perde a margem. Ooverflow:hiddendo diálogo garante que qualquer excesso fique dentro da tela em vez de pintar por fora dela. -
O anel de play sai de cena em
@media (scripting: none). Sem script o<dialog>nunca abre, e um anel de play num card inerte é uma promessa que ninguém vai atender. A consulta é a mesma que ocore/motion.cssusa para devolver a página sem script — medida, não hipótese. -
O véu é mais escuro que o padrão da casa, e isso é desenho. O
--veildo core mistura--darka 78%; aqui o diálogo redeclara o mesmo nome a 88%, via--fvid-veil-mix. Vídeo pede sala escura. Sobre dobra escura os dois graus dão o mesmo pixel — o grau só se vê quando há claro atrás. Quem quiser o padrão apaga a linha. -
--veilé declarado no<dialog>, não no::backdrop. O::backdropherda custom property do elemento que o originou, então declarar--veilna classe do diálogo basta para a primitiva do core pintar o véu certo. Uma regra.fvid-dialog::backdropsó para trocar a cor traria de volta a duplicação que a primitiva veio resolver. -
role="list"no<ol>não é redundante. O reset do core zeraul, olcomlist-style:none, elist-style:noneapaga a semântica de lista no VoiceOver do Safari. O atributo devolve o papel sem tocar no reset. -
min-inline-size:0no.fvid-item. O mínimo automático de um item de grade é o conteúdo dele: sem esta linha, um título longo faz a coluna crescer além da fração de1fre a fileira desalinha. -
line-height:0no card não é firula. O<button>alinha o conteúdo como texto, e sem isso a capa ganha um filete de descida embaixo. Ele é herdado, e os blocos internos declaram a própria entrelinha — quem apagar a de.fvid-titulovê o texto colapsar. -
appearance:nonee fundo explícito no card. O<button>nativo pinta o cromo do sistema por baixo, ecolor-scheme: only light(core/tokens.css) o deixa cinza-claro em toda parte. É o mesmo caso que já custou um botão invisível no.btndo core. -
A capa fica 16:9 em toda largura, inclusive no celular. Não é esquecimento: a capa é um quadro do vídeo, e recortá-la para 3:2 no mobile faria a peça mostrar um enquadramento que o vídeo não tem. O que muda no mobile é o respiro da legenda.
-
Os parafusos do mobile são redeclarados em
.fvid, não no elemento que os lê. Escritos no próprio.fvid-playou.fvid-palco, eles venceriam o valor que o consumidor põe na seção, e o parafuso pareceria não funcionar. Mesma forma do--display-xldo core. Quem sobrescrever--fvid-play-sizeou--fvid-cromosobrescreve os dois valores.
Compliance
A peça não devolve número, não compara e não captura dado. O terreno regulado aqui é outro: o que ela publica é conteúdo sobre investimento, e a responsabilidade viaja no vídeo, não no card. O que o consumidor tem de trocar antes de publicar:
- Título que informa, nunca que promete. Nenhum dos seis títulos de exemplo fala de retorno, ganho, percentual ou comparação com o mercado. O que muda na renda fixa com a Selic em queda descreve um fato público; Como dobrar seu patrimônio é promessa, e promessa em título de vídeo é promessa da casa.
- A ressalva de natureza vive no apoio da dobra, não no rodapé da página: "Comentário, não recomendação." É onde a pessoa lê antes de clicar. Se um episódio menciona produto ou classe de ativo específica, o aviso completo tem de estar no próprio vídeo — a dobra não tem onde pôr um aviso por card, e um aviso genérico embaixo de seis títulos não cobre nenhum deles.
- Legenda
.vttonde há fala. Não é preferência de acessibilidade só: é o único jeito de o que foi dito existir como texto — para quem não ouve, para quem está sem som, e para o registro do que a casa afirmou. - Duração e data reais. Os números do exemplo são ilustrativos e estão marcados como tal no markup. Duração que não bate com o arquivo e data de episódio errada são informação falsa numa peça que só tem quatro informações.
- Nada de instituição real, nome de cliente ou logo de terceiro — nem na capa, nem no título, nem no vídeo. Rosto na capa exige autorização de uso de imagem e voz, com escopo e prazo.
- Nada é gravado. O componente não escreve
localStorage, não conta visualização e não manda evento: o que a pessoa assistiu é dado dela. Quem precisar de métrica a tira do player ou do servidor de mídia, fora desta peça.
Movimento reduzido / toque
Com prefers-reduced-motion: reduce o diálogo continua abrindo — ele foi pedido. Some só a coreografia: o palco nasce no lugar final, sem blur nem subida, e o script nem chega a pôr a classe. Na grade, o zoom da capa e o salto do anel param; cor e opacidade ficam, porque sem elas o card deixaria de responder ao ponteiro.
No toque, nada depende de hover: o anel de play nasce visível, e é por isso que este componente não precisa do @media(hover:none) que o midia/galeria-scroll-horizontal escreve para o distintivo dele. Os controles do vídeo são os nativos, que já são os certos para tela sensível — inclusive o botão de tela cheia, que no celular é o que a pessoa realmente vai usar.
Por teclado: Tab alcança cada um dos seis cards, Enter e Espaço abrem, o foco entra no diálogo e fica preso lá, Esc fecha e o foco volta para o card que abriu. Nada disso foi escrito no script — é tudo do <dialog> com showModal().
O ciclo de Tab dentro do diálogo passa pelo <body>, e isso é nativo. Medido: fechar → vídeo → <body> → fechar, indefinidamente. O passo pelo <body> é como o Chrome dá a volta na armadilha de foco de um <dialog> modal; nenhum card e nenhum elemento da página é alcançado, porque a página está inerte. Não há o que consertar aqui, e um "consertador" que escrevesse uma armadilha própria substituiria comportamento nativo correto por código a manter.
Histórico
| Projeto | Onde | Data | Diferenças |
|---|---|---|---|
| autoral | — | 2026-09-09 | Construído do zero. Padrão de domínio comum, sem referência única |
| referência: Dudes Becker | https://portfolio.dudesbecker.com/portfolio — "06 / 06 Motion Design", três vídeos 9:16 | 2026-10-01 | variação vertical 9:16; a proporção deixou de ser cravada e virou os parafusos --fvid-pw/--fvid-ph |
Origem. O índice de série de vídeos curtos aparece em página de podcast em vídeo, em hub de conteúdo de casa de análise e em área de aulas curtas — padrão sem dono. Nada foi copiado: reescrito do zero dentro do contrato desta biblioteca. O registro consolidado vai em projetos/autorais.md.
Por que existe. A tag videos tinha uma peça, e ela é de um vídeo só. Pior: a ficha do midia/showreel-expansivel mandava quem tem vários vídeos para o overlay/card-expansivel-fullscreen — que é um trilho de cards cujo detalhe é texto, foto e CTA, e não toca vídeo nenhum. O encaminhamento estava errado porque o destino não existia. Agora existe, e a divisão da família de vídeo fica assim:
| Peça | O vídeo é |
|---|---|
hero/video-fundo |
superfície da primeira dobra — textura, laço, sem som |
midia/showreel-expansivel |
um filme, capa única, peça gráfica da dobra |
prova/depoimento-video |
a fala de uma pessoa, com a citação legível sem clique |
midia/faixa-videos |
um item de uma série, entre três e seis |
Decisões da tradução para o contrato. Grade e não trilho, porque índice do qual não se vê o fim não é índice — e porque o trilho já é o irmão galeria-scroll-horizontal, que é de fotos e leva para outra página. <button> e não <a>, porque o destino é um reprodutor nesta página. Um <dialog> por seção com um <video> só, cujo src, poster e <track> o script troca a cada abertura, em vez de seis reprodutores inline ou seis diálogos. O <video> nasce sem src, sem <source> e com preload="none". A duração é <time datetime> com rótulo .visually-hidden na frente. A lista é <ol> com role="list". O <dialog> é filho direto da seção e fora de todo [data-rv].
Primitivas do core que a peça veste em vez de recopiar: .wrap, .sec-pad, .sec-head, .eyebrow, .sec-title, .sec-lead, .ttl, .visually-hidden, .dialog-casca, .sec-deep, e o par LIB.travarRolagem / LIB.soltarRolagem — a trava com contador, para que duas sobreposições abertas não se destravem mutuamente.
Normalizações aplicadas na extração: não se aplica — a peça é autoral, escrita já em token, prefixo e gancho do core.
Divergências conhecidas vs. produção: não se aplica — não há site de origem.
Calibragem no primeiro uso. Duas coisas pedem um olhar com o material real. A primeira é --fvid-cromo contra a legenda do palco: com título longo e fonte de tema mais larga ela vira duas linhas, e o número tem de subir junto. A segunda é a duração da entrada do palco (.5s) contra o tempo real de carregamento do vídeo — com arquivo pesado a coreografia termina antes do primeiro quadro existir, e o quadro fica preto por um instante. O poster, que o script copia da capa clicada, é o que cobre essa janela: é ele que faz o palco abrir mostrando a mesma imagem em que a pessoa clicou.