Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e97e468
test: define contrato do site premium estático
pglemos Jul 20, 2026
444c1e9
feat: adiciona design system premium estático
pglemos Jul 20, 2026
d977852
feat: adiciona interações acessíveis do site premium
pglemos Jul 20, 2026
9ebeefd
feat: gera as dez páginas premium limpas
pglemos Jul 20, 2026
36fc840
feat: adiciona roteador do Worker premium isolado
pglemos Jul 20, 2026
706f272
ci: configura Worker premium de preview separado
pglemos Jul 20, 2026
bac8128
test: audita preview premium em desktop e mobile
pglemos Jul 20, 2026
4d7ddbb
ci: publica e audita preview premium isolado
pglemos Jul 20, 2026
65ad3a7
fix: usa host neutro no binding de assets
pglemos Jul 20, 2026
834c8c4
fix: desativa redirects automáticos de HTML no preview
pglemos Jul 20, 2026
3be8896
fix: elimina overflow e aplica progressive enhancement
pglemos Jul 20, 2026
cc7557d
build: finaliza site premium com overrides seguros
pglemos Jul 20, 2026
84e7fbe
test: valida build final e fallback sem JavaScript
pglemos Jul 20, 2026
0148f41
test: captura conteúdo estável e valida fallback sem JavaScript
pglemos Jul 20, 2026
53ed099
ci: usa build final com overrides validados
pglemos Jul 20, 2026
0bab09b
test: valida a regra CSS efetiva em vez do texto histórico
pglemos Jul 20, 2026
bfdcd97
fix: monta preview a partir das páginas originais aprovadas
pglemos Jul 20, 2026
e58144d
fix: serve exatamente as páginas originais aprovadas
pglemos Jul 20, 2026
04faa31
test: garante cópia exata das referências aprovadas
pglemos Jul 20, 2026
ce4f4d7
test: compara rotas limpas com as referências originais pixel a pixel
pglemos Jul 20, 2026
45c0858
ci: valida preview contra as páginas originais em três viewports
pglemos Jul 20, 2026
7536621
fix: copia helpers originais da raiz pública
pglemos Jul 20, 2026
17a94c6
test: valida helpers nos caminhos realmente usados pelo runtime
pglemos Jul 20, 2026
5807127
fix: desativa cache de HTML e versiona respostas da referência
pglemos Jul 20, 2026
02be925
fix: usa Worker novo para evitar cache legado do preview
pglemos Jul 20, 2026
26d0e60
ci: valida Worker novo sem cache HTML legado
pglemos Jul 20, 2026
8513560
ci: aguarda propagação do Worker antes do smoke test
pglemos Jul 20, 2026
682264b
fix: adiciona correção responsiva sobre as referências originais
pglemos Jul 20, 2026
8283d3e
fix: injeta correção responsiva nas cópias publicadas
pglemos Jul 20, 2026
5452430
test: valida fonte original mais patch responsivo controlado
pglemos Jul 20, 2026
ae331ac
test: ignora apenas requisições transitórias de placeholders do runtime
pglemos Jul 20, 2026
4fecf26
test: usa comparação perceptual rígida em vez de hash PNG
pglemos Jul 20, 2026
0ec9e8f
test: aguarda todas as imagens finais antes da captura
pglemos Jul 20, 2026
089b401
test: ativa lazy loading e valida somente imagens visíveis
pglemos Jul 20, 2026
9fa3a18
test: força decode das imagens sem bloquear cards ocultos
pglemos Jul 20, 2026
67102f7
test: normaliza foco das capturas e valida skip link separadamente
pglemos Jul 20, 2026
652378c
test: estabiliza rolagem antes da comparação visual
pglemos Jul 20, 2026
725c3c5
test: exige o pacote final exato do ZIP anexado
pglemos Jul 20, 2026
92a5e99
ci: executa contrato do ZIP final antes do preview
pglemos Jul 20, 2026
c7df4a7
fix: usa exatamente o pacote final enviado no ZIP
pglemos Jul 21, 2026
3ce7dbc
chore: importa fontes textuais do ZIP final
pglemos Jul 21, 2026
dd7eb0e
fix: remonta e valida exatamente a fonte do ZIP
pglemos Jul 21, 2026
a6fd4f5
chore: remove arquivo compactado corrompido
pglemos Jul 21, 2026
92a9486
ci: dispara validação completa da fonte do ZIP
pglemos Jul 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions .github/workflows/premium-static-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Premium ZIP preview

