← Biblioteca componentes/prova/carrossel-depoimentos/ficha.md CódigoTela cheia
prova/carrossel-depoimentos

Carrossel de depoimentos

🟢 estavel complexidade média prefixo depo- depoimento prova-social esteira carrossel citacao movimento-continuo sem-js mascara-horizontal sangria claro sem javascript

Incluir · as linhas que se colam num site novo, depois do core (CLAUDE.md §10)

<link rel="stylesheet" href="componentes/prova/carrossel-depoimentos/estilo.css">

markup.html · 118 linhas · 6,1 KB

<!-- ==========================================================================
     CARROSSEL DE DEPOIMENTOS — esteira de citações que não para
     Prefixo: depo-
     Requer: core (tokens, base, motion.css, motion.js) + estilo.css
     SEM JavaScript. A esteira é uma animação de CSS até -50%.

     POR QUE ESTEIRA E NÃO CARROSSEL. Depoimento não se navega, se atravessa:
     ninguém procura o terceiro depoimento. O trilho anda sozinho e devagar,
     e quem quiser ler para basta passar o ponteiro. Não há seta, não há
     indicador e não há arrasto — o midia/carrossel-perfis existe para quando
     o arrasto é o ponto, e aqui não é.

     ESTRUTURA OBRIGATÓRIA: a fila contém DOIS conjuntos idênticos de cards.
     A animação anda -50% do trilho, ou seja, exatamente a largura de um
     conjunto — é o que fecha o laço sem salto. A segunda cópia é decorativa:
     aria-hidden, senão o leitor de tela anuncia cada pessoa duas vezes.
     Mesma receita do prova/marquee-logos.

     AS PONTAS DESVANECEM. O recorte sozinho corta o card no meio com uma
     borda dura, e o olho lê "quebrou". A máscara em gradiente resolve, e é a
     primeira vez que a biblioteca usa máscara no eixo HORIZONTAL — as outras
     dez ocorrências no repositório são o véu vertical sobre foto.

     ORDEM EDITORIAL IMPORTA. Com movimento reduzido a esteira congela, e
     quem chega vê só os primeiros. Os três primeiros têm de ser os melhores.
     ========================================================================== -->

<section class="sec-light sec-pad depo">
  <div class="wrap">

    <div class="depo-head">
      <div class="depo-head-left">
        <h2 class="sec-title ttl">Quem confia o patrimônio à Liberta</h2>
      </div>
      <p class="depo-head-right" data-rv data-d="1">
        De quem está estruturando a quem já organiza a terceira geração.<br>
        A Liberta assessora famílias e empresários em todo o país.
      </p>
    </div>

  </div>

  <div class="depo-rail" data-rv data-d="2">
    <div class="depo-track">

      <ul class="depo-set">
        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-3.webp" alt="Retrato de Junior Serpa" style="--depo-face-pos:58% 14%" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Junior Serpa</span>
              <span class="depo-role">Empresário — indústria</span>
            </span>
          </div>
          <p class="depo-quote">Saí de quatro gerentes que me ligavam para vender produto e passei a ter uma pessoa que me liga para explicar. A carteira ficou mais simples e o resultado, mais previsível. Foi a primeira vez que entendi onde meu dinheiro estava.</p>
        </li>

        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-4.webp" alt="Retrato de Yan Pedro" style="--depo-face-pos:52% 26%" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Yan Pedro</span>
              <span class="depo-role">Sócio — agronegócio</span>
            </span>
          </div>
          <p class="depo-quote">Vendi participação na empresa e tinha noventa dias para decidir. A Liberta montou a estrutura, trouxe o jurídico e o contábil para a mesma mesa e me deixou decidir com número na frente.</p>
        </li>

        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-7.webp" alt="Retrato de Yuri Rossi" style="--depo-face-pos:62% 40%" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Yuri Rossi</span>
              <span class="depo-role">Família — terceira geração</span>
            </span>
          </div>
          <p class="depo-quote">Chegamos com o patrimônio dividido entre seis irmãos e nenhum acordo escrito. Hoje existe holding, testamento e um comitê que se reúne a cada trimestre. O que era assunto proibido virou pauta.</p>
        </li>
      </ul>

      <ul class="depo-set" aria-hidden="true">
        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-3.webp" alt="" style="--depo-face-pos:58% 14%" loading="lazy" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Junior Serpa</span>
              <span class="depo-role">Empresário — indústria</span>
            </span>
          </div>
          <p class="depo-quote">Saí de quatro gerentes que me ligavam para vender produto e passei a ter uma pessoa que me liga para explicar. A carteira ficou mais simples e o resultado, mais previsível. Foi a primeira vez que entendi onde meu dinheiro estava.</p>
        </li>

        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-4.webp" alt="" style="--depo-face-pos:52% 26%" loading="lazy" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Yan Pedro</span>
              <span class="depo-role">Sócio — agronegócio</span>
            </span>
          </div>
          <p class="depo-quote">Vendi participação na empresa e tinha noventa dias para decidir. A Liberta montou a estrutura, trouxe o jurídico e o contábil para a mesma mesa e me deixou decidir com número na frente.</p>
        </li>

        <li class="depo-card">
          <div class="depo-who">
            <img class="depo-face" src="../../../showroom/demo/ph-7.webp" alt="" style="--depo-face-pos:62% 40%" loading="lazy" decoding="async">
            <span class="depo-id">
              <span class="depo-name">Yuri Rossi</span>
              <span class="depo-role">Família — terceira geração</span>
            </span>
          </div>
          <p class="depo-quote">Chegamos com o patrimônio dividido entre seis irmãos e nenhum acordo escrito. Hoje existe holding, testamento e um comitê que se reúne a cada trimestre. O que era assunto proibido virou pauta.</p>
        </li>
      </ul>

    </div>
  </div>
