Dois a quatro depoimentos em grade. Cada um é um retrato em corpo grande com o nome e a praça da pessoa dentro da foto, um disco de play no centro e a citação em texto logo abaixo — visível, sem clique. No clique, o vídeo cresce do lugar exato do retrato dentro de um <dialog> nativo, com legenda declarada e os controles do navegador.
O que ele resolve: servir a prova mais forte que existe — uma pessoa falando — sem torná-la refém do vídeo. A citação é markup estático e é a versão legível do depoimento: é ela que sobra quando o som está desligado, quando a conexão não segura o arquivo, quando a pessoa não ouve, e é ela que o buscador lê. O vídeo é o reforço da citação, não o contrário.
Quando usar
- Prova social de serviço, na segunda metade da página, depois de a proposta estar apresentada e antes do fecho.
- Quando existem dois a quatro depoimentos gravados, com autorização de imagem e voz assinada, e cada um tem uma frase que se sustenta sozinha em texto.
- Quando o argumento é atendimento, clareza e acompanhamento — o que uma pessoa consegue dizer melhor do que a casa.
Quando não usar
- Depoimento só em texto, e muitos. É o
prova/carrossel-depoimentos: esteira contínua de 3 a 6 citações com retrato pequeno, sem vídeo e sem JavaScript. Ele ganha quando não há gravação, quando há mais de quatro depoimentos, ou quando o depoimento é acessório e não pode ocupar meia dobra. - Um vídeo só, institucional, que não é depoimento. É o
midia/showreel-expansivel: uma capa, um<dialog>, sem citação e sem atribuição. Ele ganha para showreel, filme de marca ou vídeo de case — e ganha também quando há um único depoimento, porque uma grade de um item não é grade, é um card solto. - Vídeo como superfície de abertura, em laço, sem fala e sangrado até a borda: é o
hero/video-fundo. Papel diferente (identidade, não prova) e posição diferente (abertura). - Uma fileira de vídeos que é índice de série — capa 16:9 com título, duração e rótulo de série, sem pessoa e sem citação: é o
midia/faixa-videos(3 a 6 itens, um<dialog>só, com o script trocandosrc,postere legenda a cada abertura). Ele ganha quando o conteúdo é a coleção de vídeos; aqui o conteúdo é a fala de uma pessoa, e o vídeo é a prova dela. A diferença de arquitetura segue disso: lá um diálogo serve muitos vídeos porque os itens são intercambiáveis; aqui cada depoimento tem o seu, com a legenda daquela pessoa declarada no markup, porque trocar o<track>por script esconde a falta de legenda. - Detalhe em texto, foto e CTA, num trilho de muitos. É o
overlay/card-expansivel-fullscreen, que carrega tudo nosdata-*do próprio card. Ele ganha quando o conteúdo do detalhe não é vídeo. - Mostrar quem é a equipe.
conteudo/grid-equipeemidia/carrossel-perfissão para as pessoas da casa; aqui as pessoas são de fora e a fala é o conteúdo. - Citação de veículo de imprensa —
prova/manchetes-imprensa. Atribuição a marca, não a pessoa, e com data e link. - Sem legenda e sem autorização assinada. Não é caso de outro componente: é caso de não publicar ainda. Ver a seção Compliance.
Qual dos três de prova em citação
prova/depoimento-video |
prova/carrossel-depoimentos |
midia/showreel-expansivel |
|
|---|---|---|---|
| Conteúdo | vídeo e citação em texto | citação em texto | vídeo |
| Itens | 2 a 4, em grade | 3 a 6, em esteira | 1 |
| Atribuição | nome, perfil e praça | nome e perfil | não tem |
| Movimento em repouso | nenhum | a esteira anda sozinha | nenhum |
| JavaScript | precisa (o diálogo) | não usa | precisa |
| Legenda | obrigatória | não se aplica | obrigatória se há fala |
Padrão editorial
Dois a quatro itens. Um só não é grade — é o midia/showreel-expansivel. Cinco começa a virar catálogo de depoimentos, e aí a esteira do prova/carrossel-depoimentos lê melhor.
| Slot | Onde | Faixa | Regra |
|---|---|---|---|
| Olho | .eyebrow |
1 a 2 palavras | o tipo de prova: Depoimentos, Na voz deles |
| Título | h2.sec-title |
4 a 7 palavras | uma ou duas em <em>. Não cite a quantidade — o mesmo bloco roda com 2, 3 ou 4 itens, e "três clientes contam" mente na primeira troca |
| Apoio | .sec-lead |
1 a 2 frases | enquadra o conjunto: quem são estas pessoas e o que foram convidadas a falar. Se disser que a fala é livre, ela tem de ser livre |
| Nome | .dvid-name |
2 a 3 palavras | por item. Nome e sobrenome, sem título acadêmico e sem empresa colada |
| Perfil | .dvid-role |
12 a 28 caracteres | por item. É o perfil, não o cargo: Empresária — embalagens, Família — segunda geração |
| Praça | .dvid-onde |
8 a 22 caracteres | por item. Cidade e UF — de onde a pessoa é |
| Duração | .dvid-dur |
4 a 12 caracteres | por item. A duração real do arquivo: 1 min 12 s, 58 s |
| Citação | .dvid-quote p |
180 a 250 caracteres | por item. O trecho mais forte da fala, sem aspas |
| Ressalva | .dvid-nota |
14 a 28 palavras | uma só, no pé da dobra |
A citação é o slot mais importante da peça, e não é resumo do vídeo: é transcrição do trecho mais forte da fala. Escreva sem aspas — o retrato e o <blockquote> já dizem que é fala — e sem corrigir a pessoa. Mantenha as citações a menos de 20% de diferença de comprimento entre si: em grade, uma fala muito mais longa que as vizinhas desalinha o pé dos cards.
A duração não é enfeite. É a informação que decide o clique: "assistir" sem duração é um convite para o desconhecido. É também a única coisa desta peça que o visitante pode conferir na hora — confira depois da edição final.
Nome e praça ficam no texto, e isso é regra, não estilo. Depoimento anônimo não é prova, e fala sem endereço é frase solta. Os dois vão dentro da foto, ancorados embaixo (§6 do contrato: legenda de card de mídia não vira parágrafo abaixo da imagem), e o nome fica onde ele é mais útil — colado ao rosto de quem fala.
O nome da pessoa é escrito uma vez só. O nome acessível do botão da capa sai do texto visível dela, precedido de "Assistir ao depoimento em vídeo de" só para leitor de tela; e o aria-label do <dialog> é escrito pelo script a partir do .dvid-name. Medido — o texto do botão em ordem de documento, que é de onde o nome é computado: Assistir ao depoimento em vídeo de Helena Fontoura Empresária — embalagens Joinville, SC 1 min 12 s; e no diálogo, Depoimento em vídeo de Helena Fontoura. Quem monta a página com a copy de um cliente troca um nó por pessoa.
Especificação dos assets
| Asset | Especificação |
|---|---|
| Vídeo | um por depoimento. mp4 com H.264, 1920×1080. Fala captada em microfone de lapela — depoimento com áudio de câmera não se salva na edição |
| Capa (retrato) | 1200×1500 ou maior, recorte em retrato de um frame do próprio vídeo: a pessoa olhando para a câmera, sem legenda queimada, sem logo, sem terço inferior de televisão. Não use o primeiro frame — ele costuma ser preto ou o meio de uma piscada |
Poster do <video> |
1600×900, o mesmo frame da capa sem o recorte. É o que segura o palco até o arquivo chegar |
| Legenda | um .vtt por vídeo, em <track kind="captions">. Obrigatório — ver Compliance |
| Autorização | uso de imagem e voz assinado por pessoa, com escopo e prazo. Pré-requisito de publicação |
Neste preview a capa e o poster são arquivos diferentes, e no uso real são o mesmo frame. showroom/demo/ guarda retrato (ph-*) e paisagem (ph-wide-*) em arquivos separados, e o preview precisa mostrar a geometria real dos dois quadros: com um retrato no palco de 16/9 o vídeo apareceria com tarja preta dos dois lados e pareceria erro de componente.
Nenhum vídeo é versionado na biblioteca, então o <source> está comentado. O que se vê é o poster e os controles nativos: abertura, crescimento, foco, Esc e fechamento funcionam e podem ser conferidos; só a reprodução não.
Compliance
Depoimento de cliente em página de assessoria de investimentos é o terreno mais delicado da biblioteca. O que tem de ser revisto antes de publicar:
- Nenhum depoimento fala de retorno, ganho, percentual ou comparação com o mercado. "Ganhei X%" é promessa de resultado por interposta pessoa, e é pior do que a casa dizer, porque parece verificado. O depoimento fala de serviço: atendimento, clareza, tempo de resposta, sensação de estar acompanhado. Isso vale para a citação em texto e para a fala gravada — a legenda torna o áudio pesquisável, e um número dito no minuto 1 não fica escondido.
- Autorização de uso de imagem e voz assinada, por pessoa, com escopo (site, campanha, redes) e prazo. Rosto e nome de pessoa real sem isso não vão ao ar. Guarde também o consentimento para a transcrição: a citação é publicação de fala.
- Legenda é obrigatória. Publicar depoimento sem
.vtté publicar prova que uma parte do público não recebe — e é o único caminho para o conteúdo mais persuasivo da página existir para o buscador. O<track kind="captions">já está declarado no markup, com osrccomentado: a falta aparece a quem for publicar em vez de passar em branco. - A ressalva do pé da dobra é ponto de partida, não parecer. Ela diz duas coisas: que houve autorização, e que os depoimentos não tratam de rentabilidade nem são recomendação. Reescreva com o compliance da casa.
- Confirme se o seu registro permite depoimento de cliente. O regime de assessoria, consultoria e gestão não é o mesmo, e em alguns deles a divulgação de declaração de cliente é restrita. A peça não decide isso — quem decide é o jurídico da casa, antes de haver gravação.
- Sem nome de instituição real, sem logo de banco e sem marca de terceiro na fala, na legenda ou na imagem.
- Nada é gravado no navegador. A peça não escreve
localStorage, não tem formulário e não mede nada de quem assiste. Se o consumidor plugar analytics no clique de play, o dado é dele e o aviso de privacidade dele.
Os nomes, praças, retratos e falas de exemplo são fictícios, escritos para a voz da Liberta Investimentos. Nenhum é cliente real.
Como usar
<link rel="stylesheet" href="componentes/prova/depoimento-video/estilo.css">
<script src="componentes/prova/depoimento-video/script.js"></script>
Cole a <section> inteira. O <dialog> de cada depoimento mora dentro do <li> dele — não o mova para o fim do <body>: é a vizinhança que dispensa id, e é ela que faz "acrescentar um depoimento" ser duplicar um <li>.
O <dialog> leva duas classes, na ordem class="dialog-casca dvid-dialog". A primeira é a primitiva do core (base.css): zera padding, borda, fundo e os limites de tamanho que o navegador dá de graça ao <dialog>, e pinta o ::backdrop. A segunda é a forma desta peça — o palco de tela cheia, o display de [open] e o grau do véu.
Depois: troque as fotos e o --dvid-poster-pos de cada uma, descomente <source> e o src do <track>, e ajuste nome, perfil, praça, duração e citação.
Ganchos
| Gancho | O quê |
|---|---|
.dvid |
a seção. Carrega os parafusos, e é o único lugar onde se mexe |
.dvid-item |
um depoimento: o invólucro do reveal e o <dialog> dele, lado a lado |
.dvid-slot |
o invólucro do [data-rv]. O <dialog> é irmão dele, nunca filho |
[data-dvid-abrir] |
a capa inteira, que é um <button> |
[data-dvid-dialog] |
o <dialog> daquele item, achado por closest('.dvid-item') |
[data-dvid-frame] |
o quadro que cresce. Recebe as três custom properties |
[data-dvid-video] |
o <video>, para tocar ao abrir e pausar ao fechar |
[data-dvid-fechar] |
o botão de fechar |
.is-abrindo |
dispara a transição do quadro para a identidade |
--dvid-cols |
colunas da grade. 3; 2 até 1080px, 1 até 680px |
--dvid-gap |
vão entre os cards |
--dvid-ratio |
proporção da capa. 4/5; 1/1 de 1080px para baixo, quando a grade vira duas colunas; 4/3 em coluna única |
--dvid-frame-ratio |
proporção do quadro do vídeo. 16/9 |
--dvid-play |
diâmetro do disco de play. 64px; 56px no toque e no celular |
--dvid-dur |
tempo da abertura do quadro. .52s |
--dvid-veil-mix |
grau do véu do ::backdrop. 88% — mais escuro que os 78% da casa, e de propósito |
--dvid-poster-pos |
recorte da foto, por card, no style do <img> |
--dvid-dx / --dvid-dy / --dvid-s |
a diferença entre a capa e o quadro, escritas pelo script |
Variações
| Variação | Como |
|---|---|
| Dois depoimentos | --dvid-cols:2 e --dvid-ratio:1 / 1. Em duas colunas a capa passa de 500px de largura, e em 4/5 ela ficaria com mais de 600px de altura — o retrato empurra a citação para fora do campo de visão, que é o que esta peça existe para evitar |
| Quatro depoimentos | --dvid-cols:4 e --dvid-ratio:1 / 1. A citação cai para o piso da faixa (180 caracteres). O quarto item repete data-d="3": o core só escalona o atraso até três |
| Vídeo vertical | --dvid-frame-ratio:9 / 16, para depoimento gravado no celular. O object-fit:contain já daria conta com tarja; o quadro em retrato aproveita a tela inteira |
| Em seção clara | trocar .sec-dark por .sec-paper. Citação e ressalva leem tokens de escopo e acompanham; a capa não muda, porque a tinta dela é sobre foto e não lê --fg |
| Vídeo hospedado fora | trocar o <video> por um <iframe>. Perde-se a pausa ao fechar, a legenda passa a ser responsabilidade do arquivo lá, e a CSP do site precisa liberar o frame |
Gotchas
-
O
<dialog>fica fora do[data-rv], e a razão medida não é a que se espera. O §5 do contrato manda pôr tudo que éfixedfora do reveal, porque[data-rv]termina emfilter:blur(0)e elemento com filtro é bloco de contenção para descendenteposition:fixed. Um<dialog>modal éfixed— mas vive na top layer, e a top layer escapa da contenção. Medido no Chrome, com o diálogo dentro do invólucro e o invólucro carregando umblur(10px)de verdade: caixa[0,0,1425,900]nos dois arranjos, e o diálogo pintou nítido. É a primeira coisafixedda biblioteca que escapa da armadilha do §5. A separação continua no markup por precaução — custa uma<div>e vale em qualquer navegador que ainda trate a top layer como filho comum. -
displaysó em.dvid-dialog[open]. O<dialog>nascedisplay:nonena folha do agente do usuário, e qualquer regra de autor comdisplayvence essa. Escrever.dvid-dialog{display:grid}deixaria os três diálogos visíveis o tempo todo, empilhados sobre a página. É a armadilha do §6.5 na versão do elemento nativo. -
.dvid-item[hidden]{display:none}não é zelo, é o caso mais provável desta peça. Depoimento é o único conteúdo da biblioteca que pode precisar sair do ar de um dia para o outro: a autorização vence, a pessoa pede para tirar. Quem faz isso põe[hidden]no<li>— e sem a linha, odisplay:flexdo item venceria o[hidden]do navegador e o depoimento continuaria na tela com o atributo lá no inspetor. -
showModal(), nuncashow(). ÉshowModalque traz o foco preso, o::backdrope a página inerte. Medido:Enterna capa abre, o foco entra no<video>(o primeiro focável), o<html>fica comoverflow:hidden, e ao fechar o foco volta para a capa — nada disso está escrito no script. -
Dois
requestAnimationFrame, não um. O FLIP escreve o transform inicial e depois o remove; com uma única espera o navegador às vezes agrupa as duas escritas e a transição não acontece — o quadro aparece no lugar final. Medido:--dvid-s:0.2763,--dvid-dx:-376.7px,--dvid-dy:126.4px, e o quadro nascendo em[164, 480, 343, 193]sobre uma capa em[165, 362, 343, 428]— a largura exata do retrato, no centro dele. -
A escala do FLIP é uniforme, e vem da largura. A capa é 4/5 e o quadro 16/9: não têm a mesma proporção, e escalar cada eixo por conta própria esticaria a imagem. O que se vê é uma faixa da largura do retrato abrindo no centro dele — a leitura certa para vídeo. Quem quiser a morfose exata tem de igualar
--dvid-ratioe--dvid-frame-ratio. -
O
play()vai dentro decatch. É consequência de um clique, então o navegador costuma permitir — "costuma". Política de autoplay muda por navegador e por configuração, e uma promessa rejeitada semcatchvira erro vermelho no console de quem só abriu um depoimento. -
O clique no fundo confere
mousedowntambém. Quem arrasta a barra de progresso do vídeo e solta o mouse fora do quadro produz um clique cujo alvo é o diálogo — e o vídeo fecharia no meio de uma busca de trecho. Medido:mousedownno quadro +clickno diálogo não fecha;mousedowneclickno diálogo fecham. Mesma proteção dooverlay/modal-dialogo. -
Pausa, trava e limpeza num lugar só. O evento
closedispara pelo botão, peloEsce pelo clique no fundo. Tratar os três separadamente é o jeito de um deles esquecer de pausar o vídeo — e vídeo tocando atrás de um diálogo fechado é um som sem origem visível. No mesmo lugar sai a trava de rolagem (LIB.soltarRolagem) e as três custom properties do FLIP. -
A trava de rolagem é a do core.
LIB.travarRolagem()escreveoverflow:hiddenno<html>, guarda o valor anterior e conta as travas — inclusive as de outra sobreposição da mesma página. Nunca escrevaoverflow:hiddenà mão aqui. O guardwindow.LIB &&existe porque um consumidor pode colar markup, estilo e script sem omotion.js: sem a trava a página rola atrás do vídeo, o que é feio; sem o guard o vídeo não abre, o que é bug. -
A ordem do DOM da identidade não é a ordem visual. No markup vem nome, perfil, duração; a grade do CSS devolve a duração para a primeira linha, à direita. O motivo é o nome acessível do botão, que é o texto dele lido em ordem de documento: com a duração no meio, o anúncio saía "Helena Fontoura 1 min 12 s Empresária…". Quem trocar a grade por um flex de duas linhas tem de trazer o
<span>da duração de volta para o meio e perde isso. -
alt=""no retrato é decisão, não esquecimento. O nome da pessoa está no texto do próprio botão, logo abaixo da foto. Umaltdescritivo faria o leitor de tela anunciar a mesma pessoa duas vezes. -
line-height:0na capa não é firula. O<button>alinha o conteúdo como texto, e sem isso a foto ganha um filete de descida embaixo. Mesmo caso da.reel-capado showreel. -
O véu do
::backdropé mais escuro que o padrão da casa, e isso é desenho.--veildo core mistura--darka 78%; aqui o diálogo redeclara o mesmo nome a 88%, via--dvid-veil-mix. Vídeo pede sala escura. O número é o domidia/showreel-expansivel, com a medição dele: sobre dobra clara, 78% e 88% valem 11 pontos deL*em CIELAB; sobre dobra escura dão o mesmo pixel, porque o grau do véu só se vê quando há claro atrás. Não foi remedido — foi reaproveitado. Medido aqui:::backdropem0.88de alfa eblur(6px). -
--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.dvid-dialog::backdropsó para trocar a cor traria de volta a duplicação que a primitiva veio resolver. -
overflow:hiddenfica local, contra ovisibleda casca. O diálogo é o palco: com um quadro maior que a janela — a variação de vídeo vertical, ou um--radius-mediagrande — o que sobra fica dentro da tela em vez de pintar por fora dela. -
O botão de fechar não é o
.btn-discdo core, e obase.cssjá registra por quê. Aquele é um disco de contorno que lê--fg-2e--rule-2, tokens do escopo de tom. Este mora sobre vídeo, cujo quadro pode ser qualquer coisa: um contorno tênue desaparece num frame claro. Daí as cores de--light/--darke o desfoque, como no.reel-fechardo showreel — é a segunda cópia dessa receita na casa, e a terceira é candidata a primitiva. -
minmax(0,1fr)na grade, não1fr. Com1fro mínimo automático é o conteúdo, e uma citação com uma palavra longa alarga a coluna e estoura a grade.
Movimento reduzido / toque
Com prefers-reduced-motion: reduce, o diálogo continua abrindo — ele foi pedido. Some o que anda sozinho: o quadro aparece no lugar final sem crescer (o script não mede nem escreve transform), a capa para de escalar no hover e as transições vão a 0s.
E o vídeo não toca sozinho — esta é a divergência deliberada em relação ao midia/showreel-expansivel, que toca sempre. Quem pediu menos movimento não pediu um filme começando na cara; os controles nativos estão ali, e o play é um gesto. Medido com --reduce: diálogo aberto, transform: none, --dvid-dx nunca escrita, video.paused continua true.
No toque, a capa é um <button> e responde como qualquer botão. Não há nada nesta peça que apareça só no ponteiro: o disco de play, o nome, a praça, a duração e a citação nascem visíveis. O que muda em @media(hover:none) é o tamanho do disco (56px). Os controles do vídeo são os nativos, inclusive a tela cheia — que no celular é o que a pessoa vai realmente usar, porque um quadro 16/9 na largura de um telefone em pé tem 206px de altura (medido em 390×844).
Por teclado: Tab chega a cada capa, Enter ou Espaço abre, o foco entra no diálogo e fica preso lá (dois nós focáveis: o <video> e o botão de fechar), Esc fecha e o foco volta para a capa que abriu. Tudo isso é do <dialog>.
Sem JavaScript a dobra continua inteira: retrato, nome, perfil, praça, duração, citação e ressalva são markup estático, e o componente não esconde nada por conta própria — o único estado invisível de repouso é o [data-rv] do core, que o motion.css devolve em @media(scripting:none). O que se perde é só o vídeo, que já estava atrás de um clique.
Histórico
| Origem | Quando | O quê |
|---|---|---|
| autoral | 2026-09-09 | Construído do zero. A grade de retratos com play é forma de domínio comum, sem referência única |
Origem. A fileira de retratos com botão de play, cada um abrindo um vídeo, aparece em site de SaaS, de escola e de clínica — padrão de domínio comum, sem dono. Nada foi copiado: reescrito do zero dentro do contrato desta biblioteca. O registro consolidado vai em projetos/autorais.md.
Por que existe ao lado dos irmãos. A biblioteca tinha depoimento em texto (prova/carrossel-depoimentos) e vídeo sem atribuição (midia/showreel-expansivel), e nenhum dos dois servia um depoimento gravado: o primeiro não tem vídeo, o segundo não tem nome, praça nem citação — e não tem grade. A lacuna era exatamente a prova mais forte que existe.
O que foi reaproveitado do midia/showreel-expansivel, como método: o <dialog> nativo com showModal() em vez de um <div role="dialog">; o FLIP medindo capa e quadro e escrevendo a diferença em custom properties, com dois requestAnimationFrame de espera; o play() dentro de catch; o display morando em [open]; o clique no fundo conferido por e.target === dlg; e o grau de véu de 88% com a medição dele.
O que é diferente, e por quê:
- A citação em texto é visível e é a razão de forma da peça. No showreel o conteúdo é o vídeo, e ponto. Aqui a versão legível vem primeiro na ordem de importância.
- N diálogos, um por item, vizinhos da sua capa dentro do
<li>. O showreel tem um. Ooverlay/modal-dialogocasa gatilho e diálogo porid, porque lá o diálogo mora no fim do<body>; aqui o par é vizinho e o script resolve porclosest('.dvid-item')— semid(dois destes componentes convivem na mesma página) e sem índice (trocar a ordem dos itens não desemparelha nada, e desemparelhar aqui seria mostrar o vídeo da pessoa errada, um erro que nada acusa). Medido com duas cópias da seção na mesma página: 6 capas, 1 diálogo aberto, no item certo da cópia certa. - Sob movimento reduzido o vídeo não toca sozinho.
- A escala do FLIP é uniforme e tirada da largura, porque capa e quadro têm proporções diferentes — no showreel os dois são 16/9 e a morfose é exata.
- A trava de rolagem vem do core (
LIB.travarRolagem), que não existia quando o showreel foi escrito. - O nome da pessoa é escrito uma vez só, e o
aria-labeldo diálogo sai dele pelo script.
Verificação (2026-09-09, bin/medir.js). 1440×900: altura da seção 1189px, overflowX ok, console limpo, nenhuma imagem sem pintar; três capas em 343×428 nas colunas 165 / 541 / 918. Diálogo aberto: position:fixed, caixa [0,0,1425,900] mesmo com o <dialog> dentro do .wrap; quadro 1240×698; ::backdrop com 0.88 de alfa e blur(6px). 390×844: uma coluna de 350px, capa 350×263 (4/3), disco de 56px, quadro 367×206 dentro da tela, botão de fechar em 44×44, overflowX ok com o diálogo aberto. --reduce: nada anima e o vídeo não toca. Hover: poster em matrix(1.04) e brightness(0.84), disco em matrix(1.08) — os dois em descendente do [data-rv], que computa transform:none e filter:blur(0px) no invólucro, como o §5 prevê.
Calibragem no primeiro uso. Espere ajustar --dvid-dur (.52s) contra o tempo real de carregamento do vídeo: com arquivo pesado a coreografia termina antes de o primeiro frame existir, e o quadro fica preto por um instante. O poster do <video> cobre essa janela — é para isso que ele é obrigatório.