Da conta de luz ao pedido de visita, numa página por cidade
Página de cidade para uma empresa de painéis solares que atua em mais de 120 cidades. Quem chega de um anúncio ou de uma busca põe a conta de luz e vê, com a conta aberta, quantos painéis vão ser instalados, quanto custam e em quanto tempo se pagam. A empresa sabe de qual anúncio cada pessoa veio, do primeiro clique ao pedido de visita.

A página abre na cidade: a foto ocupa a primeira tela, o nome de Phoenix atravessa o céu e os fatos da cidade ficam ao lado do título.
Escopo do projeto
Uma empresa de painéis solares que atua em mais de 120 cidades precisava, por SEO e para otimizar as campanhas, rastrear o caminho de cada cliente entre sessões e interações, e fazer o cliente chegar até ela já com os números exatos do que vai ser instalado.
A página faz as duas coisas sem complicar a experiência: a conta à vista aumenta a consciência do cliente e a credibilidade da empresa, e cada cidade sai do mesmo template, como arquivo estático ou num servidor Node.
Papel
Web Developer e Product Designer
Fiz a página inteira, do briefing ao ar: a fórmula prototipada e testada contra a tabela do briefing antes do plano, as decisões, cada rodada de design revisada na página real, e a medição. Trabalhei com o Claude Code de ponta a ponta, em rodadas: especificação e plano escritos, tarefas em paralelo com revisão independente, e um navegador de verdade conferindo cada versão. Todo número reportado foi conferido rodando.
Desafios
O que a empresa precisava, e o que quem visita precisa:
-
01
120 cidades em qualquer hospedagem
Quem recebe a página provavelmente tem servidor compartilhado, sem Node, e cada cidade precisa abrir rápido e ficar em cache sem ninguém mexer em código
-
02
Um preço que dê para seguir
Três regras mexem no número, e um número que muda sem explicação parece isca de anúncio
-
03
Medir anúncio sem back end
Na segunda a campanha pausa ou escala cada anúncio pelas simulações que ele trouxe, e a página não tem servidor para guardar isso
-
04
Quatro horas, com acabamento
Página de anúncio sem acabamento parece qualquer outra, e cada biblioteca a mais é peso que o celular paga antes de ver o número
Soluções
-
01
Um código, dois builds
Cada cidade sai do build como HTML pronto. Na hospedagem compartilhada, dois .htaccess dão URL limpa, cabeçalhos de segurança e um ano de cache aos arquivos com hash; no Node, o servidor manda os cabeçalhos
-
02
A conta à vista
A calculadora diz qual regra moldou cada número no instante em que ela age, e abre a fórmula inteira com os números da própria pessoa
-
03
O anúncio guardado na aba
O anúncio de origem fica na sessão da aba e sai com cada evento para o Google Tag Manager, o que basta para o relatório de segunda
-
04
Movimento em CSS nativo
Paralaxe, seção fixada e entradas sem biblioteca, todas em CSS. O simulador é o único componente grande que roda no navegador
A calculadora, peça por peça
As três regras da conta agem juntas. Aqui, cada peça aparece num recorte da página real; a calculadora inteira funciona na prévia no fim da página.
-

Duas linhas dizem qual regra agiu
Embaixo dos quatro números ficam sempre duas linhas: como o número de painéis foi definido, e se a economia cabe na conta. A pessoa arrasta o slider e lê a regra mudar junto.
- DecisãoArredondar sempre para cima: cobrir 80% de uma conta de $220 pede 16,71 painéis, e o sistema leva 17.
- Retorno ao usuárioA primeira linha mostra a fração e o inteiro a cada passo; a segunda confirma que a economia cabe na conta, ou avisa quando bate no teto.
- GuardrailUma tolerância no cálculo segura 20,000000004 em 20, para um resto de ponto flutuante não virar um painel a mais.
-

Todo sistema começa em 8 painéis
Quando a conta pede menos que o mínimo, a primeira linha fica amarela e diz o tamanho real. A $90 com 80%, a conta pede 7 painéis e o sistema fica em 8.
- Mínimo da empresa8 painéis por instalação, valor do arquivo da cidade. O menor sistema custa $6,930.00, já com o crédito federal de 30% descontado.
- DecisãoDizer que o sistema fica maior que o pedido: a $90 com 80%, os 8 painéis cobrem cerca de 94% do consumo, e numa conta de $60 geram mais do que a casa usa.
-