on:
push:
branches:
- fix/premium-static-recovery-2026-07-20
pull_request:
branches:
- main
types: [opened, synchronize, reopened]
workflow_dispatch:

permissions:
contents: read
pull-requests: write

concurrency:
group: premium-zip-preview-${{ github.ref }}
cancel-in-progress: true

jobs:
preview:
if: >-
github.event_name == 'workflow_dispatch' ||
github.ref == 'refs/heads/fix/premium-static-recovery-2026-07-20' ||
github.head_ref == 'fix/premium-static-recovery-2026-07-20'
runs-on: ubuntu-latest
timeout-minutes: 45
environment: production

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci

- name: Validate exact ZIP source
run: npx vitest run tests/premium-zip-source.test.ts tests/premium-static-recovery.test.ts

- name: Build exact ZIP package
run: node scripts/build-premium-reference.mjs premium-dist

- name: Validate generated package
run: |
node --check workers/premium-preview-worker.mjs
node --check premium-dist/assets/js/site.js
python3 premium-dist/site/qa_check.py

- name: Deploy isolated ZIP Worker
id: deploy
shell: bash
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
set -euo pipefail
npx wrangler deploy --config wrangler.premium-preview.jsonc 2>&1 | tee /tmp/premium-preview-deploy.log
preview_url=$(grep -Eo 'https://[A-Za-z0-9.-]+\.workers\.dev' /tmp/premium-preview-deploy.log | tail -1)
test -n "$preview_url"
echo "url=$preview_url" >> "$GITHUB_OUTPUT"
echo "$preview_url" > /tmp/premium-preview-url.txt

- name: Wait for Worker propagation
shell: bash
env:
PREMIUM_PREVIEW_URL: ${{ steps.deploy.outputs.url }}
BUILD_SHA: ${{ github.sha }}
run: |
set -euo pipefail
ready=0
for attempt in $(seq 1 18); do
status=$(curl -sS -o /tmp/premium-ready.html -D /tmp/premium-ready.headers -w '%{http_code}' "${PREMIUM_PREVIEW_URL}/?build=${BUILD_SHA}&attempt=${attempt}" || true)
if [[ "$status" == "200" ]] && grep -Fqi 'x-premium-site: zip-final-v1' /tmp/premium-ready.headers; then
ready=1
break
fi
sleep 5
done
test "$ready" = '1'

- name: Smoke test clean routes and ZIP assets
shell: bash
env:
PREMIUM_PREVIEW_URL: ${{ steps.deploy.outputs.url }}
BUILD_SHA: ${{ github.sha }}
run: |
set -euo pipefail
mkdir -p /tmp/premium-smoke
routes=('' 'pista' 'kart-locacao' 'campeonatos' 'eventos' 'duvidas' 'kac' 'kac-super' '200-milhas' '500-milhas')
for path in "${routes[@]}"; do
key="${path:-home}"
curl -sS -L --max-redirs 4 \
-D "/tmp/premium-smoke/${key}.headers" \
-o "/tmp/premium-smoke/${key}.html" \
-w '%{http_code} %{url_effective}\n' \
"${PREMIUM_PREVIEW_URL}/${path}?build=${BUILD_SHA}" > "/tmp/premium-smoke/${key}.meta"
read -r status effective < "/tmp/premium-smoke/${key}.meta"
test "$status" = '200'
[[ "$effective" != *'/site/'* ]]
grep -Fqi '<h1' "/tmp/premium-smoke/${key}.html"
grep -Fqi 'x-premium-site: zip-final-v1' "/tmp/premium-smoke/${key}.headers"
grep -Fqi 'cache-control: no-store' "/tmp/premium-smoke/${key}.headers"
done
curl -fsS "${PREMIUM_PREVIEW_URL}/assets/css/site.css?build=${BUILD_SHA}" -o /tmp/premium-smoke/site.css
curl -fsS "${PREMIUM_PREVIEW_URL}/assets/js/site.js?build=${BUILD_SHA}" -o /tmp/premium-smoke/site.js
test -s /tmp/premium-smoke/site.css
test -s /tmp/premium-smoke/site.js

- name: Install Chromium
run: npx playwright install --with-deps chromium