</section>

estilo.css · 139 linhas · 5,1 KB

/* ==========================================================================
   CARROSSEL DE DEPOIMENTOS — prefixo depo-
   Cabeçalho em duas colunas e uma esteira de cards brancos que não para,
   com as pontas desvanecendo.

   Tokens usados:
     --light             fundo do card
     --fg --fg-2 --fg-muted   nome, citação e área
     --rule              fio da borda do card
     --radius-media      canto do card
     --radius-pill       o retrato redondo
     --pad --max         a conta do recuo que alinha a esteira à coluna
     --ease              curva do projeto

   Sem JavaScript. O laço é CSS puro: o trilho anda -50%, que é a largura
   exata de um dos dois conjuntos idênticos.
   ========================================================================== */

.depo{
  --depo-card:340px;      /* largura do card */
  --depo-gap:20px;        /* vão entre um card e o próximo */
  --depo-dur:44s;         /* uma volta inteira. Três citações ≈ 44s. */

  /* SANGRIA SEM MARGEM NEGATIVA (§4). O cabeçalho vive dentro do .wrap; a
     esteira é IRMÃ dele, filha direta da seção, e por isso já nasce com a
     largura da página. O que falta é fazer o primeiro card começar na borda
     da coluna: é este recuo, que repete a conta do .wrap aplicada à esteira.
     Mesmo recurso do midia/galeria-scroll-horizontal. */
  --depo-inset:max(var(--pad),calc((100% - var(--max)) / 2 + var(--pad)));
}

/* ---------------------------------------------------------------- cabeçalho */
/* Título à esquerda, apoio à direita e alinhado À DIREITA. Não usa .sec-head
   do core de propósito: aquele é cabeçalho CENTRADO, e aqui os dois lados
   precisam se olhar de ponta a ponta da coluna. */
.depo-head{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:clamp(20px,3vw,32px);
  margin-bottom:clamp(30px,5vh,48px);
}
.depo-head-left{max-width:560px;min-width:0}

.depo-head-right{
  font-size:clamp(15px,1.25vw,18px);line-height:1.55;
  color:var(--fg-2);
  max-width:470px;
  text-align:right;
  flex:0 1 auto;
}

/* ---------------------------------------------------------------- esteira */
/* AS PONTAS. Só o recorte corta o card no meio com borda dura e o olho lê
   "quebrou". A máscara dissolve os dois lados em 5% da largura, que é onde
   a referência põe as paradas.

   Primeira máscara HORIZONTAL da biblioteca: as outras dez são o véu
   vertical sobre foto do §6. Se um terceiro componente pedir esta, ela é
   candidata a primitiva. */
.depo-rail{
  overflow:hidden;
  padding-inline:var(--depo-inset);
  /* O recorte come o anel de foco e a sombra do card nos dois eixos. */
  padding-block:8px;
  mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 5%,#000 95%,transparent 100%);
}

.depo-track{
  display:flex;
  width:max-content;
  animation:depoRun var(--depo-dur) linear infinite;
}

/* O padding-inline-end é o que mantém o vão na emenda entre as duas cópias:
   sem ele os dois conjuntos se encostam e o laço dá um solavanco visível a
   cada volta. */