A economia para na conta
Quando a geração passa a conta, a segunda linha fica amarela e diz quanto passou. A $430 com 100%, 41 painéis geram $431.73 por mês, $1.73 acima da conta.
- GuardrailA economia nunca passa o valor da conta. O excedente vira crédito nas próximas contas, nunca dinheiro.
- DecisãoFora do teto, o retorno é sempre 6,9 anos, porque custo e geração crescem juntos por painel. O teto só pesa quando corta muito: numa conta de $60, os 8 painéis do mínimo geram mais do que a conta, a economia para em $60 e o retorno sobe para 9,6 anos.
-

A faixa que não muda nada vem marcada
No slider de cobertura, a faixa onde o mínimo segura o resultado vem sombreada, com legenda. Quem arrasta dentro dela lê “No change” embaixo do slider, com o motivo.
- Retorno ao usuárioAntes de mexer, a pessoa já vê que naquela faixa o sistema continua em 8 painéis.
- DecisãoO aviso aparece só onde o mínimo segura o número. Antes ele saía em 164 dos 1.186 passos só por arredondamento: $160 a 60% e a 65% pedem 9,12 e 9,88 painéis, os dois viram 10, e parecia erro.
-

A conta inteira, com os números da pessoa
“Show the math” abre a fórmula em oito passos, do consumo ao retorno, com os números da estimativa que está na tela.
- DecisãoMostrar a conta além do preço: quem compara orçamentos vê o que está comprando, e não só uma parcela. A página reforça isso com um depoimento na mesma linha.
- GuardrailTarifa e custo por watt saem com até quatro casas decimais, para a divisão impressa bater com a calculada numa cidade de $0.1294 por kWh.
-

