Cartão na Hoje

A aposta: o convite pra colocar o Engrenou na tela do celular não interrompe nada - ele espera a pessoa estar calma, entra como mais um card da tela Hoje e ganha o olho pela forma e pelo momento, nunca pelo volume.

19/ago/2026 - mockup autocontido. Encaixe previsto: fim do .hj3-rail em src/pages/Hoje.jsx, o mesmo slot do NudgeCatalogo. Peça nova: .hj3-pwa em src/styles/hoje-v3.css. Cor por var(--brand), whitelabel preservado.

a + b. No celular

As duas telas mostram a mesma tela Hoje, com a topbar e a barra de abas em volta. O cartão não fica sozinho: ele divide a tela com um aviso do dia e com a caderneta do dinheiro, que é exatamente o teste da proposta.

a. Android, Chrome - tem botão de verdade

14:07
app.engrenou.com.br
Doces da Bia
Boa tarde, Bia
Terça, 19 de agosto
3 entregas pra hoje A primeira sai às 14h, pro Marcelo
Dinheiro de agosto até hoje
EntrouR$ 1.240,00
SaiuR$ 380,00
SobrouR$ 860,00
Deixe o Engrenou na tela do celular

Vira um ícone junto dos seus outros apps. Abre num toque, sem procurar a aba certa no navegador.

É um atalho, não é download de loja de apps.

Hoje, terça3 pedidos
Quarta2 pedidos

No Android o botão faz o que diz: o app segurou o evento beforeinstallprompt e o toque abre o diálogo do próprio sistema. Se o navegador nunca disparar esse evento, o cartão não nasce - nada de botão que não instala.

b. iPhone, Safari - ensina, não promete

14:07
Doces da Bia
SaiuR$ 380,00
SobrouR$ 860,00
Deixe o Engrenou na tela do celular

No iPhone quem coloca é você, em dois toques. Leva uns 10 segundos:

  1. 1 Toque em Compartilhar, na barra de baixo
  2. 2 Escolha Adicionar à Tela de Início

É um atalho, não é download da App Store.

Hoje, terça3 pedidos
Quarta2 pedidos

No iPhone não existe API de instalação, então o cartão não tem botão que instala. Ele mostra os dois passos com os ícones do próprio iOS e sai de cena com Já coloquei. Em Chrome no iPhone o texto do passo 1 muda pro menu de compartilhar do topo - mesma peça, uma frase diferente.

A seta laranja é anotação do mockup, não é interface. Nenhum site desenha em cima da barra do Safari. Quem ensina o caminho é o passo 1 escrito dentro do cartão; a seta está aqui só pra mostrar, pra quem lê esta página, onde fica o botão Compartilhar de verdade.

c. No computador: quase sempre desligado, de propósito

O Engrenou é um app de celular na prática: a pessoa lança pedido de pé, na cozinha. No computador o convite tem pouco a oferecer e a coluna da direita é o lugar menos olhado da tela. Então a regra é: o cartão só aparece no desktop se o navegador disparar o beforeinstallprompt (Chrome e Edge), em versão de uma linha, sem ilustração e uma vez só. Em Safari e Firefox de computador não aparece nada - ali o caminho é arrastar pro Dock ou criar atalho pelo menu, e ensinar isso seria transformar um convite de 10 segundos numa aula.

Doces da Bia

Pedidos de hoje

Na produção

Falta receber

Deixe o Engrenou em janela própria

Sem abas e sem barra de endereço, junto dos seus outros programas.

A copy

Duas regras que valeram pra tudo aqui: prometer só o que o produto entrega hoje, e usar as palavras que a pessoa usaria. Ninguém fala "instalar o PWA"; fala "botar na tela".

Headline 1 - a escolhida

Deixe o Engrenou na tela do celular

Vira um ícone junto dos seus outros apps. Abre num toque, sem procurar a aba certa no navegador.

Por quê: diz o que vai acontecer, não o que a gente quer. "Na tela do celular" é a imagem que a pessoa já tem na cabeça, e a frase inteira funciona igual no Android e no iPhone, o que mantém uma peça só com duas caudas.

Headline 2 - alternativa

Um toque e o Engrenou abre

Dá pra deixar um atalho na tela do celular. Sem digitar endereço, sem caçar a aba certa.

Por quê: vende o ganho em vez da ação, e é mais curta em tela pequena. Perde por não deixar claro o que a pessoa vai ter que fazer, e no iPhone ela vai ter que fazer alguma coisa.

O resto do texto, palavra por palavra

d. Como funciona

1 Quando aparece

Todas as condições ao mesmo tempo. Se faltar uma, o cartão simplesmente não nasce:

  • Está no celular (a mesma faixa de 780px do shell) ou no desktop com o beforeinstallprompt na mão.
  • Da segunda sessão em diante: Date.now() - eng_visita1_<id> > 12h. É a doutrina que já existe no app: na primeira entrada quem fala é o checklist, e só ele.
  • A pessoa já lançou 3 pedidos ou mais. Atalho pra quem ainda não usa é só mais um banner.
  • A tela Hoje está sem aviso âmbar e o nudge do catálogo não vai aparecer. Um convite por vez, e o do catálogo ganha - ele é sobre o negócio dela, o nosso é sobre a nossa conveniência.