.depo-set{
  display:flex;align-items:stretch;
  gap:var(--depo-gap);
  padding-inline-end:var(--depo-gap);
  margin:0;
}

/* Pausa no hover: quem quer ler uma citação inteira consegue parar a fila.
   É a única "navegação" da dobra, e basta. */
.depo:hover .depo-track{animation-play-state:paused}

@keyframes depoRun{
  from{transform:translateX(0)}
  to{transform:translateX(-50%)}
}

/* ---------------------------------------------------------------- card */
.depo-card{
  flex:0 0 var(--depo-card);
  display:flex;flex-direction:column;
  padding:24px;
  background:var(--light);
  border:1px solid var(--rule);
  border-radius:var(--radius-media);
}

.depo-who{display:flex;align-items:flex-start;gap:12px}

.depo-face{
  width:44px;height:44px;flex:0 0 auto;
  border-radius:var(--radius-pill);
  object-fit:cover;
  /* O corte é por pessoa, não por regra: retrato de estúdio tem o rosto no
     terço de cima, foto de ambiente tem no meio. Cada card declara o seu no
     markup, como no conteudo/pilares-texto-na-foto. */
  object-position:var(--depo-face-pos,50% 30%);
  background:var(--rule);
}

.depo-id{display:flex;flex-direction:column;min-width:0}
.depo-name{font-size:16px;line-height:1.5;font-weight:600;color:var(--fg)}
.depo-role{font-size:14px;line-height:1.45;color:var(--fg-muted)}

.depo-quote{
  margin-top:16px;
  font-size:16px;line-height:1.62;
  color:var(--fg-2);
}

/* ---------------------------------------------------------------- movimento reduzido */
/* A esteira congela. Quem chega vê os três primeiros cards, parados — por
   isso o padrão editorial da ficha manda pôr os melhores em primeiro. */
@media(prefers-reduced-motion:reduce){
  .depo-track{animation:none}
}

/* ---------------------------------------------------------------- mobile */
@media(max-width:760px){
  .depo-head{flex-direction:column;gap:16px}
  /* Empilhado, alinhar o apoio à direita descola os dois blocos. */
  .depo-head-right{text-align:left;max-width:none}
  .depo{--depo-card:min(80vw,320px);--depo-gap:14px}
}

Um cabeçalho que se abre em duas pontas — título à esquerda, apoio encostado na margem direita — e, abaixo dele, uma esteira de cards brancos que atravessa a página sem parar. Cada card é retrato redondo de 44px, nome, área de atuação e a citação embaixo. As duas pontas do trilho desvanecem em vez de cortar, então a fila não tem começo nem fim visível: o olho pega a esteira no meio, lê um card, e o próximo já entrou. Passar o ponteiro para a fila, e é a única navegação que existe aqui.

Resolve o problema do depoimento que ninguém lê. Empilhado em grade, um bloco de três citações vira parede de texto e o visitante pula; num carrossel com setas, ele teria de decidir clicar — e ninguém procura o terceiro depoimento de uma empresa. A esteira tira a decisão do caminho: ela oferece movimento e devolve legibilidade só a quem pediu, parando no hover. E como o trilho não tem borda, a dobra afirma "há mais gente aqui" sem prometer um número que uma lista completa teria de sustentar.


Quando usar

Quando não usar


Padrão editorial

Slot Regra
Título (h2.sec-title.ttl) 5 a 8 palavras, uma ou duas linhas na caixa de 560px. Diz o que as pessoas fizeram, não que elas são clientes.
Apoio (.depo-head-right) Duas linhas, separadas por <br> escrito à mão — a caixa tem 470px e alinha à direita, então quebra automática deixa a segunda linha caindo torta. Enquadra o conjunto ("de quem começa a quem já fatura milhões"); não repete o título.
Retrato Um por card, obrigatório. Rosto reconhecível a 44px.
Nome Nome e sobrenome. Sem título acadêmico, sem @, sem nome de empresa colado.
Área (.depo-role) Uma linha, até ~28 caracteres. É o perfil, não o cargo: "Empresário — indústria", "Família — terceira geração". Cargo de empresa que ninguém conhece não prova nada.
Citação 220 a 340 caracteres. Abaixo disso o card fica com um vão branco embaixo, porque todos têm a mesma largura de 340px e a altura acompanha o mais alto da fila. Acima de 340 a citação passa de sete linhas e o card cresce sozinho, desalinhando o resto.
Quantidade 3 a 6 depoimentos, escritos duas vezes no markup (ver Gotchas).

