← Biblioteca componentes/conversao/cta-com-assessor/ficha.md CódigoTela cheia
conversao/cta-com-assessor

CTA com o rosto do assessor

🟢 estavel complexidade média prefixo asr- cta fecho assessor pessoa retrato disponibilidade horario institucional

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

<link rel="stylesheet" href="componentes/conversao/cta-com-assessor/estilo.css">
<script src="componentes/conversao/cta-com-assessor/script.js"></script>

markup.html · 44 linhas · 2,4 KB

<!-- ==========================================================================
     CTA COM O ASSESSOR — a chamada final com o rosto de quem atende
     Prefixo: asr-
     Requer: core (tokens, base, motion.css, motion.js) + este estilo.css e
             este script.js (opcional: só concede o selo de disponibilidade)

     A chamada deixa de ser uma frase e vira uma pessoa: retrato, uma frase
     em primeira pessoa, nome e cargo, e os dois botões. Em assessoria, é a
     diferença entre "falar com a casa" e "falar com alguém".

     O SELO DE DISPONIBILIDADE É CONCEDIDO, NÃO ESCRITO. O card declara o
     horário (data-asr-horario) e o fuso (data-asr-fuso), e o script lê o
     relógio NAQUELE fuso: "Atende agora · até 18h" ou "Volta amanhã às 9h".
     Sem JavaScript o selo não aparece — a peça nunca diz "disponível" sem
     poder conferir. Mesmo motor do conversao/contato-escritorios.

     O RETRATO É DE QUEM ATENDE DE VERDADE. Foto de banco com nome inventado
     é o tipo de detalhe que o cliente descobre na primeira reunião.
     ========================================================================== -->

<section class="sec-dark sec-pad asr">
  <div class="wrap">
    <article class="asr-card" data-asr data-asr-horario="1-5 09:00-18:00" data-asr-fuso="America/Sao_Paulo" data-rv>
      <div class="asr-foto">
        <img class="asr-img" src="../../../showroom/demo/ph-5.webp" alt="Ricardo Couto, sócio" loading="lazy" decoding="async">
      </div>
      <div class="asr-corpo">
        <p class="asr-estado" data-asr-estado></p>
        <p class="asr-frase">Ainda com dúvida? Vamos conversar trinta minutos — eu explico como trabalhamos, e você decide sem pressa.</p>
        <p class="asr-quem">
          <span class="asr-nome">Ricardo Couto</span>
          <span class="asr-cargo">Sócio · Planejamento sucessório</span>
        </p>
        <div class="asr-acoes">
          <a class="btn btn-primary" href="#agendar">
            Agendar com o Ricardo
            <svg width="13" height="13" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 7H12M8 3L12 7L8 11"/></svg>
          </a>
          <a class="btn btn-ghost" href="https://wa.me/5511900000000" rel="noopener" target="_blank">WhatsApp</a>
        </div>
      </div>
    </article>
  </div>
</section>

estilo.css · 55 linhas · 2,1 KB

/* ==========================================================================
   CTA COM O ASSESSOR — asr-
   Retrato, frase em primeira pessoa, nome, cargo, dois botões e o selo de
   disponibilidade concedido pelo relógio.
   Tokens usados: --bg --fg --fg-2 --fg-muted --rule --rule-2 --accent
                  --display --radius-media --radius-pill
   Parafuso local:
     --asr-foco   enquadramento do retrato (object-position)
   ========================================================================== */

.asr-card{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  max-inline-size:980px;margin-inline:auto;
  border:1px solid var(--rule);border-radius:var(--radius-media);
  background:color-mix(in srgb,var(--fg) 4%,var(--bg));
  overflow:hidden;
}

.asr-foto{position:relative;min-block-size:340px}
.asr-img{
  position:absolute;inset:0;inline-size:100%;block-size:100%;object-fit:cover;
  object-position:var(--asr-foco,30% 30%);
}

