everhere · Ferramenta

A Interface
everhere

Escopo139 telas · Figma
Depende deVol. 05 — Arquitetura
Ferramenta irmãMVP Canvas (Vol. 05, Cap. 14)
Versão2.2 · Set 2026

A Arquitetura de Produto (Vol. 05) define o sistema. O MVP Canvas define o que falta no código. Este volume é o elo entre os dois: como a visão virou 139 telas navegáveis no Figma, tela a tela, decisão a decisão — inclusive as que erramos primeiro e corrigimos depois, porque o erro ensina tanto quanto o acerto.

Nota sobre esta edição

Até a v2.1, a Parte IV deste livro crescia por ordem cronológica de conversa, não por assunto — um capítulo podia nascer com um título e terminar cobrindo temas sem relação nenhuma com ele. A v2.2 reorganiza os 26 capítulos originais em 14, agrupados por assunto real. Nenhuma informação foi apagada nesse processo — só reagrupada, renumerada e com as referências cruzadas (§) corrigidas para os novos números.

Parte I — Método

Protótipo Antes do Código

Por que cada tela nova começou lendo um arquivo .tsx, não uma ideia solta

O protótipo deste volume não nasceu de uma lista de telas desejadas. Nasceu de uma regra simples, repetida em cada sessão de construção: antes de desenhar uma tela nova no Figma, ler o código real que já existe — o componente React Native, o hook de dados, a RPC do Supabase — e decidir, conscientemente, se a tela vai refletir fielmente o que o código já faz ou vai adiantar-se a ele de propósito.

Essa distinção importa porque um protótipo que finge que o backend já existe é uma mentira útil por um tempo e uma armadilha depois. Cada vez que uma tela do Figma ficou à frente do código — um campo de preço que a RPC ainda não aceita, um código de confirmação que a tabela ainda não tem — isso foi registrado como dívida técnica formal, não escondido atrás de um mock bonito. O Capítulo 13 lista essas lacunas uma a uma.

1.1 A disciplina de grounding

Na prática, isso significou abrir arquivos como useChat.ts, useMyActivities.ts, CreateActivityScreen.tsx ou ProfileScreen.tsx antes de tocar em qualquer frame do Figma. Um exemplo concreto: o chat do everhere é, no código real, sempre 1:1 e sempre contextual — a conversa chega já sabendo quem é a outra pessoa (useLocalSearchParams<{otherUserId, otherName, otherAvatar}>), nunca existe um "compor nova mensagem" genérico com busca aberta. Isso descartou de saída a ideia óbvia — e errada — de uma tela de mensagens estilo rede social aberta, e levou à tela "Nova Conversa" restrita a quem você já segue (Capítulo 5).

Outro exemplo: os selos de "atividades que já vivi" do perfil não são uma lista fixa de categorias que o usuário marca livremente. O código (ProfileScreen.tsx) calcula completedCategories ao vivo, cruzando atividades organizadas com status === 'completed' e atividades participadas com participation_status === 'attended' — e só então o usuário escolhe, dentro desse conjunto já restrito, quais quer destacar. Uma primeira versão do Figma errou isso: usou a taxonomia de categoria de comunidade (Esporte, Natureza, Bem-estar…) em vez da taxonomia de categoria de atividade (Cycling, Trail, Surf…) — duas listas diferentes no código real, confundidas por engano. O Capítulo 5 conta essa correção com mais detalhe, porque o erro em si ensina a regra.

1.2 Verificação visual, não só estrutural

Toda alteração de posição, tamanho ou hierarquia no Figma foi seguida de duas checagens automatizadas: uma varredura de colisão par-a-par entre todos os frames do canvas, e uma captura de tela do resultado. A varredura de colisão pegou bugs invisíveis a olho nu — por exemplo, uma nova aba de comunidades posicionada exatamente sobre o cluster de Detalhe da Experiência, porque as duas construções, feitas em momentos diferentes, coincidentemente escolheram a mesma coluna X. A captura de tela pegou o que a colisão não pega: texto cortado dentro de uma bolha de chat, uma fileira de chips sem espaçamento vertical entre linhas, um card menor cabendo dentro de um espaço maior sem preencher o fundo.

Princípio
Órfão no grafo de navegação não é sinônimo de obsoleto.
Uma tela sem nenhum link apontando para ela pode ser um design alternativo guardado de propósito (a Perfil v1 — cards, por exemplo, continua existindo ao lado da Perfil v2 — timeline), uma variante de erro sem forma de ramificação condicional em um protótipo estático (a tela de "nome de usuário indisponível"), ou uma referência de estado vazio deliberadamente fora do fluxo principal. A pergunta certa nunca é "por que isso não está conectado" — é "essa desconexão foi decidida ou foi esquecida".

Parte I — Método

As Oito Áreas da Interface

Depois de várias rodadas de construção, o canvas do Figma acumulou telas espalhadas por posição de criação, não por relação de uso — uma tela de edição podia estar visualmente longe da tela real que ela edita. A reorganização final agrupou as 116 telas em oito áreas funcionais, cada uma em sua própria fileira, preservando toda a navegação existente (a posição no canvas nunca afeta os links — apenas a legibilidade de quem está olhando o mapa).

ÁreaO que agrupaTelas
Onboarding & AuthSplash, Entrar, cadastro passo a passo, recuperação de senha18
Telas-raiz (abas)Home, Activities, Explorar Destinos, Comunidades, Perfil — todas as versões e estados vazios, check-in de sentimento15
Atividades — fluxoDetalhe da Experiência (todas as abas e variantes), criar/editar atividade, adicionar equipe, checkout (com e sem cupom), confirmação, cancelamento, quem curtiu24
Turismo — planejamentoBusca de destino, seleção de datas, montagem de itinerário5
PassaporteCapa, 14 dias, índice, os três formatos de compartilhamento19
Comunidade — gestãoDetalhe, criar, configurações, moderadores, editar6
Perfil & SocialPerfis de terceiros, seguindo/seguidores, viagens, ingressos, memória18
Mensagens & NotificaçõesNotificações, mensagens, conversas, câmera e fluxo pós-câmera12

2.1 Por que oito e não mais granular

A tentação, com 116 telas, é criar uma pasta para cada sub-fluxo. Isso foi descartado porque a fronteira entre "fluxo de atividade" e "fluxo de comunidade", por exemplo, é porosa por design — uma comunidade organiza atividades, uma atividade pertence a uma comunidade. Oito áreas é o nível em que cada agrupamento ainda cabe numa única fileira de scroll horizontal e ainda corresponde a uma pergunta de produto reconhecível: "o que a pessoa faz aqui".

Parte II — Decisões de Produto

Contexto, Não Diretório

Uma pergunta simples — "onde eu encontro meus amigos para conversar?" — expôs uma decisão de produto que não estava escrita em lugar nenhum: a everhere não é, e não deveria virar, uma rede social de descoberta de pessoas. O código real já apontava nessa direção (chat sempre contextual, nunca um diretório de usuários), mas o Figma ainda não tinha essa regra explícita em interface.

3.1 A distinção que resolveu o impasse

A primeira formulação da regra — "sem diretório de pessoas" — parecia, à primeira vista, entrar em conflito com o fato de que seguir alguém é uma função central do app. A correção veio de um contra-exemplo concreto: "mas podemos seguir as pessoas porque são nossas famílias e amigos". A regra final, mais precisa, separa duas coisas que a primeira versão misturava:

Permitido
Busca por nome de alguém que você já conhece — um campo de busca em "Seguindo", restrito ao seu próprio grafo social, sem navegar estranhos. E contagem de seguidores/seguindo escondida de terceiros — a função social existe sem virar vitrine de popularidade.
Fora de escopo
Um diretório aberto e navegável de todos os usuários da plataforma, ou qualquer forma de descoberta algorítmica de pessoas desconhecidas.

3.2 Onde isso apareceu na interface

Três construções saíram diretamente dessa regra: um campo de busca por nome em "Seguindo" (não um feed de sugestões abertas); uma tela "Nova Conversa" acessível a partir de Mensagens, mas que só lista pessoas que você já segue ou que já te seguem — nunca um universo maior; e o botão de mensagem em cada Detalhe da Experiência, que leva direto à conversa com o organizador daquela atividade específica, porque o motivo de falar com alguém, nesse produto, é sempre uma experiência em comum.

3.3 Reconhecimento sem virar disputa

Uma pergunta separada, mas movida pela mesma preocupação: vale ter "curtida" nas contribuições da vivência coletiva, ou o comentário/contribuição já é suficiente? A investigação real do código encontrou algo revelador — HomeScreen.tsx já tinha, como mock morto nunca ligado a nada, contagem pública de curtidas e lista de avatares de quem curtiu (likeCount, likedBy, likerAvatars). Exatamente o padrão de rede social tradicional que o Vol. 01 (A Experiência Perdida) diagnostica como raiz da "cultura da insuficiência" — comparação constante, vitrine de popularidade.

Mas o que o Vol. 01 condena não é a curtida em si — é ela ser pública, contada e ranqueada. Existe uma lacuna real sem isso: hoje, diante de uma foto ótima de outro participante, a única opção é escrever um comentário ou não fazer nada. Não existe reconhecimento leve, sem esforço.

A solução adotada mantém as duas coisas verdadeiras ao mesmo tempo: cada contribuição da vivência ganhou um coração tocável, mas nenhuma contagem aparece em lugar nenhum — nem pra quem visualiza, nem pra quem postou. Só quem publicou aquele conteúdo específico pode abrir "Ver quem curtiu" e ver a lista de nomes — uma tela privada, não descoberta por mais ninguém, e que nunca soma num total público de curtidas recebidas em nenhum perfil. Reconhecimento sem ranking: dá pra saber que alguém gostou, sem que isso vire uma régua de comparação entre posts ou entre pessoas.

Parte II — Decisões de Produto

O Vazio Também é Desenho

Por que existem dois tratamentos diferentes de estado vazio — e o mapa completo dos 12 estados do arquivo

Até certo ponto da construção, todas as telas do protótipo mostravam o app já povoado — atividades, memórias, ingressos, seguidores, tudo preenchido com dados de exemplo. Isso é correto para demonstrar o produto maduro, mas engana sobre a primeira experiência real: no dia 1, ninguém tem nada disso ainda. O código já resolve parte desse problema — o componente EmptyState (packages/ui/src/components/EmptyState.tsx) já existe e já tem copy real para várias telas — mas o Figma ainda não refletia esses estados. O Capítulo 4 lista, tela a tela, cada estado vazio construído; este capítulo registra só o princípio.

4.1 Duas categorias de vazio, dois tratamentos diferentes

A construção dos estados vazios revelou uma distinção que não estava óbvia no início: nem todo vazio merece uma mensagem visível.

Conteúdo primário da tela
Quando o conteúdo vazio é o motivo da tela existir — Comunidades, Seguindo, Seguidores, Mensagens, Meus Ingressos, a Linha do Tempo do Perfil — a ausência de qualquer mensagem deixaria a tela em branco, sem explicação. Aqui o padrão do código real foi seguido à risca: ícone emoji, título direto, descrição opcional, botão de ação quando fizer sentido (ex.: "Nova conversa" na tela de Mensagens vazia).
Seção secundária dentro de uma tela cheia
Quando o conteúdo vazio é só uma fileira dentro de uma tela com bastante outra coisa acontecendo — "Minha Lista" dentro de Activities, "Memórias da sua rede" dentro da Home — um card de placeholder vira ruído visual desnecessário. A decisão final, corrigindo uma primeira tentativa que mostrava um card tracejado nesses casos, foi simplesmente não renderizar a seção, deixando o espaço ser preenchido pelo conteúdo vizinho — o padrão comum de {items.length > 0 && <Section />} em qualquer app mobile real.

Doze telas "(vazio)" foram construídas, cada uma clonada da tela populada correspondente e nunca linkada na navegação principal — funcionam como referência de design, disponíveis para consulta, mas o protótipo sempre abre no estado povoado por padrão.

TelaÍcone / TratamentoTexto ou decisão
Comunidades🌐"Nenhuma comunidade nesta categoria" + botão "Criar comunidade" — copy exata de CommunitiesScreen.tsx
Detalhe da Experiência (Vivências)📷"Nenhuma contribuição ainda" / "Seja o primeiro a registrar esse momento!" — copy exata de ExperienceRecapScreen.tsx
Adicionar Vivência📷Mesmo padrão, mantendo os botões Escrever/Foto ativos
Activities (Minha Lista)— (some)Seção inteira (título + card) removida; conteúdo seguinte sobe para preencher o espaço
Home (memórias da rede)— (some)Mesma lógica — fileira inteira desaparece, hero e "amigos vivendo isso agora" continuam populados
Editar PerfilTexto itálico"Nenhuma atividade concluída ainda." — string exata de ProfileScreen.tsx, no lugar dos chips de selo
Minhas Viagens🧳"Nenhuma viagem ainda" + sugestões de próximo destino mantidas (ainda fazem sentido pra quem nunca viajou)
Meus Ingressos🎟️"Nenhum ingresso ainda" / "Quando você confirmar presença numa atividade, o ingresso aparece aqui."
Seguindo👥"Você ainda não segue ninguém" — busca e sugestões mantidas abaixo
Seguidores👋"Nenhum seguidor ainda" / "Quando alguém seguir você, aparece aqui."
Mensagens💬"Nenhuma conversa ainda" + botão de ação "Nova conversa", já linkado
Perfil v2Números + 🗺️Estatísticas zeradas (0 experiências, 0 fotos, "novo por aqui"); Linha do Tempo trocada por "Sua jornada começa aqui"

4.2 A correção de rota no meio da construção

As duas primeiras telas construídas — Activities (Minha Lista) e Home (memórias da rede) — inicialmente receberam o mesmo tratamento das outras dez: uma caixa tracejada com ícone e mensagem, no lugar do conteúdo ausente. Foi um julgamento de produto explícito que corrigiu isso: "se não tiver nada na lista ou de memórias da rede, melhor nem ter esses cards — o espaço é preenchido pelas demais informações, só oculta". A distinção que ficou, aplicada retroativamente a essas duas telas: quando o vazio é uma seção secundária dentro de uma tela com bastante outro conteúdo, ela some inteira; quando é o motivo da tela existir, ela ganha uma mensagem de verdade. O Capítulo 4 registra o princípio; esta tabela é o resultado aplicado a cada caso real.

Parte II — Decisões de Produto

O Selo, as Mensagens e Como Compartilhar uma Viagem

Três decisões de identidade e comunicação: o que o selo prova, por que as conversas são sempre contextuais, e as 3 formas de compartilhar uma viagem

A tela de Editar Perfil tem uma seção de "selos" — categorias de atividade que a pessoa já viveu e escolhe destacar no próprio perfil. A primeira versão dessa seção no Figma mostrava seis categorias fixas (Esporte, Natureza, Bem-estar, Fitness, Cultura, Social), três marcadas como já concluídas e três em cinza, como se fossem metas ainda não alcançadas. Fazia sentido visualmente. Estava errado.

5.1 O que o código realmente faz

O código real (ProfileScreen.tsx) não mostra uma lista fixa de categorias com estado concluído/pendente. Ele calcula, ao vivo, a cada carregamento da tela:

Trecho real — ProfileScreen.tsx
completedCategories = union(organizadas com status='completed', participadas com participation_status='attended')
Só categorias efetivamente vividas entram na lista. Não existe conceito de categoria "prometida" ou "meta" na interface de selos — o que não foi vivido simplesmente não aparece como opção.

A partir dessa lista, o usuário escolhe manualmente um subconjunto para destacar (toggleStamp), salvo em user.featured_stamps. Duas taxonomias diferentes ficaram confundidas na primeira versão: a taxonomia de categoria de comunidade (usada para filtrar a lista de comunidades) e a taxonomia de categoria de atividade (Running, Cycling, Trail, Yoga & Meditation, Surf, Swimming, Beach Volleyball, Hiking, Fitness, Dance, Climbing, Kayaking, definida em CreateActivityScreen.tsx) — que é a que realmente alimenta completedCategories.

5.2 A correção e o porquê importa

A correção reduziu a seção de seis chips fixos para os chips que realmente existem no histórico da pessoa de exemplo — três, no caso (Cycling, Trail, Surf, derivados do pedal, das trilhas e do kitesurf já registrados na linha do tempo) — todos selecionados, sem nenhum chip cinza representando algo "ainda não feito". O rótulo da seção também mudou de "Selos em destaque" para "Atividades que já vivi", copiando o texto exato do campo real, e a mensagem de estado vazio ("Nenhuma atividade concluída ainda.") passou a ser a mesma string do código, não uma paráfrase.

A regra que fica: uma interface nunca deve inventar um estado que o modelo de dados não representa. Se o banco não tem conceito de "categoria pendente", a tela não deveria ter chips cinzas sugerindo que existe.

A primeira versão navegável de Mensagens tinha um problema visível assim que se testava o fluxo: toda entrada de conversa — o botão "Falar" em cada perfil de terceiro, o ícone de mensagem do organizador em cada experiência, cada linha da lista de Mensagens — levava para a mesma tela de conversa, "Conversa · Carlos Mendes", não importa com quem a interação começasse. Era um stopgap deliberado e sinalizado enquanto o resto do fluxo de navegação era construído — mas precisava ser resolvido antes do protótipo ser considerado completo.

5.3 Uma conversa por pessoa, com conteúdo próprio

A correção clonou a tela de conversa quatro vezes — Larissa Prado, Rafael Nunes, Camila Rocha, João Pedro — cada uma com uma troca de mensagens coerente com o contexto real daquela pessoa: Larissa fala sobre repetir a trilha da Pedra Furada, Rafael sobre a carona até o ponto de encontro do kitesurf, Camila sobre a primeira vez dela na roda de capoeira, João Pedro sobre o horário da corrida do dia seguinte. Cada botão "Falar" nos quatro perfis de terceiro, e cada linha correspondente na lista de Mensagens, foi religado para a conversa certa — nenhum aponta mais para o placeholder genérico.

O botão de mensagem do organizador (presente em cada tela de Detalhe da Experiência) continuou apontando para a conversa de Carlos Mendes nos casos em que ele é de fato o organizador — esse comportamento estava correto desde o início, porque nesse caso o contexto real É o Carlos.

5.4 Uma barra de entrada mais rica

A barra de digitação original tinha só um campo de texto e um botão de enviar. Ficou parecida com o restante do produto: ícone de câmera, ícone de foto, campo de texto, ícone de áudio, botão de enviar — desenhados em SVG inline seguindo a cor moss do sistema, replicados nas cinco conversas depois de validar o layout numa só.

5.5 Nova Conversa, restrita por desenho

Um botão de compor (ícone de lápis) foi adicionado ao cabeçalho de Mensagens, abrindo uma tela "Nova Conversa" com um campo de busca — mas a lista abaixo do campo não é um diretório geral de usuários, é a lista de pessoas que você já segue (a mesma regra do Capítulo 3). Escolher uma pessoa na lista abre a conversa 1:1 correspondente, clonando exatamente o padrão de contexto que o código real já impõe.

Um bug pequeno apareceu durante essa construção e vale registrar: ao ligar os seis botões de conversa da lista de Mensagens, uma busca por nome de nó bateu primeiro no rótulo de texto "Rafael Nunes" (que já tinha sido renomeado a partir de "Rafael Souza" alguns passos antes) em vez de continuar buscando o texto original — o resultado foi dois nomes de linha ficando com "Rafael Nunes" em duplicidade até a captura de tela seguinte expor o erro. Corrigido localizando os nós certos por ID em vez de por nome de texto, que muda.

Depois de construir "Compartilhar Memória" — um card único, estilo Strava, gerado a partir de uma experiência vivida — o mesmo padrão visual foi estendido ao Passaporte de viagem, porque o pedido original ("precisamos ter uma forma de compartilhar o passaporte, tanto a capa, quanto um dia, quanto o todo") descrevia exatamente três escalas do mesmo conteúdo: a viagem inteira, um dia específico, o roteiro pronto para inspirar outra pessoa.

5.6 O botão que já existia, esquecido

Uma descoberta útil ao construir isso: as 14 telas de "Dia" do Passaporte já tinham, desde antes, um botão de texto "Compartilhar" desenhado — só nunca tinha sido religado a lugar nenhum. Não foi preciso desenhar um botão novo em cada uma das 14 telas, só religar o que já existia. Um card de compartilhamento de dia foi construído usando o conteúdo real do Dia 1 (trilha, balão, degustação de vinhos) e todos os 14 botões foram religados para ele — um stopgap sinalizado: os 14 dias hoje compartilham o mesmo card de exemplo, não um card por dia. Fica registrado como próximo passo natural, não como pendência escondida.

5.7 O bug do botão que virou tela inteira

Ao religar os 14 botões em lote, uma busca por nome de nó "Compartilhar" bateu primeiro na tela inteira em vez do frame pequeno do botão, porque a função de busca não distinguia por tamanho — o resultado, antes de ser percebido, foi a tela toda do Dia 1 virando clicável, disparando a navegação para o card de compartilhamento ao tocar em qualquer lugar da tela. Verificado inspecionando as reactions do frame raiz da tela (o que não deveria ter nenhuma), o bug foi corrigido restringindo a busca a frames com largura menor que 200px — o tamanho real de um botão, nunca de uma tela.

5.8 Capa e Índice, que não tinham botão nenhum

Diferente dos 14 dias, a Capa do Passaporte e o Índice de Dias nunca tiveram um botão de compartilhar desenhado. Um ícone de compartilhar (três círculos conectados, SVG inline) foi adicionado ao canto superior direito de cada uma, sobre a área de status bar, apontando para um card de resumo de viagem (destino, datas, "14 dias") e para um card de roteiro completo (uma síntese dos destaques dos 14 dias, pensada para inspirar a próxima viagem de outra pessoa — não uma lista literal de tudo, porque um card compartilhável precisa ser curto).

Parte II — Decisões de Produto

O Perfil: Grade, Linha do Tempo e Telas de Gestão

A saga do redesenho do Perfil e as 5 telas de gestão que ele precisa

A pergunta que originou este capítulo não veio de um bug — veio de uma dúvida de produto genuína: "faz sentido expormos em grade, estilo Instagram? Se não, esse grade poderia se transformar na segunda versão da linha do tempo e a pessoa escolheria como quer expor suas experiências." A resposta virou uma construção — e depois uma correção pública de um erro de design.

6.1 A primeira tentativa, e por que estava errada

A primeira versão de "Grade" reaproveitou um componente pronto do arquivo, "Card de Álbum" — foto de capa grande, contador de fotos, título, local e data, "você + N pessoas viveram isso" — empilhado verticalmente, um card por experiência. Visualmente rico. O problema só apareceu quando comparado lado a lado com a Perfil (v1 — cards), que já existia no arquivo: a aba "Linha do tempo" da v1 usa exatamente o mesmo tratamento de card grande empilhado. A nova "Grade" não acrescentava nada — era uma reconstrução do que já existia sob outro nome.

