/* ============================================================
   TUA PELE — Padronização de interface
   Autor: Hacker 0 5 90

   Última folha carregada em TODAS as páginas. Só uniformiza o que
   já existia em versões diferentes; não cria componentes novos nem
   altera funcionalidade.

   1. Nome da página: centrado no header, na fonte de texto do sistema.
   2. Cápsula única para filtros e interruptores de secção.
   3. Camadas fixas que a barra inferior tapava.
   4. Logótipo: mesmo desenho em todos os sítios do sistema.
   5. Faixa de instalação da PWA.

   Sobre o peso dos selectores: as folhas de cada área declaram estes
   mesmos elementos com body[data-loja-page] + duas classes e
   !important. O prefixo `html body[class] ... [class]` existe apenas
   para igualar esse peso — sem ele a padronização não se aplicaria
   nas páginas que mais precisam dela.
   ============================================================ */

:root {
  /* Igual a --tp-bottom-h do app-redesign.css, repetido porque nem
     todas as páginas carregam essa folha. */
  --tp-nav-h: 66px;
  --tp-nav-gap: calc(var(--tp-nav-h) + env(safe-area-inset-bottom));

  /* Escala única das camadas flutuantes — ver a secção 3. */
  --tp-z-nav: 2100;
  --tp-z-sheet: 3000;
  --tp-z-popup: 3600;
  --tp-z-confirm: 3800;

  /* Um único raio para filtros e interruptores de secção. */
  --tp-pill: 999px;

  /* Nome da página no header, pedido em 10/08/2026: Times New Roman.
     Nota para quem vier a seguir: o Times não é usado em mais lado nenhum
     do sistema — a serif das restantes rubricas é a Cormorant Garamond
     (--fonte-titulo). Trocar aqui muda todos os headers de uma vez. */
  --tp-page-title-font: 'Times New Roman', Times, Georgia, serif;
  /* A Times tem olho pequeno: ao mesmo tamanho lê-se menor que a DM Sans,
     por isso sobe um par de pontos. */
  --tp-page-title-size: clamp(18px, 5vw, 22px);
  --tp-page-title-weight: 700;
  --tp-page-title-color: #5C3020;

  /* Logótipo. O "tua" é a script; o "pele" é a serif de título no peso
     mais forte que a família tem. O traço fino fecha a diferença para o
     desenho aprovado sem mexer em nenhum tamanho. */
  --tp-logo-script: var(--fonte-script), 'Great Vibes', cursive;
  --tp-logo-serif: var(--fonte-titulo), 'Cormorant Garamond', Georgia, serif;
  --tp-logo-stroke: 0.022em;

  /* Cores trocadas entre si: até aqui o "tua" levava o castanho escuro e
     o "pele" o médio. Agora é ao contrário. */
  --tp-logo-cor-tua: #8B4A2E;
  --tp-logo-cor-pele: #5C3020;
}

/* ------------------------------------------------------------
   1. NOME DA PÁGINA
   Antes desta folha havia sete tipografias diferentes para a mesma
   coisa: serif 26px no cliente, serif 20px nas páginas aprovadas,
   serif 21px no ADM e, nas páginas da loja em telemóvel, um rótulo
   cinzento de 10,5px em maiúsculas encostado à esquerda.
   ------------------------------------------------------------ */

html body[class] header[class] > .header-center > h1,
html body[class] header[class] > h1,
html body[class] header[class] .dv-header-inner > .header-center > h1 {
  margin: 0 !important;
  max-width: 100% !important;
  font-family: var(--tp-page-title-font) !important;
  font-size: var(--tp-page-title-size) !important;
  font-weight: var(--tp-page-title-weight) !important;
  line-height: 1.2 !important;
  letter-spacing: 0 !important;
  text-align: center !important;
  text-transform: none !important;
  color: var(--tp-page-title-color) !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}

/* O h1 escondido (adm-estoque, listar-produtos) continua escondido:
   .visually-hidden usa !important em position/clip e não é tocado. */

/* Centragem real: colunas laterais iguais. Sem isto o título fica no
   centro da coluna do meio, que não é o centro do header sempre que
   um dos lados é a marca e o outro um botão de 40px.

   A condição repete-se em todos os blocos seguintes porque o CSS não
   permite dar nome a um selector. É sempre a mesma: headers que
   mostram o nome da página, seja em <h1> ou na pastilha do checkout. */
html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)),
html body[class] header[class]:has(> h1:not(.visually-hidden)) {
  grid-template-columns: minmax(0, 1fr) minmax(0, auto) minmax(0, 1fr) !important;
}

html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)) > .header-center {
  flex: 0 1 auto !important;
  justify-content: center !important;
  justify-self: center !important;
  min-width: 0 !important;
  width: auto !important;
  max-width: none !important;
}

/* Nos headers em flex (carrinho, checkout, loja) o mesmo efeito
   obtém-se com bases iguais. Em headers em grid estas declarações
   são inertes, e as de grid são inertes nos headers em flex.

   A largura fixa tem de cair junto: .loja-header .header-buttons
   trava o lado direito em 40px e sozinho o flex-grow não o liberta. */
html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)) > .header-left,
html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)) > .header-right {
  flex: 1 1 0 !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
}

html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)) > .header-left {
  justify-content: flex-start !important;
  justify-self: start !important;
}

html body[class] header[class]:has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)) > .header-right {
  justify-content: flex-end !important;
  justify-self: end !important;
}

/* Headers com o h1 como filho directo (ADM, transferências, cardápio,
   perfil do cliente). */
html body[class] header[class]:has(> h1:not(.visually-hidden)) > h1 {
  justify-self: center !important;
}

/* O header sobe até debaixo da barra de estado.

   Com viewport-fit=cover a página passa a ocupar o ecrã todo, incluindo
   a faixa da barra de estado. Sem esta regra o header ficava a começar
   por baixo dela e via-se a junção das duas superfícies. Dando ao header
   o env(safe-area-inset-top) como preenchimento, é o próprio header que
   pinta essa faixa — deixa de haver duas superfícies e, portanto, linha
   nenhuma entre elas.

   Fora da app instalada o inset é 0 e nada muda.

   O fixed-app-headers.js mede a altura real do header a cada mudança, por
   isso a reserva de espaço no body acompanha sozinha. */
html body[class] header[class]:is(
  .loja-header, .admin-header, .cart-header, .checkout-header,
  .delivery-header, .adm-v2-header, .transfer-page-header, .cardapio-header,
  .profile-topbar, .approved-mobile-header, .app-header, .loja-v2-header
) {
  padding-top: calc(var(--tp-header-pad-top, 8px) + env(safe-area-inset-top, 0px)) !important;
  border-top: 0 !important;
}

/* Nos headers de duas linhas (Inventário e Financeiro do ADM) a altura vem
   das linhas da grelha, não do preenchimento. Somar 8px em cima abria uma
   faixa vazia por baixo da barra de estado — aqui só entra o desvio. */
html body[class] header[class]:is(:has(> section), :has(> .filters-wrapper)) {
  --tp-header-pad-top: 0px;
}

/* Altura única para os headers com nome de página. Estavam entre 50px
   (perfil do cliente) e 65px (loja e carrinho).

   Ficam de fora os headers de duas linhas — o Financeiro do ADM leva a
   barra de filtros dentro do próprio header e uma altura fixa cortá-la-ia.
   Os 8px em cima e em baixo são o mínimo que deixa passar um botão de
   44px sem transbordar.

   A altura é mínima e não fixa: dentro da app instalada o header cresce o
   tanto da barra de estado, que ele próprio passa a pintar. */