No celular, os números ficam acima do polegar
O resumo da estimativa gruda no topo do simulador, numa linha só em qualquer largura. Arrastar um slider nunca cobre o resultado.
- DecisãoO resumo mora no começo do simulador: um elemento fixo só gruda quando a própria posição passa, então depois dos sliders ele nunca apareceria durante o arrasto.
- GuardrailNada se move enquanto o dedo arrasta. Cada linha que muda guarda o espaço do seu texto mais longo, procurado nas 627 posições dos sliders: 0 px de deslocamento em 1440, 1024, 390 e 320 px.
- Retorno ao usuárioNa primeira versão, um aviso surgia acima dos números no meio do arrasto e empurrava tudo para baixo do polegar. Agora as linhas só trocam de texto e de cor.
Visita técnica
Visita técnicaLicença e papeladaDia da instalaçãoDepois do preço, o que acontece
Logo depois de um preço vem a pergunta “e agora?”. A seção fica parada enquanto os três passos entram com a rolagem, e cada um desenha a sua parte da casa: as medidas saem das paredes, a licença chega com carimbo, os painéis sobem enquanto o sol nasce atrás do telhado. No celular, os passos sobem em vez de deslizar de lado.
- DecisãoVem logo depois do simulador porque responder “o que acontece agora” faz pedir a visita parecer um compromisso menor.
- Por que CSS nativoLinhas do tempo de rolagem do CSS movem a paralaxe, a seção fixada e as entradas, sem listener de rolagem, então nada roda na thread principal enquanto a página rola. Nenhuma biblioteca de animação entra no peso da página, e o celular em 4G não paga por ela.
- GuardrailSó anima com prefers-reduced-motion: no-preference e com @supports de animation-timeline. A seção só fixa em telas com pelo menos 720 px de altura, onde passo e desenho cabem juntos.
- Sem suporteFirefox, que ainda não tem linhas do tempo de rolagem, e quem pede menos movimento veem a mesma página parada, com todos os desenhos completos. Chrome e Safari 26 rodam a animação. O custo assumido é esse: parte dos visitantes vê a versão estática, com a mesma informação.
- DadoO prazo da licença vem do arquivo da cidade: cerca de 21 dias em Phoenix, dito antes de qualquer coisa começar.
O racional das decisões
Duas decisões que mudaram a página, cada uma com o que a sustentou.
O cálculo na frente, o agendamento logo atrás
Quem chega de um anúncio ou de uma busca ainda não sabe o próprio número. Por isso o botão principal do topo leva ao simulador, não ao agendamento; agendar continua a um toque, no menu e na barra fixa do celular.
O botão de visita mora dentro do cartão do resultado, logo abaixo dos quatro números, onde a intenção é maior. E o fecho da página repete a estimativa da pessoa ao lado do botão.
A página fecha no número da própria pessoa.
Quando a tabela e a sequência do briefing discordam
No passo 3 a cobertura fica em 100%. No passo 4 a pessoa escolhe o perfil de apartamento, que preenche a conta típica de $90. Seguindo os passos, a página fica em $90 e 100%: 9 painéis, $7,796.25 depois do crédito, $90.00 de economia e retorno de 7,2 anos.
A tabela mostra 8 painéis, $6,930.00, $84.24 e 6,9 anos, que é o resultado de $90 com 80%, como se escolher um perfil devolvesse a cobertura a 80% sem ninguém pedir. A IA apontou o conflito e ofereceu os dois comportamentos; conferi a conta num protótipo (600 kWh a 100% pedem 8,55 painéis, então 9) e fiquei com os passos.
- 9painéis seguindo os passos
- 8na tabela, com a cobertura de volta a 80%
Um controle que muda o que a pessoa não tocou confunde tanto quanto um que não reage. Os testes cobrem os dois: as seis linhas da tabela com as entradas explícitas, e a sequência como a página se comporta.
Micro vitórias de UX
Todos os perfis na tela
No celular, os perfis de casa formam duas colunas. Num carrossel lateral, o de piscina e carro elétrico ficava fora da tela justo para quem chega de um anúncio para donos de piscina
A foto nítida no celular
Celular em pé ganha um recorte vertical da foto. Antes o navegador esticava um arquivo de 640 px; agora as duas camadas ficam nítidas com cerca de 270 KB
A abertura passa uma vez
O nascer do sol do logo roda uma vez por aba. Quem recarrega uma página de anúncio não espera de novo
O botão do topo não desbota
Na rolagem, o texto do topo sobe sem perder opacidade: botão que desbota ainda na tela parece desativado
Do anúncio à visita
O relatório de segunda julga cada anúncio pelas simulações e pelos pedidos de visita que trouxe. Cada evento sai da página para o Google Tag Manager com o anúncio de origem junto.
- De qual anúncio veio
- utm_content
- gclid
- sessionStorage
- estimate-share
- Mede
- O anúncio, a campanha e o id de clique do Google, da Meta ou do Bing, com a página de entrada e a hora.
- Decisão
- A origem fica guardada na própria aba, porque não há servidor e a página não grava cookie. O link do botão de compartilhar sai marcado como indicação, para a estimativa encaminhada não contar como outra visita do anúncio.
- Por que importa
- utm_content é a coluna que decide quais anúncios seguem na semana.
- Simulou
- simulation_completed
- minimum_applied
- cap_applied
- Mede
- Quem chegou a um resultado, com os quatro números e se o mínimo ou o teto agiram.
- Decisão
- Uma simulação por página aberta, 1,5 s depois de a pessoa parar de mexer, e a estimativa inicial de $220 com 80% não conta. Um minuto arrastando o slider não vira quarenta simulações.
- Por que importa
- Como evento-chave no GA4, ela vira conversão no Google Ads e na Meta, e a campanha otimiza por quem simulou em vez de quem clicou.
- Pediu visita
- visit_cta_click
- cta_location
- has_simulated
- Mede
- Cada clique em agendar visita, com o lugar do botão e se a pessoa já tinha simulado.
- Decisão
- O link de visita leva a cidade, a estimativa e a campanha, então o pedido chega ligado a um anúncio e ao número que a pessoa viu.
- Por que importa
- Separa os anúncios que trazem pedido de visita dos que só trazem clique.
- Abriu rápido
- LCP
- CLS
- Mede
- 726 ms até o maior elemento aparecer, sem nada saltando na tela.
- Decisão
- Medido em build de produção com celular simulado, em 4G lento e CPU 4x mais lenta. A estimativa inicial já vem no HTML, e nenhum script de terceiro carrega antes do GTM.
- Por que importa
- Em anúncio pago, cada segundo de espera é verba gasta antes de a pessoa ver o número.
Construído: atribuição, eventos e o link de visita com estimativa e campanha. Falta ligar o GTM, as tags do GA4, o relatório de segunda e a automação no n8n que leva o pedido ao CRM e à equipe local.
Resultados
1
arquivo por cidade nova; um valor errado para o build e diz o nome do campo
As outras 119 cidades são conteúdo; o código já está pronto.
Não houve tráfego real, então aqui não há taxa de simulação, de agendamento nem custo por visita medidos. A prova é a página no ar e o que foi rodado contra ela.
Veja funcionando
A página inteira, dentro do portfólio. Ela carrega do começo quando você pedir, porque a abertura faz parte do projeto. O telefone é de mentira.