Havia também um problema de posição: essa primeira versão precisava de mais de 2000px de altura vertical (seis cards grandes empilhados), o que não cabia perto dos outros perfis no canvas recém-reorganizado — teve que ser colocada longe, quebrando a regra de proximidade que tinha acabado de ser aplicada ao arquivo inteiro.

6.2 A reconstrução: grade de verdade

A versão corrigida abandonou o card grande e construiu uma grade compacta de duas colunas — tiles de 165×180px, imagem de fundo, um badge pequeno de contagem de fotos no canto, título sobreposto com um degradê escuro na base, no estilo Instagram de fato. Compacta o suficiente (altura final de ~1257px, próxima da própria Perfil v2) para caber exatamente ao lado da Perfil v1 e da Editar Perfil no canvas reorganizado, sem precisar fugir para outra área.

Com isso, o app passou a ter três formatos de exibição genuinamente diferentes: a Linha do Tempo compacta (linhas pequenas, agrupadas por ano, na Perfil v2), o card grande de álbum (Perfil v1), e a grade compacta de duas colunas (Perfil v2, aba Grade) — cada um servindo um gosto de navegação diferente, não três nomes para a mesma coisa.

6.3 Ligar um alternador que já existia, sem função

Um detalhe descoberto ao construir isso: o alternador "Linha do tempo | Grade" já existia visualmente em todas as telas de perfil do arquivo — Perfil v1, Perfil v2 e os quatro Perfil de Terceiro — como dois rótulos de aba estáticos, sem nenhuma reaction ligada. A aba "Grade" nunca levava a lugar nenhum antes desta construção. A correção final ligou as duas abas entre a tela de Linha do Tempo e a nova tela de Grade, trocando também o estado visual ativo/inativo (cor do texto e sublinhado) em cada lado.

Até certo ponto, o protótipo cobria bem o lado de quem descobre e participa de uma experiência, mas não tinha nenhuma tela para quem organiza, edita ou modera. Cinco telas fecharam essa lacuna, todas desenhadas a partir de padrões visuais já estabelecidos no resto do arquivo — nenhuma introduz um componente novo do zero.

6.4 Editar Atividade

Clonada da versão completa de "Criar Atividade", mas pré-preenchida com os dados reais do Pedal ao Amanhecer, com o botão principal trocado de "Publicar atividade" para "Salvar alterações". Acessível por um novo ícone de lápis adicionado ao cabeçalho do Detalhe da Experiência, ao lado do botão de seguir já existente.

6.5 Cancelar Participação

Uma tela nova, sem equivalente anterior no arquivo: resumo da atividade, explicação do que acontece ("sua vaga será liberada... como o evento é gratuito, não há reembolso a processar — se fosse pago, o valor voltaria em até 5 dias úteis"), campo de motivo opcional, e dois botões — manter participação (preenchido, ação padrão) ou cancelar de fato (contorno, ação destrutiva). Acessível a partir de um link de texto adicionado ao Detalhe do Ingresso.

6.6 Editar Comunidade, separada de Configurações

A tela de Configurações da Comunidade, construída antes, só trata de privacidade (comunidade privada, aprovação de entrada) — não tem campo nenhum de nome, descrição ou capa. Editar Comunidade é uma tela própria para isso, com os três campos editáveis, acessada por um link novo adicionado à seção de gestão de Configurações.

6.7 Moderadores

Lista de membros com papel (Organizadora, Moderadora, Membro) e ação correspondente — promover quem é membro comum, remover quem já é moderador (a organizadora não pode ser removida). Corresponde a uma lacuna real de RPC no código, registrada no Capítulo 13: o schema já tem membership.role, mas falta a mutation de promover/remover.

Parte II — Decisões de Produto

Pós-Câmera, Autenticação Real e Check-in de Humor

Três descobertas de grounding que mudaram o desenho: o fluxo depois da câmera, a árvore real de cadastro, e o check-in de sentimento

A tela de Câmera existia desde muito antes desta fase de construção, com uma interface completa e realista — botão de captura, ícone de galeria, ícone de inverter câmera — mas nenhum desses elementos levava a lugar nenhum. Era, junto com a splash, um dos dois becos sem saída mais antigos do arquivo, encontrado na primeira auditoria de grafo (Capítulo 13).

7.1 Três telas, um caminho

Resolver isso significou desenhar o caminho inteiro que faltava, não só ligar um botão: Câmera → Pré-visualização da foto (a foto capturada em tela cheia, com opção de "Refazer" ou "Usar foto") → Legenda e Fotos (uma grade com as fotos escolhidas, um botão tracejado de adicionar mais, e um campo de legenda) → publicação de volta na tela de Adicionar Vivência.

Tanto o botão de obturador quanto a miniatura de galeria da Câmera foram ligados ao mesmo destino — Pré-visualização — simulando que tirar uma foto nova ou escolher uma da galeria chegam ao mesmo próximo passo, uma simplificação razoável para um protótipo estático.

7.2 Provar que o ciclo fecha

Ligar a navegação não bastava para demonstrar que o conteúdo publicado realmente aparece linkado à experiência de origem, então a tela de Adicionar Vivência ganhou um terceiro card de contribuição — "Você · agora", com foto e legenda — clonado dos dois cards existentes. Não é um estado dinâmico de verdade (é um protótipo estático), mas é a prova visual de que o caminho câmera → legenda → publicação desemboca exatamente onde deveria.

O botão "Foto" que já existia na barra inferior de Adicionar Vivência, antes decorativo, também foi ligado à Câmera — fechando o outro lado do mesmo ciclo: entrar na câmera a partir de dentro de uma vivência, não só a partir de um ícone solto na barra inferior do app.

Fernando notou, olhando o canvas reorganizado, que as telas de autenticação/cadastro "sentiam" diferente do resto — mais antigas, mais genéricas. A investigação (via /using-superpowers) confirmou com uma evidência concreta: o texto "Sign Up With Phone or Email" usava a fonte Avenir Next LT Pro — não Nunito, a única família usada em qualquer outra tela deste arquivo. Não era impressão: essas telas vieram de outra geração do projeto, provavelmente de um kit de UI genérico, nunca atualizadas.

7.3 O que o código real já vinha dizendo

Antes de redesenhar qualquer coisa, a leitura de apps/mobile/screens/auth/CreateAccountScreen.tsx revelou que o "assistente" de 6 telas (nome → username → e-mail → telefone → confirmar telefone → data de nascimento) nunca existiu no código — o cadastro real é uma tela só: e-mail, senha e um botão Google. Confirmar a conta é um código de 6 dígitos por e-mail (não 5, não por SMS). O comentário no código é explícito: após confirmar o OTP, "RootLayout's AuthGuard redirects to onboarding automatically" — ou seja, o próprio código já separa "criar conta" (credenciais) de "onboarding" (completar perfil) como duas fases distintas, mesmo que o Figma nunca tivesse desenhado essa separação.

Trecho real — CreateAccountScreen.tsx
const result = await signUp(email.trim().toLowerCase(), password)
...
setAwaitingConfirmation(true) // 6-digit OTP by email

7.4 A árvore, com as 4 partes separadas no canvas

O canvas foi reorganizado fisicamente (não só documentado) em 4 clusters, da esquerda pra direita, cada um com um espaçamento maior entre si pra ficar visualmente óbvio onde um termina e o outro começa:

1
Autenticação (fluxo real) — splash → menssage (manifesto de marca, primeira abertura) → sign up (convite: Google ou telefone/e-mail) → sign up 2 (Criar conta: e-mail + senha, uma tela só, igual ao código) → Verifique seu e-mail (OTP de 6 dígitos, só no caminho e-mail — Google pula direto) → Entrar (login) → Esqueci minha senha → Criar nova senha → Senha atualizada.
2
Onboarding pós-conta — Qual é o seu nome? → Crie um nome de usuário (+ estado de indisponível) → Choose activities. Essas telas existem porque nem cadastro por e-mail nem Google fornecem username ou interesses — é a etapa que preenche o que falta, pra todo mundo, depois que a conta já existe.
3
Especulativo / não mapeado no código atual — Qual é o seu telefone?, Confirme seu telefone, Qual é a sua data de nascimento?, Qual é o seu e-mail?. Nenhuma dessas quatro tem correspondência em CreateAccountScreen.tsx ou SignInScreen.tsx hoje. Ficam isoladas do fluxo principal, não porque estejam erradas, mas porque hoje ninguém sabe se são etapas futuras de onboarding (telefone/nascimento pra funcionalidades futuras) ou resíduo de um design antigo que assumia cadastro por telefone. A pergunta fica em aberto — não foram apagadas, só isoladas (ver [[feedback_nao_apagar_orfas]]).

Atualização: uma quarta categoria existiu brevemente — "Entrar" e "sign up" nas versões originais (fonte Avenir, fundo branco, componentes genéricos com cornerRadius: 0), preservadas como referência histórica. Depois de comparar lado a lado com as versões novas, Fernando pediu pra apagar as duas — a comparação já tinha cumprido seu papel. Removidas do arquivo.

7.5 O que mudou visualmente em cada tela

Toda a Parte 1 e Parte 2 da árvore passou pelo mesmo tratamento: fundo #F6F2EB (sand, a cor padrão testada nesta sessão — aprovada por Fernando depois de comparar com um teste sem preenchimento branco nos campos, que "ficou apagado"), campos de formulário brancos com radius:12 e borda sutil (neutral 20%), botão primário sólido moss, tudo em Nunito. Nenhuma tela nova foi inventada do zero — cada uma reaproveitou o padrão já validado em "Esqueci minha senha" (a primeira tela do arquivo, dessa área, que já nasceu correta).

7.6 Bugs encontrados reconstruindo

Reconstruir tela por tela expôs erros que a versão antiga escondia:

1
OTP de 5 dígitos, código pede 6 — "Verifique seu e-mail" tinha 5 caixas; o código real gera código de 6. Corrigido: 6 caixas, texto do subtítulo também estava desatualizado ("código de 5 dígitos").
2
Título duplicado na tela de confirmação de telefone — reaproveitava literalmente "What's your phone number?" (o título da tela anterior) em vez de um título de confirmação.
3
Card fantasma fora da tela — em "Choose activities", uma instância duplicada de "Passeios turísticos" (minúsculo) existia em x=855, fora da área visível de 375px — nunca aparecia, só ocupava espaço no arquivo. Removida.
4
Texto sobrepondo botão — em "menssage", o manifesto de marca vazava por cima do botão "Vamos lá" (antes "Let's go"). O texto nunca tinha espaço reservado — corrigido empurrando o botão pra baixo.
5
Bloco de termos de uso deslocado — a tela "Qual é o seu nome?" carregava um bloco enorme de Termos/Privacidade/marketing colado nela, sem relação direta com "nome". Consolidado em um só lugar: o rodapé de "sign up 2", onde o aceite de termos faz sentido de verdade (ao criar a conta).

7.7 As telas tinham "conexão" de verdade — e reconstruir apagou

Fernando notou, testando o protótipo depois da reorganização: "confira as ligações entre essas telas novas, o sign up (novo padrão) por exemplo está sem conexão". A investigação revelou algo que não tinha sido verificado antes: diferente do que um teste anterior nesta mesma sessão sugeria (dois ícones de header sem reactions), este arquivo usa conexões reais de protótipo do Figma — os botões "Next"/"Enviar" das telas antigas tinham reactions de verdade apontando pra próxima tela. Ao reconstruir uma tela inteira do zero (node.remove() em todos os filhos, depois recriar), qualquer reaction presa aos componentes antigos foi apagada junto — um efeito colateral que não tinha sido considerado até esse aviso.

Mapear as reactions sobreviventes revelou também um bug de lógica pré-existente, não causado nesta sessão: a tela "Esqueci minha senha" diz textualmente "enviaremos um link" pra redefinir a senha, mas a reaction do botão levava pra "Verifique seu e-mail" — uma tela de código de confirmação. Reset por link e reset por código são dois mecanismos diferentes; a tela prometia um e entregava outro. Corrigido: "Esqueci minha senha" agora pula direto pra "Criar nova senha" (consistente com "enviamos um link", que dispensa digitar código dentro do app), e "Verifique seu e-mail" ficou livre pra servir exclusivamente à verificação pós-cadastro, onde já fazia sentido.

O grafo de navegação reconectado, ponta a ponta:

Árvore com conexões reais (reactions do Figma, não só ordem no canvas)
splash →(1.8s)→ menssage →(Vamos lá)→ sign up
sign up →(Google)→ Crie um nome de usuário
sign up →(Criar conta c/ telefone/e-mail)→ sign up 2
sign up 2 →(Criar conta)→ Verifique seu e-mail →(Verificar código)→ Qual é o seu nome? →(Continuar)→ Crie um nome de usuário →(Continuar)→ Choose activities →(Continuar)→ Home
sign up / sign up 2 →(Já tem conta)→ Entrar →(Entrar/Google)→ Home
Entrar →(Esqueceu seus dados)→ Esqueci minha senha →(Enviar link)→ Criar nova senha →(Atualizar senha)→ Senha atualizada →(Ir para login)→ Entrar

Também corrigido no caminho: a seta de voltar de "Choose activities" apontava pra "Qual é a sua data de nascimento?" (etapa que saiu da árvore principal, ver §7.4) — redirecionada pra "Crie um nome de usuário"; e o texto dentro do botão "Continuar" de "Choose activities" tinha uma reaction própria, conflitante com a do frame que o contém (uma ia pra Home, a outra pra "menssage") — unificadas nas duas pra Home.

Lição geral, pra qualquer reconstrução futura neste arquivo: antes de apagar os filhos de uma tela pra reconstruir do zero, checar se algum deles carrega reactions — e replicar o destino na tela nova, não só o visual. "Sem conexão" é um bug tão real quanto um texto errado ou uma cor fora do padrão, só que invisível no screenshot.

7.8 A organização por fileira de "tipo de tela" virou organização por área de produto

A divisão original em 8 fileiras (Cap. 2) misturava, dentro da mesma fileira "Telas-raiz", coisas de áreas de produto diferentes — Home, a aba Activities, Comunidades e todas as variantes de Perfil, todas juntas só porque eram "tela-raiz de aba". Fernando pediu uma reorganização mais direta: tudo de Home num lugar só, tudo de Turismo junto, tudo de Atividades junto, tudo de Comunidade junto, tudo de Perfil junto — cada bloco podendo crescer em até duas linhas quando tivesse gente demais pra uma só.

1
Home — 1 linha, 2 telas (Home, Home memórias vazias). O bloco mais enxuto do arquivo.
2
Turismo — 2 linhas: a primeira com navegação de descoberta (Explorar Destinos, Categorias, Selecionar Datas, Buscar Destino, Montar/Meu Itinerário); a segunda é o Passaporte inteiro (Capa, 14 dias, Índice, 3 formatos de compartilhamento) — 19 telas que já formavam uma unidade coesa, mantidas juntas na mesma linha de propósito.
3
Atividades — 2 linhas, o maior bloco (34 telas): a primeira reúne a aba Activities e todo o Detalhe da Experiência (genérico + 6 variantes nomeadas) + Editar/Criar Atividade; a segunda reúne o pós-decisão (Adicionar Vivência, Checkout, Confirmação, Cancelar, Equipe, Curtidas) + a camada de acompanhamento (Agenda, Ingressos, Check-in).
4
Comunidade — 1 linha, 8 telas (Comunidades + vazio, Detalhe ×2, Criar, Configurações, Moderadores, Editar).
5
Perfil — 2 linhas: a primeira é identidade (as 4 versões de Perfil próprio, Editar Perfil ×2, Perfil de Terceiro ×4); a segunda é rede e histórico (Seguindo/Seguidores ×2 cada, Minhas Viagens ×2, Memória/Compartilhar Memória).
6
Mensagens & Notificações — manteve-se como bloco próprio (não é Home/Turismo/Atividades/Comunidade/Perfil, é transversal), 1 linha, 12 telas.

A fileira de Autenticação & Onboarding (§7.4) não foi tocada nesta reorganização — já tinha acabado de ser posta em ordem e também é transversal, não pertence a nenhuma das 5 áreas de produto. 117 telas no total, zero colisões, cada bloco fisicamente contíguo no canvas — quem quiser auditar "tudo de Atividades" agora rola pra um lugar só, não caça telas espalhadas em 4 fileiras diferentes.

A pergunta era simples: "e se a pessoa pudesse buscar por como está se sentindo — triste e querendo algo animado, ou querendo relaxar?" A investigação nos livros revelou que essa pergunta já tinha resposta havia tempo. O Vol. 05 (Arquitetura de Produto), Capítulo 7 — O Sistema de Descoberta, dedica uma seção inteira a isso: "O check-in de sentimento e intenção". E o Vol. 06 (Design de Sistema) já tinha até o schema esboçado: user_checkin: feelings[], wants[], created_at e activity.mood_tags. Nada disso existia em código ou em tela — era, até esta construção, só visão.

7.9 A distinção que o livro já tinha resolvido

O risco óbvio de qualquer "busca por humor" é tratar sentimento como uma tag só — a pessoa está triste, mostra atividade "triste". O Vol. 05 já rejeitava essa simplificação, separando duas perguntas diferentes:

Trecho real — the-everhere-product-architecture.md, Cap. 5
"O sentimento descreve onde a pessoa está. A intenção descreve para onde ela quer ir. [...] nem sempre a resposta certa para o cansaço é o descanso. Às vezes é o oposto."
O texto também é explícito sobre multiplicidade: "ninguém sente uma única coisa por vez" — a pessoa escolhe várias opções em cada pergunta, não um rótulo.

7.10 Onde isso entrou na interface

Três construções, ligadas entre si:

1
Check-in na Home — um card persistente logo abaixo do cabeçalho ("Como você está hoje?"), abrindo uma tela com duas fileiras de chips multi-seleção: sentimento agora (cansada, entediada, curiosa, ansiosa, sobrecarregada, animada, tranquila, triste) e o que quer sentir (relaxar, ter energia, estar perto de gente, ficar em silêncio, experimentar algo novo, comemorar, aprender algo novo) — vocabulário tirado direto do texto do Vol. 05.
2
mood_tags em Criar/Editar Atividade — o organizador marca quais sentimentos daquele segundo grupo (a "intenção") a atividade proporciona. Mesma lista de chips, porque é a ponte: o que a pessoa quer sentir precisa bater com o que a atividade entrega.
3
Filtro em Resultados da Busca — os mesmos chips de intenção, filtrando os resultados. O botão "Ver experiências pro meu momento" no check-in já leva direto pra essa tela.

7.11 O que ainda é só protótipo

O Figma demonstra a interface, não a inteligência por trás dela. Continuam como pendência real de schema/RPC (mesma categoria do Capítulo 13): a tabela user_checkin não existe — precisa ser append-only, cada mudança uma linha nova, nunca sobrescrita, exatamente como o Vol. 06 especifica; a coluna activity.mood_tags também não existe; e a lógica de cruzar as duas coisas (o check-in mais recente da pessoa com os mood_tags das atividades disponíveis) não tem nenhuma RPC — hoje, no Figma, o filtro é manual (a pessoa escolhe os chips na busca), não automático a partir do check-in. Fechar esse automatismo — o check-in alimentando a Home sozinho, sem precisar de um filtro manual — é o próximo passo natural, e é exatamente o que o Vol. 05 descreve como objetivo final: "o primeiro instrumento real da capacidade de descoberta contextual".

7.12 O primeiro rascunho parecia formulário, não sentimento

A primeira versão desses chips usava só moss, cinza e terracota — as cores "estruturais" que o resto do app reserva para botão e campo de formulário. O resultado, sinalizado diretamente: "ficou amador... tudo muito profissional, e esses cards criados não tivessem sido pensados como deveria". Uma pergunta simples resolveu: quais cores o próprio app já usa pra momentos expressivos, e por que elas não foram usadas aqui?

packages/ui/src/tokens.ts (código real) tem uma paleta inteira nunca tocada nessa construção — yellow, red, orange, green, greenLight, teal — ao lado do gradiente de marca (gradients.isotipo, laranja→verde) já usado em cards de compartilhamento e capas. A correção: cada sentimento e cada intenção ganhou sua própria cor dessa paleta e seu próprio emoji, em vez de um cinza uniforme com texto mudando; o card de entrada na Home trocou o ícone de contorno plano por um círculo preenchido com o gradiente real da marca. A lição fica geral, não só pra esse recurso: antes de desenhar algo expressivo, checar que paleta o próprio design system já reserva pra expressividade — não reaproveitar por padrão as cores de botão e formulário.

7.13 A correção corrigiu demais — e a segunda correção teve que voltar pro código-fonte

A correção do 16.4 resolveu o problema errado de forma exagerada. Trocar o cinza uniforme por cor-e-emoji por sentimento estava certo em princípio, mas a execução foi longe demais: chips grandes (até 174px de altura de fileira), preenchimento sólido de cor em cada um, emoji de 15px. O resultado, com screenshot em mãos, foi sinalizado de duas formas específicas e concretas — não um "não gostei" genérico:

Feedback real de Fernando, com 2 screenshots anexados
"o filtro ocupa muito espaço e isso não é bom, é como se estivesse fugindo do estilo que estamos criando, do estilo mobile [...] Esse card da home [...] é como se ele tivesse mais prioridade do que a foto, precisa ser algo delicado, sutil, não um mega card [...] precisa ser na nossa identidade, no nosso padrão, padrão app sofisticado."

Dois problemas distintos, na verdade: (1) o filtro de Resultados da Busca, com chips em WRAP (múltiplas fileiras), empurrava a lista de resultados pra baixo da dobra — errado num contexto de lista, onde cada pixel vertical compete com o conteúdo principal; e (2) o card de check-in na Home, com círculo de gradiente de 48px e texto em negrito, tinha mais peso visual que a foto de capa da Home — errado numa tela cujo conteúdo primário é a Hero photo, não um convite secundário.

A correção do 16.4 tinha ido buscar cor e emoji certos, mas nunca tinha ido conferir o tamanho e o peso reais que o design system usa pra chip. Essa segunda rodada corrigiu isso lendo o componente de verdade: packages/ui/src/components/Chip.tsx. A especificação real é modesta — borderRadius: pill (999), paddingVertical: 7, paddingHorizontal: 16, fundo sand com borda de 1.5px em neutral a ~27% de opacidade quando inativo, preenchimento sólido em terracota só quando ativo, texto 13px medium. Nada parecido com os chips de 174px de altura da v1.

1
Chips recalibrados (Check-in, Criar/Editar Atividade, filtro em Resultados) — altura de fileira caiu de até 174px para ~148px nas telas dedicadas, padding para 7/13-14px, borda 1.2px, emoji 12px, texto 12.5px. Continuam coloridos e com emoji (a lição do 16.4 não foi descartada) mas na escala real de um chip, não de um card.
2
Filtro de Resultados da Busca virou rolagem horizontal de fileira única, não mais WRAP — a mesma técnica que os chips de categoria da tela Comunidades já usavam (layoutMode: "HORIZONTAL", primaryAxisSizingMode: "AUTO", largura excedendo de propósito os 375px da tela, clipsContent: true na fileira). Resultado: 31px de altura em vez de 144px — o filtro deixou de competir por espaço com a lista de resultados.
3
Card de check-in na Home reduzido a uma barra fina — 44px de altura, sem preenchimento, só um traço inferior de 1px a 6% de opacidade de preto separando-o do conteúdo abaixo; ícone reduzido a um círculo de 24px com o gradiente da marca; texto em uma linha só, 13px semibold ("Como você está hoje?"); seta de 7×12px. Passou a se comportar como um convite discreto acima da Hero photo, não como um segundo herói competindo por atenção.