@media (max-width: 768px) {
  html body[class] header[class]:not(:has(> section)):not(:has(> .filters-wrapper)):has(> .header-center > :is(h1:not(.visually-hidden), .page-title-pill)),
  html body[class] header[class]:not(:has(> section)):not(:has(> .filters-wrapper)):has(> h1:not(.visually-hidden)),
  /* Os headers que trocam o nome da página por um interruptor de secções
     (carrinho, produtos, inventário) e os do delivery, que embrulham as
     três partes num .dv-header-inner. */
  html body[class] header[class]:not(:has(> section)):not(:has(> .filters-wrapper)):has(> .header-center > :is(.cart-section-switch, .stock-section-switch)),
  html body[class] header[class]:not(:has(> section)):not(:has(> .filters-wrapper)):has(> .dv-header-inner) {
    min-height: calc(62px + env(safe-area-inset-top, 0px)) !important;
    height: auto !important;
    padding-bottom: 8px !important;
  }

  /* Com a altura a deixar de ser fixa, o interruptor do carrinho passou a
     empurrar o header para 67px enquanto os outros ficavam em 62. Antes
     não se via porque a altura fixa o cortava. Encolhe-se o interruptor
     em vez de voltar a cortá-lo. */
  html body.cart-body header[class] .cart-section-tab {
    min-height: 34px !important;
  }
}

/* O checkout e a política de reembolso mostravam o nome da página
   dentro de uma pastilha de 40px com ícone e texto de 13px. Passa a
   ser o mesmo título das outras páginas. */
html body[class] header[class] .page-title-pill {
  height: auto !important;
  min-height: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  font-family: var(--tp-page-title-font) !important;
  font-size: var(--tp-page-title-size) !important;
  font-weight: var(--tp-page-title-weight) !important;
  color: var(--tp-page-title-color) !important;
}

html body[class] header[class] .page-title-pill > i {
  display: none !important;
}

/* Nota: houve aqui uma regra que dava 62px a todos os headers de
   .loja-v2-page. Cortava o Inventário, cujo header tem duas linhas —
   a segunda leva a barra de filtros. A regra de altura acima já cobre
   estas páginas e conhece essa excepção. */

/* O fixed-app-headers.js já reserva a altura do header no <body>. O
   carrinho, o checkout e a política de reembolso somavam por cima a
   sua própria reserva de 78-80px e abriam uma faixa vazia por baixo do
   cabeçalho. As restantes páginas já tinham essa reserva anulada — só
   que a regra original exigia um companheiro fixo, que estas não têm. */
html body.app-fixed-header-page > :is(.cart-page-shell, .checkout-shell) {
  padding-top: 8px !important;
  margin-top: 0 !important;
}

/* ------------------------------------------------------------
   2. CÁPSULA ÚNICA — filtros e interruptores de secção
   O sistema já usava 999px na maioria dos sítios (carrinho, entregas,
   pedidos, delivery, caixa-histórico). Ficavam de fora: 12px no ADM,
   7px e 11px no cliente, 18px e 22px nos anúncios e no caixa.
   ------------------------------------------------------------ */

html body[class] :is(
  .filter-btn,
  .order-filter-btn,
  .purchase-filter-btn,
  .transfer-filter-btn,
  .transfer-history-filter-btn,
  .transfer-tab-btn,
  .tab-btn,
  .adm-v2-tab,
  .adm-section-btn,
  .stock-section-tab,
  .cart-section-tab,
  .anuncios-tab-btn,
  .client-tab-btn,
  .profile-tab-btn,
  .profile-tab,
  .dv-tab
) {
  border-radius: var(--tp-pill) !important;
}

/* O invólucro acompanha o botão: cápsula dentro de cápsula. */
html body[class] :is(
  .cart-section-switch,
  .stock-section-switch,
  .client-section-tabs,
  .anuncios-section-tabs,
  .dv-tabs-inner
) {
  border-radius: var(--tp-pill) !important;
}

/* .adm-section-switch e .profile-tabs são grelhas sem fundo próprio:
   o raio pertence só aos botões, senão aparece uma moldura fantasma. */

/* ------------------------------------------------------------
   4. LOGÓTIPO
   O mesmo "tuapele" estava declarado em vinte folhas com pesos
   diferentes: o "tua" ora a 300 ora a 400 (a Great Vibes só tem 400,
   o 300 era inventado pelo navegador), o "pele" ora a 600, ora a 650,
   ora a 900 — e o 900 nunca existiu, a família vai só até 700 e nem
   esse era descarregado. Daí umas páginas terem um "pele" fino e
   outras um "pele" borrado pelo -webkit-text-stroke que tentava
   compensar.

   Aqui fica um só desenho: "tua" na script, "pele" na serif a 700 com
   um traço fino. Os TAMANHOS não são tocados — cada contexto (header,
   gaveta, rodapé, loader, hero do login) mantém o seu, e a proporção
   entre as duas metades continua a que já estava desenhada.
   ------------------------------------------------------------ */

html body[class] span.logo-tua[class] {
  font-family: var(--tp-logo-script) !important;
  font-weight: 400 !important;
  font-style: normal !important;
  color: var(--tp-logo-cor-tua) !important;
  -webkit-text-stroke-width: 0 !important;
}

html body[class] span.logo-pele[class] {
  font-family: var(--tp-logo-serif) !important;
  font-weight: 700 !important;
  font-style: normal !important;
  color: var(--tp-logo-cor-pele) !important;
  letter-spacing: -0.03em !important;
  /* currentColor para o traço seguir a cor da própria palavra. */
  -webkit-text-stroke: var(--tp-logo-stroke) currentColor !important;
  paint-order: stroke fill;
}

/* ------------------------------------------------------------
   11. BATIMENTO DAS FAIXAS DE AVISO
   Duas pulsações seguidas e uma pausa longa, como um coração. O
   movimento é para a frente e para trás — escala, não deslocação —
   para a faixa não empurrar nada à volta enquanto bate.

   1,6% de crescimento chega para o olho apanhar sem ser irritante:
   estas faixas ficam no ecrã até serem resolvidas, e uma animação
   forte a repetir-se sem fim cansa depressa.
   ------------------------------------------------------------ */

@keyframes tpBatimento {
  0%   { transform: scale(1); }
  8%   { transform: scale(1.016); }
  16%  { transform: scale(1); }
  24%  { transform: scale(1.012); }
  32%  { transform: scale(1); }
  100% { transform: scale(1); }   /* a pausa entre batimentos */
}

.pwa-install-bar,
.perfil-incompleto-bar {
  transform-origin: center;
  will-change: transform;
  animation: tpBatimento 2.6s ease-in-out infinite;
}

/* Enquanto o dedo está em cima, o batimento pára: ninguém quer acertar
   num alvo que se mexe. */
.pwa-install-bar:hover,
.pwa-install-bar:focus-within,
.pwa-install-bar:active,
.perfil-incompleto-bar:hover,
.perfil-incompleto-bar:focus-within,
.perfil-incompleto-bar:active {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .pwa-install-bar,
  .perfil-incompleto-bar {
    animation: none;
  }
}

/* ------------------------------------------------------------
   10. FAIXA DE PERFIL INCOMPLETO
   Quem entra pelo Google, Apple ou Microsoft chega sem telefone, sem
   província e sem ponto de entrega. A faixa vive no fluxo normal,
   logo abaixo do header — nada de position:fixed a tapar produtos.
   ------------------------------------------------------------ */

.perfil-incompleto-bar {
  width: 100%;
  margin: 0 0 16px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 11px;
  border: 1px solid rgba(192, 154, 43, .32);
  border-radius: 18px;
  background: #FDF7E8;
  color: #5C3020;
}

.perfil-incompleto-icone {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: #F4E6C3;
  color: #8A6A17;
  font-size: 15px;
}

