Cinco etapas de um processo empilhadas numa coluna só: um filete vertical à esquerda, o conteúdo à direita. O filete tem duas camadas — um trilho fraco na cor das divisórias e, por cima, um preenchimento na cor de marca que cresce conforme a página desce. Ele para no marcador da etapa que está sendo lida, e o marcador acende ali. A pessoa vê em que ponto do processo está pelo próprio ato de rolar: não há barra de progresso, não há número de passo, não há nada para clicar.
Resolve a dobra mais pedida de um site de assessoria — o "como funciona" — quando ela precisa dizer três coisas ao mesmo tempo: quais são as etapas, em que ordem e quanto tempo cada uma leva. Uma lista numerada comum entrega a primeira e a segunda e perde a terceira no meio do parágrafo; uma grade de cards perde a ordem, porque numa grade a etapa 1 e a etapa 4 são vizinhas de tabela. O filete devolve a sequência de graça, e o prazo em pílula ganha um lugar fixo no desenho em vez de virar frase.
Qual irmão ela substitui, e em que caso
Três componentes da casa encostam neste território, e a escolha entre eles não é de gosto:
listas/baralho-stickyapresenta o mesmo material — método em 4 a 6 etapas — com a forma oposta: cards de vidro que grudam no topo sobre uma foto pinada, e a etapa seguinte cobre a anterior. Ele força a sequência: a pessoa não consegue pular. Custa uma tela de rolagem por etapa e uma foto grande, e a etapa que saiu de cena não pode mais ser relida sem voltar. Use o baralho quando o método é o argumento de venda da página e a dobra pode ocupar a atenção inteira; use esta linha do tempo quando o processo é informação de serviço — alguém já decidiu contratar e quer saber o que vai acontecer, em que ordem e em quanto tempo. Aqui as cinco etapas coexistem na tela e podem ser comparadas de relance, e a peça cabe em uma tela e meia em vez de cinco.midia/roda-de-cardsé cronologia de anos, não de etapas: 6 a 10 paradas com data e foto sobre o aro de uma roda-gigante que se arrasta de lado. Ela pede foto por parada e responde a gesto. Use a roda para "quem somos desde 2012"; use esta para "o que vai acontecer depois que você assinar". A própria ficha da roda já apontava esta lacuna: uma linha do tempo vertical era o que faltava para o caso puramente sequencial.conteudo/imagem-lista-numeradaé lista numerada de 3 a 4 diferenciais ao lado de uma foto. Ali os itens não têm ordem obrigatória e não têm duração. Se o seu item 3 pode virar item 1 sem prejuízo, o componente é aquele, não este.
Quando usar
- Página de serviço, "como funciona", "nosso processo", onboarding de cliente novo — 4 a 6 etapas em ordem obrigatória.
- Quando cada etapa tem duração, e a duração é parte da resposta. É o único componente da casa que reserva um lugar fixo para ela.
- Quando o material é texto e a página não tem foto por etapa. Uma foto opcional cabe (ver a etapa 05), mas ela é o fecho, não o padrão.
- Quando a dobra pode ocupar altura: com cabeçalho, cinco etapas e a ressalva, a seção passa de 2000px em desktop e de 2500px em 390px.
Quando não usar
- Menos de 4 etapas — com uma exceção nomeada. Três marcadores não desenham uma linha do tempo, desenham três itens com um traço, e uma lista comum resolve melhor. Isso vale quando as etapas são fases de um método. Não vale quando cada etapa é uma data de calendário: aí o traço liga pontos no tempo, e dois pontos já fazem uma linha. Ver
variacoes[]— a variação de três datas éestavele não muda uma linha de código — mas muda duas coisas no conteúdo, e as duas só apareceram montando uma campanha real: o rótulovisually-hiddendo prazo deixa de ser "Prazo estimado" (com data de calendário ele mente para quem ouve a página) e o.etp-tituloprecisa de um nome para a etapa, porque a data migrou para a pílula. Data na pílula, nome no título — nunca a data nos dois. - Mais de 6. A seção passa de três telas e o filete deixa de ser lido como um único percurso.
- Itens sem ordem — serviços, benefícios, diferenciais. A forma promete sequência; sem sequência, ela mente. Use
conteudo/imagem-lista-numeradaouconteudo/pilares-texto-na-foto. - Quando cada etapa tem uma foto que vale a tela. Aí o material é de mídia, e o componente é
midia/roda-de-cardsoulistas/baralho-sticky. - Quando o conteúdo é pergunta e resposta, e o visitante vai procurar a dele:
listas/acordeao-faq. - Quando a página já tem outra dobra presa ao scroll logo acima ou abaixo. Duas peças que reagem à rolagem na mesma tela competem, e a segunda parece defeito da primeira.
Padrão editorial
| Slot | Regra |
|---|---|
Olho (.eyebrow) |
2 a 3 palavras. "Como funciona", "O processo", "Do começo ao fim". |
Título (h2.sec-title.ttl) |
5 a 9 palavras, com o arco inteiro no texto e uma palavra em <em>: "Do diagnóstico ao comitê, em cinco etapas". Evite "Nosso processo", que não informa. |
Apoio (.sec-lead) |
1 a 2 frases. É aqui que a natureza dos prazos é dita — estimativa de calendário, não compromisso. Ver Compliance. |
.etp-num |
Dois dígitos, sempre com zero à esquerda. É aria-hidden: quem numera para o leitor de tela é o <ol>. |
.etp-prazo |
3 a 5 palavras, sempre em faixa ou em cadência ("de 2 a 3 semanas", "relatório mensal", "a cada seis meses"). Nunca um número único: prazo cravado vira promessa. Acima de 22 caracteres a pílula quebra em duas linhas no celular — funciona, mas desalinha o ritmo da coluna. |
.etp-titulo |
2 a 4 palavras, substantivo. É o nome da etapa, não o que acontece nela: "Política de investimentos", não "Definimos junto a sua política". |
.etp-texto |
1 a 3 frases, 200 a 340 caracteres. Diz o que acontece e o que sai da etapa. |
.etp-nota |
1 a 2 frases. A ressalva dos prazos, no fim da lista e não no rodapé da página. |
| Quantidade | 4 a 6 <li>, numerando --etp-i a partir de 0 e em sequência. |
Comprimento parecido entre as etapas é estrutural, e não estética. A altura de cada item é o comprimento do segmento de filete que sai dele: um parágrafo com o dobro do tamanho do vizinho produz um trecho de filete com o dobro do tamanho, e o percurso deixa de parecer regular. Fique numa faixa de mais ou menos 30% entre o menor e o maior.
Nenhuma etapa fala de retorno. "Implementação" é onde a carteira é montada, não onde o dinheiro "começa a render" — ver Compliance.
Especificação dos assets
A foto é opcional e cabe em uma etapa, não em todas.
- Formato paisagem 16:9, mínimo 1600×900. A caixa é reservada por
aspect-ratio, então a foto entra sem mover a lista. - Até 180 KB. Ela é pequena na tela (520px de largura no máximo) e não precisa de mais.
- Composição com o assunto acima da metade: o terço de baixo fica sob o véu da legenda.
- Não pode ter: rosto identificável de cliente, tela com dados de carteira legíveis, logo de instituição financeira, documento com nome ou valor visível.
Como usar
<link rel="stylesheet" href="componentes/listas/linha-do-tempo-etapas/estilo.css">
<script src="componentes/listas/linha-do-tempo-etapas/script.js"></script>
Cada etapa declara a própria posição na sequência, a partir de 0:
<li class="etp-item" style="--etp-i:0">
<li class="etp-item" style="--etp-i:1">
Acrescentar ou tirar uma etapa é acrescentar ou tirar um <li> e continuar a numeração. Nada mais muda: a altura do segmento, o fim do filete e o alcance do progresso saem todos da própria lista.
Ganchos
| Gancho | Papel |
|---|---|
data-etp |
raiz da dobra. O script parte daqui, nunca do documento — a peça pode repetir na mesma página. |
data-rv |
no .etp-corpo de cada etapa, nunca no <li>. Ver Gotchas. |
.ttl |
no h2.sec-title, como em toda dobra. |
--etp-i |
índice do item, escrito à mão no markup. |
--etp-k |
escrito pelo script na seção: o progresso em unidades de etapa (0 = primeiro marcador, 4 = quinto). Só de leitura para quem consome. |
.is-live |
posta pelo script na seção. É ela que liga o filete dirigido e o apagamento dos marcadores. |
.is-vista / .is-atual |
postas pelo script em cada .etp-item. Uma .is-atual por vez. |
Parafusos
| Variável | O quê |
|---|---|
--etp-linha |
fração da janela onde mora a linha de leitura. .5 é o meio da tela, o padrão. |
--etp-max |
largura da coluna de leitura (760px). |
--etp-col / --etp-gap-col |
largura da coluna do filete e vão até o texto. |
--etp-vao |
respiro entre uma etapa e a seguinte. |
--etp-topo-h |
altura da faixa do número e do prazo — é dela que sai --etp-cap, e é ela que alinha o marcador ao número. |
--etp-suave |
suavização do preenchimento entre um valor e o seguinte (120ms). |
Variações
- Seis etapas — acrescente um
<li>e continue a numeração de--etp-i. Nada mais muda. Rodou no preview. - Sem foto — apague a
<figure>da última etapa. A foto é opcional por desenho. - Última dobra da página —
--etp-linha:.62antecipa o fecho do filete. Ver o gotcha da meia tela abaixo. Experimental: a proporção certa depende de quanto rodapé a página tem. - Sobre seção clara — troque
.sec-deeppor.sec-paperno<section>. O componente não lê cor própria em lugar nenhum, e o miolo do marcador apagado é--bg, que acompanha o escopo. Não foi exercitada em produção.
Gotchas
- O
data-rvestá no.etp-corpoe não no<li>, e isso é medido. O core termina todo reveal com[data-rv].in{transform:none}, seletor (0,2,0), que vence qualquer classe do componente. O preenchimento do filete se move portransform:scaleY()— no mesmo nó dodata-rvele seria apagado em silêncio assim que a dobra entrasse, com ostyleinline aparecendo certo no inspetor e o computado voltando anone. O segundo motivo é tão forte quanto: o repouso dodata-rvvaletranslateY(22px), e o script mede a posição dos marcadores — marcador dentro de um bloco deslocado devolveria medida errada até o reveal. Aqui o marcador e o filete são irmãos do bloco revelado, não filhos dele. Precedente da regra:efeitos/inclinacao-3dcom o.tilt-card-slot. - O reset do core zera
ul, nãool. A lista aqui é ordenada de propósito, e semlist-style:none; padding:0; margin:… 0 0no.etp-listao navegador entrega os padrões dele. Medido: 40px de recuo (o filete saía da coluna) e, num<li>que édisplay:grid, um::markernumerado que o Chrome trata comoinsidee insere na grade — o que empurrava o texto 10px para baixo do marcador, a 1440 e a 390. O número visível é a.etp-num; o::markerseria um segundo número. - O último item não desenha segmento, e é por isso que o filete nunca passa do último marcador. Não há grampo, não há
Math.min, não há medida no script: simplesmente não existe trilho depois do último ponto. Medido a 1440, a 390 e depois de redimensionar a janela — a ponta do preenchimento cai exatamente sobre o centro do último marcador, com diferença de 0,1px de arredondamento. scaleYnão engorda o filete. A largura do elemento é fixa (--etp-fio-w) e só o eixo Y escala, então o traço tem 2px em qualquer estágio do preenchimento. TrocarscaleYporheightfuncionaria visualmente e refaria o layout de quatro segmentos a cada quadro de rolagem — que é o jank que o §7 do contrato existe para evitar.- A dobra precisa de meia tela de página abaixo do último marcador. A linha de leitura mora no meio da janela; se a linha do tempo for a última coisa antes do rodapé, o último marcador pode nunca cruzá-la e o filete não fecharia. O script trata a ponta do documento grampeando a rolagem prevista de cada marcador no curso que a página realmente tem — o filete fecha no fim do documento mesmo assim —, mas o fecho fica concentrado nos últimos pixels. Quando isso incomodar,
--etp-linha:.62. Numa página normal, o rodapé já resolve. --etp-topo-hé 30px porque é a altura da.pilldo core. Trocar o rótulo de prazo por outra coisa — um.eyebrow, um texto solto — muda essa altura e tira o marcador do eixo do número. Refaça o número junto.- Movimento reduzido desliga o comportamento inteiro, e o repouso é o CHEIO. O script sai antes de pôr
.is-live: o filete nasce completo e todos os marcadores acesos. Não é "desligar a animação": desligar deixando o filete vazio apagaria a peça, e um processo sem filete não é um processo com menos movimento — é uma lista de cinco parágrafos soltos. Medido comprefers-reduced-motion: reducee com JavaScript desligado de verdade: escala 1 nos quatro segmentos, cinco marcadores na cor de marca, texto em opacidade 1. - Nada na peça é focável, e isso é decisão. Cinco marcadores clicáveis dariam cinco paradas de
Tabque levariam a lugar nenhum — o conteúdo já está inteiro na tela, não há o que abrir. Se a etapa precisar de link, ele entra dentro de.etp-textocomo link de prosa, e aí é um link de verdade, com destino.
Compliance
A peça devolve números de calendário, e é por isso que esta seção existe. Antes de publicar, o consumidor tem de fazer as quatro coisas abaixo.
- Trocar os prazos. Os intervalos do
markup.htmlsão exemplo editorial, calibrados para soarem plausíveis numa assessoria — não são compromisso de ninguém. Substituir pelos prazos reais do cliente, validá-los com quem executa o processo e datá-los na ficha do projeto. - Manter o prazo em faixa. "De 2 a 3 semanas", nunca "15 dias". Prazo cravado numa peça de marketing é lido como compromisso, e o
.etp-prazotem largura para a faixa justamente para tirar a tentação. - Manter a fronteira processo × resultado. Nenhuma etapa pode falar de rentabilidade, retorno, ganho ou desempenho. A armadilha é sempre a mesma e sempre na etapa de implementação: "onde seu dinheiro começa a render" é a frase que não pode existir. Aqui a etapa 03 diz o que acontece (a carteira é montada dentro das faixas aprovadas, na custódia que já é do cliente) e como o assessor é remunerado (taxa previamente acordada), e para por aí.
- Passar a ressalva pelo compliance do cliente. O texto da
.etp-notadiz que os prazos são estimados, de onde eles são contados e o que os faz variar. Ele fica no fim da lista, onde a pessoa acabou de ler as pílulas — não no rodapé da página.
Já resolvido no componente e que não deve regredir: nenhum nome de instituição real, nenhum nome de cliente, nenhum superlativo de mercado, nenhum dado pessoal coletado e nada gravado — a peça não tem campo, não tem clique e não usa localStorage, cookie nem envio.
Histórico
| Projeto | Onde | Data | Diferenças |
|---|---|---|---|
| autoral | padrão: linha do tempo vertical com filete preenchido pela rolagem | 2026-09-06 | construído do zero para a biblioteca; nunca rodou em produção |
Origem. Componente autoral (§11 do contrato). Não há referência única: o padrão — coluna única, marcador por etapa, fio que acompanha a leitura — aparece em página de processo de consultoria, em documentação de produto e em onboarding de fintech, e é justamente por ser um lugar-comum bem resolvido que ele merecia uma versão da casa em vez de ser improvisado a cada site. A categoria listas tinha quatro componentes e nenhuma linha do tempo vertical.
Decisões da tradução para o contrato:
- Coluna única, sem alternar lados. A alternância esquerda/direita é o desenho mais visto do padrão e o que menos sobrevive: em 390px os dois lados desabam para a mesma coluna e sobra um remendo com metade dos itens desalinhados. Processo se lê em sequência, não em simetria — e foi por ter recusado a alternância desde o começo que a media query de mobile precisou de quatro linhas, todas de escala.
- O trilho é por etapa e é calculado só em CSS. Cada
.etp-itemdesenha o próprio segmento, do centro do seu marcador ao centro do seguinte, usando--etp-cape um vazamento de--etp-cappara baixo da própria caixa. O script não mede altura de trilho nenhum, e o último item simplesmente não desenha segmento — de onde sai, de graça, a garantia de que o preenchimento nunca passa do último marcador. - Um número, cinco segmentos. O script escreve um único
--etp-kna seção; cada segmento tira a própria fatia comclamp(0, calc(var(--etp-k) - var(--etp-i)), 1). É a mesma economia do--wheel-angledomidia/roda-de-cards: uma escrita por quadro, e a distribuição fica no CSS. - O repouso é o cheio. Sem script e com movimento reduzido a peça fica completa e parada, e é a classe
.is-livedo script que liga o comportamento — como faz oconversao/diagnostico-perfil. O contrário (nascer vazio, o script encher) deixaria a dobra em branco no dia em que o script não rodasse. - A linha de leitura é grampeada nas pontas do documento. "Corrente é a etapa que cruzou o meio da janela" é o critério, e ele não fecha quando a dobra é a última da página. Converter cada marcador na rolagem que o traria até a linha, e grampear esse número em
[0, scrollHeight - innerHeight], preserva a ordem (logo o progresso continua monótono) e garante o fecho no fim do documento.
Normalizações aplicadas: prefixo etp- em toda classe; zero cor crua (o véu da legenda usa rgba(var(--dark-rgb),…), que lê token); .pill, .visually-hidden, .eyebrow, .sec-title, .sec-lead, .wrap e .nota (a ressalva) vêm do core e não foram recopiadas; scroll pelo laço único LIB.onScroll; LIB.reduce consultado com o mesmo fallback dos irmãos, para o caso de o componente ser colado sem o motion.js; JS ES5-safe dentro de IIFE, com guard silencioso e busca a partir da raiz.
Divergências conhecidas vs. produção: nenhuma — não rodou em produção ainda.
O que foi medido (bin/medir.js, Chrome headless, tema liberta-wealth):
| Medida | Resultado |
|---|---|
--etp-k em --scroll=0 / 0.5 / 0.9, a 1440 |
0.0000 / 3.8187 / 4.0000 — monótono |
| filete pintado, mesmas frações | 0px / 900,8px / 944,9px (total dos quatro segmentos: 944,8px) |
o mesmo em --mobile |
0.0000 / 3.3199 / 4.0000; 0px / 1076px / 1302px |
| ponta do preenchimento × centro do último marcador | 1378 × 1378 a 1440; 1772 × 1772 a 390 — nunca passa, em nenhuma fração |
| etapa corrente | no máximo uma .is-atual em toda fração, em 1440 e em 390 (zero antes de o primeiro marcador cruzar a linha, que é o estado "a dobra ainda está entrando") |
--reduce |
sem .is-live, escala 1 nos quatro segmentos, cinco marcadores em --accent |
| JavaScript desligado de verdade | idem, e .etp-corpo em opacidade 1 (o @media (scripting:none) do core) |
| overflow horizontal | ok em 1920, 1440, 1024, 768, 640, 390 e 360 |
| alinhamento marcador × pílula do prazo | 0,00px de desalinho nas cinco etapas, em 1440 e em 390 |
| emenda entre segmentos | 0,0px em três junções, 0,1px de arredondamento na quarta |
| redimensionar a janela no meio da rolagem | medida refeita; ponta volta a cair sobre o último marcador (1378 → 1418 → 1378) |
| console | limpo em todas as execuções |