Estamos preparando sua conta
+Recebemos seu pagamento e estamos comecando.
+ + +Pode fechar esta pagina: o acesso tambem chega por e-mail, com um + link para voce definir sua senha.
+diff --git a/moldes/consolidado/95-frontend-spa.yaml b/moldes/consolidado/95-frontend-spa.yaml index e09d9eb..b121ca2 100644 --- a/moldes/consolidado/95-frontend-spa.yaml +++ b/moldes/consolidado/95-frontend-spa.yaml @@ -81,10 +81,62 @@ spec: # 24 MiB medidos em 2026-09-18. 64Mi de request da folga de 2,5x. requests: { cpu: 50m, memory: 64Mi } limits: { cpu: 200m, memory: 128Mi } + volumeMounts: + - name: publico + mountPath: /usr/share/nginx/html/publico + readOnly: true readinessProbe: httpGet: { path: /, port: 80 } initialDelaySeconds: 5 periodSeconds: 10 + volumes: + - name: publico + projected: + sources: + - configMap: + name: frontend-publico-texto + items: + - { key: "_estilo.css", path: "_estilo.css" } + - { key: "consentimento.js", path: "consentimento.js" } + - { key: "fontes--fontes.css", path: "fontes/fontes.css" } + - { key: "lp-escolinhas.css", path: "lp-escolinhas.css" } + - { key: "lp-escolinhas.html", path: "lp-escolinhas.html" } + - { key: "lp-escolinhas.js", path: "lp-escolinhas.js" } + - { key: "minha-conta.css", path: "minha-conta.css" } + - { key: "minha-conta.html", path: "minha-conta.html" } + - { key: "minha-conta.js", path: "minha-conta.js" } + - { key: "painel.css", path: "painel.css" } + - { key: "painel.html", path: "painel.html" } + - { key: "painel.js", path: "painel.js" } + - { key: "planos-modulos.json", path: "planos-modulos.json" } + - { key: "preparando.html", path: "preparando.html" } + - { key: "preparando.js", path: "preparando.js" } + - { key: "privacidade.html", path: "privacidade.html" } + - { key: "termos.html", path: "termos.html" } + - configMap: + name: frontend-publico-binario + items: + - { key: "fontes--Barlow-400-latin-ext.woff2", path: "fontes/Barlow-400-latin-ext.woff2" } + - { key: "fontes--Barlow-400-latin.woff2", path: "fontes/Barlow-400-latin.woff2" } + - { key: "fontes--Barlow-500-latin-ext.woff2", path: "fontes/Barlow-500-latin-ext.woff2" } + - { key: "fontes--Barlow-500-latin.woff2", path: "fontes/Barlow-500-latin.woff2" } + - { key: "fontes--Barlow-600-latin-ext.woff2", path: "fontes/Barlow-600-latin-ext.woff2" } + - { key: "fontes--Barlow-600-latin.woff2", path: "fontes/Barlow-600-latin.woff2" } + - { key: "fontes--Barlow-700-latin-ext.woff2", path: "fontes/Barlow-700-latin-ext.woff2" } + - { key: "fontes--Barlow-700-latin.woff2", path: "fontes/Barlow-700-latin.woff2" } + - { key: "fontes--IBMPlexMono-500-latin-ext.woff2", path: "fontes/IBMPlexMono-500-latin-ext.woff2" } + - { key: "fontes--IBMPlexMono-500-latin.woff2", path: "fontes/IBMPlexMono-500-latin.woff2" } + - { key: "fontes--Poppins-500-latin-ext.woff2", path: "fontes/Poppins-500-latin-ext.woff2" } + - { key: "fontes--Poppins-500-latin.woff2", path: "fontes/Poppins-500-latin.woff2" } + - { key: "fontes--Poppins-600-latin-ext.woff2", path: "fontes/Poppins-600-latin-ext.woff2" } + - { key: "fontes--Poppins-600-latin.woff2", path: "fontes/Poppins-600-latin.woff2" } + - { key: "fontes--Poppins-700-latin-ext.woff2", path: "fontes/Poppins-700-latin-ext.woff2" } + - { key: "fontes--Poppins-700-latin.woff2", path: "fontes/Poppins-700-latin.woff2" } + - { key: "fontes--Poppins-800-latin-ext.woff2", path: "fontes/Poppins-800-latin-ext.woff2" } + - { key: "fontes--Poppins-800-latin.woff2", path: "fontes/Poppins-800-latin.woff2" } + - { key: "img--hero-escolinha.jpg", path: "img/hero-escolinha.jpg" } + - { key: "img--logo-athletic-map.png", path: "img/logo-athletic-map.png" } + - { key: "produto-dashboard.webp", path: "produto-dashboard.webp" } --- apiVersion: v1 kind: Service diff --git a/moldes/consolidado/96-publico-configmap.yaml b/moldes/consolidado/96-publico-configmap.yaml new file mode 100644 index 0000000..b452117 --- /dev/null +++ b/moldes/consolidado/96-publico-configmap.yaml @@ -0,0 +1,3525 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: frontend-publico-texto + namespace: {{TENANT}}-prod +data: + _estilo.css: | + /* Estilo mínimo, embutido nas páginas públicas. Sem fonte externa e sem CDN: + uma página que declara cuidado com dado pessoal não deveria, ela própria, + avisar um terceiro de que você a abriu. */ + :root { --navy:#0B2C3D; --orange:#F58220; --paper:#F6F5F3; --muted:#5b6b75; --line:#e3e0dc; } + * { box-sizing: border-box; } + body { + margin:0; background:var(--paper); color:var(--navy); + font-family: 'Segoe UI', system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif; + line-height:1.65; + } + header { background:var(--navy); color:#fff; padding:1.5rem 1rem; } + header .marca { max-width:52rem; margin:0 auto; font-weight:700; letter-spacing:.02em; } + header .marca span { color:var(--orange); } + main { max-width:52rem; margin:0 auto; padding:2rem 1rem 4rem; } + h1 { font-size:1.9rem; line-height:1.2; margin:.5rem 0 .25rem; } + h2 { font-size:1.25rem; margin:2rem 0 .5rem; border-bottom:2px solid var(--line); padding-bottom:.3rem; } + h3 { font-size:1.05rem; margin:1.5rem 0 .4rem; } + .data { color:var(--muted); font-size:.9rem; margin-bottom:1.5rem; } + table { border-collapse:collapse; width:100%; margin:1rem 0; font-size:.95rem; } + th, td { border:1px solid var(--line); padding:.5rem .6rem; text-align:left; vertical-align:top; } + th { background:#fff; } + .destaque { background:#fff; border-left:4px solid var(--orange); padding:1rem 1.2rem; margin:1.5rem 0; } + .minuta { background:#fff4e5; border:2px solid var(--orange); padding:1rem 1.2rem; margin:0 0 2rem; } + .minuta strong { display:block; margin-bottom:.4rem; } + .pendente { background:#ffe8e8; border:2px dashed #c62828; padding:1rem 1.2rem; margin:1.5rem 0; } + footer { border-top:1px solid var(--line); margin-top:3rem; padding-top:1rem; color:var(--muted); font-size:.9rem; } + a { color:#1565c0; } + @media (max-width:40rem) { body { font-size:.97rem; } h1 { font-size:1.5rem; } } + + consentimento.js: | + /* =========================================================================== + * P2.9 — o portão de consentimento, antes de qualquer rastreamento de terceiro. + * + * ── POR QUE ISTO EXISTE ──────────────────────────────────────────────────── + * + * A política de privacidade que publicamos diz, em §8: + * + * "Não usamos cookies de publicidade nem de rastreamento de terceiros." + * + * No instante em que o Meta Pixel entrar no ar, essa frase vira **falsa** — e + * ela não é marketing, é declaração pública de conformidade (LGPD art. 9º). + * Preencher o `PIXEL_ID` sem resolver isto não publica um pixel: publica uma + * mentira assinada. + * + * As duas saídas eram corrigir a política ou pedir consentimento. Este arquivo + * é a segunda, que é a que mantém a promessa de pé. + * + * ── A REGRA QUE GOVERNA TUDO AQUI: FALHA FECHADA ─────────────────────────── + * + * Em toda dúvida, NÃO rastreia. Sem decisão, não rastreia. Com o localStorage + * quebrado, não rastreia. Com o banner falhando ao montar, não rastreia. + * + * O contrário — rastrear por omissão — é exatamente o defeito que a LGPD trata, + * e é o que acontece sozinho se ninguém escrever este arquivo. + * + * ── O QUE ESTE ARQUIVO NÃO COBRE ─────────────────────────────────────────── + * + * A LP carrega `fonts.googleapis.com` no `
`, **antes de tudo isto**, e + * isso entrega o IP do visitante ao Google sem consentimento. Não dá para + * consertar daqui: o `` é servido no HTML. O conserto é hospedar a fonte + * junto (`publico/fontes/`), e está no diário como pendência própria. + * =========================================================================== */ + (function (global) { + 'use strict'; + + var CHAVE = 'atm.consentimento.v1'; + var ACEITO = 'aceito'; + var RECUSADO = 'recusado'; + + /* O localStorage joga exceção — e não devolve null — em janela anônima com + * cookies bloqueados. Um `getItem` solto aqui derrubaria o script inteiro, e + * com ele o formulário de lead, que é o que a página existe para fazer. */ + function ler() { + try { return global.localStorage.getItem(CHAVE); } catch (e) { return null; } + } + function gravar(valor) { + try { global.localStorage.setItem(CHAVE, valor); } catch (e) { /* segue sem lembrar */ } + } + + var decisao = ler(); + var pendentes = []; + + /* `aoAceitar` é o único caminho por onde código de terceiro entra na página. + * Quem chamar isto sem decisão tomada fica na fila; quem chamar depois de uma + * recusa nunca roda. */ + function aoAceitar(callback) { + if (decisao === ACEITO) { callback(); return; } + if (decisao === RECUSADO) { return; } + pendentes.push(callback); + } + + function decidir(valor) { + decisao = valor; + gravar(valor); + var fila = pendentes; + pendentes = []; + if (valor === ACEITO) { + for (var i = 0; i < fila.length; i++) { fila[i](); } + } + var banner = global.document.getElementById('atm-consentimento'); + if (banner && banner.parentNode) { banner.parentNode.removeChild(banner); } + } + + /* Recusar NÃO desfaz o que já carregou: o fbq já injetado continua na página + * até o recarregamento. Por isso a recusa recarrega — é a única forma honesta + * de "parar de rastrear" sem fingir que um `delete window.fbq` apaga o que já + * foi para o servidor do terceiro. */ + function recusar() { + var jaCarregou = decisao === ACEITO && (global.fbq || global.gtag); + decidir(RECUSADO); + if (jaCarregou && global.location && global.location.reload) { + global.location.reload(); + } + } + + var ESTILO_BOTAO = + 'font:600 14px/1 inherit;padding:10px 18px;border-radius:8px;cursor:pointer;border:0;'; + + /** + * Monta o banner. Não faz nada se já houver decisão — inclusive recusa: quem + * disse não uma vez não é perguntado de novo a cada visita. + */ + function montarBanner(doc) { + doc = doc || global.document; + if (decisao === ACEITO || decisao === RECUSADO) { return null; } + if (doc.getElementById('atm-consentimento')) { return null; } + + var caixa = doc.createElement('div'); + caixa.id = 'atm-consentimento'; + caixa.setAttribute('role', 'dialog'); + caixa.setAttribute('aria-label', 'Consentimento para medição'); + caixa.style.cssText = + 'position:fixed;left:0;right:0;bottom:0;z-index:9999;background:#12161c;' + + 'color:#e8edf4;padding:18px 20px;display:flex;flex-wrap:wrap;gap:14px;' + + 'align-items:center;justify-content:center;box-shadow:0 -2px 18px rgba(0,0,0,.35);' + + 'font:400 14px/1.5 system-ui,sans-serif;'; + + var texto = doc.createElement('p'); + texto.style.cssText = 'margin:0;max-width:60ch;'; + texto.innerHTML = + 'Usamos medição do Meta e do Google só para saber se nossos anúncios ' + + 'funcionam. Sem isso a página funciona igual, e o seu contato chega ' + + 'do mesmo jeito. Política de ' + + 'privacidade.'; + + /* Os dois botões são o MESMO elemento, com o mesmo tamanho e no mesmo lugar. + * Recusa escondida atrás de "preferências", ou em cinza claro sobre branco, + * é consentimento arrancado — e a ANPD trata como consentimento inválido. */ + var aceitar = doc.createElement('button'); + aceitar.type = 'button'; + aceitar.id = 'atm-consentimento-aceitar'; + aceitar.textContent = 'Aceitar'; + aceitar.style.cssText = ESTILO_BOTAO + 'background:#28c76f;color:#06210f;'; + + var negar = doc.createElement('button'); + negar.type = 'button'; + negar.id = 'atm-consentimento-recusar'; + negar.textContent = 'Recusar'; + negar.style.cssText = ESTILO_BOTAO + 'background:#39434f;color:#e8edf4;'; + + aceitar.addEventListener('click', function () { decidir(ACEITO); }); + negar.addEventListener('click', function () { decidir(RECUSADO); }); + + caixa.appendChild(texto); + caixa.appendChild(aceitar); + caixa.appendChild(negar); + (doc.body || doc.documentElement).appendChild(caixa); + return caixa; + } + + /** Para o link no rodapé: permite mudar de ideia nos dois sentidos. */ + function reabrir(doc) { + decisao = null; + try { global.localStorage.removeItem(CHAVE); } catch (e) { /* idem */ } + return montarBanner(doc); + } + + global.AtmConsentimento = { + ACEITO: ACEITO, + RECUSADO: RECUSADO, + estado: function () { return decisao; }, + aoAceitar: aoAceitar, + aceitar: function () { decidir(ACEITO); }, + recusar: recusar, + montarBanner: montarBanner, + reabrir: reabrir + }; + })(typeof window !== 'undefined' ? window : this); + + fontes--fontes.css: | + /* ============================================================ + * As fontes da landing page, servidas POR NOS. + * + * Gerado por `scripts/baixar_fontes_da_lp.py` — nao edite a mao. + * + * Existe para que o navegador do visitante nao peca nada ao Google: + * aquele pedido leva o IP dele e o Referer da nossa pagina antes de + * qualquer consentimento. Com isto, `style-src` e `font-src` da CSP + * voltam a ser so 'self'. + * + * So `latin` e `latin-ext`: a pagina e em portugues, e o + * `unicode-range` de cada bloco faria o navegador ignorar os outros. + * ============================================================ */ + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/publico/fontes/Barlow-400-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/publico/fontes/Barlow-400-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/Barlow-500-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/Barlow-500-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/publico/fontes/Barlow-600-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/publico/fontes/Barlow-600-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/publico/fontes/Barlow-700-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Barlow'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/publico/fontes/Barlow-700-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/IBMPlexMono-500-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'IBM Plex Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/IBMPlexMono-500-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/Poppins-500-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/publico/fontes/Poppins-500-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/publico/fontes/Poppins-600-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/publico/fontes/Poppins-600-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/publico/fontes/Poppins-700-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/publico/fontes/Poppins-700-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url(/publico/fontes/Poppins-800-latin-ext.woff2) format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + + @font-face { + font-family: 'Poppins'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url(/publico/fontes/Poppins-800-latin.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + } + + lp-escolinhas.css: | + /* + * Estilo da landing page de escolinhas. + * + * MORA AQUI, E NAO NUM + + +Recebemos seu pagamento e estamos comecando.
+ + +Pode fechar esta pagina: o acesso tambem chega por e-mail, com um + link para voce definir sua senha.
+