Texto à esquerda, palco à direita. O palco é um trilho de fotos que vira pelas setas, e sobre a foto flutuam cards de interface posicionados em porcentagem: um item de catálogo, um par de números, uma nota de conversa. Os cards boiam de leve, sem parar, e podem entrar em sequência — contando uma narrativa de três passos em laço.
O problema editorial é o de toda abertura de produto: mostrar o software sem dar print da tela. Print envelhece, não cabe em 600px e obriga o visitante a ler tipografia de 11px. Os cards flutuantes recortam só o que importa — um preço, uma conversão, uma frase de confirmação — e a foto de pessoa por baixo dá a escala humana que um print nunca dá. A headline em caixa alta com line-height:1 é o contrapeso: massa tipográfica de um lado, objetos leves do outro.
Quando usar
- Primeira dobra de página de produto, SaaS, plataforma, app
- Quando existe foto de pessoa usando a coisa — não render, não mockup de notebook flutuando
- Quando há de dois a quatro momentos distintos do produto para mostrar, um por slide
- Headline de oito a doze palavras. Menos que isso não sustenta o
line-height:1
Quando não usar
- Headline curta e cortante ("Segurança no presente"). Em três palavras a caixa alta colada vira bloco sem ritmo — ali é
hero/full-bleed-media - Sem foto de pessoa. Cards brancos sobre fundo liso são um dashboard, não um hero
- Institucional sem produto para mostrar — luxo, marca pessoal, escritório sem portal. Card de interface é vocabulário de software: numa assessoria ele só faz sentido quando existe um portal do cliente de verdade (posição consolidada, relatório, diagnóstico) para ser encenado, que é o caso do markup atual. Sem portal, a dobra é
hero/full-bleed-media - Um momento só do produto. Aí é a variação de slide único, não o carrossel
Padrão editorial
| Slot | Regra |
|---|---|
| Headline | 8 a 12 palavras, caixa alta. A última frase vai no <em> e é o que a marca vende, não um adjetivo |
| Apoio | duas a três frases curtas. O padrão da referência é bom: duas afirmações em paralelo, depois uma de ação |
| Ação primária | verbo no infinitivo ou imperativo, três palavras no máximo |
| Ação secundária | link de texto, nunca segundo botão — dois botões lado a lado disputam o clique e nenhum ganha |
| Slide | um momento do serviço por slide — o diagnóstico, o relatório consolidado, o comitê. Dois slides que mostram a mesma coisa são um slide |
| Card | 2 ou 3 por slide. Quatro cobre a foto e o rosto que dava a escala humana desaparece |
| Nota de conversa | uma frase, 40 a 50 caracteres. É fala, então aceita reticências e exclamação |
| Número | grandeza com unidade. R$ 18,4 mi lê como relatório; 18400000 lê como placeholder. Ilustrativo, sempre — número em hero de assessoria não é dado apurado |
Os cards de um slide vão em alturas diferentes, nunca alinhados. Três objetos em linha reta viram uma legenda comprida; em alturas distintas o olho circula pela foto. E as posições em % são de tuning fino: mova de dois em dois pontos, olhando o rosto da foto — o card não pode cobrir olhos nem boca.
Especificação dos assets
- Formato e dimensão mínima: paisagem, recorte 1.09:1. 1400×1290 cobre telas 2x
- Peso alvo: 180 KB por slide em WebP q75. São até quatro fotos na primeira dobra — é o orçamento inteiro de imagem da página
- Composição: pessoa em atendimento — assessor e cliente sobre a mesma tela, olhando para ela e não para a câmera. O terço esquerdo da foto precisa ser área calma (parede, fundo desfocado): é onde os cards pousam
- O que não pode ter: print de interface real na foto (o card já é a interface, e os dois competem), texto legível ao fundo, marca de terceiro, enquadramento em que o rosto ocupe o terço esquerdo
Como usar
<link rel="stylesheet" href="componentes/hero/duas-colunas-produto/estilo.css">
<script src="componentes/hero/duas-colunas-produto/script.js"></script>
O card é posicionado inline, porque a posição é conteúdo — muda a cada foto:
<div class="stage-card stage-card-stat" style="--stage-cx:36%;--stage-cy:54%"> … </div>
E a diferença entre card permanente e card de narrativa é um atributo:
<div class="stage-card stage-card-item" style="…"> <!-- sempre visível -->
<div class="stage-card stage-card-note" data-stage-step="1" style="…"> <!-- entra na vez -->
Ganchos
| Gancho | Papel |
|---|---|
[data-stage] |
a seção. Uma por página, mas o script aguenta várias |
[data-stage-track] |
o trilho. Recebe --stage-i do script |
[data-stage-slide] |
o slide. Ganha aria-hidden quando sai de vista |
[data-stage-prev] [data-stage-next] |
as setas. <button> de verdade |
data-stage-step="n" |
ordena a narrativa pelo número, não pela ordem do markup |
--stage-cx --stage-cy |
posição do card em % da foto. Inline |
--stage-ratio |
proporção do palco. Padrão 1.09; 4/3 em tablet, 1 em celular |
--stage-radius |
raio da janela. Padrão 24px |
--stage-bob --stage-bob-dur --stage-bob-delay |
amplitude, duração e fase da boiada |
.stage-card-note -item -stat |
os três tipos de card: fala do cliente, posição em um ativo, par de grandezas |
Variações
- sem narrativa — apague os
data-stage-step. Todo card fica permanente e o script não liga relógio - slide único — um slide, setas apagadas. Palco estático com cards boiando; é a versão barata
- autoplay —
experimental, e fora do padrão de propósito. Ver Gotchas - tom escuro — troque
.sec-lightpor.sec-dark. Nada mais muda, porque tudo lê token .stage-card-item— miniatura, título, valor (um fundo e a posição nele).stage-card-stat— duas grandezas com filete no meio. Três células antes de virar tabela
Gotchas
-
A boiada é
translate, a entrada étransform, e trocar isso quebra as duas. São propriedades CSS distintas e por isso se compõem: a animação contínua de flutuação e a transição de entrada do passo convivem no mesmo elemento. Se a boiada fossetransform:translateY(), a entrada do card apagaria a flutuação (ou o contrário, dependendo da ordem) e a saída seria um invólucro a mais só para separá-las. Quem for "padronizar para transform" vai reintroduzir o bug. -
A conta da translação é do CSS, não do script. O script escreve
--stage-i(um inteiro) e oestilo.cssfaztranslate3d(calc(var(--stage-i) * -100%),0,0). Mudar a curva, a duração ou o sentido do trilho é mexer no estilo. Nenhumstyle.transformsai do script — é a regra da casa e o que mantém o componente legível. -
Trocar de slide reinicia a narrativa no passo 1. Não é detalhe: entrar num slide no passo 2 lê como "peguei a conversa no meio". O
apagarPassos()noir()existe só para isso. -
visibilityentra na transição junto com a opacidade. Card comopacity:0continua sendo lido por leitor de tela e continua no caminho do Tab — três frases de narrativa viram três frases fantasma.visibility:hiddenresolve, e está na transição (não fora) para não cortar o fade no meio. -
Abaixo de 560px o terceiro card permanente sai, mas passo de narrativa nunca sai. O seletor é
:nth-child(3):not([data-stage-step]). Esconder um passo o apagaria para sempre: o laço continuaria dando a vez a um card invisível e o slide ficaria vazio um terço do tempo. -
Autoplay é variação, não padrão, e há motivo. A referência é manual. Carrossel que vira sozinho enquanto o visitante lê um card com um preço é hostil — e a narrativa de três passos já dá movimento ao palco, então o autoplay adicionaria uma segunda coisa se mexendo sem pedir licença. Se for ligar, pause no
pointerentere mate de vez no primeiro clique numa seta. -
O palco encolhe de 1.09 para 4/3 e depois para 1:1. Não é capricho responsivo: em largura cheia o 1.09 fica alto demais e empurra o CTA para fora da primeira tela. CTA acima da dobra é o motivo da dobra existir.
-
--stage-ratioe a foto têm de combinar. Oobject-fit:coverrecorta o que sobra, eobject-position:50% 42%privilegia o alto — foto com o rosto embaixo perde a cabeça. Se a foto do cliente não for 1.09:1, recorte antes em vez de mudar o ratio: mudar o ratio muda a grade toda. -
As legendas de cursor são composição, não parte do componente. O bloco
.cur-layerno markup vem deefeitos/cursor-anotacaoe está aqui porque é assim que a referência monta a dobra. Apague o bloco e o hero continua inteiro — mas se mantiver, oestilo.csse oscript.jsdaquele componente também têm de entrar (é o que opreview-css.txte opreview-js.txtfazem no preview). -
A camada de anotação leva
.cur-layer-desktop, e não só.cur-layer. A camada sai por padrão em 640px, mas esta grade colapsa para uma coluna em 980px — e na faixa entre os dois a bolha de cima cai sobre a headline e a de baixo sobre a foto. Medido no aparelho, não suposto. O modificador alinha o recuo da camada com o da grade. -
O respiro do topo e a largura da coluna de texto existem por causa da anotação.
padding-topé o dobro do necessário para limpar o menu (é onde a bolha de cima pousa) e as colunas são1.25fr 1fre não1fr 1fr(é o que abre lugar, à direita do link secundário, para a bolha de baixo). Quem usar o hero sem a camada pode apertar os dois; quem usar com ela vai reintroduzir a colisão.
Histórico
| Projeto | Onde | Data | Diferenças |
|---|---|---|---|
| referência: Corvex | https://usecorvex.com.br/ — hero | 2026-08-31 | referência visual, não origem de código |
Normalizações aplicadas na tradução: a referência é Framer — classes hash, sem licença declarada, e nada foi copiado (§11). Medido nela e reproduzido: foto 608×560 com raio 24px (virou --stage-ratio:1.09 + --stage-radius), headline 72px/72px com tracking −0.02em em caixa alta e a frase final em cor de marca, corpo 16/25.6, boiada de ~11px de amplitude, narrativa de três passos em ciclo de ~10s, carrossel manual pelas setas ao pé da foto.
O que é nosso: Anek Latin e Instrument Sans saíram (Google Fonts, proibido em produção pelo §1) e viraram --display/--sans, com o tema decidindo; os hex #F5F6FC, #8758F0 e #33196F viraram .sec-light, --accent e color-mix; a headline entra por data-split do core, com blur, em vez do fade simples do original; o conteúdo dos cards deixou de ser UI da Corvex e virou um contrato de slot em três tipos (-note, -item, -stat); os cards ganharam fases de boiada dessincronizadas (na referência os três sobem quase juntos, e isso entrega o truque); as setas viraram <button> com rótulo, navegação por flechas do teclado e aria-hidden nos slides fora de vista — na referência são <div> clicáveis; e tanto o carrossel quanto a narrativa param quando a dobra sai da tela.
Divergências conhecidas vs. a referência: três slides aqui contra quatro lá — contagem é conteúdo, não desenho. O deslize do trilho é --ease em 0,72s, não a mola do Motion. E a referência troca o texto das legendas de cursor quando o slide vira; aqui as notas são estáticas em conteúdo, porque a camada é um componente separado que não sabe nada sobre o palco. Ligar as duas coisas exigiria um gancho entre componentes — dívida assumida e registrada, não esquecimento.