.perfil-incompleto-texto {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.perfil-incompleto-texto strong {
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  color: #5C3020;
}

.perfil-incompleto-texto span {
  font-size: 11.5px;
  line-height: 1.35;
  color: #7A6154;
}

.perfil-incompleto-bar .perfil-incompleto-btn {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  border: 0 !important;
  border-radius: 999px !important;
  background: #5C3020 !important;
  color: #FFFFFF !important;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  text-decoration: none;
}

@media (max-width: 380px) {
  .perfil-incompleto-texto span { display: none; }
  .perfil-incompleto-bar { gap: 9px; padding: 9px 10px; }
}

/* ------------------------------------------------------------
   9. ABAS DO PERFIL DO CLIENTE
   A barra estava com padding 0: as pastilhas encostavam ao header em
   cima, à linha em baixo e às margens dos lados. Ganha o mesmo ar que
   a barra de abas do vendedor já tinha.
   ------------------------------------------------------------ */

html body.profile-body .profile-tabs {
  padding: 9px 16px 10px !important;
  gap: 8px !important;
}

html body.profile-body .profile-tab-btn {
  min-height: 40px !important;
}

/* As iniciais do avatar eram a única coisa em serif nesta zona. */
html body.profile-body .profile-avatar-initials {
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif !important;
  font-weight: 700 !important;
  letter-spacing: 0.02em !important;
}

/* ------------------------------------------------------------
   6. RESUMO DA COMISSÃO DO GATEWAY (cadastro e edição de produto)
   Mostra ao vendedor as três parcelas em jogo: o que o cliente paga,
   o que a PaySuite retém e o que sobra para a loja.
   ------------------------------------------------------------ */

.gateway-hint {
  margin: 10px 0 4px;
  padding: 10px 12px;
  display: grid;
  gap: 5px;
  border: 1px solid #EDE3D9;
  border-radius: 14px;
  background: #F7F1EA;
}

.gateway-hint[hidden] { display: none !important; }

.gateway-hint-linha {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12px;
  line-height: 1.3;
  color: #7A6154;
}

.gateway-hint-linha i {
  width: 15px;
  flex: 0 0 auto;
  text-align: center;
  font-size: 11px;
  color: #A8887A;
}

.gateway-hint-linha strong {
  margin-left: auto;
  font-size: 13px;
  font-weight: 700;
  color: #5C3020;
  white-space: nowrap;
}

.gateway-hint-linha.is-total {
  margin-top: 3px;
  padding-top: 7px;
  border-top: 1px solid #EDE3D9;
  color: #5C3020;
}

.gateway-hint-linha.is-total i { color: #6E7F63; }
.gateway-hint-linha.is-total strong { font-size: 15px; }

/* Interruptor de linha: usado no "frete grátis" das páginas de produto. */
.switch-linha {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 2px;
  cursor: pointer;
}

/* A `.switch-linha` deixou de ser usada: o frete e o reembolso passaram a
   usar o mesmo `.switch` + `.slider` de "Status e Visibilidade", para não
   haver dois desenhos de interruptor na mesma página. A regra fica para o
   caso de alguma página antiga ainda a usar. */
.switch-linha input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: #5C3020;
  cursor: pointer;
}

.switch-linha span {
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 13.5px;
  font-weight: 500;
  color: #3A2118;
}

/* ------------------------------------------------------------
   7. PONTO NO MAPA (endereço do cliente)
   O endereço escrito continua a mandar; o mapa é um extra que dá ao
   motoboy o sítio exacto e à loja a zona de frete certa.
   ------------------------------------------------------------ */

.local-mapa-ajuda {
  margin: 0 0 8px;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12px;
  line-height: 1.45;
  color: #7A6154;
}

.local-mapa {
  width: 100%;
  height: 210px;
  border-radius: 16px;
  border: 1px solid #EDE3D9;
  background: #F7F1EA;
  overflow: hidden;
}

/* O aviso que o mapa.js escreve quando não há chave ou o Google recusa. */
.local-mapa .mapa-aviso {
  height: 100%;
  display: grid;
  place-items: center;
  gap: 8px;
  padding: 18px;
  text-align: center;
  color: #7A6154;
  font-size: 12.5px;
  line-height: 1.5;
}

.local-mapa .mapa-aviso i { font-size: 20px; color: #A8887A; }

.local-mapa-acoes {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.local-mapa-acoes .local-mapa-btn {
  min-height: 40px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid #EDE3D9 !important;
  border-radius: 999px !important;
  background: #FFFFFF !important;
  color: #5C3020 !important;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.local-mapa-acoes .local-mapa-btn.is-primary {
  border-color: #5C3020 !important;
  background: #5C3020 !important;
  color: #FFFFFF !important;
}

.local-mapa-acoes .local-mapa-btn:disabled { opacity: 0.6; cursor: progress; }
.local-mapa-acoes .local-mapa-btn[hidden] { display: none !important; }

.local-mapa-estado {
  margin: 9px 0 0;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 11.5px;
  line-height: 1.45;
  color: #7A6154;
}

.local-mapa-estado.is-ok { color: #43533B; font-weight: 600; }

.label-opcional {
  font-weight: 500;
  opacity: 0.7;
}

/* Dentro do modal de Minhas Compras o mapa é mais baixo: o cartão já
   está apertado entre a barra de título e o botão de confirmar. */
.tua-modal .local-mapa { height: 180px; }
.tua-modal .local-mapa-campo { margin: 4px 0 2px; }

/* ------------------------------------------------------------
   8. ÁREAS DE FRETE (página do gestor)
   O gestor desenha o contorno de cada bairro em vez de contar com o
   nome que o cliente escreve.
   ------------------------------------------------------------ */

.zona-linha {
  padding: 10px 0;
  border-top: 1px solid rgba(92, 48, 32, .10);
  display: grid;
  gap: 8px;
}

.zona-linha-topo {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) 92px;
  gap: 8px;
  align-items: center;
}

/* A cor com que esta zona é desenhada no mapa. É o que liga a linha da
   tabela ao contorno lá em baixo: com cinco bairros desenhados ao mesmo
   tempo, sem isto ninguém sabe qual é qual. */
.zona-cor {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--zona-cor, #8b4a2e);
}

.zona-linha-acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.area-mapa {
  width: 100%;
  height: 300px;
  margin-top: 4px;
  border-radius: 16px;
  border: 1px solid #EDE3D9;
  background: #F7F1EA;
  overflow: hidden;
}

.area-mapa .mapa-aviso {
  height: 100%;
  display: grid;
  place-items: center;
  gap: 8px;
  padding: 18px;
  text-align: center;
  color: #7A6154;
  font-size: 12.5px;
  line-height: 1.5;
}

.area-mapa .mapa-aviso i { font-size: 20px; color: #A8887A; }

.area-acoes {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.area-acoes .area-btn {
  min-height: 40px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid #EDE3D9 !important;
  border-radius: 999px !important;
  background: #FFFFFF !important;
  color: #5C3020 !important;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.area-acoes .area-btn.is-primary {
  border-color: #5C3020 !important;
  background: #5C3020 !important;
  color: #FFFFFF !important;
}

.area-acoes .area-btn[hidden] { display: none !important; }

/* ---------- o cursor do raio da zona de frete ----------
   Fica por baixo do mapa e não dentro dele: um cursor por cima do mapa
   partilha o gesto de arrastar com o próprio mapa, e cada tentativa de
   abrir o raio saía a mexer o mapa. */
.raio-controlo {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid #EDE3D9;
  border-radius: 16px;
  background: #FFFFFF;
}

.raio-etiqueta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: #7A6154;
}

/* O número tem de ser o que mais se vê: é ele que o gestor lê enquanto
   arrasta, não a palavra "raio". */
.raio-valor {
  font-size: 16px;
  font-weight: 700;
  color: #5C3020;
  font-variant-numeric: tabular-nums;
}

.raio-cursor {
  width: 100%;
  margin: 10px 0 0;
  accent-color: #5C3020;
  cursor: pointer;
}

/* Alvo de 28px de altura: o polegar não acerta na linha de 4px que o
   navegador desenha por omissão. */
.raio-cursor {
  height: 28px;
  background: transparent;
}

.raio-atalhos {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.raio-atalhos .area-btn {
  min-height: 34px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  border: 1px solid #EDE3D9;
  border-radius: 999px;
  background: #FFFFFF;
  color: #5C3020;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.area-estado {
  margin: 9px 0 0;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 11.5px;
  line-height: 1.45;
  color: #7A6154;
}

.area-estado.is-ok { color: #43533B; font-weight: 600; }

#freightOverlapWarn {
  margin-top: 8px;
  padding: 9px 11px;
  border-radius: 12px;
  border: 1px solid rgba(192, 57, 43, .28);
  background: #FBEDEB;
  color: #A93428 !important;
  line-height: 1.45;
}

#freightOverlapWarn[hidden] { display: none !important; }

/* ------------------------------------------------------------
   5. FAIXA DE INSTALAÇÃO DA PWA
   Vive no fluxo normal do index, logo abaixo do header. Nada de
   position:fixed — era assim que taparia o primeiro produto.
   ------------------------------------------------------------ */

.pwa-install-bar {
  width: 100%;
  margin: 0 0 16px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 11px;
  border: 1px solid #EDE3D9;
  border-radius: 18px;
  background: #F7EDE3;
  color: #5C3020;
}

.pwa-install-bar[hidden] {
  display: none !important;
}

.pwa-install-icon {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 1px solid #EDE3D9;
  background: #FFFFFF;
  object-fit: contain;
}

.pwa-install-texto {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pwa-install-texto strong {
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.2;
  color: #5C3020;
}

.pwa-install-texto span {
  font-size: 11.5px;
  line-height: 1.35;
  color: #7A6154;
}

.delivery-body .pwa-install-btn,
.loja-body .pwa-install-btn,
.pwa-install-bar .pwa-install-btn {
  flex: 0 0 auto;
  min-height: 38px;
  padding: 0 16px;
  border: 0 !important;
  border-radius: 999px !important;
  background: #5C3020 !important;
  color: #FFFFFF !important;
  font-family: var(--fonte-corpo), 'DM Sans', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}

.pwa-install-bar .pwa-install-btn:disabled {
  opacity: 0.6;
  cursor: progress;
}

.pwa-install-bar .pwa-install-fechar {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  min-width: 30px;
  display: inline-grid;
  place-items: center;
  border: 0 !important;
  border-radius: 50% !important;
  background: transparent !important;
  color: #7A6154 !important;
  font-size: 14px;
  cursor: pointer;
}

.pwa-install-bar .pwa-install-fechar:hover,
.pwa-install-bar .pwa-install-fechar:focus-visible {
  outline: none;
  background: #EDE3D9 !important;
}

/* Ecrãs estreitos: o texto de apoio sai antes de espremer o botão. */
@media (max-width: 380px) {
  .pwa-install-texto span { display: none; }
  .pwa-install-bar { gap: 9px; padding: 9px 10px; }
}

/* Dentro da app instalada a faixa não faz sentido nenhum. O pwa.js já a
   esconde; isto garante que nem pisca antes de o script correr. */
@media (display-mode: standalone), (display-mode: minimal-ui), (display-mode: fullscreen) {
  .pwa-install-bar { display: none !important; }
}

/* ------------------------------------------------------------
   3. CAMADAS FIXAS vs. BARRA INFERIOR
   A barra inferior (.tua-bottom-nav) está em z-index 2100 e ocupa os
   66px de baixo do ecrã em telemóvel. Tudo o que é fixo em baixo tem
   de a contornar — ou por cima dela em z-index (modais e folhas), ou
   acima dela em geometria (barras de acção permanentes).
   ------------------------------------------------------------ */

/* Uma escala só para tudo o que flutua.

   O que havia antes: z-index entre 1600 e 25000 espalhados por vinte
   folhas, e a barra inferior em 2100 — excepto nas dez páginas da loja,
   onde o loja-v2.css a punha em 5000. Qualquer folha abaixo disso ficava
   tapada por ela, e em pedidos a lista de motoboys (2200) nascia por
   baixo da folha de detalhes do pedido (7000).

   Quatro degraus, e nada fora deles:
     barra inferior  2100
     folhas          3000   primeiro nível
     popups          3600   o que abre POR CIMA de uma folha
     confirmações    3800   o "tens a certeza?" de um popup

   Fica de fora, de propósito: .tp-select-popup (40000, tem de cobrir
   tudo, incluindo popups) e .image-modal (10000, a foto em ecrã inteiro
   na página de produto). */

html body[class] .tua-bottom-nav {
  z-index: var(--tp-z-nav) !important;
}

html body[class] :is(
  .bottom-sheet,
  .sheet-overlay,
  .sheet-backdrop,
  .ad-bottom-sheet,
  .product-options-sheet,
  .product-picker-sheet,
  .transfer-product-sheet,
  .expense-bottom-sheet,
  .adm-v2-sheet,
  .cash-products-sheet,
  .countdown-picker-sheet,
  .dashboard-sheet-overlay,
  .period-overlay,
  .period-modal,
  .adm-chat-painel
) {
  z-index: var(--tp-z-sheet) !important;
}

html body[class] :is(
  .selection-modal,
  .modal-overlay,
  .sale-detail-modal,
  .tua-inline-modal,
  .tp-popup-overlay,
  .welcome-card-overlay,
  .meta-overlay,
  .transfer-history-sheet
) {
  z-index: var(--tp-z-popup) !important;
}

/* A confirmação abre por cima do popup que a pediu — em pedidos, o
   "tens a certeza?" nasce com a lista de motoboys ainda aberta. */
html body[class] :is(
  #confirm-modal,
  .profile-confirm-modal,
  .tp-confirm-card,
  .tua-confirm-overlay
) {
  z-index: var(--tp-z-confirm) !important;
}

/* Um popup é um popup: centrado e com os quatro cantos arredondados.
   O loja-v2.css transformava os da página de pedidos em folhas —
   encostados em baixo e com os cantos de baixo a direito. */
html body[class] .selection-modal {
  align-items: center !important;
  justify-content: center !important;
  padding: 18px !important;
}

html body[class] .selection-modal > :is(
  .selection-modal-content,
  .delivery-modal-content,
  .confirm-content
) {
  width: min(560px, 100%) !important;
  max-width: min(560px, 100%) !important;
  margin: 0 auto !important;
  border-radius: 22px !important;
  padding-bottom: 0 !important;
}

/* O punho de arrastar é de folhas. Num popup centrado não serve para
   nada e ainda sugere que se puxa para baixo para fechar. */
html body[class] .selection-modal .selection-modal-header::before {
  display: none !important;
}

/* A barra do carrinho era a única barra de acção permanente sem o
   desvio: ficava em bottom:0 e z-index 1080, por baixo da barra
   inferior, e o botão "Continuar" desaparecia em telemóvel. Passa a
   usar o mesmo desvio de .profile-save-bar e .adm-v2-fab. */
@media (max-width: 768px) {
  html body.cart-body.has-tua-bottom-nav .cart-bottom-bar {
    bottom: var(--tp-nav-gap) !important;
    z-index: 2099 !important;
  }

  /* Espaço para a barra + a navegação, senão o último produto da
     lista fica escondido por baixo das duas. */
  html body.cart-body.has-tua-bottom-nav .cart-page-shell {
    padding-bottom: calc(var(--tp-nav-h) + 168px + env(safe-area-inset-bottom)) !important;
  }

  /* Em pagamentos pendentes a barra não existe (regra do carrinho.css)
     e essa reserva toda deixaria um vazio no fim da lista. */
  html body.cart-body.pending-mode.has-tua-bottom-nav .cart-page-shell {
    padding-bottom: calc(var(--tp-nav-h) + 24px + env(safe-area-inset-bottom)) !important;
  }
}

/* =========================================================
   Pedido de permissões pós-login (js/permissoes.js)
   Abre acima de tudo: é a primeira coisa que se vê depois de entrar.
   ========================================================= */
.tp-permissoes-fundo {
    position: fixed;
    inset: 0;
    z-index: var(--tp-z-confirm);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(28, 14, 8, 0.55);
    backdrop-filter: blur(3px);
    opacity: 0;
    transition: opacity 0.2s ease;
}

.tp-permissoes-fundo.is-aberto {
    opacity: 1;
}

.tp-permissoes-cartao {
    width: min(420px, 100%);
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    padding: 22px 20px 18px;
    border-radius: 22px;
    background: #fff;
    box-shadow: 0 24px 60px rgba(28, 14, 8, 0.35);
    transform: translateY(14px) scale(0.98);
    transition: transform 0.22s ease;
}

.tp-permissoes-fundo.is-aberto .tp-permissoes-cartao {
    transform: translateY(0) scale(1);
}

.tp-permissoes-topo {
    text-align: center;
}

.tp-permissoes-selo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(92, 48, 32, 0.09);
    color: var(--marrom, #5c3020);
    font-size: 1.25rem;
}

.tp-permissoes-topo h2 {
    margin: 12px 0 6px;
    font-family: var(--tp-page-title-font);
    font-size: 1.2rem;
    color: var(--marrom, #5c3020);
}

.tp-permissoes-topo p {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.45;
    color: var(--texto-medio, #6b5a52);
}

.tp-permissoes-lista {
    list-style: none;
    margin: 18px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
}

.tp-permissoes-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px;
    border-radius: 16px;
    background: rgba(92, 48, 32, 0.05);
    border: 1px solid rgba(92, 48, 32, 0.12);
}

.tp-permissoes-icone {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 12px;
    background: #fff;
    color: var(--marrom, #5c3020);
}

.tp-permissoes-texto {
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--texto-medio, #6b5a52);
}

.tp-permissoes-texto strong {
    display: block;
    margin-bottom: 2px;
    font-size: 0.87rem;
    color: var(--texto-escuro, #3b2a22);
}

.tp-permissoes-acoes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-top: 18px;
}

.tp-permissoes-btn {
    padding: 13px 12px;
    border: 0;
    border-radius: var(--tp-pill);
    font-weight: 900;
    font-size: 0.88rem;
    cursor: pointer;
}

.tp-permissoes-btn.is-primario {
    background: linear-gradient(135deg, #7a3f26, #5c3020);
    color: #fff;
}

.tp-permissoes-btn.is-primario:disabled {
    opacity: 0.7;
    cursor: default;
}

.tp-permissoes-btn.is-secundario {
    background: rgba(92, 48, 32, 0.08);
    color: var(--marrom, #5c3020);
}

.tp-permissoes-link {
    display: block;
    margin-top: 12px;
    text-align: center;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--texto-medio, #6b5a52);
    text-decoration: underline;
}

/* =========================================================
   Contador do carrinho na barra inferior (js/bottom-nav.js)
   Só aparece com alguma coisa dentro — um "0" permanente é ruído.
   ========================================================= */
html body[class] .tua-bottom-nav > a {
    position: relative;
}

html body[class] .tua-bottom-nav .tua-nav-conta {
    position: absolute;
    top: 2px;
    left: 50%;
    margin-left: 3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    border: 2px solid #fff;
    background: #c0392b;
    color: #fff;
    font-size: 9.5px;
    font-weight: 900;
    line-height: 1;
    pointer-events: none;
}

/* O `hidden` da folha do browser perde para o `display` acima. */
html body[class] .tua-bottom-nav .tua-nav-conta[hidden] {
    display: none !important;
}

/* =========================================================
   SEM LIGAÇÃO (js/sem-ligacao.js)
   Cobre tudo, inclusive a confirmação: se não há rede, não há acção nenhuma
   por baixo que valha a pena tocar.
   ========================================================= */
.tp-offline {
    position: fixed;
    inset: 0;
    z-index: calc(var(--tp-z-confirm) + 100);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(28, 14, 8, 0.94);
    backdrop-filter: blur(4px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.24s ease, visibility 0.24s ease;
}

.tp-offline.is-aberto {
    opacity: 1;
    visibility: visible;
}

.tp-offline-caixa {
    width: min(340px, 100%);
    text-align: center;
    color: #F7F1EA;
    transform: translateY(12px);
    transition: transform 0.26s ease;
}

.tp-offline.is-aberto .tp-offline-caixa {
    transform: none;
}

/* O símbolo: o Wi-Fi com um traço por cima, desenhado com um pseudo-elemento
   em vez de um ícone próprio — o Font Awesome grátis não traz "wifi-slash". */
.tp-offline-icone {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 92px;
    height: 92px;
    border-radius: 50%;
    background: rgba(247, 241, 234, 0.08);
    color: rgba(247, 241, 234, 0.55);
    font-size: 2.1rem;
}

.tp-offline-corte {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 74px;
    height: 3px;
    border-radius: 3px;
    background: #E0645A;
    box-shadow: 0 0 0 2px rgba(28, 14, 8, 0.94);
    transform: translate(-50%, -50%) rotate(-45deg);
    transform-origin: center;
}

.tp-offline.is-aberto .tp-offline-corte {
    animation: tpOfflineCorta 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.tp-offline.is-aberto .tp-offline-icone i {
    animation: tpOfflinePulsa 2.4s ease-in-out infinite;
}

.tp-offline-caixa h2 {
    margin: 18px 0 8px;
    font-family: var(--tp-page-title-font);
    font-size: 1.35rem;
    color: #F7F1EA;
}

.tp-offline-caixa p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.5;
    color: rgba(247, 241, 234, 0.72);
}

.tp-offline-btn {
    margin-top: 20px;
    padding: 13px 26px;
    border: 0;
    border-radius: var(--tp-pill, 999px);
    background: #F7F1EA;
    color: #5C3020;
    font-size: 0.9rem;
    font-weight: 900;
    cursor: pointer;
}

.tp-offline-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.tp-offline-nota {
    margin-top: 12px !important;
    font-size: 0.76rem !important;
    color: rgba(247, 241, 234, 0.5) !important;
}

@keyframes tpOfflineCorta {
    from { width: 0; opacity: 0; }
    to   { width: 74px; opacity: 1; }
}

@keyframes tpOfflinePulsa {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 0.24; }
}

@media (prefers-reduced-motion: reduce) {
    .tp-offline,
    .tp-offline-caixa,
    .tp-offline .tp-offline-corte,
    .tp-offline .tp-offline-icone i {
        animation: none !important;
        transition: opacity 0.01s linear, visibility 0.01s linear !important;
        transform: none !important;
    }
    .tp-offline-corte { transform: translate(-50%, -50%) rotate(-45deg) !important; }
}

/* =========================================================
   PRODUTO A VOAR PARA O CARRINHO (js/voar-carrinho.js)
   A cópia vive no <body> em position:fixed: dentro do cartão, qualquer
   overflow:hidden pelo caminho cortava-a a meio do trajecto.
   ========================================================= */
.tp-voa-carrinho {
    position: fixed;
    z-index: calc(var(--tp-z-confirm) + 50);
    object-fit: cover;
    border-radius: 14px;
    box-shadow: 0 12px 30px rgba(28, 14, 8, 0.28);
    pointer-events: none;
    /* Curva com sobreimpulso no início: o produto "salta" antes de partir. */
    transition: transform 0.72s cubic-bezier(0.32, 0.8, 0.24, 1),
                opacity 0.72s ease-in,
                border-radius 0.72s ease;
    will-change: transform, opacity;
}

/* O ícone do carrinho responde à chegada — sem isto, a viagem acaba no vazio. */
.tua-bottom-nav a.tp-carrinho-recebe i,
.header-cart-btn.tp-carrinho-recebe i {
    animation: tpCarrinhoRecebe 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes tpCarrinhoRecebe {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.42) rotate(-8deg); }
    60%  { transform: scale(0.92) rotate(4deg); }
    100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .tp-voa-carrinho { display: none !important; }
    .tua-bottom-nav a.tp-carrinho-recebe i,
    .header-cart-btn.tp-carrinho-recebe i { animation: none !important; }
}

/* =========================================================
   CAMPOS SEM CLASSE
   ------------------------------------------------------------
   O reset do global.css põe `padding: 0` em tudo, e as regras de campo do
   sistema são todas por classe (.input, .form-control, .tp-search-input...).
   Um <input> escrito sem classe nenhuma — como os da página Frete por Zona —
   fica com a caixa desenhada mas o texto colado à borda esquerda.

   `:not([class])` é de propósito: não toca em nenhum campo já estilizado.
   Em particular não toca nos campos de login e cadastro, que são de linha
   (sem caixa) e têm 2px à esquerda de propósito, para o texto assentar sobre
   o traço.
   ========================================================= */
html body[class] :is(input, select, textarea):not([class]):not([type="range"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="hidden"]) {
    padding: 11px 14px;
    min-height: 44px;
    line-height: 1.3;
}

/* Um <select> reserva espaço à direita para a seta do sistema. */
html body[class] select:not([class]) {
    padding-right: 34px;
}

html body[class] textarea:not([class]) {
    min-height: 88px;
    padding-top: 12px;
}

/* =========================================================
   ORIENTAÇÃO EXIF DAS IMAGENS
   ------------------------------------------------------------
   Fotos tiradas com o telemóvel guardam a rotação num campo EXIF em vez de
   rodarem os pixels. Quem as lê sem olhar para esse campo mostra-as deitadas.
   `from-image` é o padrão do browser para <img>, mas basta uma folha antiga
   pôr `image-orientation: none` num seletor largo para o perder — e num
   catálogo de cosméticos um produto ao contrário estraga a página inteira.
   ========================================================= */
html body[class] img {
    image-orientation: from-image;
}

/* =========================================================
   EXPANDIR O MAPA (js/mapa-expandir.js)
   ------------------------------------------------------------
   Canto SUPERIOR direito, de propósito: os mapas do sistema usam
   `disableDefaultUI` com `zoomControl: true`, e o Google põe o "+" e o "−"
   no canto inferior direito. É também onde o próprio Google põe o botão de
   ecrã inteiro quando está ligado — a mão já o procura aí.
   ========================================================= */
.tp-mapa-wrap {
    position: relative;
}

.tp-mapa-expandir {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 3;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(92, 48, 32, 0.16);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.96);
    color: var(--marrom, #5c3020);
    font-size: 14px;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(28, 14, 8, 0.18);
}

.tp-mapa-wrap.is-cheio {
    position: fixed;
    inset: 0;
    z-index: var(--tp-z-confirm);
    border-radius: 0;
    background: #fff;
}

/* O que entra aqui é o próprio mapa, e esse ocupa o ecrã todo. O botão de
   reduzir e o cursor do raio são camadas por cima: esticá-los a 100% da
   altura punha um cursor de 30px a ocupar o ecrã inteiro. */
.tp-mapa-wrap.is-cheio > :not(.tp-mapa-expandir):not(.raio-controlo) {
    width: 100% !important;
    height: 100% !important;
    max-height: none !important;
    border-radius: 0 !important;
}

/* ---------- o cursor do raio por cima do mapa em ecrã inteiro ----------
   Em cima e não em baixo: o Google põe o zoom e o botão "onde estou" no
   canto inferior direito, e um cartão em baixo tapava-os. O recuo à
   direita é o que deixa passar o botão de reduzir. */
.raio-controlo.is-sobre-mapa {
    position: absolute;
    top: calc(12px + env(safe-area-inset-top));
    left: 12px;
    right: 70px;
    z-index: 4;
    margin: 0;
    max-width: 460px;
    background: rgba(255, 255, 255, 0.97);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    box-shadow: 0 10px 30px rgba(92, 48, 32, 0.22);
}

.tp-mapa-wrap.is-cheio .tp-mapa-expandir {
    top: calc(12px + env(safe-area-inset-top));
    right: 12px;
    width: 46px;
    height: 46px;
}

/* Com o mapa aberto nada se desloca por baixo e a barra sai da frente. */
body.tp-mapa-cheio { overflow: hidden; }
body.tp-mapa-cheio .tua-bottom-nav { display: none !important; }

/* =========================================================
   CABEÇALHOS E FILTROS FIXOS — o que os impedia de o ser
   ------------------------------------------------------------
   A barra de filtros do index tinha `position: sticky` e nunca segurava.
   Duas razões, ambas em antepassados dela:

   1. `main.content-wrapper` corre uma animação de entrada (contentSlideUp)
      com `fill-mode: forwards`. Terminada a animação, o elemento fica com
      `transform: matrix(1,0,0,1,0,0)` — uma matriz identidade, mas ainda
      assim UM transform. Um antepassado transformado passa a ser o bloco
      de contenção dos descendentes: `sticky` deixa de ver o scroll da
      página e `fixed` passa a ser relativo a ele em vez do ecrã. Uma
      animação decorativa de 800ms ficava a segurar a página para sempre.

   2. `.products-container` tem `overflow: hidden`, e um `sticky` é
      confinado pelo primeiro antepassado com overflow diferente de visible.

   Aqui devolve-se o transform a `none` depois de a animação correr, e
   troca-se o recorte por `clip` só no eixo horizontal — que é o que a
   página realmente precisa (evitar barra lateral), sem prender o sticky.
   ========================================================= */
html body.loja-body > main.content-wrapper {
    animation-fill-mode: none !important;
    opacity: 1 !important;
    transform: none !important;
}

html body.loja-body .products-container {
    overflow: visible !important;
}

/* A barra de filtros do index encosta ao cabeçalho e fica lá. */
html body.loja-body #filtersWrapper {
    position: sticky !important;
    top: var(--app-fixed-top-stack-height, 56px) !important;
    z-index: calc(var(--tp-z-nav) - 10);
    background: rgba(245, 234, 224, 0.94);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid rgba(92, 48, 32, 0.10);
}

/* O `overflow-x: hidden` no <body> — posto para não haver barra lateral —
   força o `overflow-y` a `auto`, e um eixo em `auto` faz do <body> um
   contentor de scroll. Um `position: sticky` lá dentro passa a colar-se a
   ESSE contentor, que nunca rola (quem rola é o documento), e por isso nunca
   colava a nada.

   `clip` recorta exactamente como `hidden` mas NÃO cria contentor de scroll:
   o eixo vertical fica `visible` e o sticky volta a ver o scroll da página. */
html body[class] {
    overflow-x: clip !important;
    overflow-y: visible !important;
}

/* =========================================================
   DESKTOP (>= 1024px)
   ------------------------------------------------------------
   TUDO neste bloco vive dentro do @media. O desenho de telemóvel está
   aprovado e não pode ser tocado: acima de 1024px é que a barra inferior dá
   lugar à gaveta lateral e ao rodapé.

   Abaixo de 1024px os elementos laterais são criados na mesma pelo
   bottom-nav.js, mas nunca são mostrados — assim não há um segundo caminho
   de código a decidir o que aparece, só uma regra de largura.
   ========================================================= */

/* Fora do desktop, a lateral e o rodapé novo não existem para o olho. */
.tua-side-nav,
.tua-desk-footer { display: none; }

@media (min-width: 1024px) {
    :root { --tp-side-w: 248px; }

    /* A barra inferior é um padrão de polegar: num portátil fica longe de
       tudo e rouba altura útil. */
    html body[class] .tua-bottom-nav { display: none !important; }

    html body.has-tua-side-nav {
        padding-left: var(--tp-side-w);
        padding-bottom: 0 !important;
    }

    /* ---------- gaveta sempre aberta ---------- */
    html body[class] .tua-side-nav {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: var(--tp-z-nav);
        width: var(--tp-side-w);
        display: flex;
        flex-direction: column;
        gap: 26px;
        padding: 26px 18px calc(18px + env(safe-area-inset-bottom));
        background: #fff;
        border-right: 1px solid rgba(92, 48, 32, 0.12);
        overflow-y: auto;
    }

    .tua-side-brand {
        display: inline-flex;
        align-items: baseline;
        gap: 3px;
        padding-left: 8px;
        text-decoration: none;
    }
    .tua-side-brand .logo-tua { font-size: 2rem; }
    .tua-side-brand .logo-pele { font-size: 1.35rem; }

    .tua-side-links { display: flex; flex-direction: column; gap: 4px; }

    html body[class] .tua-side-nav .tua-side-links a {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 12px 14px;
        border-radius: 14px;
        color: var(--marrom, #5c3020);
        font-size: 0.92rem;
        font-weight: 700;
        text-decoration: none;
        transition: background 0.16s ease, color 0.16s ease;
    }
    html body[class] .tua-side-nav .tua-side-links a i {
        width: 20px;
        text-align: center;
        font-size: 1rem;
        opacity: 0.85;
    }
    html body[class] .tua-side-nav .tua-side-links a:hover {
        background: rgba(92, 48, 32, 0.06);
    }
    html body[class] .tua-side-nav .tua-side-links a.is-active {
        background: var(--marrom, #5c3020);
        color: #fff;
    }
    html body[class] .tua-side-nav .tua-side-links a.is-active i { opacity: 1; }

    .tua-side-lema {
        margin: auto 0 0;
        padding-left: 8px;
        color: var(--texto-medio, #8b7a72);
        font-size: 0.74rem;
        font-style: italic;
    }

    /* ---------- o cabeçalho fixo passa a começar depois da gaveta ---------- */
    html body.has-tua-side-nav header[class] {
        left: var(--tp-side-w) !important;
        width: calc(100% - var(--tp-side-w)) !important;
    }
    html body.has-tua-side-nav .app-header-companion-fixed {
        left: var(--tp-side-w) !important;
        width: calc(100% - var(--tp-side-w)) !important;
    }

    /* ---------- conteúdo centrado e com largura de leitura ---------- */
    html body.has-tua-side-nav > main,
    html body.has-tua-side-nav > .content-wrapper,
    html body.has-tua-side-nav > main.content-wrapper {
        width: min(100%, 1180px) !important;
        max-width: 1180px !important;
        margin-inline: auto !important;
    }

    /* Os carrosséis passam a grelha.
       Num telemóvel arrastar de lado é natural e o carrossel é a forma certa.
       Num ecrã de 1180px, o mesmo carrossel mostrava a primeira ficha cortada
       ao meio e escondia as outras atrás de um arrasto que ninguém faz com
       rato. Com espaço a sobrar, as fichas quebram em linhas e vê-se tudo. */
    html body.loja-body .products-container,
    html body.loja-body .horizontal-section {
        overflow: visible !important;
    }
    html body.loja-body .products-horizontal-grid {
        flex-wrap: wrap !important;
        overflow-x: visible !important;
        justify-content: flex-start !important;
        gap: 16px !important;
    }
    html body.loja-body .products-horizontal-grid > * {
        flex: 0 1 clamp(200px, calc((100% - 64px) / 5), 260px) !important;
    }

    /* A marca já está na gaveta: repeti-la no cabeçalho é dizer duas vezes a
       mesma coisa, e no index o lema ainda se sobrepunha ao logótipo. */
    html body.has-tua-side-nav header[class] .auth-logo,
    html body.has-tua-side-nav header[class] .header-logo-texto,
    html body.has-tua-side-nav header[class] .logo-link {
        display: none !important;
    }

    /* ---------- rodapé ---------- */
    /* Um rodapé só. As páginas trazem rodapés antigos, com larguras e textos
       diferentes; dois seguidos no fim da página é o oposto de arrumado. */
    html body.has-tua-side-nav > footer:not(.tua-desk-footer),
    html body.has-tua-side-nav .painel-footer { display: none !important; }

    html body[class] .tua-desk-footer {
        display: block;
        width: 100% !important;
        max-width: none !important;
        margin-top: 48px;
        padding: 34px 26px calc(30px + env(safe-area-inset-bottom));
        background: var(--marrom, #5c3020);
        color: rgba(247, 241, 234, 0.82);
    }

    .tua-desk-footer-inner {
        width: min(100%, 1180px);
        margin: 0 auto;
        display: grid;
        grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
        gap: 24px 40px;
        align-items: start;
    }

    /* Logótipo próprio do rodapé, em vez de reutilizar .logo-tua/.logo-pele:
       aquelas classes trazem a cor castanha e o contorno da marca, que sobre
       fundo castanho desaparecem. O "pele" ficava invisível. */
    .tua-desk-footer-logo {
        display: inline-block;
        color: #F7F1EA;
        font-family: var(--fonte-script, 'Cormorant Garamond', Georgia, serif);
        font-size: 1.9rem;
        font-weight: 300;
        line-height: 1;
    }
    .tua-desk-footer-logo strong {
        font-family: var(--fonte-titulo, Georgia, serif);
        font-size: 1.3rem;
        font-weight: 900;
        letter-spacing: -0.03em;
    }
    .tua-desk-footer-marca p {
        margin: 8px 0 0;
        max-width: 42ch;
        font-size: 0.84rem;
        line-height: 1.6;
    }

    .tua-desk-footer-links {
        display: flex;
        flex-wrap: wrap;
        gap: 10px 22px;
        justify-content: flex-end;
    }
    html body[class] .tua-desk-footer-links a {
        color: rgba(247, 241, 234, 0.9);
        font-size: 0.86rem;
        font-weight: 700;
        text-decoration: none;
        border-bottom: 1px solid rgba(247, 241, 234, 0.28);
    }

    .tua-desk-footer-nota {
        grid-column: 1 / -1;
        margin: 6px 0 0;
        padding-top: 16px;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: 8px 20px;
        border-top: 1px solid rgba(247, 241, 234, 0.18);
        font-size: 0.76rem;
        color: rgba(247, 241, 234, 0.62);
    }
    html body[class] .tua-desk-footer-nota a {
        color: rgba(247, 241, 234, 0.72);
        text-decoration: none;
        border-bottom: 1px solid rgba(247, 241, 234, 0.22);
    }

    /* O hambúrguer e a gaveta deslizante são de telemóvel: com a lateral
       sempre aberta, seriam duas navegações a dizer o mesmo. */
    html body.has-tua-side-nav .hamburger-btn,
    html body.has-tua-side-nav #menu-toggle { display: none !important; }
}

/* =========================================================
   BARRAS DE SCROLL HORIZONTAIS — sempre invisíveis
   ------------------------------------------------------------
   Os carrosséis e as barras de filtros arrastam-se com o dedo ou com a roda;
   a barra de scroll não acrescenta nada e corta o fundo das fichas.
   As folhas de área já escondiam algumas, mas cada uma à sua maneira e
   nenhuma cobria os três motores. Esta regra fecha o assunto num sítio só —
   e como o ui-padrao.css carrega por último, ganha às que ficaram para trás.
   ========================================================= */
html body[class] :is(
    .products-horizontal-grid,
    .horizontal-scroll,
    .produtos-scroll,
    .filters-container,
    .filters-inner,
    .orders-filter-wrap,
    .notificacoes-filtros,
    .adm-v2-audit-filtros,
    .tab-nav-inner,
    .client-section-tabs,
    .profile-tabs,
    .stock-section-switch,
    .categorias-scroll
) {
    scrollbar-width: none !important;      /* Firefox e Chrome moderno */
    -ms-overflow-style: none !important;   /* Edge antigo */
}

html body[class] :is(
    .products-horizontal-grid,
    .horizontal-scroll,
    .produtos-scroll,
    .filters-container,
    .filters-inner,
    .orders-filter-wrap,
    .notificacoes-filtros,
    .adm-v2-audit-filtros,
    .tab-nav-inner,
    .client-section-tabs,
    .profile-tabs,
    .stock-section-switch,
    .categorias-scroll
)::-webkit-scrollbar {
    width: 0 !important;
    height: 0 !important;
    display: none !important;
}

/* =========================================================
   INDEX — CARROSSÉIS E FILTROS DE CANTO A CANTO
   ------------------------------------------------------------
   O cabeçalho vai de extremidade a extremidade do ecrã. Os carrosséis e a
   barra de filtros, não: ficavam presos dentro do padding do <main> e as
   fichas paravam antes da borda, como se estivessem dentro de uma caixa.

   A correcção é puxar o contentor de scroll até à borda e devolver o mesmo
   valor em padding interno. A primeira ficha continua alinhada com o título
   da secção — o que muda é que as seguintes passam a correr até ao canto em
   vez de baterem numa margem.

   `calc(50% - 50vw)` mede o recuo sozinho: 50% é metade da largura útil do
   contentor, 50vw metade do ecrã, e a diferença é exactamente o espaço que
   sobra de cada lado. Não se repete aqui o padding do <main>; se ele mudar,
   isto acompanha sem ninguém tocar.

   Só em telemóvel: no computador os carrosséis viram grelha dentro de uma
   coluna de 1180px centrada, e esticá-los até à borda desalinhava-os de
   todo o resto da página.
   ========================================================= */
@media (max-width: 1023.98px) {
    html body.loja-body .products-horizontal-grid {
        margin-inline: calc(50% - 50vw) !important;
        padding-inline: calc(50vw - 50%) !important;
        max-width: none !important;
    }

    /* A barra de filtros só é caixa enquanto está no fluxo. Assim que o
       fixed-app-headers.js a cola por baixo do cabeçalho, ela ganha
       `app-header-companion-fixed` e já nasce com `left: 0; right: 0` — daí
       o :not(), que evita somar um deslocamento a quem já está na borda.
       De caminho isto acaba com o salto lateral que se via no momento em
       que a barra colava: antes recuava 38px no fluxo e 20px colada, agora
       são 20px nos dois estados. */
    html body.loja-body .filters-wrapper:not(.app-header-companion-fixed) {
        width: 100vw !important;
        max-width: 100vw !important;
        margin-inline: calc(50% - 50vw) !important;
    }

    /* O .filters-container tem `max-width: 1400px; margin: 0 auto` para o
       computador. Dentro de um wrapper que agora já é do tamanho do ecrã,
       esse limite não faz nada de mal — mas o `auto` centraria a barra num
       ecrã largo e deixaria de haver borda a atingir. */
    html body.loja-body .filters-wrapper .filters-container {
        max-width: none !important;
        margin-inline: 0 !important;
    }
}

/* ---------- botão "onde estou", dentro de todos os mapas ----------
   O Google insere-o nos controlos do mapa, por isso a margem tem de vir
   daqui: sem ela encostava ao canto e ao controlo de zoom. */
.tp-mapa-eu {
    width: 42px;
    height: 42px;
    margin: 0 10px 12px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: #FFFFFF;
    color: var(--marrom, #5c3020);
    font-size: 1rem;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    transition: background .18s ease, color .18s ease;
}

.tp-mapa-eu:hover { background: #f5f1ee; }

/* Azul, a mesma cor do ponto que o botão põe no mapa: liga uma coisa à
   outra sem precisar de legenda. */
.tp-mapa-eu.is-ativo { color: #1a73e8; }

.tp-mapa-eu:disabled { cursor: default; }

.tp-mapa-eu.is-a-procurar i {
    animation: tp-mapa-eu-pulsar 1s ease-in-out infinite;
}

@keyframes tp-mapa-eu-pulsar {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .tp-mapa-eu.is-a-procurar i { animation: none; opacity: .5; }
}

/* ---------- partilhar a minha posição com o motoboy ---------- */
.tp-partilha-btn {
    width: 100%;
    margin-top: 12px;
    padding: 13px 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    border: 1px solid rgba(92, 48, 32, 0.2);
    border-radius: 999px;
    background: rgba(92, 48, 32, 0.05);
    color: var(--marrom, #5c3020);
    font-size: 0.86rem;
    font-weight: 800;
    cursor: pointer;
    transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.tp-partilha-btn[hidden] { display: none !important; }

/* Ligada, o botão tem de parecer ligado — e pulsar, porque é uma coisa que
   está a acontecer agora e que consome bateria. */
.tp-partilha-btn.is-ativa {
    background: linear-gradient(135deg, #7a3f26, #5c3020);
    border-color: transparent;
    color: #fff;
}
.tp-partilha-btn.is-ativa i {
    animation: tpPartilhaPulso 1.8s ease-in-out infinite;
}

.tp-partilha-nota {
    margin: 8px 0 0;
    font-size: 0.75rem;
    line-height: 1.45;
    color: var(--texto-medio, #6b5a52);
    text-align: center;
}
.tp-partilha-nota[hidden] { display: none !important; }

@keyframes tpPartilhaPulso {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: 0.5; transform: scale(1.18); }
}

@media (prefers-reduced-motion: reduce) {
    .tp-partilha-btn.is-ativa i { animation: none; }
}

/* =========================================================
   SÓ DOIS DESENHOS: TELEMÓVEL E DESKTOP
   ------------------------------------------------------------
   Havia um terceiro estado entre 769px e 1023px — sem barra inferior, com a
   gaveta a fazer de navegação e o rodapé antigo no fim. Não era o telemóvel
   nem o desktop, e ninguém o tinha desenhado: nasceu de um @media antigo em
   app-redesign.css que começava aos 769px.
   Abaixo de 1024px é telemóvel. Ponto.
   ========================================================= */
@media (max-width: 1023.98px) {
    html body[class] .tua-bottom-nav {
        display: flex !important;
    }

    /* O rodapé antigo é do desktop; em telemóvel a barra inferior é o fim
       da página. */
    html body[class]:not(.auth-body) > footer:not(.tua-desk-footer) {
        display: none !important;
    }

    html body[class] .tua-side-nav,
    html body[class] .tua-desk-footer {
        display: none !important;
    }

    /* Sem o recuo da gaveta e com espaço para a barra, como no telemóvel. */
    html body.has-tua-side-nav {
        padding-left: 0 !important;
    }
}


/* ------------------------------------------------------------
   RECUPERAR SENHA POR SMS
   O indicativo é fixo e não se escreve: mostrá-lo como texto ao lado do
   campo evita que alguém o escreva outra vez e fique com "+258+258...".
   ------------------------------------------------------------ */
.rec-telefone { display: flex; align-items: stretch; gap: 8px; }
.rec-prefixo {
  display: inline-flex; align-items: center;
  padding: 0 12px;
  border: 1px solid #E6DBD0; border-radius: 11px;
  background: rgba(92, 48, 32, .05);
  font-size: 14px; font-weight: 700; color: #5C3020;
  white-space: nowrap;
}
.rec-telefone .input { flex: 1; min-width: 0; }

/* O código lê-se dígito a dígito: espaçado e ao centro custa menos a
   conferir contra o SMS. */
.rec-codigo {
  text-align: center;
  letter-spacing: .55em;
  font-size: 20px;
  font-weight: 700;
  padding-left: .55em;
}

/* O reCAPTCHA invisível não ocupa espaço enquanto não for preciso. */
#recaptchaRec:empty { display: none; }