O que mantém a fila coesa é o paralelismo de tamanho, e ele é mais rígido aqui do que em componente de grade: como os cards passam um atrás do outro na mesma linha, uma citação de duas linhas ao lado de outra de sete lê como card quebrado, não como variação. Escreva as três no mesmo comprimento e corte o excesso — depoimento cortado com reticências é aceitável e comum; card desigual não é.

Ordem é regra editorial, não gosto. Com prefers-reduced-motion: reduce a esteira congela na posição inicial, e quem tem essa preferência ligada vê exatamente os primeiros cards e mais nada. Os três primeiros depoimentos têm de ser os mais fortes do conjunto — o nome mais conhecido, a frase mais específica, o segmento mais próximo do público da página. O quarto em diante é bônus para quem espera a volta.

Especificação dos assets


Como usar

<link rel="stylesheet" href="componentes/prova/carrossel-depoimentos/estilo.css">

Sem script. O core (tokens.css, base.css, motion.css, motion.js) já é o que faz o cabeçalho entrar.

Estrutura obrigatória

O .depo-track contém dois .depo-set idênticos. O primeiro é o conteúdo; o segundo leva aria-hidden="true", alt="" nas imagens e loading="lazy". Acrescentar um depoimento significa acrescentá-lo nos dois conjuntos, na mesma posição.

O cabeçalho fica dentro do .wrap; a esteira é irmã dele, filha direta da <section> — é assim que ela sangra sem margem negativa.

<section class="sec-light sec-pad depo">
  <div class="wrap"> <div class="depo-head"> … </div> </div>
  <div class="depo-rail" data-rv data-d="2">
    <div class="depo-track">
      <ul class="depo-set">              … 3 cards … </ul>
      <ul class="depo-set" aria-hidden="true"> … os mesmos 3 … </ul>
    </div>
  </div>
</section>

Ganchos

Gancho Papel
.depo A seção. Carrega as quatro variáveis de ajuste — é o único lugar onde se mexe.
.depo-head / .depo-head-left / .depo-head-right Cabeçalho de duas pontas. A esquerda tem max-width:560px; a direita, 470px e text-align:right.
.depo-rail O recorte. Dono da máscara das pontas e do padding-inline que alinha o primeiro card à coluna.
.depo-track O que anda. Um flex de width:max-content com a animação depoRun.
.depo-set Um conjunto. Tem de haver exatamente dois, idênticos.
.depo-card / .depo-who / .depo-face / .depo-id / .depo-name / .depo-role / .depo-quote Card e suas partes.
--depo-card Largura do card. 340px no padrão; min(80vw,320px) abaixo de 760px.
--depo-gap Vão entre um card e o próximo. 20px no padrão, 14px no mobile.
--depo-dur Uma volta inteira. 44s no padrão, para três citações. Cresce junto com o número de cards (ver Gotchas).
--depo-inset Recuo que alinha o primeiro card à borda da coluna: max(--pad, (100% − --max)/2 + --pad). Refaz a conta do .wrap. Não mexer sem motivo.
--depo-face-pos Corte do retrato, por card, no style do <img>. Padrão 50% 30%.

Classes de estado: nenhuma. O componente não tem .is-* porque não tem JavaScript. O único estado é :hover na raiz .depo, que pausa a animação — não há classe para inspecionar nem para forçar.

Variações


Gotchas


Histórico

Projeto Onde Data Diferenças
referência: Kirvano https://www.kirvano.com/ — dobra "Histórias de quem cresce com a Kirvano" 2026-09-01 referência visual, não origem de código

Escrito do zero a partir da observação da dobra de depoimentos de kirvano.com, medida no navegador a 1440×900. O site roda Tailwind, com fonte de terceiro e sem licença declarada: nada foi copiado (§11). O que veio de lá é a medida e a ideia da interação. Números lidos na referência e reproduzidos aqui: card 340 × 268, gap 20, padding 24, retrato 44×44, nome 16/24 peso 600, área 14/20, citação margin-top 16, 16/26; máscara linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); cabeçalho de duas colunas com esquerda em 560 e direita em 470 alinhada à direita; três depoimentos duplicados ×2, fila de 2140 de largura — que é exatamente 340×6 + 20×5, a conta que este componente refaz por variável. Status externo: nunca rodou em produção nossa. O primeiro site que usar promove, e a ficha registra qual foi. A referência está registrada em projetos/referencias-externas.md.

Normalizações aplicadas na tradução:

Divergências conhecidas vs. a referência: