Novo evento Mixpanel Deposit Requested (useAnalytics.trackDepositRequested) disparado quando /wallet/add-credit retorna 200 OK. Espelha o legado DefaultLayout.vue das brands 7k/cassino/vera (props Amount em unidades inteiras + DepositMethod). Continua complementar ao evento de funil já existente (pix_generated no GTM e PixGenerated no Facebook).
Bugfix crítico nos eventos S2S do AppsFlyer (sendRegister, sendFTD, sendRebill). Os três estavam dentro do guard if (!shouldLoadTrackers) return do useAnalytics, mas o gate é o inverso do gate do AppsFlyer (shouldLoadTrackers = !isAppMode && !isBot, useAppsFlyer.ready = enabled && isAppMode) — resultado: nenhuma das chamadas server-to-server disparava nem na web (gate externo bloqueia) nem dentro do APK (early return do gate externo cortava o caminho). Agora as três chamadas são disparadas antes do guard e o S2S funciona em produção. Coberto por useAppsFlyer.test.ts (202 linhas) e useAppMode.test.ts (72 linhas).
useAppMode agora reconhece ?is_twa=true além de ?app=true. Os APKs em produção da família 7k/cassino/vera (publicados antes do rename do query param) continuam injetando o legado em cada landing — sem isso isAppMode ficava false pra users do app e desativava todo o pipeline de tracking S2S silenciosamente.
Valor do deposit GTM corrigido pra unidades inteiras (amountCents / 100) ao invés de cents puros — paridade com o legado e com a expectativa dos dashboards de BI.
Jornada FTD — Refatoração Completa e Novas Brands
D0 e D1 desacoplados — antes, ativar o template vera-legacy do D0 (cashback) ligava implicitamente o modal de anúncio do D1 (check-in). Agora cada brand habilita as três etapas independentemente: ftdCashback.enabled, ftdCheckin.enabled e a flag nova ftdCheckin.announcement.enabled. Quatro combinações possíveis — só D0, só D1, ambos ou nenhum.
Copy e assets configuráveis por brand no template vera-legacy — FtdCashbackConfig ganhou copy.{firstBonusToastTitle,cashbackModalTitle,cashbackModalDescriptionHtml,cashbackModalCtaText} + templateAssets.{firstBonusToastImage,cashbackModalImage}. FtdCheckinConfig ganhou announcement.copy.{title,descriptionHtml,ctaText} + templateAssets.image. Todos opcionais — fallback é o copy PT-BR + CDN da Vera (zero regressão).
16 tokens de tema novos para o template e o toast — ftd-offer.template-{shell-bg,title-text,title-shadow,image-bg-from,image-bg-to,highlight-bg,highlight-border,highlight-text,cta-bg,cta-text} e ftd-offer.toast-{bg-from,bg-to,border,icon-bg-from,icon-bg-to,icon-border}. FtdOfferModalTemplate e FtdOfferInGameToast agora leem essas cores via CSS custom properties inline (Tailwind JIT não consegue gerar classes a partir de tokens dinâmicos).
7k-bet-br ativa a jornada completa — D0 cashback, D1 check-in (com modal de anúncio "Garanta sua diversão!") e oferta-relâmpago pré-FTD, todos via template unificado. Quatro assets brand-specific da CDN do 7k substituem os fallbacks da Vera (toast, modal cashback, anúncio D1 e modal de oferta).
cassino-bet-br ativa a jornada completa — paleta + assets próprios, brand_id: 2 no Dark Verifier/Freedom (paridade com useFtdCashback.ts:52 do legado), kill-switches feFtdD0Cassino / feFtdD1Cassino, tabela bonusTiers de 35 níveis portada verbatim do legado (R$ 5 → R$ 3000+, cap em R$ 800), autoDepositModal abre o drawer de depósito automaticamente no login quando saldo ≤ R$ 0,10. Inclui lista de jogos elegíveis em cashback/eligible-games.ts.
cl-bet7k-com ativa D0 + D1 com identidade chilena — brandId: 4, kill-switch feFtdD07KCl (compartilhado D0/D1), tabela bonusTiers de 11 níveis em CLP (CLP 850 → CLP 510 000, cap CLP 136 000), 6995 IDs elegíveis portados 1:1 do legado, copy em espanhol chileno ("¡Sigue jugando para ganar un cashback!"). Moeda renderiza sem decimais ($50.000) via useFormatMoney() + CountryConfig.displayDecimalDigits. D1 começa desabilitado no primeiro rollout.
STT 2 (saldo bônus) com kill-switch remoto — saldoBonus.featureFlags?: { legacy?, configcat? } permite desligar a STT 2 instantaneamente via ConfigCat ou FF legado sem deploy. O hook useFtdCashbackFlow computa saldoBonusRemoteKillSwitchPass (closed-by-default enquanto a API está em voo, mesma semântica do D0/D1). Cassino declara feFtdSaldoBonus + feFtdSaldoBonusCassino.
Redesign completo da TopbarNotification (PR #333): novo layout com botão de fechar (X) à esquerda, ícone em chip arredondado com tokens dedicados (topbar.icon-bg / topbar.icon-text), pilha de título + subtítulo no centro e CTA pill à direita, com altura de 72 px alinhada às barras modernas de instalação de app. Os ícones emoji foram substituídos por componentes do lucide-react (Smartphone, Bell, Gift, Send, Trophy, ShieldAlert) e o tipo TopbarDefinition.icon virou LucideIcon. Os modos default e restricted foram unificados num TopbarShell compartilhado, e a topbar deixou de ser sticky — agora rola junto com a página enquanto o header permanece fixo no topo do viewport. Tooltip de instalação iOS foi reancorado para o rodapé do viewport com safe-area-inset-bottom para que a seta inferior alinhe com a barra de endereços do Safari.
Centralização do conteúdo no desktop (PR #334): o TopbarNotification recebeu um container interno max-w-[460px] mx-auto envolvendo close/ícone/texto/CTA. O fundo continua preenchendo edge-to-edge, mas em viewports largos o X e o CTA não escorregam mais para os cantos deixando um espaço vazio gigante no meio. Em mobile (< 460px) o comportamento é idêntico ao anterior — o container preenche naturalmente toda a largura.
Refresh de tokens de tema da topbar em todos os overrides (PR #347): sincronizou o override 7k-bet-br (que estava sem icon-bg e icon-text), padronizou a paleta com fundo mais suave (lifted bg-primary), chip do ícone tingido com primary e CTA combinando com o botão primário da brand. Ajustes manuais aplicados nas variantes 7k, state77, vera-bet-br, betpontobet-bet-br e cassino-bet-br. Altura interna da linha do TopbarNotification reduzida de 68 px para 62 px para compactar o footprint vertical.
Banner de consentimento de cookies com Google Consent Mode v2 chega ao base. O CookieConsentBanner (fixado no canto inferior esquerdo, animado, z-60) e o painel CookieConsentDetails (abas Configurações/Sobre, toggles por categoria, tabela de cookies) injetam os defaults do GCM antes do GTM inicializar e gravam a preferência no cookie cactusCookiesConsent. Mapeamento de categorias: performance → analytics_storage, functionality → functionality_storage, demais → ad_storage + ad_user_data + ad_personalization. Bypass para bots via useIsBot(). Feature flag brand.features.cookieConsentPopup controla a exibição por marca, sem build-time config.
Paridade total com o legado Vue (base + 7k + cassino + vera): adicionado o sétimo sinal do GCM v2 (security_storage: granted) para auditorias Lighthouse/CMP enxergarem o contrato completo; COOKIE_TABLE expandida de 6 para 19 entradas cobrindo Cloudflare, GA4, Clarity, Meta Pixel, Kwai, Amplitude, Smartico e cookies de funcionalidade (current_lang, topbar_closed, install_app_popup_closed); migração transparente do formato legado (array JSON de strings) para o novo objeto, sem reprompt de usuários existentes.
UX e visual: o banner se posiciona acima do MobileBottomNav em mobile (h-14), some quando o drawer está aberto, fica print:hidden, e tem split 50/50 entre [Personalizar | Recusar] e [Aceitar todos]. Cores 100% via tokens de tema (bg-secondary, text-texts, bg-primary), eliminando bg-white/* e border-white/* hardcoded. O botão "Salvar" dentro do painel de detalhes se torna "Aceitar todos" quando só a categoria necessária está marcada — replica o saveButton() do legado.