A lição do 16.4 ("antes de desenhar algo expressivo, checar que paleta o design system reserva pra expressividade") ficou mais completa: paleta certa não basta — escala e peso visual também precisam vir do componente real, não de uma reinterpretação livre dele. "Sofisticado", no vocabulário deste app, significa contido: cor e emoji carregam a expressividade; tamanho e padding continuam os do sistema de design, não os de uma versão ampliada e mais chamativa dele. A generalização prática: qualquer novo elemento visual expressivo deste projeto deve ser conferido contra o componente-base real (Chip.tsx, Badge.tsx, tokens.ts) em pelo menos três eixos — cor, escala, e técnica de layout (wrap vs. rolagem horizontal, conforme o contexto de espaço da tela) — antes de ser considerado pronto para revisão.

Parte II — Decisões de Produto

Roteiro: Do Rascunho ao Compartilhamento

Da lacuna de um único ponto de entrada até o rascunho compartilhável entre quem vai viajar junto

8.1 O problema: um único ponto de entrada, fechado depois de um clique

Fernando trouxe uma lacuna de fluxo, não um bug visual: "hoje estamos adicionando itinerário apenas na página de confirmação de pagamento, mas é preciso permitir adicionar itinerário não só na página de checkout". Checando o grafo real: a tela "Confirmação" (pós-pagamento) tinha exatamente UM botão "Adicionar ao itinerário", com reaction levando pra "Montar Itinerário" — e nenhum outro lugar do arquivo oferecia essa ação. Se a pessoa fechasse essa tela sem tocar no botão (ou simplesmente decidisse organizar depois), a experiência comprada ficava sem segundo caminho de volta pro plano da viagem.

Fernando já apontou o lugar certo pro segundo ponto de entrada: "quando for ver na agenda as suas próximas experiências, ele pode adicionar ao itinerário da viagem" — a tela "Agenda" (lista de experiências confirmadas, agrupadas HOJE/ESSA SEMANA/EM BREVE) já existia no arquivo como o destino natural de "o que eu comprei", mas não tinha nenhuma ação de organização — só um selo de status (ORGANIZANDO/PARTICIPANDO) herdado do fluxo de confirmação do organizador, sem relação com o roteiro.

8.2 Itinerário → Roteiro: a troca de nome não criava conflito, resolvia um

Fernando pediu a troca de termo no mesmo pedido: "no lugar de itinerário podemos chamar de Roteiro". Antes de aplicar, checagem contra a memória do projeto: "Roteiro" já tinha um significado reservado nesta sessão — a direção de monetização futura (venda de roteiros prontos por terceiros, Vol. da Biblioteca sobre Passaporte). Preocupação legítima: será que nomear o itinerário PESSOAL de "Roteiro" colide com esse "Roteiro" vendável?

A checagem no arquivo real resolveu a dúvida antes dela virar bloqueio: a tela "Compartilhar Roteiro" (parte do fluxo de Passaporte, Cap. 5 da Biblioteca) já usa exatamente esse nome pro plano completo de dias da viagem — brandTag "everhere · roteiro", conteúdo "14 dias em Gramado, RS · Trilhas · balão · vinícolas...". Ou seja: "Roteiro" já era o nome informal do itinerário completo em outro canto do produto. A troca não cria um termo novo concorrente — consolida um termo que já existia, disperso, num único nome. Aplicado file-wide: nome dos frames e texto visível — "Montar Itinerário"→"Montar Roteiro", "Meu Itinerário"→"Meu Roteiro", "Ver itinerário completo"→"Ver roteiro completo", "Adicionar ao itinerário"→"Adicionar ao roteiro". Varredura final confirmou zero ocorrências de "itinerár" restantes no arquivo.

8.3 Desenho da segunda entrada: perguntas antes de desenhar

Antes de tocar no Figma, três perguntas resolvidas com Fernando (via /using-superpowersbrainstorming) evitaram retrabalho: onde a ação vive na Agenda (resposta: os dois — ação por item E um banner geral, não um ou outro), se um item já adicionado precisa de estado visual diferente (resposta: sim — "No roteiro ✓" no lugar do botão, pra não sugerir que dá pra adicionar de novo), e se o fluxo em lote (banner) merece uma tela nova ou um modo de seleção na própria Agenda (resposta: modo de seleção — reaproveita a lista existente em vez de quase-duplicá-la, o mesmo princípio de "quebra se eu consolidar" usado no §11.19 pra decidir quando NÃO criar tela nova).

8.4 Construção: ação por item, banner, e uma segunda tela de seleção

Cada linha da Agenda (343px de largura, praticamente sem sobra horizontal — o bloco de texto já ia até 14px da borda) precisou crescer 38px de altura pra abrir espaço embaixo do conteúdo existente, sem forçar o título a quebrar linha de um jeito novo — mesma lição do Cap. 11 (Notificações): quando o conteúdo novo não cabe, redimensionar o container, não espremer o texto. Nessa faixa nova, no canto inferior direito: um botão sólido moss "+ Roteiro" nos itens pendentes, ou um texto simples "✓ No roteiro" (moss, sem preenchimento) nos já adicionados — a diferença de peso visual (botão cheio vs. texto solto) já comunica "ação disponível" vs. "nada a fazer aqui" antes mesmo de ler a palavra.