.asr-corpo{
  display:grid;align-content:center;gap:20px;
  padding:clamp(28px,4vw,56px);
}

/* O selo nasce vazio e o CSS o apaga: sem script, nenhum "disponível". O
   estado vai por extenso; o ponto repete, nunca substitui. */
.asr-estado:empty{display:none}
.asr-estado{
  display:inline-flex;align-items:center;gap:9px;justify-self:start;
  font-size:12px;letter-spacing:.04em;color:var(--fg-muted);
  border:1px solid var(--rule-2);border-radius:var(--radius-pill);padding:6px 12px;
}
.asr-estado::before{content:"";inline-size:7px;block-size:7px;border-radius:50%;background:var(--rule-2)}
.asr-card[data-aberto="sim"] .asr-estado{color:var(--fg)}
.asr-card[data-aberto="sim"] .asr-estado::before{background:var(--accent)}

.asr-frase{
  font-family:var(--display);font-weight:600;
  font-size:clamp(21px,2.2vw,30px);line-height:1.3;letter-spacing:-.018em;
  color:var(--fg);text-wrap:pretty;
}
.asr-quem{display:grid;gap:3px}
.asr-nome{font-size:15px;color:var(--fg)}
.asr-cargo{font-size:12.5px;letter-spacing:.04em;color:var(--fg-muted)}
.asr-acoes{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}

@media(max-width:760px){
  .asr-card{grid-template-columns:1fr}
  .asr-foto{min-block-size:0;aspect-ratio:4 / 3}
}

script.js · 80 linhas · 3,3 KB

/* ==========================================================================
   CTA COM O ASSESSOR — asr-
   Concede o selo de disponibilidade lendo o relógio NO FUSO DO ESCRITÓRIO:
   "Atende agora · até 18h", "Volta às 14h", "Volta amanhã às 9h".

   O horário vem em data-asr-horario, uma ou mais regras separadas por ";"
   ("1-5 09:00-18:00; 6 09:00-12:00"), dias de 0 (domingo) a 6 (sábado). O
   fuso em data-asr-fuso (IANA). Regra ilegível: nenhum selo.

   A HORA NO FUSO vem do core (LIB.relogio, core/motion.js). Esta era a
   segunda cópia da função — a primeira estava no conversao/contato-
   escritorios —, e a terceira (hero/letreiro-marca) foi o gatilho do §6. A
   regra do selo continua aqui. Não anima nada; reavalia a cada minuto.
   ========================================================================== */