- name: Compare clean routes with ZIP HTML
env:
PREMIUM_PREVIEW_URL: ${{ steps.deploy.outputs.url }}
run: npx playwright test tests/premium-static-preview.spec.ts --reporter=html,line

- name: Publish verified preview URL on pull request
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
env:
PREVIEW_URL: ${{ steps.deploy.outputs.url }}
with:
script: |
const marker = '<!-- premium-static-preview -->';
const body = `${marker}\n## Preview do ZIP final anexado\n\n${process.env.PREVIEW_URL}\n\nAs 10 rotas limpas usam os HTMLs, CSS e JavaScript do pacote \`kartodromo-betim-premium-revisado-final\`. A esteira valida hashes SHA-256, QA estrutural, recursos, overflow e screenshots em mobile, tablet e desktop.`;
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
});
const previous = comments.find((comment) => comment.body?.includes(marker));
if (previous) {
await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: previous.id, body });
} else {
await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body });
}

- name: Upload comparison evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: premium-zip-preview-evidence
path: |
/tmp/premium-preview-deploy.log
/tmp/premium-preview-url.txt
/tmp/premium-ready.headers
/tmp/premium-ready.html
/tmp/premium-smoke
playwright-report
test-results/premium-zip-comparison
if-no-files-found: ignore
1 change: 1 addition & 0 deletions premium-src/ZIP_SOURCE_VALIDATION_TRIGGER.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Validação da fonte canônica kart(1).zip em 2026-07-20.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>200 Milhas de Betim 2026 | Kartódromo de Betim</title><meta name="description" content="Endurance estratégico em equipe, com ritmo, trocas, constância e gestão de corrida."><meta name="theme-color" content="#030504"><meta name="color-scheme" content="dark"><link rel="icon" type="image/png" href="assets/brand/kib-logo.png"><link rel="stylesheet" href="assets/css/site.css"></head><body class=""><a class="skip-link" href="#conteudo">Pular para o conteúdo</a><div class="noise" aria-hidden="true"></div><div id="progress" aria-hidden="true"></div><div class="page-wipe" aria-hidden="true"></div><header class="header"><div class="container"><div class="header-inner"><a class="brand" href="index.html"><img decoding="async" src="assets/brand/kib-logo.png" alt="Kartódromo Internacional de Betim"></a><nav class="nav" aria-label="Navegação principal"><a class="" href="index.html">Home</a><a class="" href="pista.html">A pista</a><a class="" href="kart-locacao.html">Locação</a><a class="active" aria-current="page" href="campeonatos.html">Campeonatos</a><a class="" href="eventos.html">Eventos</a><a class="" href="duvidas.html">Dúvidas</a></nav><a class="btn btn-primary btn-small header-cta" href="https://tools.mylaptime.com.br/booking?uid=5729bbc1-572b-4e32-84ec-e9e93ab08ced" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="1"/><path d="M16 3v4M8 3v4M3 10h18"/></svg> Reservar agora</a><button class="menu-toggle" type="button" aria-label="Abrir menu" aria-controls="mobile-navigation" aria-expanded="false"><span></span><span></span><span></span></button></div></div></header><nav class="mobile-nav" id="mobile-navigation" aria-label="Navegação móvel" inert><a href="index.html">Home</a><a href="pista.html">A pista</a><a href="kart-locacao.html">Locação</a><a href="campeonatos.html">Campeonatos</a><a href="eventos.html">Eventos</a><a href="duvidas.html">Dúvidas</a><a class="btn btn-primary" href="https://tools.mylaptime.com.br/booking?uid=5729bbc1-572b-4e32-84ec-e9e93ab08ced" target="_blank" rel="noopener noreferrer">Reservar agora</a></nav><main id="conteudo" tabindex="-1">
<section class="hero compact"><div class="hero-media"><video preload="metadata" aria-hidden="true" tabindex="-1" autoplay muted loop playsinline poster="assets/posters/home-karting.jpg" style="object-position:center 50%"><source src="assets/videos/home-karting.mp4" type="video/mp4"></video></div><div class="speed-lines" aria-hidden="true"><i></i><i></i><i></i></div><div class="page-hero-grid"><div><p class="eyebrow">ENDURANCE</p><h1 class="page-title">200 <span class="green">Milhas</span><br><span class="outline">de Betim</span></h1><p class="page-lead">Endurance estratégico em equipe, com ritmo, trocas, constância e gestão de corrida.</p><div class="actions"><a class="btn btn-primary" href="https://wa.me/5531998842898?text=Olá!%20Quero%20ser%20avisado%20sobre%20a%20próxima%20edição%20das%20200%20Milhas%20de%20Betim." target="_blank" rel="noopener noreferrer">Avisem-me da próxima edição <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14m-5-5 5 5-5 5"/></svg></a><a class="btn btn-outline" href="assets/regulamentos/200-milhas-de-betim-2026.pdf" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12m-5-5 5 5 5-5M5 21h14"/></svg> Regulamento</a></div></div><div><img decoding="async" class="champ-logo" src="assets/championships/200-milhas-logo.png" alt="200 Milhas de Betim"><div class="hero-side-number">07 FEV<small>Edição 2026 realizada</small></div></div></div></section>
<div class="telemetry-wrap"><div class="container"><div class="telemetry"><div class="telemetry-item"><div class="telemetry-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="1"/><path d="M16 3v4M8 3v4M3 10h18"/></svg></div><div><strong>07 FEV</strong><span>Edição 2026 realizada</span></div></div><div class="telemetry-item"><div class="telemetry-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg></div><div><strong>Equipes</strong><span>Estratégia e revezamento</span></div></div><div class="telemetry-item"><div class="telemetry-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2M9 2h6"/></svg></div><div><strong>Longa duração</strong><span>Ritmo e resistência</span></div></div><div class="telemetry-item"><div class="telemetry-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 21h8M12 17v4M7 4h10v4a5 5 0 0 1-10 0V4ZM7 6H4v2a4 4 0 0 0 4 4M17 6h3v2a4 4 0 0 1-4 4"/></svg></div><div><strong>Pódio oficial</strong><span>Resultado e reconhecimento</span></div></div></div></div></div>
<section class="section"><div class="container"><div class="asym-grid"><div class="reveal"><p class="eyebrow">Formato da prova</p><h2 class="section-title">Resistência é<br><span class="accent">estratégia</span></h2><p class="section-copy">Não basta ser rápido. É preciso manter ritmo, executar trocas, ler a pista e tomar decisões corretas durante toda a prova.</p></div><div class="glass-panel booking reveal"><h2 class="panel-title">Informação principal</h2><div class="price"><small>Evento</small><strong style="font-size:58px">Próxima edição</strong></div><div class="panel-list"><div><strong>Regulamento oficial</strong>Formato, punições e procedimentos detalhados.</div><div><strong>Equipe organizada</strong>Pilotos e estratégia definidos antes da largada.</div><div><strong>Inscrição confirmada</strong>Conforme documentação e pagamento aplicáveis.</div></div></div></div></div></section>
<section class="section" style="background:var(--bg2)"><div class="container"><div class="asym-grid"><div><p class="eyebrow">Cronograma oficial</p><h2 class="section-title">Da chegada<br><span class="accent">à bandeirada</span></h2></div><div class="timeline reveal"><div class="timeline-item"><div class="timeline-date">06:30</div><div class="timeline-content"><h3>Credenciamento</h3><p>Chegada das equipes e conferência documental.</p></div></div><div class="timeline-item"><div class="timeline-date">07:15</div><div class="timeline-content"><h3>Briefing</h3><p>Regras, bandeiras, trocas e procedimento de prova.</p></div></div><div class="timeline-item"><div class="timeline-date">08:00</div><div class="timeline-content"><h3>Classificação</h3><p>Definição do grid de largada.</p></div></div><div class="timeline-item"><div class="timeline-date">09:00</div><div class="timeline-content"><h3>Largada</h3><p>Início do endurance e estratégia de equipe.</p></div></div><div class="timeline-item"><div class="timeline-date">Final</div><div class="timeline-content"><h3>Pódio</h3><p>Resultado oficial e premiação.</p></div></div></div></div></div></section>
<section class="section"><div class="container"><p class="eyebrow">Regras principais</p><h2 class="section-title">Controle, ritmo<br><span class="accent">e disciplina</span></h2><div class="rules-grid" style="margin-top:50px"><article class="rule-card reveal" data-num="01"><h3>Equipe e revezamento</h3><p>Pilotos dividem a prova e cumprem janelas e procedimentos de troca.</p></article><article class="rule-card reveal" data-num="02"><h3>Peso e lastro</h3><p>A prova aplica critérios de peso definidos no regulamento oficial.</p></article><article class="rule-card reveal" data-num="03"><h3>Abastecimento e boxes</h3><p>Entrada, velocidade e operação de boxes seguem fiscalização.</p></article><article class="rule-card reveal" data-num="04"><h3>Bandeiras</h3><p>Sinalização de pista deve ser obedecida imediatamente.</p></article><article class="rule-card reveal" data-num="05"><h3>Punições</h3><p>Condutas irregulares geram advertência, tempo ou posições.</p></article><article class="rule-card reveal" data-num="06"><h3>Resultado</h3><p>Vence a equipe que completa a distância nas condições oficiais.</p></article></div><div class="actions"><a class="btn btn-outline" href="assets/regulamentos/200-milhas-de-betim-2026.pdf" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12m-5-5 5 5 5-5M5 21h14"/></svg> Baixar PDF oficial</a></div></div></section>
<section class="section" style="background:var(--bg2)"><div class="container"><p class="eyebrow">Premiação e memória</p><h2 class="section-title">Uma prova para<br><span class="accent">entrar na história</span></h2><div class="stats-grid" style="margin-top:50px"><div class="stat"><strong>01</strong><span>Troféu<br>Equipe campeã</span></div><div class="stat"><strong>02</strong><span>Reconhecimento<br>Pódio oficial</span></div><div class="stat"><strong>03</strong><span>Memória<br>Prova histórica</span></div><div class="stat"><strong>∞</strong><span>histórias<br>de equipe</span></div></div></div></section>
<section class="section"><div class="container"><div class="big-cta reveal"><div><h2>Avisem-me da próxima edição<br><span class="accent">agora</span></h2><p>Fale com a organização para confirmar vaga, documentos e próximos passos.</p></div><div class="big-cta-actions"><a class="btn btn-primary" href="https://wa.me/5531998842898?text=Olá!%20Quero%20ser%20avisado%20sobre%20a%20próxima%20edição%20das%20200%20Milhas%20de%20Betim." target="_blank" rel="noopener noreferrer">Avisem-me da próxima edição <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14m-5-5 5 5-5 5"/></svg></a><a class="btn btn-outline" href="https://wa.me/5531998842898" target="_blank" rel="noopener noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 11.5a8 8 0 0 1-11.9 7L4 20l1.5-4.1A8 8 0 1 1 20 11.5Z"/><path d="M8.5 8.5c.5 3 2 4.5 5 5"/></svg> Falar no WhatsApp</a></div></div></div></section>
</main><footer class="footer"><div class="container"><div class="footer-grid"><div><img decoding="async" class="footer-brand" src="assets/brand/kib-logo.png" alt="Kartódromo Internacional de Betim"><p>Pista homologada de 1.110 metros, kart de locação, campeonatos e estrutura para aniversários, grupos e empresas em Betim.</p></div><div><h3>Navegar</h3><div class="footer-links"><a href="pista.html">A pista</a><a href="kart-locacao.html">Kart de locação</a><a href="campeonatos.html">Campeonatos</a><a href="eventos.html">Eventos</a><a href="duvidas.html">Dúvidas</a></div></div><div><h3>Contato</h3><div class="footer-links"><a href="tel:+553135112373">(31) 3511‑2373</a><a href="https://wa.me/5531998842898" target="_blank" rel="noopener noreferrer">(31) 99884‑2898</a><span>Av. Adutora Várzea das Flores, 477<br>Betim, MG</span></div></div></div><div class="copyright"><span>© 2026 Kartódromo Internacional de Betim</span><span>Motorsport editorial experience</span></div></div></footer><a class="whatsapp-float" href="https://wa.me/5531998842898" target="_blank" rel="noopener noreferrer" aria-label="WhatsApp"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 11.5a8 8 0 0 1-11.9 7L4 20l1.5-4.1A8 8 0 1 1 20 11.5Z"/><path d="M8.5 8.5c.5 3 2 4.5 5 5"/></svg></a><div class="mobile-sticky"><a class="btn btn-primary" href="https://tools.mylaptime.com.br/booking?uid=5729bbc1-572b-4e32-84ec-e9e93ab08ced" target="_blank" rel="noopener noreferrer">Reservar</a><a class="btn btn-outline" href="https://wa.me/5531998842898" target="_blank" rel="noopener noreferrer">WhatsApp</a></div><script src="assets/js/site.js"></script></body></html>
Loading
Loading