Guia comercial
--
-
- Busca por comércios, categorias e mapa -
- Páginas de lojas com fotos, horário e WhatsApp -
- Favoritos, ranking e promoções simples -
- Contato direto por WhatsApp e canais oficiais -
diff --git a/.github/workflows/ci-deploy.yml b/.github/workflows/ci-deploy.yml index da4cb20..bfb5a6f 100644 --- a/.github/workflows/ci-deploy.yml +++ b/.github/workflows/ci-deploy.yml @@ -51,5 +51,12 @@ jobs: - name: Generate Prisma client run: npm run build + - name: Verify generated frontend + run: npm run frontend:check + + - name: Ensure generated frontend is not tracked + working-directory: . + run: test -z "$(git ls-files backend/public)" + - name: Run tests run: npm test diff --git a/AGENTS.md b/AGENTS.md index c23e87a..2bf2e0b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,6 +20,7 @@ Vitrine digital e guia comercial para **Boa Esperança do Sul — SP**. Conecta ``` raiz/ → frontend estático (index.html, css/, js/, html/) backend/ → API Express + public/ → artefato gerado e ignorado; nunca editar diretamente src/ server.js → entry point controllers/ → lógica de negócio @@ -41,9 +42,11 @@ npm run seed # popula banco com dados de data.json npm run db:push # aplica schema.prisma no banco npm run db:reset # reset + reseed npm run setup # install + migrate + seed (primeira vez) +npm run frontend:build # gera backend/public a partir da raiz canonica +npm run frontend:check # valida que o artefato corresponde a fonte ``` -Frontend: abrir `index.html` diretamente ou `npx serve . -p 8080` na raiz. +Frontend: a raiz e a unica fonte editavel. Abrir `index.html` diretamente ou `npx serve . -p 8080`; nunca alterar `backend/public`. Docker local/producao: @@ -88,9 +91,10 @@ https://api.comerciobes.com.br ## Fase atual -**v0.1 - Scope Reset** (em andamento) +**v0.2 - Production Baseline** (em andamento) - Carrinho, checkout, pedidos e pagamentos nao fazem parte do produto publico. - Interfaces, rotas e controllers do marketplace legado foram removidos; apenas tabelas historicas aguardam migracao controlada. +- A raiz e a fonte unica do frontend; `backend/public` e somente artefato de build. - O Braga Commerce e dono de catalogo transacional, estoque, pedido, pagamento, entrega e pos-venda. - A integracao com o Braga Commerce deve passar por um adapter read-only com contrato versionado. - A vitrine vanilla sera estabilizada antes de qualquer decisao de reescrita. diff --git a/CLAUDE.md b/CLAUDE.md index b5f2bd0..64aacdd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,6 +20,7 @@ Vitrine digital e guia comercial para **Boa Esperança do Sul — SP**. O Comerc ``` raiz/ → frontend estático (index.html, css/, js/, html/) backend/ → API Express + public/ → artefato gerado e ignorado; nunca editar diretamente src/ server.js → entry point controllers/ → lógica de negócio @@ -41,9 +42,11 @@ npm run seed # popula banco com dados de data.json npm run db:push # aplica schema.prisma no banco npm run db:reset # reset + reseed npm run setup # install + migrate + seed (primeira vez) +npm run frontend:build # gera backend/public a partir da raiz canonica +npm run frontend:check # valida que o artefato corresponde a fonte ``` -Frontend: abrir `index.html` diretamente ou `npx serve . -p 8080` na raiz. +Frontend: a raiz e a unica fonte editavel. Abrir `index.html` diretamente ou `npx serve . -p 8080`; nunca alterar `backend/public`. Docker local/producao: @@ -82,10 +85,11 @@ claude/* → worktrees do Claude Code (merge na dev ao final da sessão) ## Fase atual -**v0.1 - Scope Reset** (em andamento) +**v0.2 - Production Baseline** (em andamento) - Carrinho, checkout, pedidos, pagamentos e estoque nao fazem parte do produto. - Interfaces, APIs e dependencias transacionais foram removidas. - Tabelas historicas permanecem ate inventario, backup e migracao versionada. +- A raiz e a fonte unica do frontend; `backend/public` e somente artefato de build. - O Braga Commerce e dono da experiencia de compra. - A vitrine vanilla sera simplificada e estabilizada antes de qualquer reescrita. diff --git a/README.md b/README.md index a55055a..0b827d7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,18 @@ A decisao completa esta em [`docs/adr/0001-product-scope-and-braga-commerce.md`] - Proxy/SSL: Caddy. - Deploy: Docker Compose. +## Fonte do frontend + +`index.html`, `manifest.json`, `sw.js`, `css/`, `js/`, `html/`, `icons/`, `images/` e `data/` na raiz sao a unica fonte versionada do site. `backend/public/` e um artefato ignorado pelo Git: nunca edite ou versione arquivos ali. + +O build do backend recria o artefato e o check confirma que ele corresponde byte a byte a fonte: + +```bash +cd backend +npm run frontend:build +npm run frontend:check +``` + ## Subir com Docker Crie `.env` a partir de `.env.example` e troque senhas/chaves. @@ -67,6 +79,7 @@ URLs locais: ```bash cd backend npm run build +npm run frontend:check npm test npm audit --omit=dev --audit-level=high ``` diff --git a/backend/package.json b/backend/package.json index c35d02b..934d781 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,8 +7,10 @@ "postinstall": "node scripts/run-with-root-env.js prisma generate", "predev": "node scripts/ensure-prisma-client.js", "dev": "nodemon src/server.js", - "prestart": "node scripts/ensure-prisma-client.js && node scripts/copy-public-assets.js", - "build": "node scripts/run-with-root-env.js prisma generate && node scripts/copy-public-assets.js", + "prestart": "node scripts/ensure-prisma-client.js && npm run frontend:build", + "build": "node scripts/run-with-root-env.js prisma generate && npm run frontend:build", + "frontend:build": "node scripts/copy-public-assets.js", + "frontend:check": "node scripts/copy-public-assets.js --check", "start": "node src/server.js", "seed": "node src/seed.js", "db:generate": "node scripts/run-with-root-env.js prisma generate", diff --git a/backend/public/css/style.css b/backend/public/css/style.css deleted file mode 100644 index 64fec84..0000000 --- a/backend/public/css/style.css +++ /dev/null @@ -1,3199 +0,0 @@ - :root { - --verde: #10B981; - --verde-escuro: #047857; - --laranja: #EA580C; - --azul: #0D47A1; - --creme: #FAFAFA; - --escuro: #1E293B; - --cinza: #F8FAFC; - --texto: #334155; - --borda: #E2E8F0; - --transition-base: 0.2s ease-out; - - /* Light theme */ - --bg-light: #FFFFFF; - --bg-secondary-light: #F5F5F7; - --text-light: #1A1A1A; - --text-secondary-light: #666666; - --border-light: #E5E5E5; - - /* Dark theme */ - --bg-dark: #0B1120; - --bg-secondary-dark: #1E293B; - --text-dark: #F1F5F9; - --text-secondary-dark: #94A3B8; - --border-dark: #334155; - } - - body.dark-mode { - --creme: #0B1120; - --escuro: #F1F5F9; - --cinza: #1E293B; - --texto: #CBD5E1; - --borda: #334155; - } - - /* Tema escuro para topo/banner e botoes */ - body.dark-mode nav { - background: rgba(16, 16, 16, 0.92); - border-bottom-color: #2b2b2b; - } - - body.dark-mode .nav-logo { - color: #f2f2f2; - } - - body.dark-mode .nav-links a { - color: #dbdbdb; - } - - body.dark-mode .theme-toggle { - background: #181818; - border-color: #2f2f2f; - color: #f0f0f0; - } - - body.dark-mode .theme-toggle:hover { - background: var(--verde); - border-color: var(--verde); - color: #06140b; - } - - body.dark-mode .nav-login-btn { - background: var(--verde); - color: #08140c; - border: 1px solid #14a95a; - } - - body.dark-mode .nav-login-btn:hover { - background: var(--verde-escuro); - color: #fff; - } - - body.dark-mode .nav-icon-btn { - background: #181818; - border-color: #2f2f2f; - color: #f0f0f0; - } - - body.dark-mode .nav-icon-btn:hover { - background: var(--verde); - border-color: var(--verde); - color: #fff; - box-shadow: 0 4px 14px rgba(16,185,129,0.25); - } - - body.dark-mode .nav-icon-btn .btn-tooltip { - background: #0f0f0f; - color: #f1f1f1; - border: 1px solid #2b2b2b; - } - - body.dark-mode .hero { - background: - radial-gradient(ellipse 700px 500px at 5% 30%, rgba(16,185,129,0.06) 0%, transparent 65%), - radial-gradient(ellipse 500px 400px at 85% 70%, rgba(234,88,12,0.04) 0%, transparent 65%), - var(--creme); - border-color: var(--borda); - box-shadow: 0 18px 60px rgba(0, 0, 0, 0.35); - } - - body.dark-mode .hero::before { - background: radial-gradient(circle, rgba(16,185,129,0.14) 0%, rgba(16,185,129,0) 70%); - } - - body.dark-mode .hero h1 { - color: var(--escuro); - } - - body.dark-mode .hero h1 em { - color: var(--verde); - } - - body.dark-mode .hero p { - color: #b8b8b8; - } - - body.dark-mode .hero-label { - background: #1b1b1b; - border-color: #303030; - color: #c3c3c3; - } - - body.dark-mode .search-box { - background: #171717; - border-color: #2f2f2f; - box-shadow: 0 8px 40px rgba(0,0,0,0.35); - } - - body.dark-mode .search-box input { - color: #f0f0f0; - } - - body.dark-mode .search-box input::placeholder { - color: #868686; - } - - body.dark-mode .search-tag { - background: #171717; - border-color: #2f2f2f; - color: #d0d0d0; - } - - /* Tema escuro para categorias */ - body.dark-mode .cat-chip { - background: #151515; - border-color: #2c2c2c; - color: #dcdcdc; - } - - body.dark-mode .cat-chip:hover, - body.dark-mode .cat-chip.active { - background: var(--verde); - border-color: var(--verde); - color: #07120b; - } - - /* Tema escuro para promocoes */ - body.dark-mode .promos-section { - background: #101010; - border-top-color: #2d2d2d; - border-bottom-color: #2d2d2d; - } - - body.dark-mode .promos-title { - color: #f0f0f0; - } - - body.dark-mode .ver-todas { - color: #9bcbb4; - border-bottom-color: #3f6f59; - } - - body.dark-mode .ver-todas:hover { - color: #ffffff; - } - - body.dark-mode .promo-card { - background: #171717; - border-color: #2d2d2d; - } - - body.dark-mode .promo-card:hover { - background: #1d1d1d; - border-color: var(--verde); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); - } - - body.dark-mode .promo-store { - color: #f4f4f4; - } - - body.dark-mode .promo-desc { - color: #b5b5b5; - } - - body.dark-mode .promo-original { - color: #8a8a8a; - } - - /* Tema escuro para cards/listagens */ - body.dark-mode .store-card { - background: #151515; - border-color: #2d2d2d; - } - - body.dark-mode .store-card:hover { - border-color: var(--verde); - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.38); - } - - body.dark-mode .store-name, - body.dark-mode .store-rating-num { - color: #f3f3f3; - } - - body.dark-mode .card-fav { color: #555; } - body.dark-mode .card-fav:hover { color: var(--laranja); } - body.dark-mode .card-fav.active { color: var(--laranja); } - - body.dark-mode .store-addr, - body.dark-mode .store-reviews { - color: #a0a0a0; - } - - body.dark-mode .btn-perfil { - background: #232323; - color: #f0f0f0; - } - - body.dark-mode .btn-perfil:hover { - background: #2f2f2f; - } - - /* Tema escuro para modal de detalhes da loja */ - body.dark-mode .modal { - background: rgba(30,41,59,0.90); - border: 1px solid rgba(255,255,255,0.08); - } - - body.dark-mode .modal-name, - body.dark-mode .modal-rating-big { - color: #f2f2f2; - } - - body.dark-mode .modal-info-row { - color: #b7b7b7; - } - - body.dark-mode .modal-divider { - border-top-color: #2f2f2f; - } - - body.dark-mode .review-input { - background: #1a1a1a; - color: #eeeeee; - border-color: #2f2f2f; - } - - body.dark-mode .review-input::placeholder { - color: #8b8b8b; - } - - body.dark-mode .btn-maps { - background: #1c1c1c; - border-color: #2f2f2f; - color: #efefef; - } - - body.dark-mode .btn-maps:hover { - background: #272727; - } - - /* Tema escuro para footer */ - body.dark-mode footer { - background: #0f0f0f; - color: #a2a2a2; - border-top-color: #2b2b2b; - } - - body.dark-mode .footer-brand, - body.dark-mode .footer-col h4 { - color: #f1f1f1; - } - - body.dark-mode .footer-col a { - color: #b3b3b3; - } - - body.dark-mode .footer-col a:hover { - color: var(--verde); - } - - body.dark-mode .footer-bottom { - border-top-color: #2b2b2b; - color: #9f9f9f; - } - - /* Tema escuro para FAB */ - body.dark-mode .fab { - background: var(--verde); - color: #06140b; - border: 1px solid #14a95a; - } - - body.dark-mode .fab:hover { - background: #17df72; - color: #041109; - } - - /* Tema escuro para ranking */ - body.dark-mode .ranking-section { - background: #101010; - } - - body.dark-mode .ranking-title { - color: #f2f2f2; - } - - body.dark-mode .ranking-tab { - background: #171717; - border-color: #2e2e2e; - color: #d7d7d7; - } - - body.dark-mode .ranking-tab.active, - body.dark-mode .ranking-tab:hover { - background: var(--verde); - border-color: var(--verde); - color: #06140b; - } - - body.dark-mode .ranking-item { - background: #171717; - border-color: #2e2e2e; - } - - body.dark-mode .ranking-item:hover { - border-color: var(--verde); - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35); - } - - body.dark-mode .rank-name { - color: #f2f2f2; - } - - body.dark-mode .rank-cat, - body.dark-mode .rank-score span { - color: #a8a8a8; - } - - body.dark-mode .rank-score strong { - color: #33d879; - } - - * { margin: 0; padding: 0; box-sizing: border-box; } - - html { scroll-behavior: smooth; } - - body { - font-family: 'Inter', sans-serif; - background: var(--creme); - color: var(--texto); - overflow-x: hidden; - transition: background 0.3s ease, color 0.3s ease; - } - - .icon { - width: 1em; - height: 1em; - stroke: currentColor; - fill: none; - stroke-width: 2; - stroke-linecap: round; - stroke-linejoin: round; - vertical-align: middle; - flex-shrink: 0; - } - - .icon-xs { width: 14px; height: 14px; } - .icon-sm { width: 16px; height: 16px; } - .icon-md { width: 18px; height: 18px; } - .icon-lg { width: 22px; height: 22px; } - - .with-icon { - display: inline-flex; - align-items: center; - gap: 8px; - } - - h1, h2, h3, h4 { font-family: 'Plus Jakarta Sans', sans-serif; } - - /* ===== WELCOME SCREEN ===== */ - #welcome-screen { - position: fixed; - inset: 0; - background: linear-gradient(145deg, #e8f5ed 0%, #d8efdf 100%); - z-index: 9999; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - transition: opacity 0.8s ease, visibility 0.8s ease; - } - - #welcome-screen.hidden { - opacity: 0; - visibility: hidden; - pointer-events: none; - } - - .welcome-bg { - position: absolute; - inset: 0; - overflow: hidden; - } - - .welcome-bg::before { - content: ''; - position: absolute; - width: 600px; - height: 600px; - background: radial-gradient(circle, rgba(16,185,129,0.15) 0%, transparent 70%); - top: -100px; - left: -100px; - animation: pulse-glow 4s ease-in-out infinite; - } - - .welcome-bg::after { - content: ''; - position: absolute; - width: 500px; - height: 500px; - background: radial-gradient(circle, rgba(255,109,0,0.12) 0%, transparent 70%); - bottom: -100px; - right: -50px; - animation: pulse-glow 4s ease-in-out infinite 2s; - } - - @keyframes pulse-glow { - 0%, 100% { transform: scale(1); opacity: 0.5; } - 50% { transform: scale(1.2); opacity: 1; } - } - - .welcome-grid { - position: absolute; - inset: 0; - background-image: - linear-gradient(rgba(16,185,129,0.04) 1px, transparent 1px), - linear-gradient(90deg, rgba(16,185,129,0.04) 1px, transparent 1px); - background-size: 60px 60px; - } - - .welcome-content { - position: relative; - z-index: 2; - text-align: center; - padding: 20px; - } - - .welcome-badge { - display: inline-block; - background: rgba(16,185,129,0.15); - border: 1px solid rgba(16,185,129,0.25); - color: var(--verde); - font-size: 12px; - font-weight: 500; - letter-spacing: 3px; - text-transform: uppercase; - padding: 6px 20px; - border-radius: 100px; - margin-bottom: 32px; - animation: fadeInDown 0.8s ease 0.3s both; - } - - .welcome-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: clamp(52px, 10vw, 120px); - font-weight: 800; - color: #1b4a39; - line-height: 0.9; - animation: fadeInUp 0.8s ease 0.5s both; - } - - .welcome-title span { - color: var(--verde); - } - - .welcome-subtitle { - font-size: clamp(16px, 3vw, 22px); - color: #4a6b5d; - margin-top: 20px; - font-weight: 300; - animation: fadeInUp 0.8s ease 0.7s both; - } - - .welcome-city { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: clamp(14px, 2vw, 18px); - color: #668879; - letter-spacing: 6px; - text-transform: uppercase; - margin-top: 12px; - animation: fadeInUp 0.8s ease 0.9s both; - } - - .welcome-btn { - margin-top: 52px; - background: var(--verde); - color: #000; - border: none; - padding: 18px 52px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 16px; - font-weight: 700; - letter-spacing: 1px; - border-radius: 100px; - cursor: pointer; - animation: fadeInUp 0.8s ease 1.1s both; - transition: all 0.3s ease; - position: relative; - overflow: hidden; - } - - .welcome-btn::before { - content: ''; - position: absolute; - inset: 0; - background: rgba(255,255,255,0.2); - transform: translateX(-100%); - transition: transform 0.3s ease; - } - - .welcome-btn:hover::before { transform: translateX(0); } - .welcome-btn:hover { transform: scale(1.05); box-shadow: 0 0 40px rgba(16,185,129,0.4); } - - .welcome-stats { - display: flex; - gap: 48px; - margin-top: 60px; - animation: fadeInUp 0.8s ease 1.3s both; - } - - .welcome-stat { - text-align: center; - } - - .welcome-stat strong { - display: block; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 32px; - font-weight: 800; - color: #1b4a39; - } - - .welcome-stat span { - font-size: 12px; - color: #668879; - letter-spacing: 1px; - text-transform: uppercase; - } - - @keyframes fadeInUp { - from { opacity: 0; transform: translateY(30px); } - to { opacity: 1; transform: translateY(0); } - } - - @keyframes fadeInDown { - from { opacity: 0; transform: translateY(-20px); } - to { opacity: 1; transform: translateY(0); } - } - - /* ===== MAIN SITE ===== */ - #main-site { - opacity: 1; - } - - /* ===== NAVBAR ===== */ - nav { - position: sticky; - top: 0; - z-index: 100; - background: var(--creme); - border-bottom: 1px solid var(--borda); - padding: 0 24px; - transition: background var(--transition-base), backdrop-filter var(--transition-base), box-shadow var(--transition-base); - } - - nav.scrolled { - background: rgba(250,250,250,0.82); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - box-shadow: 0 1px 0 rgba(0,0,0,0.06); - border-bottom-color: transparent; - } - - body.dark-mode nav.scrolled { - background: rgba(11,17,32,0.85); - } - - .nav-inner { - max-width: 1300px; - margin: 0 auto; - display: grid; - grid-template-columns: auto 1fr auto; - align-items: center; - height: 64px; - gap: 20px; - } - - .nav-logo { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 22px; - font-weight: 800; - color: var(--escuro); - text-decoration: none; - } - - .nav-logo span { color: var(--verde); } - - .nav-links { - display: flex; - gap: 8px; - list-style: none; - justify-self: center; - } - - .nav-links a { - text-decoration: none; - color: var(--texto); - font-size: 14px; - font-weight: 500; - padding: 8px 16px; - border-radius: 100px; - transition: all 0.2s; - display: inline-flex; - align-items: center; - gap: 6px; - } - - .nav-links a:hover, - .nav-links a.active { - background: var(--verde); - color: #000; - } - - .nav-right-section { - display: flex; - align-items: center; - gap: 12px; - justify-self: end; - margin-left: auto; - } - - .theme-toggle { - width: 40px; - height: 40px; - border-radius: 50%; - border: 1.5px solid var(--borda); - background: transparent; - color: var(--texto); - cursor: pointer; - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.3s ease; - flex-shrink: 0; - } - - .theme-toggle:hover { - background: var(--verde); - border-color: var(--verde); - color: #000; - transform: rotate(20deg); - } - - /* ===== HERO ===== */ - .hero { - padding: 72px 24px 60px; - text-align: center; - max-width: 900px; - margin: 24px auto 0; - background: - radial-gradient(ellipse 700px 500px at 5% 30%, rgba(16,185,129,0.07) 0%, transparent 65%), - radial-gradient(ellipse 500px 400px at 85% 70%, rgba(234,88,12,0.05) 0%, transparent 65%), - var(--creme); - border: 1px solid var(--borda); - border-radius: 32px; - box-shadow: 0 18px 60px rgba(0,0,0,0.06); - position: relative; - overflow: hidden; - } - - .hero::before { - content: ''; - position: absolute; - width: 220px; - height: 220px; - border-radius: 50%; - background: radial-gradient(circle, rgba(16,185,129,0.12) 0%, rgba(16,185,129,0) 70%); - top: -60px; - right: -40px; - pointer-events: none; - } - - .hero-label { - display: inline-flex; - align-items: center; - gap: 8px; - background: #fff; - border: 1px solid var(--borda); - padding: 6px 18px; - border-radius: 100px; - font-size: 13px; - color: #666; - margin-bottom: 28px; - } - - .hero-label .dot { - width: 8px; - height: 8px; - background: var(--verde); - border-radius: 50%; - animation: blink 2s ease-in-out infinite; - } - - @keyframes blink { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.3; } - } - - .hero h1 { - font-size: clamp(36px, 6vw, 72px); - font-weight: 800; - line-height: 1.05; - color: var(--escuro); - margin-bottom: 16px; - } - - .hero h1 em { - font-style: normal; - color: var(--verde); - position: relative; - } - - .hero p { - font-size: 18px; - color: #666; - font-weight: 300; - margin-bottom: 40px; - } - - /* ===== SEARCH ===== */ - .search-box { - background: #fff; - border: 2px solid var(--borda); - border-radius: 20px; - padding: 8px; - display: flex; - gap: 8px; - max-width: 700px; - margin: 0 auto 20px; - box-shadow: 0 8px 40px rgba(0,0,0,0.06); - transition: border-color 0.2s, box-shadow 0.2s; - } - - .search-box:focus-within { - border-color: var(--verde); - box-shadow: 0 8px 40px rgba(16,185,129,0.12); - } - - .search-box input { - flex: 1; - border: none; - outline: none; - font-size: 18px; - font-family: 'Inter', sans-serif; - background: transparent; - padding: 12px 16px; - color: var(--texto); - } - - .search-box input::placeholder { color: #bbb; } - - .search-btn { - background: var(--verde-escuro); - color: #fff; - border: none; - padding: 14px 28px; - border-radius: 14px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 15px; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - display: flex; - align-items: center; - gap: 8px; - white-space: nowrap; - } - - .search-btn:hover { background: var(--verde-escuro); color: #fff; transform: scale(1.02); } - - .search-tags { - display: flex; - flex-wrap: wrap; - gap: 8px; - justify-content: center; - margin-bottom: 16px; - } - - .search-tag { - background: #fff; - border: 1px solid var(--borda); - padding: 6px 14px; - border-radius: 100px; - font-size: 13px; - cursor: pointer; - transition: all 0.2s; - color: #555; - display: inline-flex; - align-items: center; - gap: 6px; - } - - .search-tag:hover { - background: var(--verde); - border-color: var(--verde); - color: #000; - font-weight: 500; - } - - /* ===== CATEGORY CHIPS ===== */ - .categories { - padding: 32px 24px; - max-width: 1300px; - margin: 0 auto; - } - - .section-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 700; - letter-spacing: 3px; - text-transform: uppercase; - color: #999; - margin-bottom: 20px; - } - - .cat-grid { - display: flex; - flex-wrap: wrap; - gap: 10px; - } - - .cat-chip { - display: flex; - align-items: center; - gap: 8px; - background: #fff; - border: 1.5px solid var(--borda); - padding: 10px 20px; - border-radius: 100px; - font-size: 14px; - font-weight: 500; - cursor: pointer; - transition: all 0.2s; - color: var(--texto); - } - - .cat-chip:hover, - .cat-chip.active { - background: var(--escuro); - border-color: var(--escuro); - color: #fff; - transform: translateY(-2px); - box-shadow: 0 4px 16px rgba(0,0,0,0.15); - } - - /* ===== PROMOS ===== */ - .promos-section { - padding: 48px 24px; - background: #e8f5ed; - position: relative; - overflow: hidden; - border-top: 1px solid var(--borda); - border-bottom: 1px solid var(--borda); - } - - .promos-section::before { - content: ''; - position: absolute; - inset: 0; - background: - repeating-linear-gradient( - 45deg, - rgba(255, 108, 0, 0.12) 0px, - rgba(255, 108, 0, 0.12) 80px, - rgba(255, 152, 0, 0.08) 80px, - rgba(255, 152, 0, 0.08) 160px, - rgba(255, 193, 7, 0.06) 160px, - rgba(255, 193, 7, 0.06) 240px, - transparent 240px, - transparent 320px - ); - background-size: 320px 320px; - animation: slideFireBands 8s linear infinite; - pointer-events: none; - } - - @keyframes slideFireBands { - from { background-position: 0 0; } - to { background-position: 320px 320px; } - } - - .promos-section::after { - content: ''; - position: absolute; - inset: 0; - background: - repeating-linear-gradient( - -45deg, - rgba(255, 61, 0, 0.1) 0px, - rgba(255, 61, 0, 0.1) 100px, - rgba(255, 109, 0, 0.07) 100px, - rgba(255, 109, 0, 0.07) 200px, - transparent 200px, - transparent 300px - ); - background-size: 300px 300px; - animation: slideFireBandsReverse 10s linear infinite; - pointer-events: none; - } - - @keyframes slideFireBandsReverse { - from { background-position: 0 0; } - to { background-position: -300px -300px; } - } - - .promos-inner { - max-width: 1300px; - margin: 0 auto; - } - - .promos-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 28px; - flex-wrap: wrap; - gap: 16px; - } - - .promos-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 32px; - font-weight: 800; - color: var(--texto); - display: flex; - align-items: center; - gap: 10px; - } - - .promos-title span { color: var(--laranja); } - - .ver-todas { - color: #527867; - text-decoration: none; - font-size: 14px; - border-bottom: 1px solid #8fb9a5; - transition: color 0.2s; - } - .ver-todas:hover { color: var(--texto); } - - .promos-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 16px; - } - - .promo-card { - background: #ffffff; - border: 1px solid var(--borda); - border-radius: 16px; - padding: 24px; - transition: transform var(--transition-base), box-shadow var(--transition-base); - cursor: pointer; - position: relative; - overflow: hidden; - } - - .promo-card::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, rgba(16,185,129,0.04) 0%, transparent 60%); - opacity: 0; - transition: opacity var(--transition-base); - } - - .promo-card:hover { - transform: translateY(-4px); - border-color: var(--borda); - background: #ffffff; - box-shadow: 0 10px 30px rgba(0,0,0,0.06); - } - - .promo-card:hover::before { opacity: 1; } - - .promo-badge { - display: inline-block; - background: var(--laranja); - color: #fff; - font-size: 11px; - font-weight: 700; - letter-spacing: 1px; - text-transform: uppercase; - padding: 4px 12px; - border-radius: 100px; - margin-bottom: 14px; - } - - .promo-store { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 18px; - font-weight: 700; - color: var(--texto); - margin-bottom: 8px; - } - - .promo-desc { - font-size: 14px; - color: #4f6f61; - line-height: 1.5; - margin-bottom: 16px; - } - - .promo-price { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 24px; - font-weight: 800; - color: var(--verde); - } - - .promo-original { - font-size: 14px; - color: #86a899; - text-decoration: line-through; - margin-left: 8px; - } - - /* ===== COMMERCE LISTINGS ===== */ - .listings-section { - padding: 48px 24px; - max-width: 1300px; - margin: 0 auto; - } - - .listings-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 28px; - flex-wrap: wrap; - gap: 16px; - } - - .listings-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 28px; - font-weight: 800; - color: var(--escuro); - display: flex; - align-items: center; - gap: 10px; - } - - .sort-select { - border: 1.5px solid var(--borda); - background: #fff; - padding: 8px 16px; - border-radius: 100px; - font-family: 'Inter', sans-serif; - font-size: 14px; - cursor: pointer; - outline: none; - } - - .listings-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); - gap: 20px; - } - - .store-card { - background: #fff; - border: 1.5px solid var(--borda); - border-radius: 20px; - overflow: hidden; - transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base); - cursor: pointer; - position: relative; - } - - .store-card:hover { - transform: translateY(-4px); - box-shadow: 0 12px 40px -8px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.04); - border-color: var(--borda); - } - - .store-img { - height: 200px; - background: var(--cinza); - background-size: cover; - background-position: center; - position: relative; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; - font-size: 60px; - transition: background-position 0.4s ease; - } - - .store-card:hover .store-img { - background-position: center 40%; - } - - .store-img img { - width: 100%; - height: 100%; - object-fit: cover; - transition: transform 0.4s ease; - } - - .store-card:hover .store-img img { - transform: scale(1.08); - } - - .store-img-bg { - position: absolute; - inset: 0; - background-size: cover; - background-position: center; - transition: transform 0.4s ease; - } - - .store-card:hover .store-img-bg { transform: scale(1.05); } - - .store-rank { - position: absolute; - top: 12px; - left: 12px; - background: rgba(0,0,0,0.7); - backdrop-filter: blur(8px); - color: #fff; - font-size: 12px; - font-weight: 700; - padding: 4px 10px; - border-radius: 100px; - display: flex; - align-items: center; - gap: 4px; - } - - .store-open { - position: absolute; - top: 12px; - right: 12px; - background: var(--verde); - color: #000; - font-size: 11px; - font-weight: 700; - padding: 4px 10px; - border-radius: 100px; - } - - .store-closed { - background: #ff4444; - color: #fff; - } - - .store-destaque { - position: absolute; - top: 12px; - left: 12px; - background: var(--laranja); - color: #fff; - font-size: 11px; - font-weight: 700; - padding: 4px 10px; - border-radius: 100px; - } - - .store-card-destaque { - border: 2px solid var(--laranja); - box-shadow: 0 4px 24px rgba(255, 109, 0, 0.15); - } - - body.dark-mode .store-card-destaque { - border-color: var(--laranja); - box-shadow: 0 4px 24px rgba(255, 109, 0, 0.25); - } - - .store-body { - padding: 20px; - } - - .store-cat { - font-size: 11px; - font-weight: 600; - letter-spacing: 2px; - text-transform: uppercase; - color: var(--verde-escuro); - margin-bottom: 6px; - } - - .store-name-row { - display: flex; - align-items: flex-start; - justify-content: space-between; - gap: 8px; - margin-bottom: 8px; - } - - .store-name { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 20px; - font-weight: 700; - } - - .card-fav { - flex-shrink: 0; - background: none; - border: none; - cursor: pointer; - font-size: 20px; - color: #ccc; - padding: 0; - line-height: 1; - margin-top: 3px; - transition: color 0.2s, transform 0.15s; - } - - .card-fav:hover { color: var(--laranja); transform: scale(1.2); } - .card-fav.active { color: var(--laranja); } - - .store-addr { - font-size: 13px; - color: #888; - display: flex; - align-items: center; - gap: 4px; - margin-bottom: 12px; - } - - .store-stars { - display: flex; - align-items: center; - gap: 4px; - margin-bottom: 16px; - } - - .star { color: #FFB800; font-size: 14px; } - .star-empty { color: #ddd; font-size: 14px; } - .store-rating-num { - font-size: 13px; - font-weight: 600; - color: var(--texto); - margin-left: 4px; - } - .store-reviews { font-size: 12px; color: #aaa; } - - .store-actions { - display: flex; - gap: 8px; - } - - .btn-whats { - flex: 1; - background: #25D366; - color: #fff; - border: none; - padding: 12px; - border-radius: 12px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 700; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - gap: 6px; - transition: all 0.2s; - text-decoration: none; - } - - .btn-whats:hover { background: #128C7E; transform: scale(1.02); } - - .btn-catalogo { - background: var(--cinza); - color: var(--texto); - border: 1.5px solid var(--borda); - padding: 12px 14px; - border-radius: 12px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: all 0.2s; - white-space: nowrap; - } - - .btn-catalogo:hover { border-color: var(--verde); color: var(--verde); background: rgba(16,185,129,0.06); } - - .btn-perfil { - background: var(--cinza); - border: 1.5px solid var(--borda); - padding: 12px 16px; - border-radius: 12px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: all 0.2s; - color: var(--texto); - white-space: nowrap; - } - - .btn-perfil:hover { background: var(--borda); } - - /* ===== RANKING ===== */ - .ranking-section { - padding: 48px 24px; - background: var(--cinza); - } - - .ranking-inner { - max-width: 1300px; - margin: 0 auto; - } - - .ranking-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 32px; - font-weight: 800; - margin-bottom: 32px; - color: var(--escuro); - display: flex; - align-items: center; - gap: 10px; - } - - .ranking-tabs { - display: flex; - gap: 8px; - margin-bottom: 28px; - flex-wrap: wrap; - } - - .ranking-tab { - padding: 10px 24px; - border-radius: 100px; - border: 1.5px solid var(--borda); - background: #fff; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - color: var(--texto); - display: flex; - align-items: center; - gap: 6px; - } - - .ranking-tab.active, - .ranking-tab:hover { - background: var(--escuro); - border-color: var(--escuro); - color: #fff; - } - - .ranking-list { - display: flex; - flex-direction: column; - gap: 12px; - } - - .ranking-item { - background: #fff; - border: 1.5px solid var(--borda); - border-radius: 16px; - padding: 20px 24px; - display: flex; - align-items: center; - gap: 20px; - transition: all 0.2s; - cursor: pointer; - } - - .ranking-item:hover { - border-color: var(--verde); - transform: translateX(4px); - box-shadow: 0 4px 20px rgba(0,0,0,0.06); - } - - .rank-num { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 28px; - font-weight: 800; - color: var(--borda); - min-width: 44px; - text-align: center; - } - - .rank-num.top1 { color: #FFB800; } - .rank-num.top2 { color: #C0C0C0; } - .rank-num.top3 { color: #CD7F32; } - - .rank-emoji { - font-size: 36px; - min-width: 48px; - text-align: center; - } - - .rank-info { flex: 1; } - - .rank-name { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 18px; - font-weight: 700; - } - - .rank-cat { - font-size: 13px; - color: #999; - margin-top: 2px; - } - - .rank-score { - text-align: right; - } - - .rank-score strong { - display: block; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 22px; - font-weight: 800; - color: var(--verde-escuro); - } - - .rank-score span { - font-size: 12px; - color: #aaa; - } - - /* ===== MAP SECTION ===== */ - .map-section { - padding: 48px 24px; - max-width: 1300px; - margin: 0 auto; - } - - .map-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 32px; - font-weight: 800; - margin-bottom: 8px; - color: var(--escuro); - display: flex; - align-items: center; - gap: 10px; - } - - .map-sub { - color: #888; - font-size: 15px; - margin-bottom: 28px; - } - - .map-container { - border-radius: 20px; - overflow: hidden; - border: 1.5px solid var(--borda); - height: 480px; - position: relative; - background: var(--cinza); - } - - .map-container iframe { - width: 100%; - height: 100%; - border: none; - } - - .map-legend { - position: absolute; - bottom: 16px; - left: 16px; - background: #fff; - border-radius: 12px; - padding: 12px 16px; - box-shadow: 0 4px 20px rgba(0,0,0,0.1); - font-size: 13px; - } - - .map-legend-item { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: 6px; - color: #555; - } - - .map-legend-item:last-child { margin-bottom: 0; } - .map-dot { width: 10px; height: 10px; border-radius: 50%; } - - /* ===== SEARCH RESULTS ===== */ - #search-results { - display: none; - padding: 32px 24px; - max-width: 1300px; - margin: 0 auto; - } - - .results-header { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 22px; - font-weight: 700; - margin-bottom: 20px; - padding-bottom: 16px; - border-bottom: 2px solid var(--borda); - } - - .results-header span { color: var(--verde); } - - #no-results { - display: none; - text-align: center; - padding: 60px 24px; - color: #aaa; - } - - #no-results h3 { - font-size: 48px; - margin-bottom: 12px; - } - - /* ===== MODAL PERFIL ===== */ - .modal-overlay { - display: none; - position: fixed; - inset: 0; - background: rgba(0,0,0,0.6); - backdrop-filter: blur(8px); - z-index: 1000; - align-items: center; - justify-content: center; - padding: 20px; - } - - .modal-overlay.open { display: flex; } - - .modal { - background: rgba(255,255,255,0.92); - backdrop-filter: blur(24px); - -webkit-backdrop-filter: blur(24px); - border: 1px solid rgba(255,255,255,0.6); - border-radius: 24px; - max-width: 640px; - width: 100%; - max-height: 90vh; - overflow-y: auto; - box-shadow: 0 20px 60px -12px rgba(0,0,0,0.18); - animation: modalIn 0.3s ease; - } - - @keyframes modalIn { - from { opacity: 0; transform: scale(0.95) translateY(20px); } - to { opacity: 1; transform: scale(1) translateY(0); } - } - - .modal-img { - height: 220px; - background: var(--cinza); - background-size: cover; - background-position: center; - position: relative; - display: flex; - align-items: center; - justify-content: center; - font-size: 80px; - } - - .modal-img.has-photo::after { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(to bottom, rgba(0,0,0,0.35) 0%, transparent 55%); - pointer-events: none; - } - - .modal-img.has-photo .modal-close, - .modal-img.has-photo .modal-fav { - z-index: 1; - } - - .modal-close { - position: absolute; - top: 16px; - right: 16px; - background: rgba(0,0,0,0.5); - color: #fff; - border: none; - width: 36px; - height: 36px; - border-radius: 50%; - font-size: 18px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: background 0.2s; - } - - .modal-close:hover { background: rgba(0,0,0,0.8); } - - .modal-body { padding: 28px; } - - .modal-cat { - font-size: 11px; - font-weight: 700; - letter-spacing: 2px; - text-transform: uppercase; - color: var(--verde-escuro); - margin-bottom: 8px; - } - - .modal-name { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 28px; - font-weight: 800; - margin-bottom: 16px; - } - - .modal-info { - display: flex; - flex-direction: column; - gap: 12px; - margin-bottom: 24px; - } - - .modal-info-row { - display: flex; - align-items: flex-start; - gap: 12px; - font-size: 15px; - color: #555; - } - - .modal-info-icon { - font-size: 18px; - min-width: 24px; - } - - .modal-divider { - border: none; - border-top: 1px solid var(--borda); - margin: 20px 0; - } - - .modal-stars-big { - display: flex; - align-items: center; - gap: 6px; - margin-bottom: 20px; - } - - .modal-stars-big .star { font-size: 22px; } - .modal-rating-big { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 28px; - font-weight: 800; - } - - .modal-actions { - display: flex; - flex-direction: column; - gap: 10px; - } - - .btn-whats-big { - background: #25D366; - color: #fff; - border: none; - padding: 16px; - border-radius: 14px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 16px; - font-weight: 700; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - text-decoration: none; - transition: all 0.2s; - } - - .btn-whats-big:hover { background: #128C7E; transform: scale(1.01); } - - .btn-maps { - background: var(--cinza); - color: var(--texto); - border: 1.5px solid var(--borda); - padding: 14px; - border-radius: 14px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 700; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - text-decoration: none; - transition: all 0.2s; - } - - .btn-maps:hover { background: var(--borda); } - - .btn-compartilhar { - background: transparent; - color: var(--texto); - border: 1.5px solid var(--borda); - padding: 14px; - border-radius: 14px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 600; - cursor: pointer; - width: 100%; - transition: all 0.2s; - } - - .btn-compartilhar:hover { background: var(--borda); } - - .carrinho-actions { - display: flex; - gap: 10px; - margin-top: 12px; - } - - .btn-add-cart { - flex: 1; - background: var(--verde); - color: #000; - border: none; - padding: 14px; - border-radius: 12px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - } - - .btn-add-cart:hover { background: var(--verde-escuro); color: #fff; } - - .btn-enviar-pedido { - flex: 1; - background: #25D366; - color: #fff; - border: none; - padding: 14px; - border-radius: 12px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - } - - .btn-enviar-pedido:hover { background: #128C7E; } - - /* ===== AUTH GATE NO MODAL ===== */ - .auth-gate-modal { - margin-top: 20px; - background: var(--cinza); - border: 1.5px solid var(--borda); - border-radius: 16px; - padding: 28px 20px 24px; - text-align: center; - opacity: 0; - transform: translateY(12px); - transition: opacity 0.25s ease, transform 0.25s ease; - } - - .auth-gate-modal.visible { - opacity: 1; - transform: translateY(0); - } - - .auth-gate-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - font-size: 17px; - color: var(--texto); - margin-bottom: 6px; - } - - .auth-gate-sub { - font-size: 13px; - color: #888; - margin-bottom: 20px; - } - - .auth-gate-btn-create { - display: block; - background: var(--verde); - color: #000; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - font-size: 15px; - padding: 14px; - border-radius: 12px; - text-decoration: none; - margin-bottom: 12px; - transition: transform 0.15s, box-shadow 0.15s; - } - - .auth-gate-btn-create:hover { - transform: scale(1.02); - box-shadow: 0 6px 20px rgba(16,185,129,0.25); - } - - .auth-gate-btn-login { - display: block; - font-size: 13px; - color: var(--verde-escuro); - text-decoration: none; - padding: 6px; - } - - .auth-gate-btn-login:hover { text-decoration: underline; } - - body.dark-mode .auth-gate-modal { - background: #1a1a1a; - border-color: #2a2a2a; - } - - body.dark-mode .auth-gate-sub { color: #666; } - body.dark-mode .auth-gate-btn-login { color: var(--verde); } - - /* ===== FOTO GALERIA ===== */ - .foto-galeria { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 8px; - margin-bottom: 20px; - } - - .foto-thumb { - aspect-ratio: 1; - background: var(--cinza); - border-radius: 8px; - overflow: hidden; - display: flex; - align-items: center; - justify-content: center; - font-size: 28px; - cursor: pointer; - transition: transform 0.2s; - } - - .foto-thumb:hover { transform: scale(1.03); } - - .foto-thumb img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; - border-radius: 8px; - } - - .foto-thumb[onclick] { cursor: zoom-in; } - - .foto-emoji { - font-size: 32px; - pointer-events: none; - } - - /* ===== MAPA EMBED ===== */ - .modal-mapa-wrap { - margin: 16px 0 20px; - border-radius: 12px; - overflow: hidden; - border: 1.5px solid var(--borda); - } - - .modal-mapa-wrap iframe { - width: 100%; - height: 200px; - border: none; - display: block; - } - - /* ===== LIGHTBOX ===== */ - .lightbox-overlay { - display: none; - position: fixed; - inset: 0; - z-index: 9999; - background: rgba(0, 0, 0, 0.92); - align-items: center; - justify-content: center; - } - - .lightbox-overlay.open { display: flex; } - - .lightbox-img { - max-width: 90vw; - max-height: 85vh; - object-fit: contain; - border-radius: 8px; - box-shadow: 0 8px 48px rgba(0,0,0,0.5); - user-select: none; - } - - .lightbox-close { - position: absolute; - top: 20px; right: 24px; - background: rgba(255,255,255,0.12); - border: none; - color: #fff; - font-size: 22px; - width: 44px; height: 44px; - border-radius: 50%; - cursor: pointer; - display: flex; align-items: center; justify-content: center; - transition: background 0.2s; - } - - .lightbox-close:hover { background: rgba(255,255,255,0.25); } - - .lightbox-nav { - position: absolute; - top: 50%; - transform: translateY(-50%); - background: rgba(255,255,255,0.12); - border: none; - color: #fff; - font-size: 36px; - width: 52px; height: 52px; - border-radius: 50%; - cursor: pointer; - display: flex; align-items: center; justify-content: center; - transition: background 0.2s; - line-height: 1; - } - - .lightbox-nav:hover { background: rgba(255,255,255,0.25); } - .lightbox-prev { left: 20px; } - .lightbox-next { right: 20px; } - - .lightbox-counter { - position: absolute; - bottom: 24px; - left: 50%; - transform: translateX(-50%); - color: rgba(255,255,255,0.6); - font-size: 13px; - font-family: 'DM Sans', sans-serif; - } - - /* ===== PUBLIC ROADMAP ===== */ - .public-roadmap { - margin: 64px 24px 0; - padding: 56px 0; - background: #f8fafc; - border-top: 1px solid var(--borda); - border-bottom: 1px solid var(--borda); - } - - .roadmap-inner { - max-width: 1300px; - margin: 0 auto; - padding: 0 24px; - } - - .roadmap-heading { - max-width: 760px; - margin-bottom: 28px; - } - - .roadmap-heading h2 { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: clamp(28px, 4vw, 44px); - line-height: 1.08; - color: var(--escuro); - margin: 8px 0 14px; - } - - .roadmap-heading p { - color: #64748b; - font-size: 16px; - line-height: 1.7; - } - - .roadmap-grid { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 16px; - } - - .roadmap-card { - background: #fff; - border: 1px solid var(--borda); - border-radius: 8px; - padding: 24px; - min-height: 280px; - box-shadow: 0 16px 44px rgba(15, 23, 42, 0.06); - } - - .roadmap-card-live { - border-color: rgba(16, 185, 129, 0.42); - box-shadow: 0 16px 44px rgba(16, 185, 129, 0.10); - } - - .roadmap-status { - display: inline-flex; - align-items: center; - min-height: 28px; - padding: 0 10px; - border-radius: 100px; - background: rgba(16, 185, 129, 0.12); - color: var(--verde-escuro); - font-size: 12px; - font-weight: 800; - text-transform: uppercase; - letter-spacing: 0; - } - - .roadmap-card h3 { - font-family: 'Plus Jakarta Sans', sans-serif; - color: var(--escuro); - font-size: 21px; - margin: 18px 0 12px; - } - - .roadmap-card ul { - list-style: none; - display: grid; - gap: 10px; - } - - .roadmap-card li { - position: relative; - padding-left: 18px; - color: #475569; - font-size: 14px; - line-height: 1.55; - } - - .roadmap-card li::before { - content: ''; - position: absolute; - left: 0; - top: 9px; - width: 7px; - height: 7px; - border-radius: 50%; - background: var(--verde); - } - - .roadmap-note { - margin-top: 16px; - padding: 18px 20px; - background: #fff; - border: 1px solid var(--borda); - border-radius: 8px; - display: flex; - gap: 10px; - align-items: center; - flex-wrap: wrap; - } - - .roadmap-note strong { - color: var(--escuro); - } - - .roadmap-note span { - color: #64748b; - } - - body.dark-mode .public-roadmap { - background: #111827; - border-color: #263244; - } - - body.dark-mode .roadmap-heading h2, - body.dark-mode .roadmap-card h3, - body.dark-mode .roadmap-note strong { - color: #f8fafc; - } - - body.dark-mode .roadmap-heading p, - body.dark-mode .roadmap-card li, - body.dark-mode .roadmap-note span { - color: #cbd5e1; - } - - body.dark-mode .roadmap-card, - body.dark-mode .roadmap-note { - background: #0b1120; - border-color: #263244; - } - - /* ===== FOOTER ===== */ - footer { - background: #e8f5ed; - color: #4f6f61; - padding: 48px 24px 32px; - margin-top: 80px; - border-top: 1px solid var(--borda); - } - - .footer-inner { - max-width: 1300px; - margin: 0 auto; - } - - .footer-top { - display: grid; - grid-template-columns: 2fr 1fr 1fr; - gap: 40px; - margin-bottom: 40px; - } - - .footer-brand { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 28px; - font-weight: 800; - color: var(--texto); - margin-bottom: 12px; - } - - .footer-brand span { color: var(--verde); } - - .footer-desc { - font-size: 14px; - line-height: 1.7; - max-width: 280px; - } - - .footer-col h4 { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 700; - letter-spacing: 2px; - text-transform: uppercase; - color: var(--texto); - margin-bottom: 16px; - } - - .footer-col a { - display: flex; - align-items: center; - gap: 6px; - color: #5d7b6e; - text-decoration: none; - font-size: 14px; - margin-bottom: 10px; - transition: color 0.2s; - } - - .footer-col a:hover { color: var(--verde); } - - .footer-bottom { - border-top: 1px solid var(--borda); - padding-top: 24px; - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - gap: 12px; - font-size: 13px; - } - - .footer-bottom a { - color: var(--verde); - text-decoration: none; - } - - /* ===== CADASTRO BTN FLUTUANTE ===== */ - .fab { - position: fixed; - bottom: 24px; - right: 24px; - background: var(--escuro); - color: #fff; - border: none; - padding: 16px 24px; - border-radius: 100px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 700; - cursor: pointer; - box-shadow: 0 8px 32px rgba(0,0,0,0.3); - z-index: 200; - display: flex; - align-items: center; - gap: 8px; - transition: all 0.3s; - } - - .fab:hover { - background: var(--verde); - color: #000; - transform: scale(1.05); - box-shadow: 0 8px 32px rgba(16,185,129,0.35); - } - - /* ===== RESPONSIVO ===== */ - @media (hover: none) { - .store-card:hover, .promo-card:hover { transform: none; box-shadow: none; } - } - - @media (max-width: 768px) { - .nav-links { display: none; } - .nav-inner { display: flex; justify-content: space-between; } - .footer-top { grid-template-columns: 1fr; } - .listings-grid { grid-template-columns: 1fr; } - .promos-grid { grid-template-columns: 1fr; } - .roadmap-grid { grid-template-columns: 1fr; } - .public-roadmap { margin-inline: 0; } - .roadmap-card { min-height: auto; } - .welcome-stats { gap: 24px; } - .welcome-stat strong { font-size: 24px; } - } - - /* ===== AVALIACAO STARS INPUT ===== */ - .review-stars { - display: flex; - gap: 4px; - margin: 12px 0; - } - - .review-star { - font-size: 28px; - cursor: pointer; - transition: transform 0.1s; - color: #ddd; - } - - .review-star.active, .review-star:hover { color: #FFB800; transform: scale(1.2); } - - .review-input { - width: 100%; - border: 1.5px solid var(--borda); - border-radius: 12px; - padding: 12px; - font-family: 'Inter', sans-serif; - font-size: 14px; - resize: vertical; - min-height: 80px; - outline: none; - transition: border-color 0.2s; - } - - .review-input:focus { border-color: var(--verde); } - - .btn-avaliar { - background: var(--verde); - color: #000; - border: none; - padding: 12px 24px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - margin-top: 10px; - transition: all 0.2s; - } - - .btn-avaliar:hover { background: var(--verde-escuro); color: #fff; } - - .toast { - position: fixed; - bottom: 100px; - left: 50%; - transform: translateX(-50%) translateY(20px); - background: var(--escuro); - color: #fff; - border: 1px solid transparent; - padding: 14px 28px; - border-radius: 100px; - font-size: 14px; - font-weight: 500; - opacity: 0; - transition: all 0.3s; - z-index: 9999; - white-space: nowrap; - } - - .toast.show { - opacity: 1; - transform: translateX(-50%) translateY(0); - } - - body.dark-mode .toast { - background: #141414; - color: #f1f1f1; - border-color: #2f2f2f; - box-shadow: 0 10px 28px rgba(0, 0, 0, 0.4); - } - - /* ===== FORM STYLES ===== */ - .form-group { - margin-bottom: 16px; - } - - .form-row { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 16px; - } - - .form-group label { - display: block; - margin-bottom: 6px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 600; - font-size: 14px; - color: var(--texto); - } - - .form-group input, - .form-group textarea, - .form-group select { - width: 100%; - padding: 10px 12px; - border-radius: 10px; - border: 1.5px solid var(--borda); - font-family: 'Inter', sans-serif; - font-size: 14px; - transition: border-color 0.2s; - background: transparent; - color: var(--texto); - } - - .form-group input::placeholder, - .form-group textarea::placeholder { - color: #999; - } - - .form-group input:focus, - .form-group textarea:focus, - .form-group select:focus { - outline: none; - border-color: var(--verde); - box-shadow: 0 0 0 3px rgba(16,185,129,0.15); - } - - .form-group textarea { - resize: vertical; - min-height: 80px; - } - - body.dark-mode .form-group label { - color: #e5e5e5; - } - - body.dark-mode .form-group input, - body.dark-mode .form-group textarea, - body.dark-mode .form-group select { - background: #1a1a1a; - border-color: #333; - color: #f1f1f1; - } - - body.dark-mode .form-group input::placeholder, - body.dark-mode .form-group textarea::placeholder { - color: #777; - } - - body.dark-mode .form-group input:focus, - body.dark-mode .form-group textarea:focus, - body.dark-mode .form-group select:focus { - border-color: var(--verde); - box-shadow: 0 0 0 3px rgba(16,185,129,0.15); - } - - /* ===== CART DRAWER ===== */ - .drawer-overlay { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.4); - z-index: 999; - opacity: 0; - visibility: hidden; - transition: all 0.3s ease; - } - - .drawer-overlay.open { - opacity: 1; - visibility: visible; - } - - .cart-drawer { - position: fixed; - right: -400px; - top: 0; bottom: 0; - width: 380px; - background: rgba(255,255,255,0.92); - backdrop-filter: blur(24px); - -webkit-backdrop-filter: blur(24px); - border-left: 1px solid rgba(255,255,255,0.6); - z-index: 1000; - display: flex; - flex-direction: column; - transition: right 0.3s ease; - box-shadow: -4px 0 40px rgba(0,0,0,0.12); - } - - .cart-drawer.open { right: 0; } - - .drawer-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 20px; - border-bottom: 1.5px solid var(--borda); - } - - .drawer-header h3 { - margin: 0; - font-size: 18px; - font-weight: 700; - font-family: 'Plus Jakarta Sans', sans-serif; - color: var(--texto); - display: flex; - align-items: center; - gap: 8px; - } - - .drawer-close { - background: none; - border: none; - font-size: 24px; - cursor: pointer; - color: var(--texto); - padding: 0; - width: 32px; height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 8px; - transition: all 0.2s; - } - - .drawer-close:hover { - background: rgba(16,185,129,0.1); - color: var(--verde); - } - - .drawer-body { - flex: 1; - overflow-y: auto; - padding: 12px 0; - } - - .drawer-footer { - padding: 20px; - border-top: 1.5px solid var(--borda); - display: flex; - flex-direction: column; - gap: 12px; - } - - .drawer-total { - display: flex; - justify-content: space-between; - font-size: 16px; - font-weight: 700; - color: var(--texto); - padding-bottom: 12px; - border-bottom: 1px solid var(--borda); - } - - .btn-checkout { - background: var(--verde); - color: #fff; - border: none; - padding: 12px 16px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - font-size: 14px; - } - - .btn-checkout:hover { - background: var(--verde-escuro); - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(16,185,129,0.25); - } - - .btn-checkout-whats { - background: #25D366; - color: #fff; - border: none; - padding: 12px 16px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - font-size: 14px; - } - - .btn-checkout-whats:hover { - background: #128C7E; - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(37, 211, 102, 0.3); - } - - body.dark-mode .drawer-header { background: #1a1a1a; border-bottom-color: #333; } - body.dark-mode .drawer-header h3 { color: #f1f1f1; } - body.dark-mode .drawer-close { color: #f1f1f1; } - body.dark-mode .drawer-close:hover { background: rgba(16,185,129,0.15); } - body.dark-mode .cart-drawer { - background: rgba(11,17,32,0.92); - border-left-color: rgba(255,255,255,0.08); - } - body.dark-mode .cart-item { border-bottom-color: #222; } - body.dark-mode .cart-item-name { color: #f1f1f1; } - body.dark-mode .drawer-footer { background: #1a1a1a; border-top-color: #333; } - body.dark-mode .drawer-total { color: #f1f1f1; border-bottom-color: #333; } - - /* ===== MODAL OVERLAYS ===== */ - .checkout-overlay, - .merchant-overlay, - .orders-overlay { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - background: rgba(0, 0, 0, 0.5); - display: none; - align-items: center; - justify-content: center; - z-index: 1200; - padding: 20px; - animation: fadeIn 0.2s ease; - } - - .checkout-overlay.open, - .merchant-overlay.open, - .orders-overlay.open { - display: flex; - } - - @keyframes fadeIn { - from { opacity: 0; } - to { opacity: 1; } - } - - /* ===== CHECKOUT / MERCHANT / ORDERS MODALS ===== */ - .checkout-modal, - .merchant-modal, - .orders-modal { - background: var(--creme); - border-radius: 16px; - width: 100%; - max-width: 500px; - max-height: 90vh; - overflow-y: auto; - position: relative; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); - animation: slideUp 0.3s ease; - } - - @keyframes slideUp { - from { opacity: 0; transform: translateY(20px); } - to { opacity: 1; transform: translateY(0); } - } - - .checkout-modal h2, - .merchant-modal h2, - .orders-modal h2 { - margin: 0; - padding: 24px 24px 12px; - font-size: 18px; - font-weight: 700; - font-family: 'Plus Jakarta Sans', sans-serif; - color: var(--texto); - } - - .merchant-sub { - padding: 0 24px 16px; - font-size: 13px; - color: #666; - } - - .checkout-close, - .merchant-close, - .orders-close { - position: absolute; - top: 16px; right: 16px; - width: 32px; height: 32px; - background: rgba(0, 0, 0, 0.05); - border: none; - border-radius: 8px; - font-size: 20px; - cursor: pointer; - transition: all 0.2s; - display: flex; - align-items: center; - justify-content: center; - } - - .checkout-close:hover, - .merchant-close:hover, - .orders-close:hover { - background: var(--verde); - color: #fff; - } - - .checkout-modal > form, - .merchant-form { - padding: 0 24px 24px; - } - - .checkout-total { - background: #f0f8f4; - padding: 12px 16px; - border-radius: 10px; - margin: 16px 0; - font-size: 14px; - color: var(--texto); - } - - .checkout-total strong { - color: var(--verde); - font-weight: 700; - } - - .checkout-actions { - display: flex; - flex-direction: column; - gap: 12px; - margin-top: 16px; - } - - .btn-confirmar-pedido { - background: var(--verde); - color: #fff; - border: none; - padding: 12px 20px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - font-size: 14px; - } - - .btn-confirmar-pedido:hover { - background: var(--verde-escuro); - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(16,185,129,0.25); - } - - .btn-confirmar-whats { - background: #25D366; - color: #fff; - border: none; - padding: 12px 20px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - font-size: 14px; - } - - .btn-confirmar-whats:hover { - background: #128C7E; - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(37, 211, 102, 0.3); - } - - .auth-btn { - width: 100%; - background: var(--verde); - color: #fff; - border: none; - padding: 12px 20px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 700; - cursor: pointer; - transition: all 0.2s; - font-size: 15px; - margin-top: 8px; - } - - .auth-btn:hover { - background: var(--verde-escuro); - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(16,185,129,0.25); - } - - /* ===== ORDERS MODAL ===== */ - .order-card { - padding: 16px 24px; - border-bottom: 1px solid var(--borda); - line-height: 1.6; - } - - .order-card:last-child { border-bottom: none; } - - .order-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; - } - - .order-header strong { - font-weight: 700; - color: var(--texto); - font-size: 14px; - } - - .order-status { font-size: 12px; font-weight: 700; } - .order-date { font-size: 12px; color: #999; margin-bottom: 8px; } - - .order-items { margin: 8px 0; font-size: 13px; color: var(--texto); } - .order-items div { padding: 4px 0; } - .order-total { font-weight: 700; color: var(--verde); margin: 8px 0; font-size: 14px; } - .order-payment { font-size: 12px; color: #999; } - - body.dark-mode .checkout-modal, - body.dark-mode .merchant-modal, - body.dark-mode .orders-modal { background: #0f0f0f; } - - body.dark-mode .checkout-modal h2, - body.dark-mode .merchant-modal h2, - body.dark-mode .orders-modal h2 { color: #f1f1f1; } - - body.dark-mode .merchant-sub { color: #999; } - body.dark-mode .checkout-total { background: rgba(16,185,129,0.1); } - - body.dark-mode .checkout-close, - body.dark-mode .merchant-close, - body.dark-mode .orders-close { background: rgba(255,255,255,0.05); color: #f1f1f1; } - - body.dark-mode .checkout-close:hover, - body.dark-mode .merchant-close:hover, - body.dark-mode .orders-close:hover { background: var(--verde); color: #000; } - - body.dark-mode .order-header strong, - body.dark-mode .order-items { color: #f1f1f1; } - - body.dark-mode .order-date, - body.dark-mode .order-payment { color: #777; } - - /* ===== DRAWER STORE GROUPS ===== */ - .drawer-store-name { - padding: 8px 20px; - font-weight: 700; - font-family: 'Plus Jakarta Sans', sans-serif; - color: var(--verde); - font-size: 13px; - background: rgba(16,185,129,0.05); - border-left: 3px solid var(--verde); - } - - .drawer-item { - padding: 12px 20px; - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid var(--borda); - } - - .drawer-item-info { flex: 1; } - .drawer-item-name { font-weight: 600; color: var(--texto); font-size: 14px; margin-bottom: 4px; } - .drawer-item-price { color: var(--verde); font-weight: 700; font-size: 13px; } - - .drawer-item-controls { - display: flex; - align-items: center; - gap: 8px; - margin-left: 12px; - } - - .qtd-btn-sm { - width: 28px; height: 28px; - border: 1.5px solid var(--borda); - background: transparent; - border-radius: 6px; - cursor: pointer; - font-size: 14px; - font-weight: 700; - color: var(--texto); - transition: all 0.2s; - } - - .qtd-btn-sm:hover { - border-color: var(--verde); - color: var(--verde); - background: rgba(16,185,129,0.05); - } - - .drawer-item-controls span { - width: 28px; - text-align: center; - font-weight: 700; - color: var(--texto); - } - - .drawer-remove { - background: none; - border: none; - cursor: pointer; - font-size: 16px; - padding: 4px; - transition: all 0.2s; - } - - .drawer-remove:hover { transform: scale(1.2); } - - .drawer-empty { padding: 40px 20px; text-align: center; color: #999; } - - body.dark-mode .drawer-store-name { background: rgba(16,185,129,0.1); } - body.dark-mode .drawer-item { border-bottom-color: #222; } - body.dark-mode .drawer-item-name { color: #f1f1f1; } - body.dark-mode .qtd-btn-sm { border-color: #333; color: #f1f1f1; } - body.dark-mode .qtd-btn-sm:hover { background: rgba(16,185,129,0.1); } - body.dark-mode .drawer-item-controls span { color: #f1f1f1; } - - /* ===== FAVORITES SECTION ===== */ - .favorites-section { - padding: 40px 20px; - background: var(--creme); - } - - .favorites-inner { - max-width: 1200px; - margin: 0 auto; - } - - .favorites-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 32px; - } - - .favorites-title { - margin: 0; - font-size: 20px; - font-weight: 700; - font-family: 'Plus Jakarta Sans', sans-serif; - color: var(--texto); - display: flex; - align-items: center; - gap: 8px; - } - - .favorites-title span { - font-size: 16px; - font-weight: 600; - color: #999; - } - - .favorites-back { - background: transparent; - border: 1.5px solid var(--borda); - color: var(--texto); - padding: 10px 16px; - border-radius: 10px; - font-family: 'Plus Jakarta Sans', sans-serif; - font-weight: 600; - cursor: pointer; - font-size: 14px; - transition: all 0.2s; - } - - .favorites-back:hover { - background: var(--verde); - border-color: var(--verde); - color: #fff; - } - - .favorites-empty { - padding: 40px 20px; - text-align: center; - color: #999; - } - - .favorites-empty p { margin: 0; } - - body.dark-mode .favorites-section { background: #0f0f0f; } - body.dark-mode .favorites-title { color: #f1f1f1; } - body.dark-mode .favorites-back { border-color: #333; color: #f1f1f1; } - body.dark-mode .favorites-back:hover { background: var(--verde); border-color: var(--verde); color: #000; } - - /* ===== PWA INSTALL BANNER ===== */ - .pwa-install-banner { - position: fixed; - bottom: 80px; - left: 50%; - transform: translateX(-50%); - background: var(--escuro); - color: #fff; - border-radius: 16px; - padding: 16px 20px; - z-index: 300; - box-shadow: 0 8px 32px rgba(0,0,0,0.3); - max-width: 400px; - width: calc(100% - 48px); - } - - .pwa-install-inner { - display: flex; - align-items: center; - gap: 12px; - flex-wrap: wrap; - } - - .pwa-install-inner span { flex: 1; font-size: 14px; } - - .pwa-install-actions { - display: flex; - gap: 8px; - } - - .pwa-install-btn { - background: var(--verde); - color: #000; - border: none; - padding: 8px 16px; - border-radius: 8px; - font-weight: 700; - cursor: pointer; - font-size: 13px; - } - - .pwa-dismiss-btn { - background: rgba(255,255,255,0.1); - color: #fff; - border: none; - padding: 8px 12px; - border-radius: 8px; - cursor: pointer; - font-size: 13px; - } - - /* ===== PAGINATION ===== */ - .pagination { - display: flex; - gap: 8px; - justify-content: center; - align-items: center; - margin-top: 32px; - flex-wrap: wrap; - } - - /* Botões Anterior / Próxima */ - .page-btn { - height: 40px; - padding: 0 18px; - border: 1.5px solid var(--borda); - background: var(--cinza); - border-radius: 10px; - cursor: pointer; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 13px; - font-weight: 600; - transition: all 0.2s; - color: var(--texto); - white-space: nowrap; - } - - .page-btn:hover:not(:disabled) { - background: var(--escuro); - border-color: var(--escuro); - color: #fff; - } - - .page-btn:disabled { - opacity: 0.35; - cursor: default; - } - - /* Números de página */ - .page-num { - width: 40px; - height: 40px; - border: 1.5px solid var(--borda); - background: var(--cinza); - border-radius: 10px; - cursor: pointer; - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 14px; - font-weight: 600; - transition: all 0.2s; - color: var(--texto); - } - - .page-num:hover, .page-num.active { - background: var(--escuro); - border-color: var(--escuro); - color: #fff; - } - - body.dark-mode .page-btn, - body.dark-mode .page-num { - background: #1a1a1a; - border-color: #333; - color: #e0e0e0; - } - - body.dark-mode .page-btn:hover:not(:disabled), - body.dark-mode .page-num:hover, - body.dark-mode .page-num.active { - background: var(--verde); - border-color: var(--verde); - color: #000; - } - - /* ===== SORT SELECT DARK ===== */ - body.dark-mode .sort-select { - background: #1a1a1a; - border-color: #333; - color: #e0e0e0; - } - - /* ===== RESPONSIVE SMALL ===== */ - @media (max-width: 480px) { - .form-row { grid-template-columns: 1fr; } - .cart-drawer { width: 100%; right: -100%; } - .checkout-modal, - .merchant-modal, - .orders-modal { max-width: 100%; max-height: 100vh; border-radius: 16px 16px 0 0; } - } - - /* ===== MODAL FAV BUTTON ===== */ - .modal-fav { - position: absolute; - top: 16px; - left: 16px; - background: rgba(0,0,0,0.5); - color: #fff; - border: none; - width: 36px; - height: 36px; - border-radius: 50%; - font-size: 18px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s; - } - - .modal-fav:hover { background: rgba(255,68,68,0.8); } - .modal-fav.ativo { background: rgba(255,68,68,0.8); } - - /* ===== CATALOG IN MODAL ===== */ - .catalogo-section { margin: 16px 0; } - .catalogo-title { - font-family: 'Plus Jakarta Sans', sans-serif; - font-size: 16px; - font-weight: 700; - margin-bottom: 12px; - color: var(--texto); - } - - .catalogo-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 0; - border-bottom: 1px solid var(--borda); - } - - .catalogo-item:last-child { border-bottom: none; } - - .catalogo-item-info { flex: 1; } - .catalogo-item-name { font-weight: 600; font-size: 14px; color: var(--texto); } - .catalogo-item-desc { font-size: 12px; color: #888; margin-top: 2px; } - .catalogo-item-price { font-weight: 700; color: var(--verde); font-size: 15px; margin: 0 12px; } - - .catalogo-qty { - display: flex; - align-items: center; - gap: 8px; - } - - .catalogo-qty button { - width: 28px; height: 28px; - border: 1.5px solid var(--borda); - background: transparent; - border-radius: 6px; - cursor: pointer; - font-size: 16px; - font-weight: 700; - transition: all 0.2s; - color: var(--texto); - } - - .catalogo-qty button:hover { - border-color: var(--verde); - color: var(--verde); - } - - .catalogo-qty span { - width: 24px; - text-align: center; - font-weight: 700; - font-size: 14px; - } - - body.dark-mode .catalogo-item { border-bottom-color: #2a2a2a; } - body.dark-mode .catalogo-item-name { color: #f1f1f1; } - body.dark-mode .catalogo-title { color: #f1f1f1; } - body.dark-mode .catalogo-qty button { border-color: #333; color: #f1f1f1; } - body.dark-mode .catalogo-qty button:hover { background: rgba(16,185,129,0.1); } - - /* ===== USER MENU (legacy compat) ===== */ - .nav-user-wrapper { position: relative; } - - .nav-user-menu { - display: none; - position: absolute; - top: calc(100% + 8px); - right: 0; - background: #fff; - border: 1.5px solid var(--borda); - border-radius: 12px; - box-shadow: 0 10px 30px rgba(0,0,0,0.12); - padding: 8px 0; - min-width: 200px; - z-index: 200; - } - - .nav-user-menu.open { display: flex; flex-direction: column; } - - .user-menu-header { - padding: 12px 16px 8px; - font-size: 13px; - color: #666; - border-bottom: 1px solid var(--borda); - margin-bottom: 4px; - } - - .user-menu-item { - padding: 10px 16px; - font-size: 14px; - color: var(--texto); - cursor: pointer; - transition: background 0.15s; - text-decoration: none; - display: block; - } - - .user-menu-item:hover { background: var(--cinza); color: var(--verde); } - - body.dark-mode .nav-user-menu { - background: #1a1a1a; - border-color: #2f2f2f; - } - - body.dark-mode .user-menu-header { - color: #aaa; - border-bottom-color: #2f2f2f; - } - - body.dark-mode .user-menu-item { color: #e0e0e0; } - body.dark-mode .user-menu-item:hover { background: #252525; } - - /* ===== LEAFLET MAP ===== */ - #leaflet-map { - width: 100%; - height: 100%; - } diff --git a/backend/public/data/data.json b/backend/public/data/data.json deleted file mode 100644 index 5b3193e..0000000 --- a/backend/public/data/data.json +++ /dev/null @@ -1,603 +0,0 @@ -{ - "comercios": [ - { - "id": 1, - "slug": "pizzaria-bella-massa", - "nome": "Pizzaria Bella Massa", - "categoria": "restaurante", - "tags": [ - "pizza", - "restaurante", - "delivery", - "comida" - ], - "emoji": "🍕", - "rating": 4.8, - "visitas": 1240, - "recomendados": 98, - "aberto": true, - "endereco": "Rua XV de Novembro, 45", - "lat": -21.9925, - "lng": -48.3908, - "tel": "16991112222", - "whatsapp": "5516991112222", - "horario": "Ter-Dom · 18h às 23h", - "fotos": [ - "🍕", - "🍝", - "🥗" - ], - "promo": { - "ativo": true, - "desc": "Pizza Grande + 2 Refrigerantes", - "preco": "R$52", - "original": "R$72" - }, - "catalogo": [ - { - "nome_produto": "Pizza Grande Margherita", - "descricao": "Molho de tomate, mussarela, manjericão fresco e azeite", - "preco": 42.0 - }, - { - "nome_produto": "Pizza Grande Calabresa", - "descricao": "Calabresa fatiada, cebola e mussarela", - "preco": 45.0 - }, - { - "nome_produto": "Pizza Grande Frango c/ Catupiry", - "descricao": "Frango desfiado temperado com catupiry cremoso", - "preco": 48.0 - }, - { - "nome_produto": "Pizza Grande Portuguesa", - "descricao": "Presunto, ovo, cebola, azeitona e mussarela", - "preco": 50.0 - }, - { - "nome_produto": "Refrigerante 2L", - "descricao": "Coca-Cola, Guaraná ou Fanta", - "preco": 12.0 - } - ] - }, - { - "id": 2, - "slug": "pizzaria-central", - "nome": "Pizzaria Central", - "categoria": "restaurante", - "tags": [ - "pizza", - "restaurante", - "delivery" - ], - "emoji": "🍕", - "rating": 4.5, - "visitas": 980, - "recomendados": 85, - "aberto": true, - "endereco": "Av. Saudade, 210", - "lat": -21.994, - "lng": -48.3885, - "tel": "16993334444", - "whatsapp": "5516993334444", - "horario": "Qua-Dom · 18h às 22h30", - "fotos": [ - "🍕", - "🥤", - "🧀" - ], - "promo": null, - "catalogo": null - }, - { - "id": 3, - "slug": "farmacia-boa-esperanca", - "nome": "Farmácia Boa Esperança", - "categoria": "farmácia", - "tags": [ - "farmácia", - "remédio", - "medicamento", - "saúde" - ], - "emoji": "💊", - "rating": 4.9, - "visitas": 2100, - "recomendados": 195, - "aberto": true, - "endereco": "Praça Cel. Marcondes, 8", - "lat": -21.9932, - "lng": -48.392, - "tel": "16994445555", - "whatsapp": "5516994445555", - "horario": "Seg-Sab · 7h às 20h · Dom 8h às 13h", - "fotos": [ - "💊", - "🩺", - "🧴" - ], - "promo": null, - "catalogo": null - }, - { - "id": 4, - "slug": "farmacia-popular-bes", - "nome": "Farmácia Popular BES", - "categoria": "farmácia", - "tags": [ - "farmácia", - "remédio", - "genérico", - "saúde" - ], - "emoji": "💉", - "rating": 4.6, - "visitas": 1650, - "recomendados": 140, - "aberto": false, - "endereco": "Rua Floriano Peixoto, 77", - "lat": -21.9918, - "lng": -48.3932, - "tel": "16996667777", - "whatsapp": "5516996667777", - "horario": "Seg-Sex · 8h às 19h · Sab 8h às 14h", - "fotos": [ - "💉", - "💊", - "🏥" - ], - "promo": null, - "catalogo": null - }, - { - "id": 5, - "slug": "pet-shop-mundo-animal", - "nome": "Pet Shop Mundo Animal", - "categoria": "pet", - "tags": [ - "pet", - "cachorro", - "gato", - "ração", - "banho", - "tosa", - "veterinário" - ], - "emoji": "🐾", - "rating": 4.9, - "visitas": 1890, - "recomendados": 178, - "aberto": true, - "endereco": "Rua das Flores, 120", - "lat": -21.9945, - "lng": -48.3898, - "tel": "16997778888", - "whatsapp": "5516997778888", - "horario": "Seg-Sab · 8h às 18h", - "fotos": [ - "🐾", - "🐕", - "🐈" - ], - "promo": { - "ativo": true, - "desc": "Banho e Tosa com 20% de desconto", - "preco": "R$40", - "original": "R$50" - }, - "catalogo": null - }, - { - "id": 6, - "slug": "mecanica-do-ze", - "nome": "Mecânica do Zé", - "categoria": "mecânica", - "tags": [ - "mecânico", - "carro", - "conserto", - "auto", - "mecânica", - "revisão" - ], - "emoji": "🔧", - "rating": 4.7, - "visitas": 780, - "recomendados": 92, - "aberto": true, - "endereco": "Rod. SP-255, km 3", - "lat": -21.988, - "lng": -48.395, - "tel": "16998889999", - "whatsapp": "5516998889999", - "horario": "Seg-Sex · 7h às 18h · Sab 7h às 12h", - "fotos": [ - "🔧", - "🚗", - "⚙️" - ], - "promo": null, - "catalogo": null - }, - { - "id": 7, - "slug": "barbearia-estilo", - "nome": "Barbearia Estilo", - "categoria": "barbearia", - "tags": [ - "barbearia", - "cabelo", - "barba", - "corte" - ], - "emoji": "💈", - "rating": 4.8, - "visitas": 1100, - "recomendados": 115, - "aberto": true, - "endereco": "Rua Tiradentes, 33", - "lat": -21.9935, - "lng": -48.3915, - "tel": "16992223333", - "whatsapp": "5516992223333", - "horario": "Ter-Sab · 8h às 19h", - "fotos": [ - "💈", - "✂️", - "🪒" - ], - "promo": { - "ativo": true, - "desc": "Corte + Barba", - "preco": "R$25", - "original": "R$35" - }, - "catalogo": null - }, - { - "id": 8, - "slug": "barbearia-do-marcos", - "nome": "Barbearia do Marcos", - "categoria": "barbearia", - "tags": [ - "barbearia", - "cabelo", - "barba", - "corte" - ], - "emoji": "✂️", - "rating": 4.5, - "visitas": 720, - "recomendados": 68, - "aberto": false, - "endereco": "Av. Brasil, 55", - "lat": -21.995, - "lng": -48.387, - "tel": "16993332211", - "whatsapp": "5516993332211", - "horario": "Seg-Sab · 8h às 18h", - "fotos": [ - "✂️", - "💈", - "🪒" - ], - "promo": null, - "catalogo": null - }, - { - "id": 9, - "slug": "supermercado-central", - "nome": "Supermercado Central", - "categoria": "supermercado", - "tags": [ - "supermercado", - "mercado", - "feira", - "compras", - "alimento" - ], - "emoji": "🛒", - "rating": 4.4, - "visitas": 3200, - "recomendados": 210, - "aberto": true, - "endereco": "Praça da República, 1", - "lat": -21.9928, - "lng": -48.3905, - "tel": "16994441234", - "whatsapp": "5516994441234", - "horario": "Seg-Sab · 7h às 21h · Dom 7h às 14h", - "fotos": [ - "🛒", - "🥩", - "🥦" - ], - "promo": null, - "catalogo": null - }, - { - "id": 10, - "slug": "loja-moda-e-estilo", - "nome": "Loja Moda & Estilo", - "categoria": "roupa", - "tags": [ - "roupa", - "roupas", - "moda", - "vestuário", - "blusa", - "calça" - ], - "emoji": "👗", - "rating": 4.6, - "visitas": 640, - "recomendados": 72, - "aberto": true, - "endereco": "Rua XV de Novembro, 102", - "lat": -21.9922, - "lng": -48.3912, - "tel": "16991234567", - "whatsapp": "5516991234567", - "horario": "Seg-Sex · 9h às 18h · Sab 9h às 15h", - "fotos": [ - "👗", - "👕", - "👠" - ], - "promo": { - "ativo": true, - "desc": "50% OFF em toda linha inverno", - "preco": "a partir de R$29", - "original": "R$59" - }, - "catalogo": null - }, - { - "id": 11, - "slug": "hamburgueria-central", - "nome": "Hamburgueria Central", - "categoria": "restaurante", - "tags": [ - "hamburguer", - "lanche", - "burger", - "restaurante", - "delivery" - ], - "emoji": "🍔", - "rating": 4.7, - "visitas": 1560, - "recomendados": 145, - "aberto": true, - "endereco": "Av. Saudade, 85", - "lat": -21.9938, - "lng": -48.389, - "tel": "16997654321", - "whatsapp": "5516997654321", - "horario": "Seg-Dom · 11h às 23h", - "fotos": [ - "🍔", - "🍟", - "🥤" - ], - "promo": { - "ativo": true, - "desc": "X-Burger + Batata Frita", - "preco": "R$18", - "original": "R$28" - }, - "catalogo": [ - { - "nome_produto": "X-Burger Clássico", - "descricao": "Pão brioche, hambúrguer 150g, queijo, alface, tomate e molho especial", - "preco": 22.0 - }, - { - "nome_produto": "X-Bacon Duplo", - "descricao": "Pão brioche, 2 hambúrgueres 120g, bacon crocante, queijo cheddar e molho BBQ", - "preco": 32.0 - }, - { - "nome_produto": "X-Frango Crispy", - "descricao": "Pão australiano, frango empanado crocante, queijo, alface e maionese temperada", - "preco": 26.0 - }, - { - "nome_produto": "Batata Frita Grande", - "descricao": "Porção de batata frita crocante com cheddar e bacon", - "preco": 18.0 - }, - { - "nome_produto": "Milk Shake 500ml", - "descricao": "Chocolate, morango ou ovomaltine", - "preco": 16.0 - }, - { - "nome_produto": "Refrigerante Lata", - "descricao": "Coca-Cola, Guaraná, Fanta ou Sprite", - "preco": 7.0 - } - ] - }, - { - "id": 12, - "slug": "salao-beleza-total", - "nome": "Salão Beleza Total", - "categoria": "salão", - "tags": [ - "salão", - "cabelo", - "manicure", - "pedicure", - "beleza", - "corte" - ], - "emoji": "💅", - "rating": 4.9, - "visitas": 920, - "recomendados": 130, - "aberto": true, - "endereco": "Rua das Palmeiras, 14", - "lat": -21.9915, - "lng": -48.3925, - "tel": "16993219876", - "whatsapp": "5516993219876", - "horario": "Ter-Sab · 8h30 às 18h", - "fotos": [ - "💅", - "💆", - "✨" - ], - "promo": null, - "catalogo": null - }, - { - "id": 13, - "slug": "padaria-pao-quente", - "nome": "Padaria Pão Quente", - "categoria": "padaria", - "tags": [ - "padaria", - "pão", - "café", - "salgado", - "lanche", - "bolo" - ], - "emoji": "🍞", - "rating": 4.8, - "visitas": 1780, - "recomendados": 188, - "aberto": true, - "endereco": "Rua Sete de Setembro, 23", - "lat": -21.9942, - "lng": -48.3918, - "tel": "16992341234", - "whatsapp": "5516992341234", - "horario": "Seg-Dom · 5h30 às 12h", - "fotos": [ - "🍞", - "☕", - "🥐" - ], - "promo": null, - "catalogo": null - }, - { - "id": 14, - "slug": "distribuidora-de-gas-bes", - "nome": "Distribuidora de Gás BES", - "categoria": "gás", - "tags": [ - "gás", - "botijão", - "glp", - "entrega" - ], - "emoji": "🔥", - "rating": 4.5, - "visitas": 890, - "recomendados": 95, - "aberto": true, - "endereco": "Rua Independência, 67", - "lat": -21.9955, - "lng": -48.3875, - "tel": "16991122334", - "whatsapp": "5516991122334", - "horario": "Seg-Sab · 7h às 19h", - "fotos": [ - "🔥", - "🏠", - "🚚" - ], - "promo": null, - "catalogo": null - }, - { - "id": 15, - "slug": "material-de-construcao-bes", - "nome": "Material de Construção BES", - "categoria": "material", - "tags": [ - "material", - "construção", - "tinta", - "cimento", - "ferragem", - "obra" - ], - "emoji": "🏗️", - "rating": 4.3, - "visitas": 560, - "recomendados": 62, - "aberto": true, - "endereco": "Av. João Paulo II, 300", - "lat": -21.996, - "lng": -48.394, - "tel": "16994433221", - "whatsapp": "5516994433221", - "horario": "Seg-Sex · 7h às 17h · Sab 7h às 12h", - "fotos": [ - "🏗️", - "🪓", - "🔨" - ], - "promo": null, - "catalogo": null - }, - { - "id": 16, - "slug": "aquaflora-groshop", - "nome": "AquaFlora AgroShop", - "categoria": "Pet", - "tags": ["pet", "rações", "agro", "campo", "pesca", "lazer", "plantas", "jardim", "aquário", "animais"], - "emoji": "🌿", - "rating": 4.8, - "visitas": 20, - "recomendados": 20, - "aberto": true, - "destaque": true, - "endereco": "R. Ten. Penha, 1076", - "lat": -21.998827015702744, - "lng": -48.39176912705583, - "tel": "16999611708", - "whatsapp": "5516999611708", - "horario": "Seg-Sex 7h30–18h30 · Qua até 19h30 · Sáb 7h30–16h · Dom fechado", - "fotos": [ - "/images/lojas/aquaflora/fachada.jpg", - "/images/lojas/aquaflora/foto1.jpg", - "/images/lojas/aquaflora/foto2.jpg", - "/images/lojas/aquaflora/foto3.jpg" - ], - "promo": { - "ativo": true, - "desc": "Toda quarta: até 15% off em rações selecionadas", - "preco": "até -15%", - "original": "" - }, - "catalogo": [ - { - "nome_produto": "Special Dog Raça Pequena Ultralife Sênior 15Kg", - "descricao": "Ração premium para cães de raça pequena sênior", - "preco": 185.16 - }, - { - "nome_produto": "Special Dog Raça Pequena Ultralife Suíno Frango 3Kg", - "descricao": "Ração sabor suíno e frango para raças pequenas", - "preco": 61.75 - }, - { - "nome_produto": "Special Dog Raça Pequena Ultralife 10Kg", - "descricao": "Ração premium para cães de raça pequena", - "preco": 126.26 - }, - { - "nome_produto": "Special Dog Raça Pequena Carne 20Kg", - "descricao": "Ração sabor carne para raças pequenas — embalagem família", - "preco": 170.91 - } - ] - } - ] -} \ No newline at end of file diff --git a/backend/public/html/cadastro.html b/backend/public/html/cadastro.html deleted file mode 100644 index 19788b6..0000000 --- a/backend/public/html/cadastro.html +++ /dev/null @@ -1,715 +0,0 @@ - - - -
- - -Escolha o tipo de conta que deseja criar
- -Já tem uma conta? Entrar aqui
-Entre na sua conta para continuar
- -Restaurantes, farmácias, mecânicas, pet shops e muito mais
- -Nenhum comércio encontrado para ""
-Tente outros termos como pizza, farmácia, mecânico...
-Categorias
-Encontre os comércios no mapa da cidade
-- 💡 Dica: Para adicionar sua loja no mapa, cadastre-se gratuitamente -
-Construindo em público
-Estamos construindo uma vitrine confiável para encontrar lojas locais. Quando um comércio também usar o Braga Commerce, o perfil poderá apontar para a experiência de compra mantida por ele.
-