Um banner foi inserido entre o título "Minha Agenda" e a primeira seção de data, com contagem dinâmica de pendentes ("Adicionar 2 experiências ao roteiro") — reaproveitando o mesmo tom quase-branco/sálvia (#F3F6F2) já padronizado no Cap. 12 pro card de conteúdo sobre fundo sand. Todo o fluxo vertical da tela foi recalculado a partir daí (mesma disciplina do Cap. 11: medir, não chutar), crescendo a Agenda de 578px pra 788px de altura total.

A tela de seleção em lote foi construída clonando a Agenda já atualizada (evita reconstruir a mesma lista do zero, e garante que qualquer ajuste futuro na lista original não precisa ser replicado manualmente) — "Agenda (seleção)", adaptada em 3 pontos: o banner virou um cabeçalho de estado ("2 selecionadas" + "✓" no lugar do "+"), os botões "+ Roteiro" dos itens pendentes viraram checkboxes já marcados (a pessoa entra no modo de seleção com tudo que está pendente pré-selecionado, ajustando pra menos se quiser — não o contrário), e uma barra de confirmação nova foi adicionada ao fim ("Adicionar 2 ao roteiro", moss, cheia). Tocar no botão de um item OU confirmar a seleção em lote levam ambos pro mesmo destino — "Montar Roteiro" — em vez de inventar uma lógica de posicionamento automático por dia; é lá que a distribuição por dia já acontece hoje, um único lugar pra essa decisão.

Zero colisões nas 118 telas (117 + a nova "Agenda (seleção)", posicionada fora da área ocupada do canvas já que a fileira de telas vizinhas da Agenda não tinha vão livre suficiente pra um frame novo de 375px).

8.5 O pedido: testar o roteiro antes de comprar, decidir em grupo

Fernando descreveu uma lacuna de planejamento: "hoje conseguimos comprar atividades e elas são direcionadas pra Agenda, além disso conseguimos adicionar à lista de experiências as que temos interesse, mas seria interessante se conseguíssemos adicionar as experiências ao passaporte pra que a pessoa possa testar como ficaria o roteiro da viagem e possa compartilhar com quem for viajar, pra poderem decidir se concordam". Em outras palavras: hoje o Roteiro só recebe experiências já COMPRADAS (via Confirmação/Agenda) — não dá pra rascunhar um plano com itens que ainda são só interesse, pra decidir em grupo antes de qualquer um pagar.

Grounding antes de desenhar revelou uma surpresa: a conexão já existia, pela metade. O botão "Adicionar experiência" dentro de "Montar Roteiro" já navegava pra "Activities (Minha Lista ativada)" — a variante da tela de Activities filtrada pela lista de interesse. Mas os botões "Minha Lista"/"Participar" nos cards dessa tela não tinham NENHUMA reação de volta — um link de ida sem volta, o mesmo tipo de "stopgap" catalogado no Cap. 13 da Biblioteca (telas conectadas de um lado só). O pedido de Fernando, na prática, pedia pra fechar esse loop — mais uma peça nova: o compartilhamento pra decisão em grupo.

8.6 A tensão real: Passaporte é só pós-viagem, por decisão já registrada

Antes de desenhar, valia confrontar o pedido com uma decisão já tomada nesta sessão: o Passaporte é compartilhado só DEPOIS da viagem, decisão registrada explicitamente pra resolver "a preocupação de privacidade de expor datas de viagem futura publicamente". O pedido de Fernando — testar e compartilhar o roteiro ANTES da viagem — pareceria, à primeira vista, contradizer isso diretamente.

A diferença que resolve a tensão: a tela de decisão antiga tratava de exposição pública (Instagram, link aberto, qualquer um vê). O pedido novo é compartilhar com um grupo fechado — "quem for viajar" —, pessoas que, por definição, já sabem as datas da viagem (estão indo). Não é o mesmo tipo de exposição. Via /using-superpowersbrainstorming, confirmado com Fernando: o rascunho fica dentro de "Montar/Meu Roteiro", sem usar o nome nem o visual do Passaporte — não reabre a regra já decidida, resolve o pedido por um caminho que não conflita com ela.

Segunda decisão de escopo: o que os convidados conseguem fazer com o rascunho recebido? Confirmado só visualização — decidir "concordam" acontece fora do produto (WhatsApp, conversa), sem mecanismo de reação/voto por item. Menor escopo, sem inventar um sistema de colaboração multi-usuário que o resto do arquivo (protótipo estático, sem estado real) não tem como sustentar de verdade.

8.7 Fechando o loop: da lista de interesse de volta pro dia

O card "Yoga nas Falésias do Cotovelo" (um dos 2 exemplos de "Minha Lista ativada") ganhou a reação que faltava: tocar em "Minha Lista" nesse card agora leva de volta pra "Montar Roteiro", com o item já aparecendo no Dia 1 — um 4º item na lista, com "A definir" no lugar de um horário (diferente dos 3 itens já com hora marcada, sinalizando visualmente "adicionado mas ainda sem posição no dia", sem inventar um mecanismo de arrastar-e-soltar que o Figma estático não sustenta).

Erro no caminho — quarta variação da mesma família de bug: posicionar o novo item manualmente não funcionou de novo. Dessa vez a causa era um "primo" das duas anteriores: a lista de itens do dia (lista) também é auto-layout de verdade (VERTICAL, itemSpacing: 12) — igual à Home do §9.3 — mas aqui o sintoma era diferente: a POSIÇÃO calculada pelo motor de auto-layout estava certa, só a ORDEM dos filhos é que estava errada (o item novo tinha sido anexado no fim da lista, depois do botão "Adicionar experiência", não antes). Corrigido não com layoutPositioning = "ABSOLUTE" (que teria tirado o item do fluxo automático, perdendo o espaçamento correto de 12px de graça) — e sim com insertChild(index, node) no índice certo, deixando o motor de auto-layout recalcular a posição sozinho, do jeito que ele já faz bem.

Quarta causa registrada pra mesma família de sintoma: quando o filho novo precisa PARTICIPAR do fluxo automático (não ser uma exceção fixa como o scrim do §9.3), o problema não é de posição — é de ORDEM na lista de filhos, e a correção é insertChild no índice certo, não forçar x/y nem isentar do auto-layout.

8.8 Compartilhar rascunho: mesmo padrão visual, conteúdo com tom diferente

Adicionado um ícone de compartilhar no cabeçalho de "Montar Roteiro" (canto superior direito, clonado do mesmo "Btn Compartilhar Passaporte" já usado em 3 outras telas — reaproveitando um componente validado, não desenhando um novo ícone) — leva pra uma tela nova, "Compartilhar Roteiro (rascunho)", clonada de "Compartilhar Roteiro" (o card de compartilhamento do Passaporte, §12.4) com o texto trocado pro tom de rascunho: brandTag "everhere · roteiro" → "everhere · rascunho", citação de destaque trocada da celebrativa "Um roteiro completo, pronto pra inspirar a próxima viagem de alguém" pra "Ainda em construção — dá uma olhada e me diz o que acha!", texto de apoio trocado de "compartilhe o roteiro completo" pra "compartilhe esse rascunho com quem vai viajar com você". Mesmos 4 ícones de destino (Instagram/WhatsApp/Salvar imagem/Copiar link), mesma estrutura visual — só o texto muda o que a tela está comunicando.

Zero colisões nas 122 telas (117 + Agenda (seleção) + Avaliar Experiência + Avaliação Enviada + Experiência Concluída + Compartilhar Roteiro (rascunho)).

8.9 Um botão só, dois significados — corrigido pra dois botões

Fernando reportou um print (recorte só do rodapé de "Montar Roteiro" — botão "Adicionar experiência" + topo do "Ver roteiro completo") dizendo "o card adicionado não ficou completo", e perguntou: "se eu adicionar a experiência em minha lista, vai direto pra criar roteiro?". Investigação da estrutura real não achou defeito visual no card do §8.7 — mas a pergunta revelou o problema de verdade, por trás do "incompleto": o botão "Minha Lista" do card (§8.7) tinha sido religado pra SEMPRE navegar pro Roteiro, mesmo quando a pessoa chega nessa tela navegando normalmente (não pelo fluxo "Adicionar experiência"). Marcar interesse numa experiência não deveria, por si só, jogar a pessoa pra montagem de roteiro — são duas intenções diferentes disfarçadas de um botão só.

Fernando propôs a correção certa: "no lugar de ter um + Minha Lista, poderiam ter dois botões, um pra lista e outro pra roteiro". Investigado o espaço real do card antes de aplicar (via /using-superpowers): 166px de largura, "Participar" (69px) + "Minha Lista" (76px) já ocupavam quase toda a linha de 150px disponível — sem espaço de sobra pra um 3º botão de texto lado a lado. Confirmado com Fernando: troca CONTEXTUAL — nessa tela específica ("Activities (Minha Lista ativada)", que já mostra só o que a pessoa salvou), "Minha Lista" vira "+ Roteiro" no lugar de repetir uma ação redundante (o item já está na lista, óbvio pelo contexto). Fora dessa tela — Activities normal — "Minha Lista" continua exatamente como estava, sem navegar.

Erro cometido no caminho, corrigido no mesmo fôlego: a varredura por texto "Minha Lista" pra trocar os 2 botões dos cards achou um 3º resultado inesperado — um nó de texto cujo PAI direto era a própria tela ("Activities (Minha Lista ativada)"), não um card. Sem perceber a diferença, o script renomeou a TELA inteira pra "Btn + Roteiro" e deu a ela uma reação de navegação — um erro real, não cosmético. Investigando o 3º nó: era o chip de filtro "Minha Lista" da própria Activities (a etiqueta que dá nome a essa variante de tela), sem relação nenhuma com os cards. Corrigido revertendo o nome da tela, removendo a reação indevida, e devolvendo o texto do chip pro original — confirmado por reinspeção, não só assumido corrigido.

Lição: uma varredura por texto igual ("Minha Lista" aparece em mais de um lugar com papéis diferentes: botão de card E chip de filtro de tela) precisa checar o CONTEXTO de cada resultado antes de aplicar em lote — não só o texto bate, o papel do nó importa. Zero colisões nas 122 telas depois da correção.

8.10 Faltava ver o resultado de tocar em "+ Roteiro"

Fernando apontou a lacuna seguinte, direto no print dos 2 cards corrigidos: "ficou faltando como ficará se clicar em + roteiro, crie a tela". Até aqui, os botões "+ Roteiro" dos 2 cards levavam OS DOIS pro mesmo "Montar Roteiro" — que só mostra visivelmente o item da Yoga (adicionado no §8.7). Tocar no "+ Roteiro" do card do Pedal levaria pra uma tela que não refletia aquele toque especificamente — um mismatch de identidade do mesmo tipo já catalogado no critério do §11.19 ("quebra se eu consolidar?").

Construída uma tela de confirmação leve — fundo sand (não o forest celebrativo de "Confirmação"/"Avaliação Enviada", ação de menor peso que não merece o mesmo tratamento), selo de check moss (64px, mais discreto que o selo grande de "Presença confirmada!"), título "Adicionado ao roteiro!", card de contexto (foto+nome+categoria da experiência específica) e botão "Ver roteiro" (→ Montar Roteiro) + link secundário "Continuar explorando" (→ de volta pra Activities filtrada). Construída DUAS vezes — uma pro Pedal, clonada e adaptada pra Yoga — cada botão "+ Roteiro" agora leva pra SUA própria confirmação, nomeando a experiência certa antes de seguir pro roteiro.

Zero colisões nas 124 telas (122 + as 2 confirmações).

8.11 Organizando as telas novas nos blocos certos do canvas

Fernando pediu, na sequência: "organize todas as telas criadas em seus respectivos locais" — as 7 telas construídas nos Caps. 23 e 24 ("Agenda (seleção)", "Avaliar Experiência", "Avaliação Enviada", "Experiência Concluída", "Compartilhar Roteiro (rascunho)", "Adicionado ao Roteiro (Pedal)" e "(Yoga)") tinham sido colocadas em espaço vazio genérico, fora dos 6 blocos por área de produto estabelecidos no §7.8, só pra evitar colisão no momento da criação.

Mapeados os limites direitos reais de cada fileira temática (não assumidos — lidos direto do canvas) antes de mover qualquer coisa, cada tela nova foi movida pro final da fileira certa, mantendo o espaçamento de 80px já usado no resto do arquivo entre telas da mesma fileira:

1
Fileira de Agenda/pós-decisão (mesma linha de "Agenda", "Meus Ingressos", "Check-in") — "Agenda (seleção)" movida pra logo depois de "Check-in".
2
Fileira de Detalhe da Experiência (mesma linha das 6 variantes nomeadas + "Editar Atividade"/"Criar Atividade") — "Avaliar Experiência", "Avaliação Enviada" e "Experiência Concluída" movidas juntas pro final, na mesma ordem do fluxo (mesmo a "Experiência Concluída" sendo tecnicamente amarrada ao login — pertence, pelo conteúdo, à família de avaliação, não à de autenticação).
3
Fileira de Turismo/Roteiro (mesma linha de "Montar Roteiro"/"Meu Roteiro") — "Compartilhar Roteiro (rascunho)", "Adicionado ao Roteiro (Pedal)" e "(Yoga)" movidas juntas pro final, logo depois de "Meu Roteiro" — fisicamente perto de onde são navegadas de/pra, não perto de "Compartilhar Roteiro" (o original, que mora na fileira do Passaporte) — decisão consciente pra não sugerir visualmente uma associação com Passaporte que o §8.6 decidiu explicitamente evitar.

Zero colisões nas 124 telas depois da reorganização — nenhuma reação quebrada, já que reactions referenciam id, não posição.

8.12 "Experiência Concluída" não é uma tela de login — é uma tela de fim de experiência

Fernando corrigiu o enquadramento, olhando o print de "Experiência Concluída": "essa deve ser a mesma tela de quando finaliza uma experiência, não só de quando faz login — finalizou experiência já aparece essa tela; em caso de deslogar e relogar, aparece essa tela pra avaliação". O gatilho de login (§9.4) não estava errado — só não devia ser o ÚNICO. A tela representa, por natureza, "você acabou de viver isso"; o login é um caso secundário (retomar uma avaliação pendente), não a origem principal.

Busca no arquivo por um momento real de "fim de experiência" veio vazia — não existe hoje. "Check-in" (nome que sugeria chegada no evento) é na real a feature de humor do Cap. 7 ("Como você está agora?"), sem nenhuma relação com o fim de uma experiência. "Detalhe do Ingresso" é o código de entrada, mostrado ANTES da experiência acontecer ("Apresente este código na entrada do evento"), não depois. Nenhum candidato óbvio.

Confirmado com Fernando o melhor proxy disponível: o fim do fluxo de câmera — "Legenda e Fotos" → "Publicar na vivência" — hoje leva direto pra "Adicionar Vivência" (o mural de fotos do grupo). É o momento mais próximo de "acabei de viver isso" que já existe de verdade no arquivo: a pessoa acabou de tirar foto e publicar na vivência compartilhada, gesto que só faz sentido tendo participado. Redirecionado pra passar por "Experiência Concluída" primeiro.

O botão "Fechar" da tela — que precisa funcionar pros dois gatilhos agora (login E publicar foto) — foi mantido levando pra Home nos dois casos, em vez de tentar ramificar o destino por origem (um protótipo estático não tem como saber de onde a pessoa veio); "Home" já funciona como destino genérico de "dispensar e voltar pro app" em outros pontos do arquivo, então não é uma exceção nova. Zero colisões nas 124 telas depois da religação.

8.13 "+ Roteiro" pertence à lista de verdade, não aos cards de destaque

Fernando revisou o §8.9 e propôs uma organização melhor: "primeiro botão é de Minha Lista, em Minha Lista deve-se ter um botão pra adicionar ao roteiro". Investigado antes de aplicar (via /using-superpowers) qual das duas leituras possíveis era a certa — pergunta objetiva com 2 opções, confirmada: "Participar" + "Minha Lista" voltam a aparecer SEMPRE, sem troca contextual (nem nos cards de "Destaque", nem em Activities normal); "+ Roteiro" deixa de ser um botão de card e passa a viver DENTRO da seção "Minha Lista" — a lista de verdade, não os 2 cards de destaque que ficam no topo da tela.

Investigando a estrutura real da seção "Minha Lista" (que não tinha sido mapeada até agora — só os 2 cards de "Destaque" tinham sido tocados no §8.9): é um card COMPACTO de 88×120px, mesmo componente reaproveitado nas fileiras de categoria (Corrida/Ciclismo/Trilha) mais abaixo na tela — bem menor que os cards de Destaque (166px), com só um ícone "i" de info no canto inferior direito, sem nenhum botão de texto. Não cabia repetir o padrão "Participar + + Roteiro" aqui — a solução foi um ícone compacto (20×20, moss, só "+"), no canto superior direito, livre porque o "i" já ocupa o inferior.

Dois erros técnicos no caminho, ambos já catalogados, resolvidos com o mesmo fix de antes: (1) o card "Minha Lista" é uma INSTANCE de componente — tentar adicionar um filho novo direto deu o erro já conhecido "cannot move node, new parent is an instance"; corrigido com detachInstance() primeiro (mesmo fix do Cap. 11). (2) depois de destacado, o card revelou ser auto-layout de verdade (VERTICAL) — o ícone novo, com layoutPositioning: "AUTO" por padrão, ficava sendo empilhado pelo motor em vez de ficar no canto fixo pedido; corrigido com layoutPositioning = "ABSOLUTE" (mesmo fix do §9.3/Home). Nenhum dos dois é um bug novo — ambos já estavam no repertório de causas conhecidas desta sessão, só precisavam ser reconhecidos rápido.

Limpeza, não acúmulo: com "+ Roteiro" saindo dos 2 cards de Destaque, as 2 telas de confirmação construídas no §8.10 pra eles ficariam órfãs (sem gatilho nenhum apontando pra elas). Como são construção da própria sessão, recém-criada — não conteúdo legado ambíguo — a tela da Yoga foi apagada (.remove()), e a tela do Pedal foi REAPROVEITADA: renomeada e com o texto trocado pra "1ª Race of happy divas" (a experiência real da seção Minha Lista), em vez de descartar e reconstruir do zero. Zero colisões nas 123 telas (124 − 1 apagada).

8.14 Cor do "+ Roteiro" e o "i" que nunca fez nada — em nenhum lugar do arquivo

Fernando pediu antes de tudo pra ver a tela apagada da Yoga de novo — reconstruída (clonando a do Pedal/Race e trocando o conteúdo de volta), confirmada por screenshot, e só então apagada de novo com autorização explícita ("realmente não precisa, pode apagar"). Lição prática: mesmo uma tela criada pela própria sessão pode merecer uma checagem antes do apagar definitivo, se o pedido do usuário sinalizar dúvida — apagar de novo depois de mostrar é diferente de nunca ter mostrado.

Cor do "+ Roteiro": Fernando notou, olhando o ícone novo do §8.13, que talvez precisasse de "outra cor, o laranja, pra ficar diferente". Checagem confirmou o problema exato: o ícone "+ Roteiro" e o botão "Participar" do mesmo card usavam a MESMA cor moss — indistinguíveis por cor, só pela posição. Trocado pra terracota (a mesma cor de CTA/preço já usada em outras telas do arquivo) — moss continua reservado pra "Participar"/ações de organização, terracota passa a marcar "+ Roteiro" como uma ação de natureza diferente.

O "i": gap real, confirmado no código, não só no Figma. Fernando perguntou o que o ícone "i" mostra — investigação achou ZERO reações em 56 instâncias do mesmo botão espalhadas pelas telas de Activities, e o código real (ActivitiesScreen.tsx) confirmou a mesma lacuna: o card inteiro já navega pra "Detalhe da Experiência" ao toque (onPress={() => router.push(...)}), mas o "i" — um Pressable separado dentro do card — não tem onPress nenhum, e seu estilo no código é literalmente infoBtn: {}, um objeto vazio. Confirmado em 3 componentes diferentes (featuredCard, SmallCard, Top10Card) — não é descuido pontual, é uma feature inacabada nos dois lados do produto.

Pedido pra desenhar a função agora, num exemplo antes de espalhar pros 56: um bottom-sheet de "espiada rápida" — scrim + card subindo do rodapé com foto maior, título, data/categoria, descrição curta, e dois botões ("Ver detalhes completos" → tela cheia de verdade; "Participar" → Checkout) — pensado como alternativa mais leve à navegação completa, pra quem só quer confirmar um detalhe antes de decidir tocar no card.

Erro de padrão evitado no caminho: a primeira tentativa colou o scrim + bottom-sheet direto como filhos da tela AO VIVO ("Activities (Minha Lista ativada)") — o que faria a espiada aparecer SEMPRE, não só quando o "i" fosse tocado, quebrando o padrão do arquivo inteiro (cada estado é uma tela própria, ligada por reação, nunca um overlay permanente numa tela viva). Corrigido a tempo, antes de qualquer verificação: scrim removido da tela viva, reconstruído numa tela clonada nova — "Activities (Minha Lista ativada) · Espiada" — com o "i" da tela original levando até ela, e "Fechar" voltando.

Zero colisões nas 124 telas. O rollout pros outros 55 "i" do arquivo não foi feito — só o exemplo pedido, validando a ideia antes de multiplicar.

Revertido na sequência: vendo o resultado construído, Fernando decidiu que o card não ficou bom e pediu pra tirar — "retirar esse i e qualquer coisa, em outro momento adicionamos, mas não agora". Tela "· Espiada" apagada, "i" devolvido ao estado inerte (igual aos outros 55). A investigação e o gap real no código continuam válidos e registrados — só a solução construída foi desfeita, fica pra quando for retomado.

E depois, removido de vez — pelo caminho certo: Fernando pediu, numa mensagem seguinte, pra tirar o ícone "i" de todos os cards. A primeira tentativa (apagar instância por instância) esbarrou no limite do Figma em 49 das 56 ocorrências — filhos estruturais de instância não podem ser removidos direto, só depois de destacadas. Antes de seguir destacando 49 instâncias uma a uma, Fernando perguntou: "não seria o caso de componentizar e já ajustar esse problema?" — a pergunta certa. As 49 instâncias vinham todas do MESMO component set, "Card Atividade" (variantes Estado=Compacto e Estado=Expandido). Removido o "Btn info" das duas variantes na RAIZ do componente — propagou pras 49 instâncias de uma vez só, zerando o ícone no arquivo inteiro (0 de 56 restantes, confirmado por varredura), sem precisar destacar nenhuma instância e sem perder o vínculo delas com o componente pra atualizações futuras. Zero colisões nas 123 telas.

Parte II — Decisões de Produto

Avaliação Pós-Experiência

Como medir se uma experiência foi boa, e onde a interface faz essa pergunta

Enquanto o Capítulo 8 documenta a construção do Roteiro (rascunho de viagem), esta seção separada cobre uma decisão de produto diferente, encontrada no meio do mesmo trabalho: como medir se uma experiência foi boa — e onde, na interface, essa pergunta é feita.

9.1 "Voltaria a fazer?" media intenção de repetir, não qualidade percebida

Fernando trouxe um problema de metodologia, não de tela: "hoje nossa avaliação principal é 'você voltaria a participar dessa experiência?'... mas muitas pessoas podem querer fazer a experiência apenas uma vez, mesmo gostando, então isso pode prejudicar a avaliação". Grounding no arquivo real confirmou o tamanho do problema: essa pergunta é o ÚNICO sinal de qualidade mostrado no produto — aparece duas vezes na mesma tela de "Detalhe da Experiência" (selo compacto "❤ 92%" no cabeçalho de todas as 13 variantes, e como estatística central da aba "Avaliações", ao lado de "com base em 42 respostas pós-experiência" e 2 depoimentos em destaque). Busca no restante do arquivo confirmou que não existe uma tela de formulário de coleta separada — só essa exibição agregada, então a correção tinha um único ponto real de mudança.

O problema é um clássico de metodologia de pesquisa: "voltaria a fazer?" mede intenção de repetição, que só coincide com qualidade quando a experiência é naturalmente recorrente (aula de yoga semanal). Numa experiência de "uma vez na vida" (passeio de balão, um festival específico), até quem amou pode responder "não" só por já ter riscado aquilo da lista — penalizando experiências excelentes apenas por não serem repetíveis, e inflando artificialmente o placar de experiências recorrentes só por serem recorrentes.

Usado /using-superpowersbrainstorming antes de decidir: 3 direções levantadas — trocar a pergunta principal por "recomendaria?" (mede qualidade percebida, independente de repetição, sem mexer em schema nem layout), perguntar as duas coisas (recomendaria + voltaria, dois números), ou diferenciar por tipo de experiência (única vs. recorrente, campo novo + lógica condicional). Fernando escolheu a primeira — a troca mais simples que resolve a causa raiz sem inflar o formulário nem o schema.

Texto trocado no único nó real da aba Avaliações: "voltariam a fazer essa atividade" → "recomendariam essa experiência" (aproveitado pra padronizar o substantivo também — "atividade" destoava do resto da tela, que usa "experiência" em todo o restante). O selo compacto "❤ 92%" no cabeçalho não precisou de edição de texto — já era só o numeral, sem legenda; seu significado muda silenciosamente junto com a pergunta que o alimenta. Os depoimentos em destaque ("Voltarei com certeza", de Camila Rocha) foram mantidos sem alteração — são conteúdo livre escolhido pelo organizador, não a métrica em si, e continuam fazendo sentido como cor adicional abaixo do número. Zero colisões nas 118 telas depois da troca.

9.2 A pergunta existia, mas não existia onde respondê-la

Na sequência do §9.1, Fernando notou a lacuna óbvia: "temos a porcentagem de avaliação, mas não temos uma tela pra responder a avaliação após a experiência". Grounding confirmou o buraco dos dois lados — nem no Figma (nenhum formulário de coleta) nem no código real (ExperienceRecapScreen.tsx, o único ponto de "pós-experiência" existente, coleta fotos/texto pra memória, sem nenhum campo de nota) existia esse fluxo. Também não havia gatilho natural pra encaixar — "Legenda e Fotos" (fluxo de câmera) é sobre postar numa vivência compartilhada, pode acontecer no MEIO da experiência, não é o momento de fechamento; e "Agenda" só tem seções futuras (HOJE/ESSA SEMANA/EM BREVE), sem noção de "experiências passadas" ainda.

Via /using-superpowersbrainstorming, decidido: gatilho por notificação (padrão real de apps de avaliação pós-compra, não exige reestruturar a Agenda), permanente no histórico — reabrir uma notificação já respondida mostra a confirmação, não o formulário em branco de novo.

A forma da pergunta passou por 3 rodadas de revisão, cada uma puxando pra mais longe do "tradicional": a 1ª proposta era estrelas 1-5 (rejeitada — "esse método é muito tradicional"); a 2ª foi Sim/Não com ícone de coração, ecoando o selo "❤ 92%" já existente (aceita como direção, mas Fernando sugeriu ir além: "poderiam ser 5 botões com textos diferentes, correspondentes às notas de 1 a 5"); a 3ª — a que foi construída — são 5 botões empilhados, cada um com uma frase própria em gradiente de negativo a positivo, sem nenhum número ou estrela visível. Duas famílias de texto foram construídas de verdade no Figma (não só listadas) pra comparação lado a lado — "que história isso virou" (foco em lembrança: "Ficou marcado pra sempre") vs. "voz de quem viveu" (reação em primeira pessoa: "Uma das melhores que já vivi") — Fernando escolheu a 2ª depois de ver as duas no layout real, não só o texto solto.

1
Notificação "Como foi [experiência]?" inserida no topo da seção "Hoje" de Notificações, mesmo padrão visual das notificações dinâmicas existentes (miniatura + texto + link de ação, aqui "Avaliar agora" em moss no lugar de "Ver detalhes").
2
Tela "Avaliar Experiência" — card de contexto (foto+título+data, reaproveitando o padrão visual da Agenda), pergunta aberta "Como foi sua experiência?", 5 opções empilhadas (Não era bem isso / Cumpriu o combinado / Valeu a experiência / Superou o esperado / Uma das melhores que já vivi — a 4ª pré-selecionada como exemplo de estado ativo), campo de texto opcional "Conte como foi" (fonte real dos depoimentos em destaque da aba Avaliações — sem esse campo, aquele conteúdo não tinha origem no fluxo), botão "Enviar avaliação" e link secundário "Agora não".
3
Tela "Avaliação Enviada" — clonado o selo/checkmark já usado em "Confirmação" (mesmo fundo forest, mesma peça de marca) em vez de redesenhar do zero; texto de confirmação referencia a opção escolhida ("Você disse que a experiência 'superou o esperado'"). Serve tanto de confirmação imediata quanto de estado "já respondida" ao reabrir a notificação depois.

Cálculo do agregado, decisão implícita da escolha de 5 opções: como as 5 frases carregam um gradiente de recomendação sem expor número, o "% recomendariam" já em produção (§9.1) passa a contar as 2 opções mais positivas ("Superou o esperado" e "Uma das melhores que já vivi") como "recomendação" — sem precisar mudar nenhum texto já escrito na aba Avaliações, só a regra de contagem por trás do número.

Erro encontrado no caminho: inserir a nova notificação no topo de "Hoje" e recalcular o fluxo vertical (mesma técnica dos Caps. 21/22) quebrou de um jeito novo — os 3 rótulos de seção ("Hoje", "Ontem", "Últimos 7 dias") saltaram pra posições erradas depois do resize() do frame pai, mesmo com os valores de y corretos já escritos. Causa raiz, dessa vez confirmada por inspeção de propriedade, não suposição: os rótulos tinham constraints.vertical = "SCALE" (as linhas de conteúdo tinham "MIN") — redimensionar o frame pai reescala automaticamente qualquer filho com esse constraint, sobrescrevendo qualquer y manual escrito ANTES do resize(). Corrigido em duas etapas: constraints de todos os rótulos trocado pra MIN/MIN (trava a posição, elimina o comportamento futuro), então todas as posições recalculadas do zero e escritas DEPOIS do resize() final. Lição pra qualquer inserção futura nesse tipo de fluxo: checar constraints de cada nó antes de redimensionar o pai — um y "certo" pode não sobreviver ao resize se o constraint não for MIN.

Zero colisões nas 120 telas (117 + Agenda (seleção) + Avaliar Experiência + Avaliação Enviada).

9.3 Um segundo gatilho: aviso ao abrir o app, não só na Notificações

Fernando propôs mais um caminho pro mesmo destino: "seria interessante que, após a experiência ter sido finalizada, ao abrir o app aparecesse uma tela pra avaliar... você participou de tal evento, clique aqui pra avaliar sua experiência". Antes de desenhar, valia confrontar com um precedente direto desta própria sessão: no Cap. 7, o card de check-in de sentimento foi tirado da Home porque ela é dominada por uma foto hero de UMA atividade (feed estilo Strava) — não é uma tela sobre "o estado da pessoa". Esse precedente não invalidava a ideia, mas moldava a forma: não um card fixo competindo com o hero, um overlay temporário por cima.

Duas perguntas resolvidas via /using-superpowersbrainstorming: o aviso substitui a notificação do §9.2 ou os dois coexistem? Fernando escolheu manter os dois — "a pessoa pode fechar a tela de avaliação e querer avaliar em outro momento", e é exatamente pra isso que a notificação permanente no histórico serve; o aviso ao abrir o app é só reforço de visibilidade pra quem não entra em Notificações sozinho, mesmo destino final, dois gatilhos. E o formato — confirmado overlay temporário sobre a Home (não card fixo), coerente com o precedente do Cap. 7.

Construído clonando "Home" — scrim semitransparente (45% preto) cobrindo a viewport inicial (812px) e um card estilo bottom-sheet subindo do rodapé (268px, cantos superiores arredondados, alça de arrasto decorativa) com foto+"Você participou do Pedal ao Amanhecer na Via Costeira", texto de apoio, botão "Avaliar agora" (→ Avaliar Experiência) e "Agora não"/"×" (→ Home normal, dispensa sem bloquear).

Erro encontrado no caminho, terceira variação do mesmo tipo de bug: posicionar o scrim e o card com x/y manuais não funcionou — cada um aparecia empilhado exatamente na borda inferior do elemento anterior (scrim "grudado" embaixo da Bottom Nav, card ainda mais abaixo), inflando a altura renderizada de 1281px pra 2361px. Causa, dessa vez uma terceira variante do mesmo tipo de problema dos §§11.15/23.6 (posição sobrescrita por uma regra do próprio nó pai): "Home" — diferente da maioria das telas do arquivo, que usam posicionamento manual — usa layoutMode: "VERTICAL" (auto-layout de verdade), então qualquer filho novo é automaticamente empilhado no fluxo, ignorando x/y manual. Corrigido setando layoutPositioning = "ABSOLUTE" no scrim e no card — a propriedade que isenta um filho do fluxo de auto-layout (equivalente a position: absolute dentro de um flexbox) — só depois disso o x/y manual passou a colar.

Três variações do mesmo sintoma, três causas diferentes, registradas juntas pra próxima vez: posição errada depois de mexer no layout pode ser (1) erro aritmético puro (§11.15, a primeira rodada de Notificações), (2) constraints.vertical sobrescrevendo y manual quando o frame PAI é redimensionado (§9.2, os rótulos de seção), ou (3) o frame pai ser auto-layout de verdade, empilhando qualquer filho novo independente do x/y escrito (§9.3, aqui). Nenhuma das três se resolve do mesmo jeito — vale checar layoutMode do pai tão cedo quanto constraints do próprio nó, antes de gastar uma rodada inteira supondo erro de conta.

Zero colisões nas 121 telas.

9.4 Overlay rejeitado: "tem que ser uma tela inteira, tipo a capa do Passaporte"

Vendo o resultado do §9.3, Fernando corrigiu a forma: "não dessa forma, tem que ser uma tela inteira... é como se fosse uma tela extra, sem ser por cima da home. Se fechar vai pra home, se clicar em avaliar, vai pra avaliação". O overlay/bottom-sheet foi rejeitado — não pela lógica (gatilho duplo, destino, dispensa sem bloquear seguiam corretos), mas pela FORMA: um card por cima da Home ainda é "por cima", enquanto o pedido era uma tela própria no fluxo de navegação, igual a como "Passaporte · Capa" funciona — uma parada obrigatória e completa antes de continuar.

"Passaporte · Capa" foi usada como referência literal, não como inspiração solta: fundo forest sólido, ícone centralizado, rótulo tracked pequeno ("P A S S A P O R T E"), foto grande centralizada, título grande, subtítulo, e uma ação no rodapé. A tela nova ("Experiência Concluída") reaproveita a MESMA fórmula com o mesmo valor de cor de fundo (rgb(0.247,0.290,0.192), lido direto do nó, não reconstruído de memória) e os mesmos tamanhos de fonte por papel (rótulo 11.5px tracked, título 22-25px ExtraBold, subtítulo 14px SemiBold) — só trocando os elementos de conteúdo: rótulo "EXPERIÊNCIA CONCLUÍDA", ícone de coração (clonado do próprio selo "❤" já usado no cabeçalho de Detalhe da Experiência, escalado — reaproveitando um glifo já validado em vez de desenhar um novo), foto da experiência, nome da experiência como título, pergunta "Como foi essa experiência pra você?" como subtítulo, e um botão explícito "Avaliar agora" no lugar do "Toque para abrir" (aqui a ação pede clique claro, não gesto implícito) — mais um "×" de fechar no canto superior direito, ausente na Capa do Passaporte (que não precisa de saída, só de entrada).

A tela antiga (overlay clonado de Home) foi apagada, não deixada como órfã — a Home clonada, o scrim e o bottom-sheet inteiros, removidos num só .remove(). Fechar ("×") leva pra Home normal; "Avaliar agora" leva pra "Avaliar Experiência" — mesmos dois destinos do desenho original, só a embalagem mudou.

Amarrando ao fluxo de verdade: uma tela "que aparece ao abrir o app" não tem, num protótipo estático, um gatilho de "abertura de app" de verdade — precisa de um ponto real da árvore de navegação que representa esse momento. Investigado quem navega pra "Home" hoje: o candidato certo era "Entrar (novo padrão)" — a tela de login real, cujo sucesso já levava direto pra Home. Os 4 alvos de toque dessa tela (botão "Entrar", "Continuar com Google", e as áreas de clique correspondentes) foram redirecionados pra passar por "Experiência Concluída" primeiro, com o fechar dessa tela levando à Home como destino final — inserindo a tela realmente NO caminho de login→app, não como uma tela solta sem entrada, igual ao padrão real de "Passaporte · Capa" (que também tem entradas reais, de "Meu Roteiro" e "Minhas Viagens").

Zero colisões nas 121 telas (mesmo total do §9.3 — uma tela removida, uma tela nova, saldo zero).

Parte II — Decisões de Produto

Configurações e Perfil

A tela que faltava e as 9 sub-telas que ela precisava — do zero

10.1 O pedido: o que uma tela de Configurações precisa, e onde ela cabe

Fernando trouxe uma pergunta de duas partes: "o que precisa ter em uma tela de configurações de um app desse nível? onde devemos por? no perfil? mas lá já temos muitos ícones, como resolver isso?". Grounding no código real confirmou o tamanho da lacuna: não existe nenhuma tela de Configurações em lugar nenhum do produto — nem no Figma, nem no código (ProfileScreen.tsx) — e nem sequer um ícone de engrenagem à espera de conteúdo. Existe um signOut() pronto em AuthContext.tsx, sem nenhuma tela que o chame.

Mais revelador ainda: o cabeçalho real do Perfil (ProfileScreen.tsx) é bem mais simples que o do Figma — só 2 botões, "Editar perfil" e "Compartilhar perfil" (ou "Cancelar"/"Salvar" durante a edição). Os 7 ícones que o cabeçalho do Figma acumulou (Editar capa, trocar foto, Agenda, Seguindo, Minhas Viagens, Check-in, Meus Ingressos) são uma invenção só do Figma, sem equivalente no código — o que confirmava a suspeita de Fernando antes mesmo de eu propor qualquer solução.

10.2 Antes de somar um 8º ícone, auditar os 7 que já existiam

Pedido pra revisar os 7 antes de decidir onde a engrenagem entra (opção escolhida entre "engrenagem separada direto" e "revisar os 7 primeiro"). A auditoria achou dois já mortos — zero reações: "Check-in" e "Meus Ingressos". Dos outros 5: "Editar capa" e "trocar foto" são ações de EDIÇÃO (no código real só aparecem depois que a pessoa toca "Editar perfil", aqui sempre visíveis mesmo fora do modo de edição); só "Agenda", "Seguindo" e "Minhas Viagens" eram atalhos de navegação funcionando de verdade.

Correção importante, vinda de Fernando: a primeira proposta tratava os 2 ícones mortos do mesmo jeito — remover os dois. Fernando corrigiu: "pra onde o check-in iria? não entendi, porque temos aquela definição de como estou me sentindo e do que desejo participar né?" — critério certo. O ícone de Check-in é, por decisão já registrada no Cap. 7, o ponto de entrada real do check-in de sentimento/intenção — estar sem reação é BUG, não motivo pra remover. "Meus Ingressos", ao contrário, Fernando decidiu remover de propósito: "meus ingressos não precisa, a pessoa deve acessar os ingressos a partir da agenda" — os dois ícones mortos tinham o MESMO sintoma (zero reações) mas pediam tratamentos opostos, e só perguntar "pra onde iria" revelou a diferença.

10.3 Religar, remover, e não deixar órfão no processo

Antes de remover "Meus Ingressos" dos 4 cabeçalhos de Perfil, checagem de órfão: "Meus Ingressos" só era alcançável por 1 dos 4 cabeçalhos (os outros 3 já estavam mortos também) — e "Detalhe do Ingresso" só é alcançável a partir de "Meus Ingressos". Removê-lo sem construir o caminho novo pela Agenda deixaria as telas de ingresso genuinamente inalcançáveis, não só menos visíveis.

Construído o caminho novo: cada item da Agenda ganhou um ícone compacto de ingresso (24×24, moss, 🎫) abaixo do botão "+ Roteiro", levando direto pra "Detalhe do Ingresso" — só no item "Pedal ao Amanhecer na Via Costeira", que já tem um ingresso real construído pra essa experiência específica; os outros 2 itens da Agenda (Yoga, Kitesurf) não ganharam o ícone, porque não existe tela de ingresso pra eles — mesmo critério de identidade do §11.19, não fabricar um destino que não bate com o item de origem.

Aplicado nos 4 cabeçalhos de Perfil: "Btn Check-in" religado pra tela de humor (3495:70); "Btn Meus Ingressos" removido; os 4 ícones restantes (Check-in, Minhas Viagens, Seguindo, Agenda) realinhados pra preencher o vão. "Editar capa" e "trocar foto" também removidos da visualização normal — não descartados, movidos pro modo edição (§10.4).

Bug no caminho, quinta variação da família de auto-layout: o ícone de ingresso novo, ao ser inserido no item da Agenda, saltou pra uma posição errada (a mesma linha do botão "+ Roteiro", em vez de abaixo dele) — dessa vez o item da Agenda é auto-layout HORIZONTAL (as anteriores eram VERTICAL). Mesmo fix de sempre: layoutPositioning = "ABSOLUTE" resolveu, confirmando que a família de causas já é bem conhecida independente da direção do auto-layout.

10.4 As 4 telas de "Perfil em modo edição"

Perguntado se valia replicar a diferença visualização/edição do código real (câmeras escondidas até tocar "Editar perfil") ou deixar sempre visível — mais simples, sem telas novas. Fernando escolheu a réplica fiel, mesmo custando 4 telas novas (uma por variante de Perfil: v1-cards, v2-timeline, v2-grade, v2-vazio).

Construídas clonando cada tela-base e reaproveitando peças já existentes no arquivo em vez de desenhar do zero: o botão "Btn Editar capa" (ícone de câmera + texto "Editar") clonado inteiro da tela "Editar Perfil", que já tinha essa peça pronta; "Btn trocar foto" construído com a mesma geometria de ícone de câmera, envolvida num badge circular branco sobre o canto da foto de perfil. Os botões "Editar perfil"/"Compartilhar" viraram "Cancelar"/"Salvar" com os estilos TROCADOS entre si — no código real, Cancelar é contorno (estilo que "Compartilhar" já tinha) e Salvar é preenchido moss (estilo que "Editar perfil" já tinha) — não bastava trocar o texto, a troca de estilo entre as duas posições é que faz a tela ler como "modo edição" de verdade.

Wiring: "Editar perfil" (visualização) → tela de edição correspondente; "Cancelar" e "Salvar" (edição) → de volta pra visualização — sem diferenciar o que aconteceria com dados reais (não existe estado de verdade num protótipo estático), só a navegação de ida e volta.

10.5 A engrenagem, e a tela de Configurações de verdade

Com a fileira caída de 7 pra 4 ícones em modo visualização, sobrou espaço pra engrenagem — reaproveitado o mesmo ícone já usado em "Configurações da Comunidade" (uma tela diferente, sobre moderação de comunidade, não confundir as duas), posicionada com um vão visível dos 4 ícones de atalho, sinalizando que é uma ação de natureza diferente, não mais um atalho de navegação frequente.

Construída a tela "Configurações" reaproveitando o padrão visual exato de linha (label + chevron) e de toggle (label + descrição + interruptor) já usados em "Configurações da Comunidade" — 11 itens em 6 seções:

1
CONTA — Editar perfil, Email e telefone, Senha e segurança
2
PREFERÊNCIAS — Notificações push (toggle, com descrição do que inclui), Idioma
3
PRIVACIDADE — Privacidade de comunidades (linka conceitualmente com o gap de privacidade já registrado)
4
PAGAMENTO — Métodos de pagamento
5
SUPORTE — Central de ajuda, Termos de uso, Política de privacidade
6
Sair da conta / Excluir conta (vermelho, sem seção nomeada) — Sair da conta wired de verdade pra "Entrar (novo padrão)", coerente com o signOut() real já existente no código

Wiring real aplicado só onde já existe destino concreto no arquivo: engrenagem (4 telas de Perfil) → Configurações; "Voltar" → Perfil v1; "Editar perfil" → tela de edição do §10.4; "Sair da conta" → tela de login. Os outros 8 itens (Email e telefone, Senha e segurança, Idioma, Privacidade de comunidades, Métodos de pagamento, Central de ajuda, Termos de uso, Política de privacidade, Excluir conta) ficam como itens de lista sem tela própria ainda — categorias reais, sem sub-tela construída nesta rodada, registrado como próximo passo, não esquecimento.

Telas novas organizadas na mesma fileira das outras variantes de Perfil (não em espaço solto), seguindo a disciplina do §8.11. Zero colisões nas 128 telas (123 + 4 telas de edição + Configurações).

10.6 Cancelamento de ingresso: popup que faltava, "Meus Ingressos" que nunca precisou existir

Fernando revisou o resultado do capítulo com uma lista de correções: "a tela de cancelar ingresso está direcionando para a página errada, deve aparecer um popup para confirmação do cancelamento e marcando sim, deve ir para uma tela de confirmação que foi cancelado... não direciona para meus ingressos. Meus ingressos na verdade ele some. Tudo deve ser relacionado a minha agenda e de minha agenda deve direcionar para o detalhe do ingresso com o qrcode. Pode eliminar a tela de meus ingressos".

Grounding na tela real "Cancelar Participação" mostrou que o "popup de confirmação" pedido já existia — a tela já mostra o aviso ("Sua vaga será liberada...") com os dois botões "Manter participação"/"Cancelar participação". O que faltava de verdade era o DEPOIS: tocar em "Cancelar participação" levava direto pra "Meus Ingressos", sem nenhuma tela dizendo que o cancelamento tinha sido feito.

Antes de apagar "Meus Ingressos", checagem de quem apontava pra ela — 4 origens: o botão de voltar de "Detalhe do Ingresso" (e suas 2 variantes, balão/vinhos) e o botão "Cancelar participação". Todas as 4 religadas antes da exclusão: os 3 botões de voltar agora levam pra "Agenda" (não pra uma lista de ingressos separada — "tudo deve ser relacionado à Agenda", exatamente como pedido); "Cancelar participação" agora leva pra uma tela nova.

1
"Cancelamento Confirmado" — tela nova, tom neutro (não celebrativo — cancelar não é uma conquista), selo cinza com check, "Participação cancelada", nome da experiência, botão "Voltar à agenda".
2
"Cancelar Participação (bloqueado)" — segunda tela nova, pro caso "após os 7 dias não pode mais ser cancelado": mesmo card de contexto, selo de alerta terracota, "Não é mais possível cancelar", explicação, botão "Entendi". Não tem gatilho ao vivo (um protótipo estático não sabe comparar a data de hoje com a da experiência) — existe como estado documentado, mesmo padrão de outros estados condicionais do arquivo (ex.: "Perfil, vazio") que representam uma condição real sem precisar de um caminho de clique dedicado.

Com as 4 referências religadas e zero restantes, "Meus Ingressos" e "Meus Ingressos (vazio)" apagadas com segurança (confirmado por nova varredura antes de apagar, não só assumido). O ingresso com QR code continua com um caminho de entrada de verdade — o ícone de ingresso construído no §10.3, direto da Agenda pro "Detalhe do Ingresso" — só que agora é o ÚNICO caminho, não um atalho redundante ao lado de uma lista solta.

De brinde, corrigido no mesmo lote: a engrenagem de Configurações clonada no §10.5 tinha um problema estrutural que só ficou óbvio olhando de perto — Fernando: "a engrenagem parece um sol". Inspecionando os vetores: o ícone clonado era só 2 círculos concêntricos com contorno, SEM dentes de engrenagem nenhum — lia como alvo/sol, não como configuração. Trocado nos 4 cabeçalhos por um glifo de engrenagem de verdade (⚙), mais simples e sem ambiguidade que tentar herdar um vetor que já nascia incompleto na fonte original.

Zero colisões nas 128 telas (2 apagadas, 2 novas — saldo zero).

10.7 Uma pergunta honesta revelou uma tela real que estava esquecida

Fernando revisou o capítulo inteiro com 3 pontos numa mensagem só. O mais importante não era um ajuste — era uma pergunta: "qual é o ganho de fazer essas 4 telas? porque olhando, o botão de editar perfil já existe, e você criou um editar foto após o editar perfil? ficou meio sem sentido, ou tem uma explicação que não percebi?"

Investigando pra responder direito — não defendendo a decisão anterior de cabeça — a resposta honesta apareceu rápido: existe uma tela "Editar Perfil" de verdade no arquivo, com campos reais (Nome, Bio, Profissão, Cidade, Idiomas, seleção de carimbos de atividade, botão "Salvar alterações") — e ela tinha ZERO telas apontando pra ela, órfã desde antes de qualquer coisa nesta sessão. As 4 telas "· Edição" do §10.4 eram só casca (2 ícones de câmera + troca de rótulo de botão), sem nenhum campo editável de verdade — literalmente mais rasas que a tela real que já existia, esquecida do lado. A pergunta de Fernando estava certa: não tinha explicação que justificasse manter as 4 novas.

Corrigido: as 4 telas "· Edição" apagadas, e os 4 botões "Editar perfil" religados direto pra tela real — 3 pra "Editar Perfil" (a completa), e a variante "Perfil (v2, vazio)" pra "Editar Perfil (vazio)" (o par vazio correspondente, que também já existia). O botão "Salvar alterações" da tela real já estava wired corretamente (→ Perfil v2-timeline), não precisou de ajuste. Zero colisões nas 124 telas depois da correção (128 − 4).

Lição: "ficou meio sem sentido" foi o sinal certo — quando uma construção nova parece redundante ou fora de lugar, vale checar se já existe algo real fazendo aquele trabalho antes de assumir que a construção nova é que precisa de mais justificativa. Nesse caso, a construção nova não precisava de mais justificativa — precisava ser apagada.

10.8 Confirmação de cancelamento em duas camadas, e ingresso pra cada item da Agenda

Segundo ponto: "após clicar em cancelar, precisa vir algo perguntando 'tem certeza que deseja cancelar essa experiência?' algo do tipo pra não ser um cancelamento acidental". A tela "Cancelar Participação" (§10.6) já cumpria a primeira camada de confirmação (aviso + 2 botões) — mas isso não impedia um toque acidental direto no botão vermelho de confirmar. Construída uma SEGUNDA camada: um diálogo pequeno e centralizado ("Tem certeza que deseja cancelar?" + 2 botões, "Não, manter" neutro e "Sim, cancelar" em terracota) inserido entre "Cancelar Participação" e "Cancelamento Confirmado" — padrão de confirmação em 2 passos pra ação destrutiva, comum em apps reais, agora replicado aqui.

Terceiro ponto: "cada experiência precisa ter seu próprio ingresso e que seja redirecionado. Aproveite e ajuste os nomes nos ingressos para que reflita o que está em agenda." Até aqui só o item "Pedal ao Amanhecer" tinha ícone de ingresso (§10.3) — os outros 2 (Yoga, Kitesurf) foram deixados de fora por não terem tela de ingresso correspondente. As telas "Detalhe do Ingresso · balao" e "Detalhe do Ingresso · vinhos" já existiam no arquivo, mas com conteúdo que não batia com nada da Agenda — reaproveitadas em vez de descartadas: renomeadas pra "· yoga" e "· kitesurf", com título, data e local trocados pra bater exatamente com os itens reais da Agenda ("Yoga ao pôr do sol · 10 set 2026 · 17:30 · Praia do Meio, RN" e "Kitesurf em São Miguel do Gostoso · 02 out 2026 · 09:00 · Gostoso, RN").

Ícone de ingresso adicionado nos 2 itens restantes da Agenda, cada um levando pro ingresso certo — os 3 itens da Agenda agora têm ingresso próprio, cada um redirecionando pro destino que o nome promete. Os links "Cancelar participação" dentro dos ingressos de Yoga/Kitesurf já estavam sem reação (conferido antes de mexer) — não seria correto ligá-los à mesma tela "Cancelar Participação" hardcoded pro Pedal (mismatch de identidade, mesmo critério do §11.19), então ficaram como estão, registrado como gap conhecido, não esquecimento.

Zero colisões nas 125 telas (124 + diálogo de confirmação).

10.9 A engrenagem-emoji e o sorriso que parecia triste

Fernando, olhando os 5 ícones do cabeçalho do Perfil lado a lado: "os icones de engrenagem e carinha ficaram horríveis, o de carinha, parece triste e o de engrenagem é uma imagem". O glifo ⚙ do §10.6 (trocado ali pra resolver o problema anterior — "parece um sol") tinha um problema diferente e mais fundamental: inspecionando o nó, ele não era um vetor — era um CARACTERE DE TEXTO Unicode (⚙, fonte Nunito). A maioria das fontes não tem um glifo desenhado pra esse caractere, então o sistema troca silenciosamente por uma fonte de emoji colorida — daí "é uma imagem": literalmente estava renderizando como uma foto de engrenagem 3D, não como um ícone.

O sorriso do Check-in tinha uma causa diferente: a boca era 2 segmentos de reta retos ("M 0 0 L 5 4 L 10 0", strokeJoin: MITER) formando um "V" pontudo, não uma curva. Sem suavização, o vértice anguloso no meio lê como uma careta/bico, não como um sorriso — apesar da matemática do path apontar pra cima nas pontas.

1
Engrenagem reconstruída como vetor de verdade (1ª tentativa): círculo central + 8 dentes (retângulos posicionados por coordenada polar, 45° entre si) unidos via boolean union, com um furo central via boolean subtract — um único vetor fechado, preenchido, cor cinza-escuro (a mesma dos outros ícones do cabeçalho: Agenda, Seguindo, Minhas Viagens). Testado isoladamente com screenshot antes de propagar pros 4 cabeçalhos. Botão redimensionado de 32×32 pra 34×34 com cornerRadius:17, igual aos outros 4 ícones da fileira (antes ele destoava também no tamanho).
2
Boca do Check-in redesenhada como curva suave: substituído o "V" de 2 retas por uma curva bezier única (setVectorNetworkAsync com tangentes simétricas), mesmo strokeCap: ROUND, mesma cor musgo. Testado isoladamente com screenshot antes de aplicar aos 4 cabeçalhos — resultado lê como sorriso sem ambiguidade.

Aplicado aos 4 cabeçalhos de Perfil (v1-cards, v2-timeline, v2-grade, v2-vazio) de uma vez, cada correção testada isoladamente primeiro. Zero colisões nas 125 telas (nenhuma tela criada ou apagada, só edição de vetor).

Lição: um caractere Unicode/emoji usado como "ícone rápido" é um risco silencioso — ele depende de qual fonte de fallback o visualizador escolhe pra esse glifo específico, e pode virar uma imagem colorida fora do controle do design system a qualquer momento. Ícones devem ser vetores de verdade, sempre — a mesma lição do §10.6 (o círculo-sem-dentes clonado), agora reforçada de um ângulo diferente (o glifo de texto), confirma que vale a pena desenhar o vetor certo desde a primeira vez, em vez de atalhos que parecem rápidos.

Mas a engrenagem feita à mão (1ª tentativa) também não convenceu. Fernando, olhando de perto: "olhe o icone de engrenagem, escolha uma engrenagem que faça sentido". Com razão — os 8 "dentes" (retângulos rotacionados por coordenada polar) ficaram com aparência de losango, desalinhados do corpo circular, lendo mais como uma flor irregular do que como uma engrenagem mecânica de verdade.

2ª tentativa, abandonando geometria feita à mão: em vez de desenhar dentes com boolean ops, importado o path SVG exato do ícone "settings" clássico do Material Design — a mesma forma usada em milhões de apps, com dentes trapezoidais uniformes e proporções testadas. O parser de vetor do Figma só aceita comandos absolutos (M/L/C/Z maiúsculos) — o path original do Material usa comandos relativos minúsculos (c/l/h/s/z) e o comando de repetição implícita do M. Escrito um conversor SVG→absoluto próprio no script (parser de tokens + acumulador de ponto atual/ponto de controle, com reflexão pra "S"), convertendo os 60+ comandos do path original sem perder nenhuma curva. Testado isolado com screenshot — resultado é a engrenagem clássica e inconfundível — só então propagado pros 4 cabeçalhos, substituindo a versão de dentes-losango.

Zero colisões nas 125 telas (mesma contagem — só troca de vetor, nenhuma tela nova).

Lição: geometria "óbvia" feita à mão (círculo + N formas repetidas em roda) parece simples de calcular mas erra fácil em proporção/alinhamento quando comparada a um ícone real testado por milhões de usos. Pra formas icônicas e reconhecíveis (engrenagem, coração, estrela), importar o path SVG de um ícone consagrado (Material/Ionicons/Feather) é mais confiável do que reconstruir a geometria do zero — mesmo que isso exija escrever um pequeno conversor de comandos relativos pra absolutos.

A tela "Configurações" (Cap.10) tinha 9 dos seus 11 itens sem destino — links prontos, sem tela do outro lado. Este capítulo fecha esse gap: nove telas novas (Email e telefone, Senha e segurança, Idioma, Privacidade de comunidades, Métodos de pagamento, Central de ajuda, Termos de uso, Política de privacidade, e o fluxo de 3 telas de Excluir conta), grounded no que o código real já suporta e no que ainda é gap dos dois lados.

10.10 Nove links sem destino, um gap escondido, e o que a grounding revelou

Fernando: "agora vamos construir cada tela após a tela de configurações". A tela "Configurações" (Cap.10) tinha 11 itens — só "Editar perfil" e "Sair da conta" levavam a algum lugar; os outros 9 ficavam sem sub-tela, registrados como gap consciente no §10.5. Antes de desenhar qualquer uma, grounding no código real (`apps/mobile/...`) pra saber o que já existe de verdade e o que é conceito novo:

Telefone — parcialmente real: AuthContext.updateProfile() aceita phone.
Idioma — real, mas menor do que o Figma poderia supor: LanguageContext.tsx implementa só PT/EN (sem persistência em storage ainda), não uma lista longa de países.
Os outros 7 — gap completo dos dois lados (Figma e código): e-mail (não existe updateUser({email})), senha (nenhum fluxo de troca), privacidade de comunidade (tabela community só tem role, sem coluna de privacidade), pagamento (zero Stripe, zero tabela), central de ajuda, termos de uso e política de privacidade (só rótulos estáticos não-clicáveis em OnboardingScreen.tsx, sem texto real por trás), excluir conta (nenhum RPC de auto-exclusão).

Com o terreno mapeado, 9 telas construídas — cada uma no padrão visual já estabelecido (linha 343×56 com cornerRadius:14 e chevron "›" pra links; linha 343×72 com pill-toggle pra preferências; campo com label maiúsculo+caixa 54px pra formulários, todos clonados/reaproveitados de Configurações e Editar Perfil, não reinventados):

1
Email e telefone — 2 campos (E-mail, Telefone) com legenda explicando o uso de cada um, botão "Salvar alterações".
2
Senha e segurança — 3 campos de senha (atual/nova/confirmar) + toggle "Autenticação em duas etapas", botão "Salvar nova senha".
3
Idioma — lista de seleção única com só 2 opções (Português marcado, English), fiel ao que o código realmente suporta hoje — não uma lista de 20 países que o app não tem.
4
Privacidade de comunidades — 2 toggles (comunidades privadas por padrão, mostrar comunidades no perfil) + 1 seletor (quem pode me convidar).
5
Métodos de pagamento — estado vazio ("Nenhum método salvo" + ícone de cartão + botão "+ Adicionar cartão"), seguindo a filosofia de estado vazio já estabelecida no Cap.4 em vez de inventar cartões falsos salvos.
6
Central de ajuda — 5 perguntas frequentes + botão "Falar com o suporte".
7
Termos de uso e 8. Política de privacidade — texto corrido em 6 seções cada, claramente placeholder (não é o texto legal real da empresa, que não existe em lugar nenhum do repositório) mas estruturalmente correto pro tipo de documento.
9
Excluir conta — não 1 tela, e sim o MESMO padrão de confirmação em 2 camadas do §10.8 (cancelamento de participação), reaproveitado por analogia: tela de aviso ("Isso é permanente" + o que se perde + 2 botões) → diálogo "Tem certeza?" clonado do §10.8 e retextado → tela de confirmação neutra "Conta excluída" (clonada de "Cancelamento Confirmado", mesmo selo cinza não-celebrativo) → botão final leva pra "Entrar (novo padrão)", a mesma tela de destino de "Sair da conta" (faz sentido: sem conta, sem sessão).

Gap real encontrado no caminho, não no código dessa vez — no próprio Figma: conferindo as reactions antes de ligar as novas, o link "Editar perfil" dentro de Configurações tinha reactions: [] — nunca foi ligado, apesar da documentação do §10.5 registrar "Editar perfil→tela de edição" como already-wired. Corrigido junto com o resto: agora leva de verdade pra "Editar Perfil" (3171:70).

Bug pequeno no caminho: o título clonado do diálogo "Tem certeza?" ("Tem certeza que deseja excluir sua conta?") é mais longo que o original ("Tem certeza que deseja cancelar?") e vazou pra fora do card — texto sem textAutoResize travado tentando caber numa única linha larga demais. Corrigido travando a largura (263px, igual ao card) e deixando quebrar em 2 linhas, empurrando o resto do diálogo pra baixo proporcionalmente.

Todas as 9 telas ligadas a partir de Configurações; botões de voltar e "Salvar" de cada uma levam de volta pra Configurações (padrão simples de formulário — sem tela de confirmação extra pra ações não-destrutivas, reservando a confirmação em camadas só pra Excluir conta). Itens sem destino real ficam sem reação, registrados como gap consciente (não esquecimento): "+ Adicionar cartão", as 5 perguntas de "Central de ajuda", "Falar com o suporte", "Quem pode me convidar" — todos esperando a contraparte real de backend antes de ganhar uma tela própria.

Zero colisões nas 136 telas (125 + 11 novas: 9 telas de Configurações + o diálogo "Tem certeza?" da Excluir conta contado à parte + "Conta Excluída").

Lição: reaproveitar um padrão já validado (a confirmação em 2 camadas do §10.8) por ANALOGIA — não porque a tela é literalmente igual, mas porque a FORMA do problema é igual (ação destrutiva e irreversível, risco de toque acidental) — é mais rápido e mais consistente do que desenhar do zero. E: documentar "religado" na Biblioteca não é garantia de que a reaction foi realmente escrita no Figma — vale conferir o estado real (node.reactions) antes de assumir, mesmo quando a própria documentação anterior diz que já está feito.

10.11 "Estilo Instagram tem histórico de atividades?" — 3 conceitos diferentes escondidos numa pergunta só

Fernando perguntou se Configurações precisa de um "histórico de atividades, estilo Instagram". A pergunta parece simples, mas o Instagram na verdade tem 3 features bem diferentes que uma pessoa pode estar lembrando com esse nome — perguntado de volta qual delas, Fernando pediu pra ver as 3 antes de decidir. Construídos 3 protótipos de comparação, lado a lado, nenhum ligado ao fluxo principal ainda (mesmo padrão de exemplar-não-comprometido do §8.14 — servem pra decidir, não pra usar):

A
Sua Atividade (interações) — log do que VOCÊ fez no app: avaliações dadas, comentários, curtidas em fotos, comunidades que entrou. Equivalente ao "Sua atividade" do Instagram.
B
Atividade de Login (segurança) — lista de dispositivos/sessões conectados à conta, com botão "Encerrar todas as outras sessões". Equivalente ao "Atividade de login" do Instagram — feature de segurança, não de conteúdo.
C
Histórico de Experiências — lista cronológica de experiências vividas (Kitesurf, Yoga, Pedal, Trilha, Show), datas em ordem decrescente.

Um alerta que vale registrar antes da decisão: o conceito C tem sobreposição real com o que já existe — o Passaporte (pós-viagem, plano+memória, ver project_passaporte_roteiros.md) e a Agenda (confirmadas) já cobrem "quais experiências eu vivi/vou viver". Construído mesmo assim, pra comparação ficar completa e honesta — mas se a escolha for o conceito C, vale revisitar se ele deveria ser uma tela própria ou só um link mais visível pro Passaporte que já existe, em vez de uma 3ª lista fazendo o mesmo trabalho.

Zero colisões nas 139 telas (136 + 3 conceitos). Decisão pendente — nenhum dos 3 ligado a Configurações ainda.

Decisão de Fernando: "as 3 opções são relevantes, linkeas com as configurações, abra novos campos se for necessário" — os 3 ficam, todos ligados de verdade. Criada uma seção nova "ATIVIDADE" em Configurações (entre CONTA e PREFERÊNCIAS — ambas "Sua atividade" e "Atividade de login" são sobre a conta, e "Histórico de experiências" acompanha bem ao lado), com as 3 linhas novas. Como a tela usa posicionamento manual (não auto-layout), inserir no meio significou empurrar CADA elemento abaixo do ponto de inserção 244px pra baixo (não só os textos de rótulo — os campos, toggles e botões também, senão a nova seção ficaria sobreposta com PREFERÊNCIAS). Tela cresceu de 1204px pra 1448px. Os 3 links religados pros protótipos do §10.11, e os 3 protótipos ganharam o botão de voltar religado de volta pra Configurações — deixaram de ser exemplares soltos e viraram telas de verdade do fluxo. Zero colisões nas 139 (mesma contagem — só telas existentes ganhando conexão, nenhuma criada).

O alerta sobre o conceito C (sobreposição com Passaporte/Agenda) continua registrado como está — Fernando optou por manter as 3 mesmo sabendo da sobreposição potencial, decisão explícita, não descuido.

10.12 Um vão de 1820px no meio da fileira do Perfil, e 3 telas perdidas fora de qualquer bloco

Fernando: "preciso que você reorganize novamente as telas, pois foram criadas novas telas e estão fora de ordem". Mapeando o canvas inteiro por posição, dois problemas reais apareceram — nenhum deles visível a olho nu num zoom normal, só varrendo coordenadas.

1
O conjunto de Configurações (14 telas: a tela principal + 9 sub-telas + 3 conceitos de histórico) tinha sido colado bem à direita do resto da fileira do Perfil, deixando um vão vazio de ~1820px entre "Perfil de Terceiro · João Pedro" e "Configurações" — sobrou desse jeito porque a construção original (§10.5) só checou "onde tem espaço livre", não "onde a fileira realmente termina". Corrigido deslocando as 14 telas 1820px pra esquerda, fechando o vão, sem tocar em nenhuma reaction (id não muda com posição).
2
As 3 telas do fluxo de cancelamento em 2 camadas ("Tem certeza?", "Cancelamento Confirmado", "Cancelar Participação (bloqueado)") estavam literalmente fora de qualquer fileira — flutuando isoladas centenas de pixels abaixo do canvas inteiro, desconectadas de qualquer bloco por área de produto. Movidas pra dentro da fileira de Agenda/Atividades, logo depois de "Agenda (seleção)".

Zero colisões nas 139 telas depois do ajuste (mesma contagem — só reposicionamento, nenhuma tela criada ou apagada).

Parte III — Padrão Visual e Auditoria

Padrão Visual: Fundo, Ícones e Navegação

Sand como fundo, ícones que sumiam, categorias copiadas — consertos de consistência visual, tela a tela

Depois de aprovar o fundo #F6F2EB (sand) nas telas de autenticação recém-refeitas, Fernando decidiu que não era só um teste local: "acho que podemos adotar como padrão o sand mesmo e fazer os pequenos ajustes necessários nas telas que precisarem". A pergunta virou: quantas telas realmente precisavam de ajuste?

11.1 A varredura: menos telas erradas do que parecia

Em vez de reconstruir tela por tela, a correção foi uma varredura programática: para cada um dos 117 frames de topo, checar o próprio fill — se fosse branco sólido, trocar por sand; se já fosse sand, não mexer; se fosse outra coisa, registrar pra checar manualmente. O resultado surpreendeu: 80 das 117 telas já usavam #F6F2EB como fundo, mesmo antes desta sessão — a maioria do arquivo, construída com o grounding correto desde o início. Só 26 telas realmente tinham fundo branco por engano, entre elas Home, a aba Activities (+ variantes), Checkout (+ cupom), Agenda, Explorar Destinos, Buscar Destino, Selecionar Datas, Montar/Meu Itinerário, Criar Comunidade, Editar Perfil (+vazio), Criar/Editar Atividade, Configurações da Comunidade, Moderadores, Resultados da Busca, Mensagens (+vazio), Notificações, Categorias e "menssage".

11.2 As 10 exceções — de propósito, não por engano

10 telas ficaram fora da troca, e cada uma tem uma razão real pra isso, não um esquecimento: splash (verde moss, momento de marca), Câmera e Pré-visualização da foto (interface escura de câmera), Confirmação (verde forest escuro, tela de sucesso celebrativa), e as telas dominadas por foto — Detalhe da Memória, Passaporte · Capa, Compartilhar Memória, Compartilhar Passaporte (Capa), Compartilhar Dia, Compartilhar Roteiro. Nenhuma delas foi tocada.

11.3 O ajuste que a troca de fundo expôs: campos cinza ficaram "apagados"

Trocar só o fundo da página não foi suficiente. Muitas telas (principalmente formulários — Criar/Editar Atividade, Checkout, Criar Comunidade, Editar Perfil, Agenda, telas de conversa) usavam campos com um cinza clarinho antigo (#F0F0F0-ish) — perto o bastante do tom do sand pra quase desaparecer, o mesmo problema de contraste que Fernando já tinha sinalizado antes ("talvez fique muito apagado") quando o fundo branco dos campos de "Entrar" foi testado sem preenchimento. A correção replicou o mesmo padrão já aprovado nas telas de autenticação: campo branco sólido, borda sutil (neutral a 20%), radius:12. 90 campos, em 30 telas, corrigidos numa só varredura recursiva — de "Criar Atividade" (10 campos) e "Editar Atividade" (10) a coisas pequenas como o campo de mensagem das 5 telas de Conversa (1 cada).

11.4 Por que a varredura funcionou sem quebrar nada

Duas decisões tornaram essa correção em massa segura: (1) a checagem de cor usava tolerância apertada (diferença menor que 0.015 no canal RGB) — só pegava o cinza antigo específico, não qualquer coisa remotamente clara; (2) o Card.tsx real já resolve esse problema por design — borderWidth:1, borderColor: neutral+'22' funciona independente do que está atrás do card, então o padrão branco-com-borda não precisou ser reinventado por tela, só replicado. Verificação por screenshot em 3 telas de perfis diferentes (formulário longo, checkout com resumo de preço, lista de agenda) confirmou legibilidade em todos os casos. Zero colisões nas 117 telas — a varredura só mudou cor de preenchimento, nunca posição.

Bem no início desta sessão, ao decidir onde colocar o ícone de entrada do check-in de sentimento, a tela "Activities" (e suas 2 variantes de estado, "Minha Lista ativada"/"vazia") já tinha sido identificada como um draft antigo — em inglês, com componentes genéricos, visualmente destoante do resto do arquivo. Na época, a decisão foi só não piorar — colocar o ícone em outro lugar (Perfil) em vez de forçar consistência numa tela que já estava fora do padrão. Agora, com o padrão sand+Nunito+chips reais consolidado em quase todo o resto do arquivo (Cap. 7 e 11), a tela "Activities" ficou visualmente isolada — e Fernando pediu o ajuste final.

11.5 Grounding: a tela real já resolvia tudo isso

A leitura de apps/mobile/screens/activities/ActivitiesScreen.tsx (código real, nunca lido a fundo antes desta correção) revelou a especificação exata que faltava no Figma: chips de filtro em formato pill (radius.pill, borda #E0E0E0, ativo = colors.moss sólido com texto branco), barra de busca também pill (#F5F5F5, radius.pill, altura 48), e o botão "Participar" dos cards em destaque usando colors.moss — nunca vermelho. O Figma antigo usava chips retangulares com cornerRadius: 0, busca numa caixa reta cinza, e um botão "Participar" vermelho (colors.red) que lia como alerta/perigo, não como ação principal de produto.

11.6 O que foi corrigido, nas 3 variantes ao mesmo tempo

1
Logo — o "everhere" do cabeçalho era um grupo de vetores desenhados letra por letra (o mesmo problema já encontrado em "Entrar", §7.3), substituído pelo texto Nunito ExtraBold 22px que o resto do arquivo usa.
2
Chips de filtro — "Indoor / Outdoor / Categoria / Saúde e bem-estar / Mulheres e meninas" reconstruídos como pill, com "Outdoor" ativo em moss (batendo com activeFilterIdx=1 do código real, não "Indoor" que estava marcado como ativo no Figma antigo).
3
Busca — caixa reta cinza virou pill #F5F5F5, placeholder traduzido pra "Buscar atividades...".
4
Botão Participar — vermelho → moss, nos 2 cards em destaque de cada uma das 3 variantes (6 botões no total).
5
Textos em inglês restantes — títulos dos cards em destaque ("Cycling from Ponta Negra to Tabatinga" → "Pedal de Ponta Negra a Tabatinga", "Yoga on the Cotovelo Cliffs" → "Yoga nas Falésias do Cotovelo"), CTA de criar atividade, títulos de seção ("Running"→"Corrida", "Cycling"→"Ciclismo", "Trail"→"Trilha", "Brazil: Top 10 activities today"→"Brasil: Top 10 atividades hoje", "Health and well-being"→"Saúde e bem-estar") e o rótulo "My List"→"Minha Lista".
6
Fundo — branco → sand, seguindo o padrão do Capítulo 11.

11.7 O que ficou de fora, de propósito

A grade de cards por categoria (Corrida/Ciclismo/Trilha/Saúde e bem-estar) continua no layout antigo — cartões de 88×120 com blocos de cor sólida no lugar de foto em vários deles. O código real especifica um componente SmallCard próprio (138×200, sempre com foto, gradiente escuro por baixo do texto) e um Top10Card com número gigante sobreposto — nenhum dos dois foi reconstruído pixel a pixel nesta rodada. A correção priorizou o que fazia a tela "gritar" um padrão diferente à primeira vista (cor, forma dos chips, idioma) sobre a paridade exata de dimensão dos cards — fica registrado como próximo passo, não como esquecimento.

O aviso de Fernando era pontual: "o ícone de turismo da navbar está desconfigurado quando clica" — com um screenshot mostrando um quadrado branco no lugar do ícone de Turismo, na tela "Explorar Destinos". A investigação, porém, não parou aí: pediu-se também "reveja a navbar em todas as telas, deve ficar claro quando marcado a aba que está clicado e os demais mais escuros" — e essa segunda parte da instrução foi o que revelou que o problema real era muito maior que um ícone quebrado numa tela só.

11.8 Grounding: o real BottomNav.tsx é simples — dois estados, ponto final

packages/ui/src/components/BottomNav.tsx (lido pela primeira vez nesta correção) especifica exatamente o comportamento que Fernando descreveu: cada aba tem só dois estados possíveis — ativa (#FFFFFF, ícone e texto 100% brancos) ou inativa (rgba(255,255,255,0.5), 50% de opacidade sobre o fundo moss). Sem caixa branca, sem pill de destaque — só a diferença de brilho entre o ícone/texto ativo e os demais. O código também revela um detalhe de produto que o Figma nunca tinha registrado: as abas Tourism e Guide & Community estão marcadas disabled: true — cliques nelas não fazem nada, porque essas seções ainda não têm rota implementada no app real.

11.9 A causa do ícone "desconfigurado"

O ícone de localização (Turismo) fica dentro de um Frame container de 20×20. Em "Explorar Destinos" — e só ali — esse Frame tinha ganhado um preenchimento branco sólido próprio, por cima do qual os dois vetores do ícone (também brancos) ficavam completamente invisíveis. O resultado: um quadrado branco liso onde deveria estar um pino de localização. Nas outras 11 navbars, o mesmo Frame está corretamente com o preenchimento oculto (visible:false) — só essa instância tinha o bug.

11.10 A auditoria revelou três bugs sistêmicos, não um

Comparar as 12 navbars lado a lado (uma checagem que nunca tinha sido feita neste arquivo) expôs que o ícone quebrado do Turismo era o sintoma mais visível de um problema bem mais espalhado — os ícones "simples" (vetores desenhados à mão, não instâncias de componente real) tinham perdido o preenchimento em algum momento da história do arquivo, provavelmente num copiar-e-colar entre telas:

1
Ícone de Perfil invisível nas 12 navbars, sem exceção — inclusive nas 4 telas onde Perfil é a aba ativa (as variantes de Perfil próprio). O rótulo de texto "Profile" ficava branco corretamente, mas o ícone de pessoa nunca aparecia — fills: [], vazio, em toda instância do arquivo.
2
Ícone de Comunidade invisível em 10 das 12 — só as 2 telas de Comunidade (onde a aba está ativa) tinham sido corrigidas manualmente em algum momento; as outras 10 herdavam o mesmo fills vazio.
3
Isotipo de Atividades nunca escurecia — o desenho principal do ícone usava um preenchimento de gradiente branco-para-branco fixo, que não respondia ao estado ativo/inativo; só um detalhe secundário (um pontinho) mudava de cor. Resultado: em qualquer tela que não fosse "Activities", o ícone de Atividades aparecia com o mesmo brilho de quando estava ativo — o oposto do "os demais mais escuros" que Fernando pediu.

11.11 A correção: normalizar em vez de remendar

Em vez de corrigir só o bug relatado, a correção percorreu as 12 navbars e resetou todo vetor de ícone (Home, Turismo, Comunidade, Perfil, e o isotipo de Atividades) pra um de dois estados possíveis — branco sólido se aquela aba é a ativa daquela tela, cinza sólido (#C3C3C3) se não é — e forçou o container do ícone de Turismo a ficar sempre com preenchimento oculto, nas 12 instâncias, não só na que tinha o bug visível. Verificado por screenshot em "Explorar Destinos" (Turismo agora aparece como um pino branco limpo, sem quadrado) e "Perfil (v2 — grade)" (o ícone de pessoa, invisível havia sabe-se lá quanto tempo, agora aparece branco e nítido). Zero colisões nas 117 telas — só preenchimento de cor foi alterado, nenhuma posição.

Uma decisão que não foi tomada, de propósito: como o código real marca Turismo e Comunidade como disabled, tecnicamente nenhuma tela do app deveria conseguir mostrar essas abas como "ativas" hoje. O Figma continua mostrando Turismo ativo em "Explorar Destinos" e Comunidade ativa nas telas de Comunidade — uma escolha deliberada de manter a leitura de contexto no protótipo (fica claro em que área da navegação você está navegando), mesmo sabendo que isso é mais avançado do que o app real permite agora. Fica registrado como gap consciente, não como inconsistência: quando essas abas forem implementadas de verdade, esse comportamento já é o esperado.

11.12 Categorias — não era reskin, era lixo de cópia acumulado

A tela "Categorias" (o modal de filtro por categoria da busca de atividades) não precisava de reskin — precisava de demolição. Inspecionando a árvore de nós, ficou claro que ela era uma cópia inteira da tela "Activities" (cards em destaque, fileiras de categoria, chips de filtro, busca, ícones de header) com uma camada escura por cima e a lista inteira de categorias despejada como um único bloco de texto multi-linha sobreposto a tudo — exatamente o que o screenshot mostrava: fotos vazando por trás, "My List" aparecendo duas vezes, texto cortando texto. Reconstruída do zero seguindo o modal real de ActivitiesScreen.tsx: título "Categoria" centralizado, 17 categorias reais (a lista de ALL_CATEGORIES do código, incluindo as 6 que só existiam em inglês no código-fonte — traduzidas aqui pra manter a leitura em português: "Women-only"→"Somente mulheres", "Adults 50+"→"Adultos 50+", "Families & kids"→"Famílias e crianças", "Neurodiverse-friendly"→"Amigável a neurodivergentes", "Autism-friendly"→"Amigável ao autismo", "Reduced mobility friendly"→"Acessível a mobilidade reduzida"), cada linha com divisor fino, e selo "Minha Lista" nas 4 categorias que o código marca como MY_LIST_CATEGORIES.

Correção de cor, na rodada seguinte: a primeira versão usava o rgba(18,18,18,0.93) do código literalmente — um preto quase neutro, sólido. Fernando notou: "essa cor preta foge um pouco do padrão". A observação técnica: o código real aplica essa cor como overlay translúcido por cima da tela de Activities (as fotos e o sand de fundo continuam visíveis por trás, a ~7% de transparência) — no Figma, um frame estático não tem "tela de trás" pra vazar, então a cor virou um preto chapado genérico, sem identidade. Corrigido com duas mudanças: (1) o preto neutro virou colors.forest (#3F4A31, o mesmo verde escuro já usado em "Confirmação") — mantém o modal escuro e imersivo, mas reconhecivelmente da paleta da marca; (2) uma foto real já usada no arquivo (a mesma dos ciclistas, reaproveitada da capa de Perfil) foi posta atrás do scrim com blur de camada (LAYER_BLUR, raio 18), recriando o "vazamento" de textura e cor que o overlay translúcido tem no app de verdade. O resultado lê como parte da mesma família visual de "menssage" (foto desfocada + scrim + texto branco), não mais como uma tela emprestada de outro app.

11.13 Notificações — a estrutura já era boa, só a casca estava velha

Diferente de Categorias, "Notificações" não precisou de demolição — a estrutura (seção "SUA REDE" com atividade social real, depois grupos "Em breve/Hoje/Ontem/Últimos 7 dias") já era coerente e até mais rica que o NotificationsScreen.tsx real (que não tem uma seção de rede social separada). A correção foi tradução e casca: título "Notification"→"Notificações", os 5 chips de filtro reconstruídos no radius.sm real (não pill — essa tela usa cantos de 12px, diferente do padrão pill de Activities/Home, e o ativo é colors.red, não moss, porque é assim que o código real especifica pra essa tela especificamente) e traduzidos ("Your activities"→"Suas atividades", "Your connections"→"Suas conexões", "Your groups"→"Seus grupos", "Nearby"→"Perto de você"), e todo o texto em inglês restante das notificações ("Layla scheduled...", "1st Race of Happy Divas is in 3 days", "That's all for now") traduzido, fundo branco→sand.

Nota de método: nem toda tela "no padrão antigo" pede o mesmo tratamento — Categorias exigiu reconstrução total (o conteúdo estava genuinamente corrompido), Notificações só precisou de tradução e reestilo (o conteúdo já estava certo). A lição de sempre: inspecionar a árvore de nós antes de decidir reconstruir ou reaproveitar, não assumir pelo screenshot sozinho.

11.14 Margem de 8px, escondida atrás do reskin

Uma rodada de revisão depois, Fernando notou que "Activities e todas as suas variantes e a tela de notificações ainda permanecem desalinhadas das demais telas... até mesmo as margens estão incorretas." Certo: as correções dos §11.5–11.7 e §11.12–11.13 tinham trocado cor, fonte e idioma, mas nunca checaram a margem lateral em si — e tanto Activities (3 variantes) quanto Notificações usavam 8-9px de margem, contra os 16px (spacing[4]) que ActivitiesScreen.tsx e NotificationsScreen.tsx especificam e que o resto do arquivo já usa consistentemente.

1
Chips, busca, CTA, títulos de seção, fileiras de cards — deslocados de 8px pra 16px nas 3 variantes de Activities. A barra de busca também teve a largura recalculada (358→343) pra respeitar a margem direita, não só a esquerda.
2
Os 2 cards em destaque — o maior problema real: com 180px de largura cada e só 4px de vão entre eles, não cabiam dentro de uma margem de 16px nos dois lados (o código real usa uma grade de 2 colunas fixas, não rolagem horizontal). Precisaram ser redimensionados pra 165.5px cada — o que exigiu desconectar as instâncias de componente primeiro (detachInstance(); a API do Figma não deixa mover/redimensionar filhos presos numa instância) e escalar cada elemento interno proporcionalmente. Efeito colateral: os textos dos botões "Participar"/"+ Minha Lista" passaram a quebrar em 2 linhas dentro da caixa mais estreita — corrigido com fonte de auto-largura numa linha só (9.5px).
3
Notificações — cards de tamanhos diferentes entre si, não só errados — a auditoria achou miniaturas de 32×34 na seção "SUA REDE" e de 24×33 nas notificações agrupadas — dois tamanhos incorretos e incoerentes entre si, nenhum batendo com os 44×44 (radius.sm) do código real. Unificados: todas as 8 linhas de notificação (6 agrupadas + 2 de rede) agora usam a mesma miniatura 44×44, o mesmo espaçamento de texto (56px do início da linha) e o mesmo par de tamanhos de fonte (14px pro título, 13px itálico pro link "Ver detalhes"/"Ver vivência").

Zero colisões nas 117 telas depois da correção. Lição registrada: reskin de cor/fonte/idioma pode deixar um problema de layout inteiro escondido por baixo — vale sempre conferir a margem lateral contra o spacing[4] real como um passo separado, não assumir que "parece certo" visualmente sem medir.

11.15 Notificações: a linha ainda cortava o conteúdo

A correção do §11.14 tinha redimensionado as miniaturas das notificações pra 44×44, mas esqueceu de redimensionar o container da linha — que continuava com 34px de altura e clipsContent: true, cortando um terço da miniatura (por isso o formato "arredondado só em cima" no print de Fernando) e a segunda linha de texto de vários itens. Corrigido com uma medição real: cada linha teve sua altura recalculada a partir da altura de fato do texto (node.height depois do textAutoResize, não um valor chutado), e todo o fluxo vertical abaixo — os quatro rótulos de grupo ("Em breve", "Hoje", "Ontem", "Últimos 7 dias") e a linha do checkbox — recalculado em sequência a partir dessas alturas reais. Na primeira tentativa os rótulos de grupo ficaram fora de posição (sobrepondo a linha seguinte); a causa não foi um bug de auto-layout (o frame confirmadamente não é auto-layout) — foi erro aritmético na primeira passada, corrigido reposicionando cada rótulo manualmente no vão real entre as linhas medidas, com verificação de leitura imediata depois de cada escrita.

11.16 "Parece duplicata" nem sempre é duplicata

Fernando notou que várias telas "não têm funcionalidade diferente além de repetir a informação" e pediu uma varredura: as 6 variantes nomeadas de "Detalhe da Experiência" (trilha-caracol, feira-inverno, pedal-noturno, chocolataria, mirante-vale, roda-música) e as 5 telas "Conversa · [Nome]". A investigação — não pelo visual, pelas reactions reais de cada uma — encontrou justificativa concreta pras duas famílias:

1
Detalhe da Experiência (6 variantes) — cada uma é o destino real de um resultado diferente em "Resultados da Busca". Apagar qualquer uma quebraria um card de resultado específico, deixando-o sem pra onde ir. Estruturalmente idênticas (mesmas 4 abas, mesmo layout) — mas cada uma existe porque a busca precisa de resultados de verdade pra demonstrar, não porque foram esquecidas duplicadas.
2
Conversa · [Nome] (5 telas) — ainda mais fortemente amarradas: cada uma é referenciada de 4 lugares diferentes (a lista "Mensagens", a tela "Nova Conversa", o botão "Falar"/"Btn Mensagem" no respectivo "Perfil de Terceiro", e o botão de mensagem em telas de Detalhe da Experiência). Cada pessoa precisa da própria conversa porque o conteúdo da conversa é sobre uma atividade específica que aquela pessoa fez — o princípio de "Contexto, Não Diretório" do Cap. 3 aplicado à mensageria: a conversa não é genérica, é ancorada numa experiência real compartilhada.

Nenhuma das 11 telas foi apagada. A lição, registrada pra próximas rodadas: antes de julgar uma tela redundante pelo visual parecido, checar se ela é destino de alguma reaction real — "parece igual" e "está em uso" são perguntas diferentes.

11.17 A navbar inteira ainda estava em inglês

Fernando perguntou por que a aba de comunidade se chamava "Guide & Community" — "poderia ser apenas Comunidade?" A investigação revelou um problema maior que o nome de uma aba só: as 5 etiquetas da navbar nunca tinham sido traduzidas — "Home", "Tourism", "Activities", "Guide & Community", "Profile" continuavam em inglês em todas as 12 instâncias, destoando do resto do arquivo, que é 100% português. O código real já resolve isso: NAV_LABELS.pt em BottomNav.tsx define { home:'Início', tourism:'Turismo', activities:'Atividades', community:'Comunidade', profile:'Perfil' } — as 5 etiquetas foram trocadas pra bater exatamente com essas, nas 12 navbars.

11.18 O ícone de Comunidade era fiel ao código — e mesmo assim confuso

Fernando também notou que os ícones "ainda estão dando trabalho" e suspeitou de um bug — "está marcado comunidade, mas em profile parece que também está marcado". Uma auditoria fresca das 12 navbars (cor de cada ícone, tab por tab) não encontrou esse bug: em todas as 12, exatamente uma aba está branca (ativa) e as outras quatro cinza — incluindo Perfil, corretamente cinza nas telas de Comunidade. A leitura de "duas abas acesas" no print provavelmente foi ilusão de ótica: um ícone cinza-claro contra o fundo escuro do canvas do Figma (fora da tela, no card do print) pode parecer mais aceso do que é.

O ícone em si, porém, era um problema real — só que não de bug, e sim de escolha de design herdada do código: o losango/quadrado rotacionado usado pra Comunidade é a tradução literal do ícone layers/layers-outline do Ionicons, que BottomNav.tsx usa de propósito pra essa aba. Fiel ao código, mas nada nele sugere "pessoas" ou "grupo" — Fernando confirmou a suspeita e pediu a troca. Substituído por um ícone simples de duas pessoas (dois círculos sobrepostos representando cabeças, duas formas arredondadas representando ombros), no mesmo estilo de preenchimento sólido branco/cinza das outras 4 abas — nas 12 instâncias.

Gap registrado pro código real: essa troca deixou o Figma um passo à frente do BottomNav.tsx, que ainda usa layers-outline/layers. Recomendação pra quando o código for atualizado: usar people-outline/people do Ionicons, que já existe na biblioteca e comunica "comunidade" de forma muito mais direta que "camadas".

11.19 A justificativa certa não é "está conectado" — é "quebra se eu juntar"

Fernando devolveu a explicação do §11.16 com uma pergunta melhor: "elas informam a mesma coisa... não poderia ter uma conexão apenas com uma das telas de mensagem ou uma das telas de detalhes?" Justo — "está conectado de 4 lugares" é um fato técnico, não uma justificativa de produto por si só. O teste certo é outro: se eu consolidar num frame só e redirecionar todas as origens pra ele, alguma coisa visível quebra?

Sim, quebra — testado com um exemplo concreto. Na tela "Seguindo", o item "Sugestão · Camila Rocha" aponta pro perfil da Camila especificamente; "Seguidor · Rafael Nunes" aponta pro do Rafael. Cada linha de origem nomeia uma pessoa específica no próprio texto/label — é uma promessa de identidade. Consolidar os 4 "Perfil de Terceiro" num só faria "Sugestão · Camila Rocha" abrir o perfil de outra pessoa: um erro visível no primeiro teste do protótipo, não uma economia de manutenção sem custo. O mesmo raciocínio, testado e confirmado, vale pras 5 telas de Conversa (tocar no nome da Larissa não pode abrir a conversa do Carlos) e pras 6 de Detalhe da Experiência (um resultado de busca não pode abrir o título de outra atividade).

Achado à parte, verificando "Perfil de Terceiro" mais de perto: a linha do tempo é idêntica, copiada literalmente, nas 4 telas ("Show na Praça", "Trilha da Cachoeira do Pinga"...) mesmo com bio e estatísticas diferentes por pessoa. Isso é um problema real de qualidade de conteúdo — cada pessoa devia ter atividades coerentes com a própria bio — mas é diferente do problema de "tela duplicada"; a estrutura continua justificada, o conteúdo é que precisa de ajuste.

11.20 Os ícones, terceira tentativa: sólido preenchido não escala bem entre formas diferentes

As duas primeiras correções da navbar (Cap. 11, §11.18) trocaram cor mas mantiveram o preenchimento sólido — e Fernando continuou vendo problema: o pino de Turismo "fica todo escuro quando não marcado", o ícone de Perfil "mesmo não estando marcado parece marcado". Auditoria de valores confirmou que a cor cinza era idêntica, pixel a pixel, nos dois — rgb(195,195,195) — então não era bug de cor. Era geometria: silhuetas preenchidas de formas muito diferentes (um pino fino e alongado, uma cabeça redonda robusta) carregam quantidades de área bem diferentes na mesma caixa de 20×20 — a mesma cor exata "lê" mais escura numa forma fina e mais clara numa forma arredondada, um efeito óptico, não um valor errado.

Com dois erros já cometidos, a correção dessa vez não foi um terceiro palpite — foi uma pergunta direta com 3 caminhos. Fernando escolheu contorno (stroke) no lugar de preenchimento sólido, com uma restrição clara: o isotipo de Atividades não muda (é a marca da everhere) e Home já estava bom — só Turismo, Comunidade e Perfil precisavam de reconstrução. Com contorno de 2px uniforme, o peso visual passa a depender da espessura da linha, não da área da forma — resolve o problema pela raiz, não só empurra ele.

1
Turismo — o pino de localização virou um alvo (anel de contorno + ponto sólido no centro), um glifo de "local" mais simples e à prova de erro de geometria do que tentar redesenhar um pino em contorno.
2
Comunidade — reconstruído pela segunda vez: dois círculos de contorno sobrepostos (cabeças) + duas formas de "ombro" (retângulo com topo arredondado, contorno, sem base) por baixo. Diferente da primeira tentativa (dois círculos preenchidos que se fundiram num blob sem forma clara), o contorno mantém os dois anéis visíveis separadamente mesmo sobrepostos — lê como "duas pessoas" de verdade.
3
Perfil — mesma técnica de cabeça (círculo de contorno) + ombro (retângulo topo-arredondado, contorno), só que numa escala maior, ocupando a caixa de ícone inteira.

Zero colisões nas 117 telas depois da reconstrução. Verificado por screenshot em duas telas com abas ativas diferentes (Comunidades e Explorar Destinos) pra confirmar que o contraste ativo/inativo ficou consistente nos três ícones reconstruídos.

Parte III — Padrão Visual e Auditoria

Fotos Reais e Calibração de Cor

De conteúdo placeholder a fotos reais em todo o arquivo, e a calibração de cor que foi longe demais e voltou

O trabalho de trocar conteúdo placeholder por fotos reais e calibrar a cor de fundo do arquivo aconteceu inteiro dentro do que era, na época, o Capítulo 22 — misturado com o trabalho de navbar e ícones do capítulo anterior. Como os dois assuntos não têm relação um com o outro, viraram capítulos separados nesta reorganização. Este aqui reúne toda a saga de popular fotos reais (da linha do tempo de Perfil de Terceiro até a grade do Passaporte) e toda a calibração de cor do fundo quase-branco do arquivo — incluindo a vez em que a decisão foi revertida.

12.1 Linha do tempo: de conteúdo copiado a fotos reais do próprio arquivo

Com a duplicação de estrutura justificada (§11.19), sobrava o problema de conteúdo real: as 4 linhas do tempo eram idênticas, e a maioria dos itens usava blocos de cor sólida no lugar de foto — só 2 dos 6 itens por pessoa tinham imagem de verdade. Fernando pediu pra resolver os dois problemas juntos, e sugeriu a fonte: "em Choose activities temos muito boas opções" — 15 fotos reais de categoria (corrida, ciclismo, trilha, ioga, escalada, caiaque, surf, meditação, crossfit, skate, natação, passeios turísticos) já embutidas no arquivo, nunca reaproveitadas fora daquela tela.

Achado técnico no caminho: a primeira tentativa de ler as fotos de "Choose activities" retornou vazio — o preenchimento de imagem não estava no índice 0 do array fills de cada círculo, e sim no índice 1 (havia um preenchimento sólido cinza embaixo, de placeholder, com a foto real por cima). Corrigido filtrando por fills.find(f => f.type === "IMAGE") em vez de assumir a posição.

Com o banco de fotos em mãos, cada uma das 4 pessoas ganhou 6 atividades novas, coerentes com a própria bio — reaproveitando as fotos por tema, não inventando descrição nova pra imagem nenhuma:

1
Larissa Prado (instrutora de yoga) — Yoga na Praia do Meio, Meditação nas Dunas, Natação na Ponta Negra, Retiro de fim de ano na praia, Primeira aula de SUP, Respiração ao pôr do sol. Fotos: Ioga, Meditação, Natação, Passeios Turísticos, Surf.
2
Rafael Nunes (ciclista amador) — Pedal noturno na Via Costeira, Mountain bike no Pium, Pedal matinal até a Redinha, Tarde de skate na orla, Pedal em grupo até Genipabu, Desafio de MTB na Serra. Fotos: Ciclismo (×3), Trail (×2), Skate.
3
Camila Rocha (trilheira) — Trilha da Cachoeira do Pinga, Escalada no Vale Encantado, Caiaque na Lagoa de Pitangui, Trilha do Pôr do Sol em Pipa, Bugue em Genipabu, Primeira escalada em Martins. Fotos: Trail (×2), Escalada em rochas (×2), Caiaquismo, Passeios Turísticos.
4
João Pedro (explorador de fim de semana) — Pedal em grupo, gente nova, Trilha surpresa com a galera, Caiaque no Rio Potengi, Treino funcional ao ar livre, Primeira aula de surf em Pipa, Corrida beneficente em Natal. Tema deliberadamente mais variado que os outros 3 (bate com a bio: "sempre em busca da próxima trilha ou pedal") — usa 6 categorias de foto diferentes, nenhuma repetida.

Ajuste de meio de caminho: vários títulos novos, mais longos que os originais ("Meditação ao amanhecer no Parque das Dunas", "Pedal em grupo pra conhecer gente nova"), quebraram em 2 linhas dentro da caixa de texto dimensionada pra 1 — sobrepondo o texto de localização/contagem de fotos logo abaixo. Encurtados pra caber numa linha só (limite prático observado: ~29 caracteres nessa largura de caixa), em 8 dos 24 itens.

12.2 Ícone de Comunidade desalinhado, e o resto do arquivo cheio de blocos de cor

Um ajuste fino primeiro: o ícone de Comunidade reconstruído em §11.20 tinha ficado alto demais dentro da caixa — comparado aos outros 4 ícones (que começam por volta de y=9-10 dentro da barra), o de Comunidade começava em y=1, um deslocamento de 8px que o deixava visualmente "flutuando" longe do próprio rótulo. Corrigido deslocando as 4 formas (2 círculos + 2 ombros) pra baixo em 8px, nas 12 navbars.

Fernando então pediu pra ir além dos 4 perfis já corrigidos (§12.1): usar o mesmo banco de fotos de "Choose activities" pra popular qualquer tela do arquivo que ainda mostrasse bloco de cor sólida no lugar de foto de experiência. Uma varredura por nome de nó ("Miniatura", "Degradê", "thumb", "Capa", "Foto") em todas as 117 telas — filtrando falsos positivos como botões "Editar capa" e frames cujo próprio nome continha essas palavras por coincidência — encontrou mais de 70 slots de foto ainda em cor chapada, o maior grupo de longe sendo os 51 cards da grade de categorias (Corrida/Ciclismo/Trilha/Saúde e bem-estar) repetidos nas 3 variantes de Activities — nenhum deles, na real, tinha foto verdadeira, mesmo os que pareciam ter em screenshots antigos (eram variações de cor sólida, não fotos).

1
Grade de categorias (51 cards, 3 telas Activities) — populada por tema: Corrida/Trail alternados na fileira Running, Ciclismo predominante na fileira Cycling, Trail/Escalada/Caiaquismo na fileira Trail, e as 4 categorias reais de bem-estar (Ioga/Meditação/Natação/Crossfit) na fileira Saúde e bem-estar — a única seção que já tinha correspondência 1-pra-1 exata com o banco de fotos.
2
Home — "Amigos vivendo isso agora" e "Memórias da sua rede" (8 cards, incluindo a variante vazia) — cada card recebeu uma foto coerente com a legenda já escrita: Corrida na orla→Corrida, Trilha da Pedra Furada→Trail, Kitesurf em Gostoso→Surf. Dois títulos sem correspondência boa no banco (Roda de capoeira, Feira orgânica) receberam a opção mais próxima disponível (Crossfit, Passeios Turísticos) — uma aproximação assumida, não uma coincidência temática perfeita.
3
Perfil (álbuns e miniaturas), Detalhe da Memória, Buscar Destino, Editar Comunidade — mais 15 slots menores, mesma técnica.

Reaproveitado o mesmo achado técnico do §12.1 (a foto real fica no índice 1 do array fills de cada círculo de categoria, não no 0) pra reconstruir o banco de fotos ao vivo dentro de cada script, em vez de copiar hashes manualmente — elimina risco de erro de transcrição numa lista de 12 hashes longos. Zero colisões nas 117 telas depois de mais de 75 preenchimentos de imagem no total (51 da grade + 6 da Home + 6 da variante vazia + 15 diversos).

12.3 A varredura por nome de nó tinha um ponto cego: largura

Fernando apontou mais um card cinza sem foto — mas dessa vez sem saber dizer o nome exato da tela, só um screenshot recortado. Em vez de adivinhar, ele mandou um print mais largo mostrando a fileira inteira do Passaporte (14 dias) e Comunidades — vários cards visivelmente sem foto ali. A instrução ficou clara: "ainda falta popular muitos telas, todas as telas que referenciam experiências devem ser populadas".

A varredura do §12.2 (por nome de nó — "Miniatura", "Degradê", "thumb", "Capa", "Foto") tinha um ponto cego real: os cards do Passaporte e Comunidades usam só "Frame" como nome, sem nenhuma palavra-chave de foto. Corrigido com uma varredura diferente, por forma em vez de nome — qualquer FRAME/RECTANGLE/ELLIPSE de 80–400px de largura, preenchimento 100% sólido, sem filho de texto (o que já separa foto de botão, já que todo botão tem rótulo) — rodada nas 117 telas de uma vez. Achado: 20 entradas reais — 17 no Passaporte (espalhadas por 12 dos 14 dias — os Dias 6 e 11 não têm nenhuma atividade registrada, dias de descanso genuínos na viagem, não bug), 2 em Comunidades (Trilheiros do RN, Ciclismo Urbano Natal) e 2 em "Legenda e Fotos" (fluxo de câmera, fotos-exemplo do que a pessoa acabou de tirar).

A varredura por forma também trouxe ruído — "overlay" dentro de "Mapa" (13 ocorrências, um efeito de esmaecimento por trás do botão "Ver no mapa", não foto), "Scrim"/"Scrim inferior" (gradiente escuro sobre foto real já existente, nas telas de Compartilhar), "Campo legenda" (fundo de campo de texto), "Card atividade"/o bg de bio de Editar Comunidade (cards de conteúdo textual). Todos descartados manualmente antes de aplicar qualquer correção — a lição do Cap. 11 ("inspecionar a árvore antes de decidir") vale também pra varreduras automáticas: elas acham candidatos, não substituem checar cada um.

Ajuste de qualidade no meio do caminho: como o tema "Passeios Turísticos" é o único que serve bem pra atrações genéricas de Gramado (Mini Mundo, Snowland, Museu de Cera, Fórum da Cultura...), ele acabou repetido 11 vezes no total — inclusive duas vezes na mesma tela, em 3 dias diferentes (Dia 1, Dia 5, Dia 13), o que ficaria visualmente óbvio como cópia colada rolando a tela. Corrigido trocando a segunda ocorrência em cada um desses 3 dias por um tema diferente (Meditação, Natação, Skate) — repetir o mesmo tema entre telas diferentes passa despercebido; repetir na mesma tela, lado a lado, não.

12.4 Um "achado" do §12.3 estava errado: o scrim não tinha foto nenhuma por baixo

Fernando mandou dois prints novos numa mensagem só. O primeiro era uma pergunta de localização: o card de avaliação (depoimento de Camila Rocha/João Pedro, selo "+ DESTAQUE") tinha recebido o teste de branco-esverdeado do Cap. anterior? Resposta, confirmada relendo o nó: não — o teste (#F3F6F2) foi aplicado só na "Barra inferior" (rodapé de preço/CTA) da tela-base "Detalhe da Experiência", nenhum outro lugar. O card de depoimento é um elemento diferente, ainda branco puro, que não tinha sido tocado.

O segundo print mostrava "Passaporte · Índice" (a grade de miniaturas dos 14 dias) e as 3 telas "Compartilhar" (Passaporte/Dia/Roteiro), todas com blocos de cor sólida em vez de foto — "precisa popular também". Investigando o Índice: 4 dos 14 cards já tinham foto real (Dias 1, 2, 7, 10), os outros 10 estavam sólidos — e 3 deles (Dias 4, 6, 11) nem tinham a camada de gradiente que os outros 11 têm, estrutura genuinamente incompleta, não só sem foto.

Populados os 10 cards com o banco de 12 fotos categorizadas já usado nos capítulos anteriores, reconstruindo a camada de gradiente (Frame + Vector com GRADIENT_LINEAR preto, 35%→78% de opacidade) do zero nos 3 que não tinham. Na conferência por screenshot, dois problemas de repetição apareceram na mesma grade visível: a foto "Corrida" do banco é, na prática, a mesma imagem (grupo de pessoas na praia) já usada nos Dias 2 e 10 — atribuí-la ao Dia 14 sem perceber, criando um terceiro card idêntico na mesma tela. E os Dias 1 e 7 (ambos pré-existentes, não tocados nesta rodada) usavam a mesma foto de ciclismo, agora visíveis lado a lado na mesma rolagem. Os dois corrigidos trocando por temas não usados (Trail no Dia 14, Passeios Turísticos no Dia 7).

Nos 3 "Compartilhar", a investigação revelou que a classificação do §12.3 estava errada: o "Scrim inferior" tinha sido descartado ali como "gradiente sobre foto real já existente" — na verdade, inspecionando a árvore completa, o nó "Card" por baixo do scrim é um RECTANGLE de cor sólida chapada (a cor de marca — sálvia, terracota conforme a tela), sem nenhum preenchimento de imagem. E o "Scrim inferior" também não era um gradiente: era um RECTANGLE preto 100% opaco, cobrindo a metade de baixo inteira. As 3 telas nunca tiveram foto nenhuma — o julgamento anterior assumiu o padrão do Índice sem checar caso a caso.

1
Compartilhar Passaporte (Capa) — foto Passeios Turísticos no "Card"; scrim trocado de preto opaco pra gradiente (transparente no topo → 92% opaco na base), preservando a legibilidade de "Gramado, RS" e a citação por cima.
2
Compartilhar Dia — foto Trail, escolhida por bater com a citação já escrita nessa tela ("A trilha rendeu a melhor vista da viagem").
3
Compartilhar Roteiro — foto Escalada em rochas, evitando repetir o tema já usado na Capa.

Lição de método: a varredura por forma do §12.3 encontrou o nó certo ("Scrim inferior"), mas a suposição de por que ele existia (gradiente decorativo sobre foto real) não foi verificada node a node — foi generalizada do padrão mais comum no arquivo. Card cinza + scrim escuro por cima parece, à primeira vista, sempre a mesma receita; só a inspeção da árvore revelou que aqui faltava a metade de baixo da receita (a foto). Vale reforçar: mesmo um achado já documentado como "ruído descartado" merece re-checagem quando aparece de novo num contexto diferente (aqui, um print literal mostrando ausência de foto, não apenas a suspeita de Fernando). Zero colisões nas 117 telas depois de 13 preenchimentos de imagem (10 do Índice + 3 do Compartilhar) e 2 trocas de tema pra evitar repetição visível na mesma tela.

12.5 O teste de branco-esverdeado tinha ficado sutil demais

Depois de confirmar onde o teste do §12.4 estava aplicado, Fernando avaliou o resultado: "pode dar um pouco mais de cor, levemente, ainda parece muito branco". Correto — o valor original, #F3F6F2 (r:0.953, g:0.965, b:0.949), é uma diferença de ~5% em relação ao branco puro, quase imperceptível ao lado de fotos e texto saturado. Aprofundado pra #E7F0E2 (r:0.906, g:0.941, b:0.886), ainda dentro da família "sálvia apagado" pedida originalmente (não é colors.moss saturado, que quebraria a hierarquia sand-fundo/branco-conteúdo do Cap. 11) mas agora com presença visual clara no rodapé de preço contra o botão terracota.

Ainda só aplicado na mesma "Barra inferior" de teste (tela-base "Detalhe da Experiência") — a decisão de espalhar pras outras 12 telas "Preço" segue pendente de aprovação, agora com o tom recalibrado.

12.6 Duas telas genuinamente quebradas: sem foto, texto escondido atrás do card do organizador

No mesmo print do §12.4, Fernando apontou mais um problema nas duas variantes "Passeio de Balão" e "Degustação de Vinhos": sem foto no topo e texto sumindo atrás do card "Organizado por Carlos Mendes". Comparando com as 4 outras variantes nomeadas (trilha-caracol, feira-inverno, pedal-noturno, chocolataria — todas com 896px de altura, aba "Detalhes/Para quem é/Vivências/Avaliações" e foto real no Hero), as duas telas problemáticas eram cópias incompletas: 690px de altura (206px a menos), Hero em cor sólida chapada em vez de foto, e sem a fileira de abas inteira. Isso empurrava a descrição, o card do organizador e a barra de preço pra cima do esperado, sem espaço suficiente — o texto de descrição (100px de caixa) terminava em y:572 enquanto o card do organizador começava em y:548, uma sobreposição de 24px onde o card (opaco) cobria as últimas linhas do parágrafo.

Corrigido reconstruindo as duas telas no padrão das 4 irmãs saudáveis: Hero recebeu o mesmo imageHash reaproveitado em todas as 11 variantes da família "Detalhe da Experiência" (a foto de ciclistas — confirmado que nenhuma variante desse grupo, nem as "corretas", tenta bater tematicamente com o nome da experiência; é um placeholder único reaproveitado em todo o grupo, precedente já estabelecido, não uma nova aproximação). A fileira de abas foi clonada da tela "trilha-caracol" (node.clone(), evitando reconstruir 4 tabs + indicador do zero) e inserida na posição correta. Frame redimensionado pra 896px de altura, com descrição/organizador/barra de preço reposicionados pra y:530/650/818 — os mesmos valores exatos das 4 telas de referência.

12.7 "Um pouquinho menos verde" — e depois, todo branco do arquivo

Depois de ver o resultado do §12.5 aplicado à "Barra inferior", Fernando aprovou a direção mas pediu duas coisas na mesma mensagem: recalibrar o tom ("gostei da cor verde, talvez um poquinho menos verde") e, então, espalhar pra todo elemento branco do arquivo inteiro — "inclusive nas telas de cadastro, login, detalhes, em tudo, a não ser que seja algo que realmente você acredite melhor não" — com a decisão final de aplicar deixada a critério de quem está construindo ("aplique que confiro depois").

Tom recalibrado primeiro: de #E7F0E2 (r:0.906, g:0.941, b:0.886) pra #EDF4E9 (r:0.930, g:0.955, b:0.915) — um passo de volta em direção ao branco, mantendo presença visual sem virar um verde mais carregado.

Pra "tudo que está branco", a varredura precisava ser ampla mas com critério — não bastava trocar qualquer {r:1,g:1,b:1} encontrado. Definidos os limites: só nós FRAME/RECTANGLE/ELLIPSE/COMPONENT/INSTANCE (nunca TEXT — preserva cor de texto branco sobre foto/fundo escuro — nem VECTOR — preserva o glifo de ícones, que precisa de contraste garantido contra o próprio botão), com preenchimento sólido opaco (opacidade ≥ 0.5, pra pegar também botões "vidro fosco" como o coração de "Seguir" sobre o Hero, que usa 85% de opacidade) e cor quase branca pura (cada canal ≥ 0.97 — limite escolhido pra não confundir com cores já deliberadamente claras mas distintas, como o cinza-esverdeado do placeholder de mapa).

A varredura de teste (só relatório, sem aplicar) achou 613 candidatos em 99 telas — e revelou uma exceção real antes de qualquer coisa ser tocada: as linhas de 86×2px dentro de cada "Tab" das telas de Detalhe da Experiência. Só a aba ativa tem essa linha na cor moss; as 3 abas inativas usam a MESMA linha branca como espaçador invisível — pintar isso de verde criaria um traço visível embaixo de abas que deveriam parecer "apagadas", mudando o significado visual do estado ativo/inativo. Essa é exatamente a exceção que Fernando abriu margem pra eu decidir sozinho. Junto com pontinhos de status minúsculos (6×6px, ex.: indicador "ao vivo" da Home), ambos excluídos por regra de tamanho (linhas finas ≤3px na menor dimensão, pontos ≤8×8px inteiros) — não por nome, pra generalizar sem precisar listar cada caso manualmente.

1
563 preenchimentos aplicados em 99 telas — cards de conteúdo, campos de formulário (login/cadastro/checkout inclusos), botões "vidro fosco" sobre foto, chips não-selecionados (Activities, Notificações, seletor de nível em Criar/Editar Atividade), avatares vazios, barras de preço, cards de álbum/ingresso/comunidade, e os cards de depoimento (Camila Rocha/João Pedro) que motivaram a pergunta original do §12.4.
2
50 exclusões corretas — 41 linhas de indicador de aba inativa, 9 pontos de status minúsculos.

Conferido por screenshot em 6 telas de família diferente (cadastro, Activities, Checkout, Perfil, Notificações, Avaliações) — leitura consistente em todas, sem perda de contraste em botão nem em texto. Zero colisões nas 117 telas depois da varredura.

12.8 Voltar atrás: o tom mais sutil era o mais bonito

Vendo o #EDF4E9 espalhado pelas 99 telas, Fernando reconsiderou: "retiro o que falei, prefiro o tom que estava antes, quase branco, fica mais bonito" — voltando à mesma leitura do §12.4, antes de qualquer aprofundamento: o valor mais sutil, mais perto do branco puro, é o que funciona melhor espalhado pelo arquivo inteiro, mesmo não tendo bastado como teste isolado numa única barra de preço contra o botão terracota. Revertidos os 564 preenchimentos (563 do rollout do §12.7 + a "Barra inferior" original de teste) de volta pro valor exato do primeiro teste, #F3F6F2 (r:0.953, g:0.965, b:0.949) — nenhuma tentativa intermediária nova, simplesmente desfazendo as duas escaladas de saturação em uma só operação, filtrando por cor atual em vez de re-rodar a detecção de branco (que não pegaria mais os nós já tingidos).

Lição registrada: a mesma cor pode ler diferente isolada (um card só, ao lado de uma foto e um botão saturado, onde "mais presença" parece necessário) versus espalhada (99 telas inteiras, onde o acúmulo de um tom mais carregado passa a competir visualmente com o resto da interface). Testar uma decisão de cor num elemento isolado não substitui ver o resultado em escala — #EDF4E9 parecia certo na "Barra inferior" sozinha, mas "carregado demais" quando multiplicado por quase 600 elementos. Zero colisões nas 117 telas depois da reversão.

12.9 "Resultados da Busca" também tinha cards sem foto

Fernando apontou mais uma tela com o mesmo problema de base: "em Resultados da Busca também tem opções sem imagens de experiências". Dos 8 cards de resultado (grade 2 colunas, 163×190 cada), 4 já tinham foto real — Trilha da Cachoeira do Caracol, Feira de inverno de Gramado, Mirante do Vale Encantado, Roda de música gaúcha. Os outros 4 — Passeio de balão no vale, Degustação de vinhos, Pedal noturno pelas ruas de Gramado, Chocolataria e fondue em grupo — ainda estavam em cor sólida. Não por coincidência: são exatamente os 4 nomes que também precisaram de reconstrução como telas de destino nos §12.6/anteriores — o problema de conteúdo se repetia tanto no card de entrada (aqui) quanto na tela de destino.

Populados com o banco de fotos categorizadas já em uso no arquivo, escolhidas pra não repetir a foto do vizinho na mesma linha da grade (Passeios Turísticos ao lado da Trilha-com-ciclistas, Escalada em rochas ao lado da Feira-com-grupo-de-mulheres, Ciclismo/Trail ao lado um do outro na linha do Pedal noturno/Chocolataria) — mesma disciplina de diversificação já usada no Índice do Passaporte (§12.4). Os 4 cards que já tinham foto (2 usando a mesma foto de ciclistas, 2 usando a mesma foto de grupo-de-mulheres, repetidas entre si 2 linhas de distância) não foram tocados — fora do escopo do que foi reportado, registrado aqui como possível ajuste futuro de qualidade, não como bug urgente.

Zero colisões nas 117 telas depois de 4 preenchimentos de imagem.

12.10 "Perfil 2" tinha os mesmos 6 momentos que o Perfil 1 — só sem as fotos

Fernando mandou um print de "Perfil (v2 — grade)" — a grade de 6 blocos de cor sólida (Show na Praça, Trilha da Cachoeira do Pinga, Pedal noturno na Via Costeira, Réveillon na Praia de Pipa, Primeira vez no kitesurf, Trilha do Pôr do Sol) embaixo da capa e bio, já populadas, da Marina Alves — "faltou popular o perfil 2 com as mesmas informações do perfil 1". O arquivo tem 3 variantes do próprio perfil (não de terceiros): "Perfil (v1 — cards)", "Perfil (v2 — timeline)" e "Perfil (v2 — grade)" — todas com o mesmo texto (bio, stats, nome), mas destinos de foto tratados de forma independente em cada uma.

Comparando: "Perfil (v1 — cards)" já tinha as 4 "Capa do álbum" com imageHash real. "Perfil (v2 — grade)" tinha as MESMAS 4 experiências, mais 2 novas ("Show na Praça", "Trilha do Pôr do Sol") — mas todas as 6 ainda em cor sólida chapada, sem foto nenhuma. Em vez de sortear fotos novas do banco pras 4 que já existiam em v1, a correção reaproveitou o imageHash EXATO de cada uma (mesma experiência, mesma foto, em duas variantes de layout diferentes do mesmo perfil) — o sentido literal do pedido "as mesmas informações do perfil 1". Só as 2 experiências sem correspondência em v1 (Show na Praça, Trilha do Pôr do Sol) receberam fotos novas do banco, escolhidas pra não repetir o vizinho de grade na mesma linha.

Mesmo achado de scrim opaco dos §§12.4/22.15: as 6 tiles tinham um "scrim" preto 100% opaco cobrindo o terço de baixo (64 de 180px) — corrigido junto pra gradiente translúcido, senão a foto nova ficaria escondida atrás do preto sólido.

Checagem de tela-irmã antes de fechar: "Perfil (v2 — timeline)" usa as mesmas 6 experiências em formato de lista — investigando se tinha o mesmo problema, a varredura inicial (que só considera nós ≥60px como candidato a foto) reportou falso-positivo de "sem foto" nas 6, por ter pulado a "Miniatura" real (52×52, menor que o limite) e capturado por engano outro preenchimento sólido mais abaixo na árvore. Checagem direta do imageHash de cada "Miniatura" confirmou: as 6 já tinham foto real — nenhuma correção necessária ali. Zero colisões nas 117 telas depois de 6 preenchimentos de imagem + 6 scrims corrigidos.

Parte III — Padrão Visual e Auditoria

Auditoria, Gaps e Lições Técnicas

Metodologia de auditoria, lacunas de schema e as lições técnicas que valeram a pena errar primeiro

Duas rodadas completas de auditoria de grafo de navegação foram feitas sobre o arquivo inteiro, em momentos diferentes da construção. O método é sempre o mesmo: percorrer todas as telas, extrair toda reaction de todo nó, montar um mapa de grau de entrada e saída por tela, e então separar sinal de ruído.

13.1 Separar sinal de ruído

A parte mais importante do método não é encontrar telas sem link — é não confundir duas coisas que parecem iguais no grafo bruto: uma reaction de navegação real, entre duas telas de fato, e uma reaction de troca de variante dentro de um componente (por exemplo, um card de atividade que expande e recolhe ao tocar, usando CHANGE_TO para um estado chamado "Estado=Expandido"). As duas aparecem como "aresta" no grafo. Só a primeira é navegação de verdade. Na auditoria mais recente, 84 arestas "quebradas" (apontando para algo que não é uma tela de 375px) foram investigadas uma a uma e todas as 84 eram trocas de variante legítimas, concentradas em só três componentes — nenhuma era um link quebrado de verdade.

13.2 Achados reais, por rodada

Primeira rodada (raio-x inicial): a splash não tinha nenhum elemento clicável (corrigida com avanço automático via AFTER_TIMEOUT + Smart Animate, uma sensação de movimento sem precisar de tap); a Câmera não levava a lugar nenhum (resolvida no Capítulo 7); a tela "menssage" (o manifesto de marca "Sinta a vida acontecer") carregava indevidamente uma barra de navegação de abas completa, como se fosse uma tela-raiz — removida, porque é uma tela de passagem do onboarding, não uma aba principal.

Segunda rodada (varredura minuciosa final): a tela "Senha atualizada" tinha um botão "Ir para login" desenhado e nunca ligado — corrigido, apontando para Entrar. Confirmados como órfãos intencionais (não bugs): a splash (não precisa de entrada por natureza), a Perfil v1 — cards (design alternativo guardado de propósito), as doze telas "(vazio)" (referência deliberadamente fora do fluxo principal), e a variante de erro "nome de usuário indisponível" — que está totalmente funcional por dentro (botões de voltar e continuar religados corretamente), só não tem nenhum link apontando para ela, porque um protótipo estático não tem como ramificar condicionalmente "se o nome já existir, mostra isto".

13.3 Stopgaps de conteúdo resolvidos pela auditoria

Duas lacunas de conteúdo — não de navegação — também vieram à tona durante as auditorias e foram corrigidas:

Resolvido
Seis resultados de busca com conteúdo errado
Uma busca por "Gramado, RS" mostrava 8 cards de experiência, mas 6 deles levavam para o Detalhe de uma atividade de Natal (Pedal ao Amanhecer) — coerente na navegação, incoerente no conteúdo. Corrigido clonando o Detalhe da Experiência 6 vezes com texto, avaliação, preço e organizador próprios de cada resultado (trilha da Cachoeira do Caracol, feira de inverno, pedal noturno, chocolataria, mirante, roda de música). A foto de capa continua reaproveitada — falta asset novo por resultado, sinalizado como limitação, não como bug.
Resolvido
Dois de três ingressos sem tela de ingresso própria
Em "Meus Ingressos", só a primeira linha (Pedal) abria a tela real de ingresso com QR code — as outras duas (Passeio de Balão, Degustação de Vinhos) levavam para a página genérica da experiência. Corrigido clonando a tela de ingresso duas vezes, com código de confirmação e contagem de participantes próprios de cada uma.

Complementa os Gaps Críticos do MVP Canvas (Vol. 05, Cap. 14), que listam o que falta no código já escrito. Este capítulo lista o que falta no schema e nas RPCs para sustentar telas que já existem no Figma — descobertas durante a própria construção do protótipo, não antes dela.

Schema
Ticket sem código de confirmação
A tabela participation (id, activity_id, user_id, status, joined_at) não tem campo de número de confirmação nem código único para gerar QR code. A tela "Detalhe do Ingresso" no Figma já mostra um QR funcional — o schema real precisa crescer primeiro (um confirmation_code, ou derivar do próprio id).
Schema
Comunidade sem campo de privacidade
A tabela community (id, name, category, city, cover_url, created_at) não tem campo de visibilidade (pública/privada) nem de aprovação obrigatória de entrada. A tela "Configurações da Comunidade" já propõe esses dois toggles.
RPC
Sem mutation para promover moderador
membership.role já existe no schema — o que falta é a RPC. As mutations hoje documentadas (createCommunity, joinCommunity, leaveCommunity) não incluem promoteMember/demoteMember, que a tela "Moderadores" já assume existir.
RPC
Criar atividade sem preço nem vagas reais
CreateActivityScreen.tsx real tem só 5 campos (título, descrição, categoria, data, local) — a chamada RPC hardcoda p_capacity: 20 e p_price_cents: 0. A versão completa no Figma já propõe foto de capa, preço, vagas e nível de dificuldade editáveis. O schema (activity.capacity, activity.price_cents) já tem essas colunas — falta o formulário real aceitar e a RPC gravar valores reais em vez de fixos.
RPC
Sem forma de adicionar equipe sem custo
join_activity(p_activity_id uuid) só deixa a própria pessoa entrar, checando capacidade via contagem de status='joined'. Não existe RPC para um organizador adicionar outra pessoa como participante. A necessidade real: equipe de trabalho precisa aparecer como participante (pra poder contribuir na vivência depois, que é restrita a quem participou) mas sem contar na capacidade pública — são pessoas a mais, não uma vaga reservada.
→ nova coluna participation.added_by_organizer boolean DEFAULT false; nova RPC add_team_member(p_activity_id, p_user_id) só callable pelo organizador; queries de capacidade passam a filtrar AND added_by_organizer = false.
Schema
Sem sistema de cupom de desconto
Zero menções a cupom, desconto, promoção ou combo em qualquer migration ou hook. O campo "Cupom de desconto" já existia desenhado no Checkout do Figma desde antes desta rodada — nunca tinha sido ligado a nada. A Economia (Vol. 07) não define um sistema de cupom, só a postura geral de cautela contra "desconto disfarçado" sem retenção.
→ nova tabela coupon (id, code, activity_id nullable, discount_type, discount_value, max_uses, uses_count, expires_at, created_by); RPC de resgate integrada ao fluxo de checkout, recebendo p_coupon_code pra recalcular o preço final.
Schema
Sem tabela de check-in de sentimento
O Vol. 05 (Cap. 7) e o Vol. 06 já especificam o conceito e até o formato — user_checkin: feelings[], wants[], created_at, append-only — mas a tabela não existe em nenhuma migration. O Figma (Capítulo 7) já constrói a tela de check-in inteira sobre um dado que hoje não é persistido em lugar nenhum.
→ criar user_checkin exatamente como especificado: nunca sobrescrever, o estado atual é sempre a linha mais recente por usuário.
Schema
Sem mood_tags na atividade nem RPC de cruzamento
activity.mood_tags também já está nomeado no Vol. 06 mas não existe como coluna. Sem ela, o filtro por sentimento em Resultados da Busca (Capítulo 7) é só visual — não filtra nada de verdade. Falta também a lógica que cruza o check-in mais recente da pessoa com os mood_tags das atividades disponíveis para alimentar a Home automaticamente, sem exigir filtro manual.
→ coluna activity.mood_tags text[]; RPC de descoberta contextual que já parte do check-in mais recente do usuário, não só do filtro manual.
Como usar esta lista
Antes de portar qualquer uma dessas quatro telas do Figma para código de produção, tratar como trabalho de schema e RPC primeiro — não é só interface faltando, como foi o caso da maioria das outras telas construídas nesta fase.

Nenhum destes erros comprometeu o produto final — todos foram pegos pela disciplina de verificação (Capítulo 1) antes de avançar. Ficam registrados porque o padrão se repetiu mais de uma vez, o que indica que é um erro fácil de cometer de novo, não um acidente isolado.

13.4 Inserir num contêiner de auto-layout

Em qualquer frame configurado como auto-layout vertical, adicionar um elemento novo com appendChild não respeita a posição X/Y manual — o elemento é empilhado no fim da ordem dos filhos, depois de tudo que já existia, mesmo que a posição pedida fosse no meio da tela. Isso aconteceu de forma quase idêntica em pelo menos três momentos distintos da construção: ao adicionar um botão de editar perfil dentro do cabeçalho de foto de capa, ao inserir um bloco de estado vazio entre a seção "adicionar foto" e a barra de navegação inferior do Perfil, e ao inserir a grade de fotos-tile dentro da tela de Grade do perfil. Em todos os casos, o elemento apareceu visualmente depois da barra de navegação, com o fundo preto do canvas aparecendo por trás — sintoma característico do bug. A correção é sempre a mesma: usar insertChild(índice, nó) na posição exata da árvore, nunca appendChild, quando o pai tem auto-layout.

13.5 Eixos invertidos em fileiras que quebram linha

Para uma fileira com layoutWrap: "WRAP", primaryAxisSizingMode precisa ser FIXED (fixa a largura, o que dispara a quebra de linha) e counterAxisSizingMode precisa ser AUTO (a altura cresce conforme as linhas se acumulam) — o inverso do que a intuição sugere. Configurado ao contrário, a fileira de chips de categoria simplesmente vazava para fora da tela em vez de quebrar linha. Um efeito colateral do mesmo componente, corrigido depois: quando a fileira quebra corretamente em duas linhas, o espaçamento entre linhas (counterAxisSpacing) é uma propriedade separada do espaçamento horizontal entre itens (itemSpacing) — deixar a primeira em zero gruda visualmente uma linha na outra mesmo com o wrap funcionando certo.

13.6 Buscar por texto muda; buscar por ID não

Duas vezes nesta fase (Capítulos 6 e 7), uma busca de nó por nome de texto pegou o elemento errado porque o texto tinha sido alterado num passo anterior, ou porque um frame e seu próprio conteúdo interno compartilhavam o mesmo nome. A lição prática: para automações que rodam em lote sobre várias telas parecidas, guardar o ID do nó assim que ele é criado é mais confiável do que buscar de novo por nome a cada passo seguinte.

13.7 Órfão não é convite para apagar

Numa auditoria de grafo de navegação, a Perfil (v1 — cards) apareceu sem nenhuma tela apontando para ela. A leitura errada seria "a v2 substituiu a v1, pode apagar". A leitura certa — confirmada depois — é que a v1 é uma segunda versão de design guardada de propósito, não lixo esquecido. Conectividade no grafo é um fato sobre navegação, não um veredito sobre relevância.

Referência

Mapa das Telas

Onde encontrar qualquer uma das 139 telas do protótipo

O arquivo vivo está no Figma (não neste documento — este é o registro de decisões, não o protótipo em si). As oito áreas abaixo correspondem exatamente às fileiras do Capítulo 2, na ordem em que aparecem no canvas, de cima para baixo.

01
Onboarding & Auth — splash com avanço automático, Entrar (com Google), cadastro em 7 passos, recuperação de senha em 4 telas.
02
Telas-raiz — Home, Activities, Explorar Destinos, Comunidades, Perfil (3 formatos de exibição + estados vazios de cada aba raiz).
03
Atividades — fluxo — Categorias, Detalhe da Experiência (Detalhes/Para quem é/Vivências/Avaliações + 8 experiências distintas), criar/editar atividade, adicionar equipe (participante extra sem custo), vivência coletiva, checkout (com estado de cupom aplicado), confirmação, cancelamento.
04
Turismo — buscar destino, resultados, selecionar datas, montar itinerário.
05
Passaporte — capa, 14 dias de roteiro, índice, compartilhamento em 3 formatos (capa/dia/roteiro completo).
06
Comunidade — gestão — detalhe (2 abas), criar, configurações de privacidade, moderadores, editar informações.
07
Perfil & Social — 4 perfis de terceiros, seguindo/seguidores (com estados vazios), viagens, agenda, ingressos com QR, compartilhar memória.
08
Mensagens & Notificações — notificações, lista de conversas, 5 conversas 1:1 com conteúdo próprio, nova conversa, câmera e fluxo completo de pós-captura (preview → legenda → publicação).

14.1 Documentos relacionados

A Arquitetura de Produto da everhere (Vol. 05) — a visão que esta interface implementa.
MVP Canvas (Vol. 05, Cap. 14) — o que falta no código real para o ciclo fechar; o Capítulo 13 deste volume é o espelho desse documento, olhando para schema e RPC em vez de tela.
O Design de Sistema da everhere (Vol. 06) — a arquitetura técnica que vai sustentar estas telas.