2 Quando nunca aparece

  • Já está instalado: matchMedia('(display-mode: standalone)') ou navigator.standalone. Convidar quem já entrou é o jeito mais rápido de parecer um app burro.
  • Na loja da cliente (/loja/:slug e /m/:slug). O manifesto já é removido nessas rotas: quem compra um bolo não recebe convite pra instalar a ferramenta de gestão de outra pessoa. O cartão respeita a mesma fronteira.
  • No adm.engrenou.com.br - o painel interno nem registra service worker.
  • Na demo pública - conta de avaliação, sem tenant de verdade.
  • Depois do segundo "agora não".

3 Quantas vezes

Duas, no máximo, na vida da conta. O motor é o mesmo do nudge do catálogo, só com o prazo maior:

  • 1ª aparição. Se sair com "agora não", volta uma única vez, 21 dias depois.
  • No 2º "agora não", nunca mais.
  • Android: se a pessoa tocar em "Colocar na tela" e recusar o diálogo do sistema, isso conta como um "agora não" - ela já viu a oferta.
  • iPhone: "Já coloquei" encerra pra sempre, mesmo que ela não tenha colocado. Acreditar na pessoa custa menos que insistir.

4 O que acontece ao dispensar

Grava eng_pwa_convite_<bakeryId> com {fechado_em, vezes} - mesma forma e mesmo prefixo do resto da casa, dentro de try/catch (modo privado: só não lembra).

  • O cartão sai da tela na hora, sem toast e sem "tem certeza?". Dispensar é uma resposta, não um erro.
  • Não tem X, de propósito. No Hoje o X quer dizer "guarda por hoje, volta amanhã". Este cartão não volta amanhã, volta em 21 dias - usar o mesmo X aqui estragaria o significado que o app já ensinou.
  • Quem dispensou e depois quiser: o caminho continua em Meu negócio, na lista de ações da conta. Sem gritar, mas existindo.

O risco do brief: card no meio de outros é fácil de ignorar

É verdade e não dá pra resolver com tamanho. Quatro mecanismos, nenhum deles barulhento:

A Forma emprestada do convite

Todo card de dado no Hoje é branco com borda cinza de 1px. A borda de 1,5px na cor da marca só existe hoje no checklist de primeiro uso - ou seja, o app já ensinou que aquela moldura quer dizer "isto é um convite, não é um número". Quando o checklist morre, essa forma fica livre. O cartão herda o significado em vez de inventar um.

B Objeto, não parágrafo

O olho pousa em desenho antes de texto. Por isso a tela de celular em miniatura com o ícone do Engrenou no meio dos outros apps: em meio segundo ela mostra o resultado, sem precisar da headline. É o único card da Hoje com ilustração, e essa singularidade é o que compra atenção sem subir o tom.

C Momento, não posição

Ele não briga por topo. Aparece na 2ª sessão em diante, com 3 pedidos no histórico e num dia sem aviso âmbar - quer dizer, num dia calmo, com a pessoa já convencida de que volta ali todo dia. Atenção comprada por contexto dura mais que atenção comprada por interrupção.

D Slot exclusivo

Um convite por vez na tela, sempre. O nudge do catálogo tem preferência; o aviso âmbar cancela os dois. Sozinho num campo limpo, um card de 200px não precisa gritar. Empilhado com outros três, nenhum tamanho salvaria.

Notas de quem vai construir

i Onde encaixa

  • Componente novo src/components/ConviteInstalar.jsx, renderizado no fim do .hj3-rail do Hoje.jsx, ao lado do NudgeCatalogo e sob a mesma trava !temAmber.
  • CSS .hj3-pwa em src/styles/hoje-v3.css. Sem token novo: usa --brand, --linha, --creme2, --shadow-sm.
  • Botão primário reusa .btn.btn-terra. Nada de variante nova de botão - o app tem três e continua com três.
  • Régua: fonte mínima 12px no rodapé (acima do piso de 11px), botão e "agora não" com 44px de alvo, raio 16px.

ii Detecção

  • Segurar o beforeinstallprompt num listener global (junto do iniciarPwa()), guardar o evento e só então liberar o cartão do Android. Sem evento em mão, sem botão.
  • iPhone: /iphone|ipad|ipod/i no user agent e ausência de navigator.standalone. Chrome/Firefox no iOS usam o mesmo motor, mas o menu é outro - a frase do passo 1 muda.
  • Instalado: display-mode: standalone ou navigator.standalone, checado a cada montagem.

iii Medição, sem inventar

Não existe tipo de evento pra isso e criar um exige migração na whitelist da policy de eventos. Enquanto isso, o caminho já usado pelo Tutorial: nav com meta:{para:'pwa_convite_ok'} e meta:{para:'pwa_convite_nao'}.

E a honestidade que precisa constar em qualquer leitura: no Android dá pra ler o userChoice; no iPhone não dá pra saber se a pessoa instalou. Qualquer taxa de instalação que alguém apresentar vai ser parcial por natureza.

Mockup estático, sem JavaScript. Os ícones das abas e das barras de sistema são desenhos aproximados: na implementação valem os do Tabler, que o app já carrega. O ícone do Engrenou aqui é um esquema do public/favicon.svg; no produto quem aparece na tela de início é o /icons/icon-192.png real.