(function () {
  var cards = document.querySelectorAll('[data-asr][data-asr-horario]');
  if (!cards.length) return;                   // guard: sem o componente, saída silenciosa
  if (!window.LIB || !LIB.relogio) return;     // core antigo: nenhum selo

  var DIAS = ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'];

  function hora(min) {
    var h = Math.floor(min / 60), m = min % 60;
    return h + 'h' + (m ? (m < 10 ? '0' : '') + m : '');
  }
  function minutos(hhmm) {
    var m = /^(\d{1,2}):(\d{2})$/.exec(hhmm);
    return m ? (+m[1]) * 60 + (+m[2]) : NaN;
  }
  function ler(texto) {
    var regras = [];
    (texto || '').split(';').forEach(function (parte) {
      var m = /^\s*(\d)(?:-(\d))?\s+(\d{1,2}:\d{2})-(\d{1,2}:\d{2})\s*$/.exec(parte);
      if (!m) return;
      var dias = [];
      for (var d = +m[1]; d <= (m[2] ? +m[2] : +m[1]); d++) dias.push(d);
      var ini = minutos(m[3]), fim = minutos(m[4]);
      if (!isNaN(ini) && !isNaN(fim) && fim > ini) regras.push({ dias: dias, ini: ini, fim: fim });
    });
    return regras;
  }
  function estado(regras, agora) {
    var i, r;
    for (i = 0; i < regras.length; i++) {
      r = regras[i];
      if (r.dias.indexOf(agora.dia) >= 0 && agora.min >= r.ini && agora.min < r.fim) {
        return { aberto: true, texto: 'Atende agora · até ' + hora(r.fim) };
      }
    }
    for (var passo = 0; passo <= 7; passo++) {
      var dia = (agora.dia + passo) % 7, melhor = null;
      for (i = 0; i < regras.length; i++) {
        r = regras[i];
        if (r.dias.indexOf(dia) < 0 || (passo === 0 && r.ini <= agora.min)) continue;
        if (melhor === null || r.ini < melhor) melhor = r.ini;
      }
      if (melhor !== null) {
        var quando = passo === 0 ? '' : (passo === 1 ? 'amanhã ' : DIAS[dia] + ' ');
        return { aberto: false, texto: 'Volta ' + quando + 'às ' + hora(melhor) };
      }
    }
    return null;
  }

  function avaliar() {
    [].forEach.call(cards, function (card) {
      var alvo = card.querySelector('[data-asr-estado]');
      if (!alvo) return;
      var regras = ler(card.getAttribute('data-asr-horario'));
      var agora = LIB.relogio(card.getAttribute('data-asr-fuso') || 'America/Sao_Paulo');
      var e = regras.length && agora ? estado(regras, agora) : null;
      alvo.textContent = e ? e.texto : '';
      if (e) card.setAttribute('data-aberto', e.aberto ? 'sim' : 'nao');
      else card.removeAttribute('data-aberto');
    });
  }

  avaliar();
  setInterval(avaliar, 60000);
})();

A chamada final com uma pessoa. Retrato à esquerda; à direita, uma frase em primeira pessoa ("Ainda com dúvida? Vamos conversar trinta minutos…"), o nome, o cargo e dois botões — agendar com essa pessoa ou falar no WhatsApp. Acima da frase, um selo concedido pelo relógio: "Atende agora · até 18h" ou "Volta amanhã às 9h".

O problema que ela resolve: assessoria é relação entre pessoas, e a chamada típica de fim de página fala em nome de uma marca. Quem hesita em "agendar uma reunião" hesita menos em "conversar com o Ricardo". O selo responde a pergunta de logo antes do clique: tem alguém lá agora?


Quando usar

Quando não usar


Padrão editorial

Slot Regra
Frase 10 a 26 palavras, primeira pessoa, com o convite concreto
Nome quem atende de verdade
Cargo cargo e especialidade
Botão com o nome: "Agendar com o Ricardo"

O que mantém a peça: a frase é da pessoa, não da empresa. "Vamos conversar trinta minutos — eu explico como trabalhamos" funciona; "Nossa equipe está pronta para atendê-lo" desmonta o retrato ao lado.

Especificação dos assets


Como usar

<link rel="stylesheet" href="componentes/conversao/cta-com-assessor/estilo.css">
<script src="componentes/conversao/cta-com-assessor/script.js"></script>

O script é opcional: sem ele, tudo funciona e o selo não aparece.

Ganchos

Gancho Papel
data-asr-horario regras separadas por ;, dias 0 (domingo) a 6 (sábado): 1-5 09:00-18:00
data-asr-fuso fuso IANA do escritório. America/Sao_Paulo se ausente
[data-asr-estado] o selo, preenchido pelo script; vazio, some
.asr-card[data-aberto] sim ou nao; o ponto acende na cor de marca
--asr-foco enquadramento do retrato

Variações


Gotchas


Movimento reduzido / toque

Nada anda além do reveal do core. O selo é estado, não chamada: não pulsa.


Histórico

Origem Quando O quê
referência: poch.studio 2026-09-29 Clone de referência, reescrito do zero

Referências visuais: poch.studio e leandra-isler.ch, via cta.gallery. O indicador "online" das referências virou selo concedido pelo relógio. Registro consolidado em projetos/referencias-externas.md.