/* Estilos globais do Storefront PWA (layout mestre — ADR-012).
   Cabeçalho de 2 linhas, menu flutuante do rodapé e grid de cards
   seguem os modelos descritos no ADR-017. */

/* DM Sans (SIL Open Font License 1.1 — licença em
   `/assets/vendor/fonts/OFL.txt`, obrigatória junto do arquivo). Servida
   localmente, nunca pelo fonts.googleapis.com: o Service Worker só cacheia
   `/assets/` (fonte de CDN quebraria offline) e um request ao Google levaria
   o IP do cliente para fora, o que a LGPD não perdoa.

   Arquivo único variável (peso 100–1000) no subset `latin`, que cobre todo
   acento do português (ã, õ, ç, é, â). `swap` mostra o texto na fonte de
   sistema enquanto os 61 KB não chegam — em 3G, nada de tela em branco. */
@font-face {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 100 1000;
    font-display: swap;
    src: url('/assets/vendor/fonts/dm-sans-latin.woff2') format('woff2');
}

:root {
    --pwa-header-bg: var(--tenant-theme-color, #0d6efd);
    --pwa-header-fg: var(--tenant-foreground-color, #fff);
    --pwa-secondary-bg: var(--tenant-secondary-color, #6c757d);
    --pwa-secondary-fg: var(--tenant-secondary-foreground-color, #fff);
}

/* Cores da loja (definidas pelo Gerente em Configurações) aplicadas aos
   botões do storefront. O escopo `.pwa-body` evita vazar para o painel. */
.pwa-body .btn-primary {
    background-color: var(--pwa-header-bg);
    border-color: var(--pwa-header-bg);
    color: var(--pwa-header-fg);
}

.pwa-body .btn-outline-primary {
    border-color: var(--pwa-header-bg);
    color: var(--pwa-header-bg);
}

.pwa-body .btn-outline-primary:hover,
.pwa-body .btn-outline-primary:focus {
    background-color: var(--pwa-header-bg);
    color: var(--pwa-header-fg);
}

.pwa-body .btn-secondary {
    background-color: var(--pwa-secondary-bg);
    border-color: var(--pwa-secondary-bg);
    color: var(--pwa-secondary-fg);
}

.pwa-body {
    font-family: 'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    background: #f5f6f8;
    padding-bottom: 76px; /* espaço do bottom-nav flutuante */
}

/* Em telas largas o storefront (pensado mobile-first, ADR-012) esticava até
   a borda da janela e ficava com linhas de texto e grades de produto enormes
   — a mesma tela de celular, só que ampliada. Acima do breakpoint, tudo vira
   uma coluna central do tamanho de um app: conteúdo e bottom-nav ganham o
   mesmo `max-width` e o cinza de `.pwa-body` aparece nas laterais. Abaixo do
   breakpoint fica exatamente como já era (sem alteração). */
@media (min-width: 992px) {
    .pwa-main {
        max-width: 720px;
        margin-left: auto;
        margin-right: auto;
    }
}

/* `.pwa-sticky-top` fica de fora da regra acima de propósito: a tarja do
   cabeçalho (cor do tenant) e a do carrinho (preta) precisam esticar até a
   borda da janela — só o conteúdo de dentro (busca, total) fica na mesma
   largura da coluna central. */
@media (min-width: 992px) {
    .pwa-header__row1,
    .pwa-header__row2,
    .pwa-cart-bar__inner,
    .store-status-banner__inner {
        max-width: 720px;
        margin-left: auto;
        margin-right: auto;
    }
}

/* Numeral de largura fixa em tudo que muda ao vivo (preço do card, total
   parcial do topo, quantidade do stepper e do carrinho): com numeral
   proporcional, trocar 11,50 por 9,90 muda a largura do texto e o valor
   "pula" na tela a cada toque no +/−. */
.product-card__price,
.product-card__prices del,
.product-card__qty-value,
.product-modal__price,
.pwa-cart-bar,
.cart-total,
.cart-item__price,
.cart-item__qty,
.cart-item__subtotal {
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------
   Cabeçalho em 2 linhas
   Linha 1: logo | nome centralizado | avatar + carrinho
   Linha 2: busca com lupa (largura total)
------------------------------------------------------------------ */
.pwa-sticky-top {
    position: sticky;
    top: 0;
    z-index: 1020;
}

.pwa-header {
    background: var(--pwa-header-bg);
    color: var(--pwa-header-fg);
    padding: 8px 12px;
}

/* Total parcial do carrinho: some sob o cabeçalho, some subindo quando o
   carrinho esvazia. Estado inicial vem do servidor (`is-visible` já
   renderizado); trocas ao vivo são `Pwa.updateCartBar` (app.js). */
.pwa-cart-bar {
    box-sizing: border-box;
    background: #1a1b26;
    color: var(--pwa-secondary-bg);
    font-size: .85rem;
    font-weight: 400;
    max-height: 0;
    padding: 0 14px;
    overflow: hidden;
    opacity: 0;
    transition: max-height .25s ease, padding .25s ease, opacity .2s ease;
}

.pwa-cart-bar.is-visible {
    max-height: 32px;
    padding: 6px 14px;
    opacity: 1;
}

/* Separado do fundo (acima) pra poder esticar a tarja preta 100% e ainda
   assim manter o texto alinhado com o resto do conteúdo centralizado em
   telas largas — ver regra em `.pwa-header__row1`. */
.pwa-cart-bar__inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.js-cart-bar-total {
    font-weight: 700;
}

/* Três colunas: logo | nome (elástico) | ações. Avatar e carrinho vivem
   juntos na terceira célula em vez de ocuparem colunas próprias — assim o
   par não depende da contagem de colunas para ficar lado a lado. */
.pwa-header__row1 {
    display: grid;
    grid-template-columns: 60px 1fr auto;
    align-items: center;
    gap: 8px;
}

.pwa-header__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}

.pwa-header__logo img {
    width: 52px;
    height: 52px;
    border-radius: 10px;
    object-fit: cover;
    background: #fff;
}

/* `min-width: 0` libera a coluna 1fr a encolher: sem isso o mínimo automático
   do grid é o conteúdo e o texto longo empurra as ações para fora da tela.

   Sem recuo próprio: nome e slogan encostam no logotipo, separados apenas
   pelo `gap` da fileira. O respiro à direita continua vindo da coluna de
   ações, então o texto longo não chega a colar nos ícones. */
.pwa-header__identity {
    min-width: 0;
    padding-left: 0;
    /* Puxa a coluna para dentro do `gap` de 8px do grid — o encosto que o
       `padding: 0` sozinho não dá, sem mexer no gap (que também separa a
       identidade das ações do outro lado). */
    margin-left: -4px;
}

.pwa-header__name {
    font-size: 1.05rem;
    font-weight: 600;
    text-align: left;
    margin: 0;
    color: var(--pwa-header-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pwa-header__slogan {
    margin: 0;
    font-size: .78rem;
    line-height: 1.2;
    color: var(--pwa-header-fg);
    opacity: .85;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Fundo na cor secundária escolhida pelo Gerente — mesma variável usada no
   botão do carrinho da barra inferior. Sino e avatar dividem a forma: são
   dois destinos de mesmo peso na terceira coluna do cabeçalho. */
.pwa-header__action,
.pwa-header__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--pwa-secondary-bg);
    text-decoration: none;
}

/* `overflow: visible` é o padrão, mas a bolha estoura a borda do círculo de
   propósito — deixar explícito evita que uma mudança futura em
   `.pwa-header__action` a corte sem ninguém perceber. */
.pwa-header__bell {
    position: relative;
    overflow: visible;
}

/* Contador de não lidas. `min-width` + `padding` lateral: cresce de "1" para
   "9+" sem deformar o círculo. */
.pwa-header__badge {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 9px;
    background: #dc3545;
    color: #fff;
    font-size: .62rem;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    /* Anel na cor do cabeçalho separa a bolha do ícone atrás dela. */
    box-shadow: 0 0 0 2px var(--pwa-header-bg, #fff);
}

.pwa-header__row2 {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.pwa-header__search {
    flex: 1;
    position: relative;
}

.pwa-header__search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.pwa-header__search input {
    width: 100%;
    border: 0;
    border-radius: 20px;
    padding: 8px 12px 8px 38px;
}

/* ------------------------------------------------------------------
   Menu principal flutuante do rodapé (bottom nav)
------------------------------------------------------------------ */
.bottom-nav {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 12px;
    display: flex;
    justify-content: space-around;
    background: #1a1b26;
    border-radius: 26px;
    padding: 8px 6px;
    z-index: 1030;
    transform: translateY(0);
    /* Só transform: o fade simultâneo fazia o menu parecer que sumia antes de
       terminar o percurso. Curto e com saída acelerada, sem dar espera. */
    transition: transform .22s cubic-bezier(.4, 0, .2, 1);
    will-change: transform;
}

/* `.bottom-nav` é `position: fixed` (relativo à viewport, não a um
   ancestral) — centralizar com `margin: auto` não funciona aqui. `left: 50%`
   + largura fixa + metade negativa faz o mesmo efeito sem mexer no
   `transform`, que já é usado pra esconder/mostrar o menu. Precisa vir
   depois da regra base acima: mesma especificidade, então quem manda é a
   ordem no arquivo. */
@media (min-width: 992px) {
    .bottom-nav {
        left: 50%;
        right: auto;
        width: calc(720px - 24px);
        margin-left: calc(-360px + 12px);
    }
}

/* Rolando para baixo: desce além da própria altura + o respiro de 12px, para
   não deixar borda aparecendo. */
.bottom-nav.is-hidden {
    transform: translateY(calc(100% + 12px));
    pointer-events: none;
}

/* Quem pediu menos movimento no sistema não recebe o deslize, mas ainda
   recebe um fade curto — `transition: none` aqui fazia o menu piscar. */
@media (prefers-reduced-motion: reduce) {
    .bottom-nav {
        transition: opacity .18s ease;
    }

    .bottom-nav.is-hidden {
        transform: none;
        opacity: 0;
    }
}

.bottom-nav__item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    text-decoration: none;
    color: #fff;
    font-size: .7rem;
    min-width: 56px;
    /* Simétrico de propósito: junto com o padding igual da barra, o atalho
       fica com o mesmo respiro em cima e embaixo. */
    padding: 4px 0;
    border-radius: 12px;
}

/* Entrelinha curta: o rótulo tem uma linha só, então a altura da caixa de
   texto padrão viraria folga morta entre o ícone e a palavra. */
.bottom-nav__label {
    line-height: 1.1;
}

/* Destaque do item ativo sempre em amarelo (bs-warning), fixo — não a cor
   secundária do tenant: item ativo precisa continuar óbvio em qualquer loja,
   mesmo quando a cor secundária escolhida pelo Gerente for próxima do branco
   do fundo. O ícone recebe a mesma cor por atributo na célula (shadow DOM
   não é alcançado por este seletor). */
.bottom-nav__item--active {
    color: var(--bs-warning);
    font-weight: 600;
}

/* Feedback de "carregando" entre o clique e a página nova chegar (app.js):
   a cor pisca (opacidade) em vez de ficar parada — o item já marcado ativo
   por JS, mas o pulso avisa que ainda está em andamento. */
@keyframes bottom-nav-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}

.bottom-nav__item.is-loading {
    animation: bottom-nav-pulse .9s ease-in-out infinite;
}

/* Altura casada com o `size` do <box-icon> (22px): sem caixa maior que o
   glifo, o par ícone+rótulo fica com folga igual acima e abaixo. */
.bottom-nav__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 22px;
}

.bottom-nav__badge {
    position: absolute;
    top: 0;
    right: 6px;
    font-size: .6rem;
}

/* ------------------------------------------------------------------
   Grid e cards de produto
------------------------------------------------------------------ */
/* Três por linha no celular. `minmax(0, 1fr)` em vez de `1fr` porque o
   mínimo automático da track é o conteúdo — sem isso um nome longo estoura a
   coluna e o grid passa da largura da tela. */
.product-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

/* No desktop, três cards ocupariam meia tela cada: volta a preencher. */
@media (min-width: 768px) {
    .product-grid {
        grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
        gap: 10px;
    }
}

/* A partir do mesmo breakpoint que centraliza o layout (992px, ver a coluna
   central em `.pwa-main`), fixa em 4 por linha em vez de auto-preencher —
   com a coluna central de 720px, `auto-fill` já ficava em 4 na prática, mas
   fixar evita que produtos de nome curto formem uma 5ª coluna estreita. */
@media (min-width: 992px) {
    .product-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* Carrossel arrastável (US-204) — mesmo efeito do de categorias: scroll
   nativo com o dedo, sem animação sozinha. `scroll-snap` para de forma
   alinhada em vez de flutuar entre dois cards. */
.product-grid--scroll {
    display: flex;
    overflow-x: auto;
    padding-bottom: 6px;
    scroll-snap-type: x proximity;
}

/* Largura fixa (não só mínima): sem isso um nome de produto mais comprido
   alarga o card inteiro — e junto dele a imagem quadrada (aspect-ratio 1),
   ficando maior que as vizinhas na mesma fileira. */
.product-grid--scroll .product-card {
    scroll-snap-align: start;
    flex: 0 0 150px;
    width: 150px;
}

.product-card__image-wrap {
    position: relative;
    display: block;
    aspect-ratio: 1;
    background: #fff;
    cursor: pointer;
}

.product-card__image {
    width: 100%;
    height: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    background: #fff;
    padding: 8px;
    opacity: 0;
    transition: opacity .15s ease;
}

.product-card__image-wrap.is-loaded .product-card__image { opacity: 1; }

.product-card__spinner {
    position: absolute;
    inset: 0;
    margin: auto;
}

.product-card__image-wrap.is-loaded .product-card__spinner { display: none; }

.product-card__name {
    text-align: center;
}

/* Em promoção, o "de" riscado fica numa linha e o "por" vigente embaixo —
   mais legível que os dois espremidos lado a lado. */
.product-card__prices {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
}

.product-card__price--promo {
    color: #dc3545;
}

/* Badge por cima da imagem (US-204), canto superior direito, dentro do
   card — não fica preso ao fluxo do card-body. `.product-card` já é
   `position:relative` via `.card` do Bootstrap. */
.product-card__badge {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
    font-size: .68rem;
}

.product-card--unavailable { opacity: .55; }

/* Contorno na cor da loja: produto já no carrinho se destaca na vitrine sem
   precisar abrir o carrinho pra conferir. `box-shadow` (não `border`) pra
   não empurrar o layout do card. */
.product-card--in-cart {
    border: 2.5px dashed color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 80%, #fff);
}

/* Modal de foto do produto (US-201): fundo escurecido, imagem maior com o
   mesmo spinner/fade do card enquanto carrega, nome completo e preço. Sem
   ação de adicionar — isso continua só no card por trás. */
.product-modal {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: none;
}

.product-modal.is-open {
    display: block;
}

.product-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .75);
}

.product-modal__dialog {
    position: relative;
    width: min(320px, calc(100vw - 48px));
    margin: 12vh auto 0;
    background: #fff;
    border-radius: 14px;
    padding: 18px;
    text-align: center;
}

.product-modal__close {
    position: absolute;
    top: -16px;
    right: -8px;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: 50%;
    background: #1a1b26;
    display: flex;
    align-items: center;
    justify-content: center;
}

.product-modal__image-wrap {
    position: relative;
    display: block;
    aspect-ratio: 1;
    background: #fff;
}

.product-modal__image {
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    transition: opacity .15s ease;
}

.product-modal__image-wrap.is-loaded .product-modal__image { opacity: 1; }

.product-modal__spinner {
    position: absolute;
    inset: 0;
    margin: auto;
}

.product-modal__image-wrap.is-loaded .product-modal__spinner { display: none; }

.product-modal__name {
    margin: 12px 0 4px;
    font-weight: 600;
}

.product-modal__price {
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: baseline;
    gap: 8px;
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--tenant-theme-color, #0d6efd);
}

.product-modal__price-original {
    font-weight: 400;
    font-size: .85rem;
    color: #6c757d;
}

.product-modal__cart-qty {
    margin: 8px 0 0;
    font-size: .85rem;
    color: #6c757d;
}

/* Trava o scroll de fundo enquanto o modal está aberto. */
body.product-modal-open {
    overflow: hidden;
}

/* Controle de quantidade do card: fechado mostra só o "+", ocupando a pílula
   inteira; com item no carrinho abre em "− qty +". */
.product-card__stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 3px;
    border-radius: 999px;
    background: #f1f3f5;
}

.product-card__stepper .js-qty-dec,
.product-card__stepper .js-qty-value {
    display: none;
}

.product-card__stepper.is-active {
    justify-content: space-between;
    background: color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 12%, #fff);
}

.product-card__stepper.is-active .js-qty-dec {
    display: inline-flex;
}

.product-card__stepper.is-active .js-qty-value {
    display: inline-block;
}

.product-card__stepper.is-busy {
    opacity: .6;
    pointer-events: none;
}

.product-card__step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #fff;
    line-height: 0;
}

.product-card__step--add {
    background: var(--tenant-theme-color, #0d6efd);
}

.product-card__step:disabled {
    opacity: .5;
}

.product-card__qty-value {
    flex: 1 1 auto;
    text-align: center;
    font-weight: 600;
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}

/* Preço em destaque, na cor primária escolhida pelo Gerente. */
.product-card__price {
    font-size: 1.15rem;
    line-height: 1.2;
    color: var(--tenant-theme-color, #0d6efd);
}

/* Nome preso a duas linhas para os cards da mesma linha ficarem alinhados. */
.product-card__name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: .82rem;
    line-height: 1.25;
}

@media (min-width: 768px) {
    .product-card__name {
        font-size: .95rem;
    }
}

.category-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Carrossel de categorias (CategoryCarouselCell) — compartilhado pela home
   (sem filtro) e por /catalogo?categoria= (filtrado, card ativo com borda):
   arrasta com o dedo (scroll nativo), sem setas — mesmo padrão de
   `.product-grid--scroll`. `scroll-snap` deixa o arrasto parando alinhado em
   vez de flutuar entre dois cards. */
.category-cards {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding-bottom: 4px;
    scroll-snap-type: x proximity;
}

.category-card {
    flex: 0 0 auto;
    width: 132px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-decoration: none;
    scroll-snap-align: start;
}

/* Borda reservada (transparente) mesmo fora do estado ativo: sem isso, ativar
   a borda faria a imagem "crescer" 2px e empurrar a fileira (reflow). */
.category-card__image-wrap {
    width: 132px;
    height: 132px;
    border-radius: 27px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
    border: 2.5px solid transparent;
}

/* Card "Todos" (CategoryCarouselCell::$showAll): mesmo tamanho do card de
   categoria, mas com um ícone genérico no lugar da foto. */
.category-card__image-wrap--icon {
    background: #f1f3f5;
    box-shadow: none;
}

/* Categoria aberta no momento — borda na cor primária do tenant, a mesma
   variável já usada no cabeçalho e nos botões do storefront. */
.category-card.is-active .category-card__image-wrap {
    border-color: var(--tenant-theme-color, #0d6efd);
}

/* Feedback de "carregando" entre o clique e a página nova chegar (app.js):
   a borda pulsa em vez de ficar parada, pra ficar óbvio que o toque
   registrou e algo está em andamento. */
@keyframes category-card-pulse {
    0%, 100% { border-color: var(--tenant-theme-color, #0d6efd); }
    50% { border-color: color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 25%, #fff); }
}

.category-card.is-loading .category-card__image-wrap {
    animation: category-card-pulse .9s ease-in-out infinite;
}

.category-card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Nome em 1 linha só: estoura vira "..." em vez de quebrar e desalinhar as
   imagens da fileira (US pedida explicitamente: no máx. uma linha). */
.category-card__name {
    max-width: 100%;
    font-size: .78rem;
    font-weight: 500;
    text-align: center;
    color: #212529;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Carrossel de subgrupos (SubgroupCarouselCell) — segundo nível da navegação,
   logo abaixo dos cards de categoria. Só texto: o primeiro nível já carrega a
   imagem, e repetir cards com foto empurraria os produtos para fora da
   primeira dobra. Arrasta com o dedo, sem setas, igual ao nível de cima.

   `scrollbar-width: none` (e o equivalente WebKit) porque numa fileira de uma
   linha só a barra rouba altura visível do próprio texto. */
.subgroup-chips {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    border-bottom: 1px solid #dee2e6;
    margin-bottom: 4px;
    scrollbar-width: none;
}

.subgroup-chips::-webkit-scrollbar {
    display: none;
}

/* A borda inferior do chip ativo precisa cobrir a borda da fileira, daí o
   `-1px`: sem isso ficariam duas linhas empilhadas sob o item aberto. */
.subgroup-chip {
    flex: 0 0 auto;
    padding: 10px 2px;
    margin-bottom: -1px;
    font-size: .82rem;
    font-weight: 500;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    color: var(--tenant-theme-color, #0d6efd);
    border-bottom: 2px solid transparent;
    scroll-snap-align: start;
}

/* Subgrupo aberto: peso e sublinhado também na cor primária do tenant — a
   mesma variável usada na borda do card de categoria ativa. */
.subgroup-chip.is-active {
    font-weight: 700;
    border-bottom-color: var(--tenant-theme-color, #0d6efd);
}

/* ------------------------------------------------------------------
   Checkout: seções e cards de opção

   Todo o checkout é uma pilha de escolhas (como receber, onde, quando, como
   pagar). Um card por opção, com marcador à esquerda e ícone à direita, deixa
   a área de toque grande no celular e mantém as quatro seções com a mesma
   gramática visual.
------------------------------------------------------------------ */
.checkout-section {
    margin-bottom: 18px;
    padding: 14px;
    border-radius: 14px;
    background: #f7f8fc;
}

.checkout-section__title {
    float: none;
    width: auto;
    margin-bottom: 10px;
    font-size: 1rem;
    font-weight: 700;
    color: #212529;
}

.option-card {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-bottom: 8px;
    padding: 12px 14px;
    border: 0;
    border-radius: 12px;
    background: #fff;
    text-align: left;
    cursor: pointer;
}

.option-card:last-child {
    margin-bottom: 0;
}

/* O radio nativo sai de vista mas continua sendo o dono do estado: o card é
   um `<label>`, então clicar em qualquer parte dele marca a opção, e a
   navegação por teclado segue funcionando. */
.option-card__input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.option-card__radio {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border: 2px solid #adb5bd;
    border-radius: 50%;
    position: relative;
}

.option-card__input:checked ~ .option-card__radio,
.option-card.is-active .option-card__radio {
    border-color: var(--tenant-theme-color, #1f3bb3);
}

.option-card__input:checked ~ .option-card__radio::after,
.option-card.is-active .option-card__radio::after {
    content: '';
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: var(--tenant-theme-color, #1f3bb3);
}

/* Foco visível no card inteiro: sem isso o teclado navegaria às cegas, já
   que o radio que recebe o foco está oculto. */
.option-card__input:focus-visible ~ .option-card__radio {
    outline: 2px solid var(--tenant-theme-color, #1f3bb3);
    outline-offset: 3px;
}

.option-card__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.option-card__title {
    font-size: .95rem;
    font-weight: 600;
    color: #212529;
}

.option-card__desc {
    font-size: .8rem;
    line-height: 1.35;
    color: #6c757d;
}

/* ------------------------------------------------------------------
   Checkout: opção principal de entrega (localização atual)
------------------------------------------------------------------ */

/* Contorno tracejado marca a opção como o caminho recomendado sem precisar de
   rótulo "recomendado" — e a distingue dos cards comuns logo abaixo. */
.delivery-primary {
    padding: 12px;
    margin-bottom: 14px;
    border: 1.5px dashed color-mix(in srgb, var(--tenant-theme-color, #1f3bb3) 45%, #fff);
    border-radius: 14px;
    background: #fff;
    transition: border-color .2s ease, background-color .2s ease;
}

/* Captura de GPS concluída com sucesso: pontilhado e fundo viram verde — a
   cor deixa de ser a da loja porque aqui a informação é "deu certo", não
   "esta é a opção recomendada". Volta ao padrão assim que outra origem é
   escolhida (`checkout.js`). */
.delivery-primary.is-captured {
    border-color: #198754;
    background: #eafbf1;
}

/* GPS perde o contorno "recomendado" quando o endereço da última compra
   assume esse lugar — continua com o mesmo botão e tamanho, só menos em
   destaque, porque ainda é uma opção de um toque só. */
.delivery-primary--secondary {
    border-style: solid;
    border-color: #dee2e6;
}

.option-card--lead {
    margin-bottom: 10px;
    padding: 0;
    background: none;
}

.option-card--lead .option-card__title {
    font-size: 1.02rem;
    font-weight: 700;
}

.delivery-primary__action {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px;
    border-radius: 10px;
    font-weight: 600;
}

.delivery-primary__hint {
    margin: 10px 0 0;
    font-size: .78rem;
    line-height: 1.35;
    color: #6c757d;
}

.delivery-primary__hint.is-error {
    color: #b02a37;
    font-weight: 500;
}

.delivery-primary__hint.is-ok {
    color: #146c43;
    font-weight: 500;
}

/* ------------------------------------------------------------------
   Checkout: outras opções de entrega (recolhíveis)
------------------------------------------------------------------ */
.delivery-others__toggle {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 0 2px 8px;
    border: 0;
    background: none;
    text-align: left;
}

.delivery-others__label {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.delivery-others__title {
    font-size: .95rem;
    font-weight: 700;
    color: #212529;
}

.delivery-others__desc {
    font-size: .78rem;
    line-height: 1.3;
    color: #6c757d;
}

/* A seta acompanha o estado do collapse do Bootstrap. */
.delivery-others__toggle box-icon {
    transition: transform .2s ease;
}

.delivery-others__toggle[aria-expanded="false"] box-icon {
    transform: rotate(180deg);
}

/* ------------------------------------------------------------------
   Checkout: modal de confirmação da localização
------------------------------------------------------------------ */
.geo-modal {
    border: 0;
    border-radius: 16px;
}

.geo-modal__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 62px;
    height: 62px;
    margin-bottom: 12px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--tenant-theme-color, #1f3bb3) 12%, #fff);
}

.geo-modal__title {
    margin: 0 0 8px;
    font-size: 1.1rem;
    font-weight: 700;
}

.geo-modal__text {
    margin: 0 0 12px;
    font-size: .88rem;
    line-height: 1.45;
    color: #495057;
}

/* Aviso da permissão de GPS: destacado porque é a causa nº 1 de o cliente
   travar aqui sem entender o motivo. */
.geo-modal__notice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px;
    border-radius: 10px;
    background: #e7f1ff;
    font-size: .8rem;
    line-height: 1.4;
    color: #084298;
    text-align: left;
}

.geo-modal__notice box-icon {
    flex: 0 0 auto;
}

.geo-modal__footer {
    border-top: 0;
    padding-top: 0;
    gap: 8px;
}

.geo-modal__footer .btn {
    flex: 1 1 0;
    margin: 0;
}

/* ------------------------------------------------------------------
   Checkout: offcanvas de endereços
------------------------------------------------------------------ */

/* Largura limitada em telas grandes; no celular ocupa quase tudo, que é onde
   o storefront realmente roda. */
.address-canvas {
    width: min(92vw, 420px);
}

.address-canvas .offcanvas-body .option-card {
    background: #f7f8fc;
}

.checkout-troco {
    margin-top: 10px;
    padding: 12px 14px;
    border-radius: 12px;
    background: #fff;
}

/* ------------------------------------------------------------------
   Checkout: wizard (onde entregar / endereço / pagamento / resumo)

   Timeline de bolinhas ligadas por uma linha, sem nome embaixo — só a
   posição atual e o que já foi percorrido acendem na cor primária do
   tenant (`--tenant-theme-color`), acompanhando o avanço no formulário
   (`checkout.js`). Um passo por vez: o resto do formulário some via
   `display: none` até o JS revezar o `.is-active`.
------------------------------------------------------------------ */
.checkout-stepper__list {
    display: flex;
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
}

.checkout-stepper__item {
    position: relative;
    flex: 1 1 0;
    display: flex;
    justify-content: center;
}

.checkout-stepper__item:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 17px;
    left: 50%;
    width: 100%;
    height: 3px;
    background: #dee2e6;
    z-index: 0;
}

.checkout-stepper__item.is-done:not(:last-child)::after {
    background: var(--tenant-theme-color, #1f3bb3);
}

.checkout-stepper__icon {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid #dee2e6;
}

.checkout-stepper__item.is-active .checkout-stepper__icon,
.checkout-stepper__item.is-done .checkout-stepper__icon {
    border-color: var(--tenant-theme-color, #1f3bb3);
    background: var(--tenant-theme-color, #1f3bb3);
}

.checkout-step {
    display: none;
}

.checkout-step.is-active {
    display: block;
}

.checkout-step__nav {
    margin-bottom: 18px;
}

/* ------------------------------------------------------------------
   Meus pedidos: destaque do pedido mais recente
------------------------------------------------------------------ */

.order-history {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.order-history__card {
    background: #fff;
    border: 1px solid #eef0f2;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
    padding: 10px 12px;
}

.order-history__body {
    min-width: 0;
}

.order-history__meta {
    line-height: 1.4;
}

.order-history__valor {
    font-size: 1.05rem;
    color: var(--tenant-theme-color, #0d6efd);
}

/* A lista já vem ordenada do controller — este item é sempre o topo. Sem
   selo de texto (custaria uma linha inteira de altura); só a borda na cor
   do tenant já basta pra destacar quem acabou de fazer o pedido. */
.order-history__item--recent {
    border: 2px solid var(--tenant-theme-color, #0d6efd);
}

/* Avatar circular do status atual (OrderStatusAvatarCell) — mesmo ícone do
   acompanhamento do pedido, pra reconhecimento imediato na lista. */
.order-status-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.order-status-avatar--ativo {
    background: var(--tenant-theme-color, #0d6efd);
}

.order-status-avatar--concluido {
    background: #198754;
}

.order-status-avatar--cancelado {
    background: #e9ecef;
}

/* ------------------------------------------------------------------
   Caixa de entrada do cliente (/notificacoes)
------------------------------------------------------------------ */

/* Título de cada grupo de data ("Hoje", "03/08/2026") — mesma hierarquia
   visual dos rótulos de seção do catálogo (`.h6.text-uppercase`), mas sem
   depender daquelas classes para não acoplar as duas telas. */
.notification-group__date {
    margin: 14px 0 4px;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: #6c757d;
}

.notification-group__date:first-child {
    margin-top: 0;
}

.notification-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.notification-item + .notification-item {
    border-top: 1px solid #e9ecef;
}

/* O item inteiro é um botão de formulário: precisa perder a aparência de
   botão e recuperar a de linha de lista. */
.notification-item__button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 8px;
    background: none;
    border: 0;
    text-align: left;
}

/* Fundo levemente tingido na cor do tenant é o que separa não lida de lida a
   um relance, sem depender de ler o texto. */
.notification-item.is-unread .notification-item__button {
    background: color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 7%, #fff);
}

/* Marcador redondo à esquerda: cheio quando não lida, reservado (invisível)
   quando lida — a coluna não muda de largura entre os dois estados. */
.notification-item__dot {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: transparent;
}

.notification-item.is-unread .notification-item__dot {
    background: var(--tenant-theme-color, #0d6efd);
}

.notification-item__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.notification-item__title {
    font-size: .92rem;
    font-weight: 500;
    color: #495057;
}

.notification-item.is-unread .notification-item__title {
    font-weight: 700;
    color: #212529;
}

.notification-item__text {
    font-size: .84rem;
    color: #6c757d;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.notification-item__meta {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .74rem;
    color: #adb5bd;
}

.notification-item__tag {
    padding: 1px 6px;
    border-radius: 8px;
    background: var(--tenant-theme-color, #0d6efd);
    color: #fff;
    font-size: .64rem;
    font-weight: 700;
    text-transform: uppercase;
}

.store-status-banner { font-size: .85rem; }

/* ------------------------------------------------------------------
   Lista de itens do carrinho
------------------------------------------------------------------ */
.cart-item {
    display: grid;
    /* Nome e preço à esquerda, controles à direita; o subtotal fecha a linha
       embaixo, do lado dos controles. */
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 2px 10px;
    padding: .75rem;
}

.cart-item__name {
    grid-column: 1;
    margin: 0;
    font-weight: 500;
    line-height: 1.25;
    min-width: 0;
}

.cart-item__price {
    grid-column: 1;
    margin: 0;
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--tenant-theme-color, #0d6efd);
}

.cart-item__unit {
    font-weight: 400;
    font-size: .78rem;
    color: #6c757d;
}

.cart-item__controls {
    grid-column: 2;
    grid-row: 1 / span 2;
    display: flex;
    align-items: center;
    gap: 6px;
}

.cart-item__remove,
.cart-item__step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: 10px;
    background: transparent;
    border: 1px solid #dee2e6;
    line-height: 0;
}

/* A lixeira não é um botão emoldurado: fica discreta ao lado dos passos. */
.cart-item__remove {
    border-color: transparent;
}

.cart-item__step--add {
    background: var(--tenant-theme-color, #0d6efd);
    border-color: var(--tenant-theme-color, #0d6efd);
}

.cart-item__remove:disabled,
.cart-item__step:disabled {
    opacity: .4;
}

.cart-item__qty {
    min-width: 2.5rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.cart-item__subtotal {
    grid-column: 1;
    margin: 0;
    font-size: .78rem;
    color: #6c757d;
}

/* Enquanto o servidor responde, a linha inteira fica inerte. */
.cart-item.is-busy {
    opacity: .6;
    pointer-events: none;
}

/* ------------------------------------------------------------------
   Checkout e acompanhamento do pedido
------------------------------------------------------------------ */
.checkout-summary .list-group-item { padding: .5rem .75rem; }

/* ---- Timeline visual: bolhas horizontais ---- */
.tl-track {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    position: relative;
    padding: 8px 0 0;
    margin: 0 0 .5rem;
}

.tl-track__node {
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative;
    flex: 1 1 0;
    min-width: 0;
}

/* Linha conectora entre bolhas */
.tl-track__line {
    position: absolute;
    top: 20px;
    right: 50%;
    width: 100%;
    height: 3px;
    background: #dee2e6;
    z-index: 0;
    border-radius: 2px;
}

.tl-track__line.is-done {
    background: var(--tenant-theme-color, #0d6efd);
}

/* Animação: linha enchendo da esq→dir */
@keyframes tl-line-pulse {
    0%   { background-size: 0% 100%; }
    50%  { background-size: 100% 100%; }
    100% { background-size: 0% 100%; }
}

.tl-track__line.is-animating {
    background: linear-gradient(
        to right,
        var(--tenant-theme-color, #0d6efd),
        var(--tenant-theme-color, #0d6efd)
    ) no-repeat left center,
    #dee2e6;
    background-size: 0% 100%;
    animation: tl-line-pulse 2s ease-in-out infinite;
}

/* Bolinha */
.tl-track__bubble {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #e9ecef;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    z-index: 1;
    transition: background .3s ease, box-shadow .3s ease;
    flex-shrink: 0;
}

.tl-track__node.is-done .tl-track__bubble {
    background: var(--tenant-theme-color, #0d6efd);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 20%, transparent);
}

/* Bolinha do step atual (pulsando suavemente) */
@keyframes tl-bubble-pulse {
    0%, 100% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 20%, transparent); }
    50%      { box-shadow: 0 0 0 8px color-mix(in srgb, var(--tenant-theme-color, #0d6efd) 12%, transparent); }
}

.tl-track__node.is-current .tl-track__bubble {
    animation: tl-bubble-pulse 2s ease-in-out infinite;
}

/* Último step completado = verde */
.tl-track__node.is-final .tl-track__bubble {
    background: #198754;
    box-shadow: 0 0 0 4px rgba(25, 135, 84, .2);
}

.tl-track__node.is-final.is-current .tl-track__bubble {
    animation: none;
    box-shadow: 0 0 0 4px rgba(25, 135, 84, .25);
}

/* Linha que chega no último step quando done → verde */
.tl-track__node.is-final .tl-track__line.is-done {
    background: #198754;
}

/* Cancelado: tom vermelho na bolinha ativa */
.tl-track.is-cancelado .tl-track__node.is-current .tl-track__bubble {
    background: #dc3545;
    box-shadow: 0 0 0 4px rgba(220, 53, 69, .2);
    animation: none;
}

/* Label abaixo da bolha */
.tl-track__label {
    font-size: .7rem;
    color: #6c757d;
    text-align: center;
    margin-top: 6px;
    line-height: 1.2;
    word-break: break-word;
    max-width: 80px;
}

.tl-track__node.is-done .tl-track__label {
    color: #212529;
    font-weight: 500;
}

.tl-track__node.is-current .tl-track__label {
    font-weight: 700;
    color: var(--tenant-theme-color, #0d6efd);
}

.tl-track__node.is-final .tl-track__label {
    color: #198754;
}

/* ---- Accordion "Mais detalhes" ---- */
.tl-details-btn {
    background: none !important;
    padding: .5rem .75rem;
    font-size: .85rem;
    font-weight: 600;
    color: #6c757d;
    border: none;
    box-shadow: none !important;
}

.tl-details-btn::after {
    width: .8rem;
    height: .8rem;
    background-size: .8rem;
}

.tl-details-btn:not(.collapsed) {
    color: var(--tenant-theme-color, #0d6efd);
}

/* ---- Lista detalhada dentro do accordion ---- */
.tl-detail-list {
    padding-left: 12px;
    padding-right: 12px;
}

.tl-detail-list__item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 3px 0;
    font-size: .82rem;
    color: #6c757d;
}

.tl-detail-list__item.is-done {
    color: #212529;
}

.tl-detail-list__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ced4da;
    flex: 0 0 auto;
    position: relative;
    top: 1px;
}

.tl-detail-list__item.is-done .tl-detail-list__dot {
    background: var(--tenant-theme-color, #0d6efd);
}

.tl-detail-list__item.is-current .tl-detail-list__label {
    font-weight: 600;
}

.tl-detail-list__at {
    font-size: .75rem;
    margin-left: auto;
    white-space: nowrap;
}


.price-adjusted del { color: #6c757d; margin-right: 6px; }

.price-adjusted .reajustado { color: #b02a37; }

/* Preço não quebra linha (del + valor + badge de reajuste juntos); o nome
   do item é quem cede espaço quando o card fica estreito. */
.order-items .list-group-item {
    gap: .5rem;
}

.order-items .list-group-item > span:first-child {
    min-width: 0;
}

.order-items .price-adjusted {
    flex: 0 0 auto;
    white-space: nowrap;
    text-align: right;
}

/* Mesmo ajuste do resumo do pedido (`.order-items` acima): preço não quebra
   linha, nome do produto cede espaço quando o card fica estreito. */
.checkout-summary .list-group-item {
    gap: .5rem;
}

.checkout-summary .list-group-item > span:first-child {
    min-width: 0;
}

.checkout-summary .list-group-item > span:last-child {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* Destaque na cor da loja: Total do pedido, Endereço e Forma de pagamento
   escolhidos no resumo (passo 4 do checkout). */
.checkout-summary__item--accent,
.checkout-summary__item--accent span {
    color: var(--tenant-theme-color);
}

.delivery-pin [data-pin] { letter-spacing: .25rem; }

.cart-total-label { font-size: 1.15rem; }

.cart-total { font-size: 1.4rem; }

/* Títulos de seção da home (Categorias) na cor primária da loja. */
.home-section-title {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--tenant-theme-color, #0d6efd);
}

/* "Ver todas" ao lado do título: cor primária da loja, sem sublinhado. */
.home-link-secondary {
    color: var(--tenant-theme-color, #0d6efd);
    text-decoration: none;
}

/* Carrossel de banners da home (US-201, painel/gerente/banners): 1 slide
   por vez, trilha desliza via transform — `banner-carousel.js` controla
   índice/autoplay/arrasto. */
.banner-carousel {
    position: relative;
    overflow: hidden;
    border-radius: 12px;
}

.banner-carousel__track {
    display: flex;
    transition: transform .35s ease;
}

.banner-carousel__slide {
    flex: 0 0 100%;
    display: block;
    line-height: 0;
}

.banner-carousel__image {
    width: 100%;
    aspect-ratio: 16 / 7;
    object-fit: cover;
}

.banner-carousel__dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
}

.banner-carousel__dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #ced4da;
    transition: width .2s ease, border-radius .2s ease, background .2s ease;
}

.banner-carousel__dot.is-active {
    width: 20px;
    border-radius: 4px;
    background: var(--tenant-theme-color, #0d6efd);
}

/* Banner de topo da página de promoção (`/promocao/<slug>`) — mesma
   proporção do slide do carrossel da home, mas fixo (sem arrasto/dots). */
.promocao-banner {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 7;
    object-fit: cover;
    border-radius: 10px;
    margin-top: 8px;
}

/* Botão de compartilhar nativo (Web Share API), ao lado da validade. */
.promocao-compartilhar {
    flex-shrink: 0;
    border: 1px solid #dee2e6;
    border-radius: 999px;
    background: #fff;
    padding: .3rem .75rem;
    font-size: .75rem;
    font-weight: 600;
    color: var(--tenant-theme-color, #0d6efd);
    cursor: pointer;
}

/* Lista de "Todas as categorias" (/categorias): alvo de toque maior que o
   padrão do list-group, com foto e nome em tamanho confortável no celular. */
.category-list__item {
    padding-top: 12px;
    padding-bottom: 12px;
}

.category-list .category-icon {
    width: 56px;
    height: 56px;
    object-fit: cover;
    flex-shrink: 0;
}

.category-list__nome {
    font-size: 1.05rem;
    font-weight: 500;
}

/* ------------------------------------------------------------------
   Alertas (OW.notify / global/alert.js) — SweetAlert2 com fundo na cor do
   tipo (severidade visível antes mesmo de ler o texto) e texto/ícone
   brancos por cima. O botão "OK" usa a cor primária do tenant em vez da
   cor do tipo, pra continuar reconhecível como ação da loja.
------------------------------------------------------------------- */
.ow-alert {
    background: var(--ow-alert-color) !important;
    color: #fff !important;
}

.ow-alert .swal2-title,
.ow-alert .swal2-html-container,
.ow-alert .swal2-close {
    color: #fff !important;
}

.ow-alert .swal2-close:hover {
    color: #fff !important;
    opacity: .8;
}

/* Ícone (X do erro, ! do aviso, ✓ do sucesso, i do info) em branco sobre o
   fundo colorido — a cor própria de cada ícone (vermelho/laranja/verde)
   ficaria invisível num fundo da mesma família de cor. */
.ow-alert .swal2-icon {
    border-color: rgba(255, 255, 255, .85) !important;
    color: #fff !important;
}

.ow-alert .swal2-icon .swal2-success-ring {
    border-color: rgba(255, 255, 255, .35) !important;
}

.ow-alert .swal2-icon [class^="swal2-success-line"],
.ow-alert .swal2-icon [class^="swal2-x-mark-line"] {
    background-color: #fff !important;
}

.ow-alert .swal2-timer-progress-bar {
    background: rgba(255, 255, 255, .65) !important;
}

/* Botão de ação (OK/Confirmar) de qualquer SweetAlert2 do storefront — alerta
   bloqueante ou confirmação (`OW.confirm`): cor primária da loja, não a cor
   de severidade do card quando houver uma — o botão é ação da loja. Sem o
   `.ow-alert` na frente porque `OW.confirm()` não usa fundo colorido. */
.swal2-confirm.swal2-styled {
    background: var(--tenant-theme-color, #0d6efd) !important;
    color: #fff !important;
    box-shadow: none !important;
}

.ow-alert--danger    { --ow-alert-color: #dc3545; }
.ow-alert--warning   { --ow-alert-color: #fd7e14; }
.ow-alert--success   { --ow-alert-color: #198754; }
.ow-alert--info      { --ow-alert-color: #0d6efd; }
.ow-alert--secondary { --ow-alert-color: #6c757d; }

/* Convite de instalação do PWA (home.php): a imagem já traz o texto e o
   botão "Instalar agora" desenhados — o elemento inteiro é o alvo do clique,
   por isso zera o estilo padrão de <button>. */
.pwa-install-banner {
    display: block;
    width: 100%;
    margin: .5rem 0 1rem;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.pwa-install-banner__img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 12px;
}

/* ------------------------------------------------------------------
   Login do cliente — tela isolada, sem cabeçalho/nav (modelo
   `docs/ilustracoes/modelo-login.png`): logo no topo, campos
   sublinhados, botão em pílula na cor da loja, ilustração no rodapé.
   Classes `.auth-*` espelhadas em `painel.css` com o mesmo nome —
   mesma linguagem visual, cada stylesheet com sua cópia porque as duas
   telas nunca carregam o mesmo arquivo CSS.
   ------------------------------------------------------------------ */

.pwa-login {
    position: relative;
    display: flex;
    justify-content: center;
    min-height: 100vh;
    /* Logo perto do topo, não no centro morto da tela — a ilustração é quem
       ocupa a metade de baixo. */
    padding: 6vh 1rem 1rem;
    overflow-x: hidden;
    background: #fff;
}

/* Decorativa: colada no rodapé da tela. Em telas largas fica encostada à
   direita; em telas estreitas vira uma faixa ocupando a largura inteira,
   mais baixa pra não engolir a área de toque do formulário. O
   `translateY(30%)` afunda 30% da altura da imagem para fora da tela;
   como o elemento é `fixed`, o transbordo não gera barra de rolagem. */
.pwa-login__ilustracao {
    position: fixed;
    right: 0;
    bottom: 0;
    z-index: 0;
    max-width: 50%;
    max-height: 70vh;
    width: auto;
    height: auto;
    transform: translateY(30%);
    pointer-events: none;
    user-select: none;
}

@media (max-width: 700px) {
    .pwa-login__ilustracao {
        left: 0;
        right: 0;
        width: 100%;
        max-width: 100%;
        max-height: 32vh;
        object-fit: cover;
        object-position: top;
    }
}

.auth-link-funcionario {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 2;
    font-size: .75rem;
    color: #9aa0a8;
    text-decoration: underline;
}

.auth-conteudo {
    position: relative;
    /* Acima da ilustração de fundo — `z-index` sozinho não bastaria sem
       `position` num elemento fixed/absolute concorrente. */
    z-index: 1;
    width: 100%;
    max-width: 380px;
}

.auth-logo {
    display: flex;
    justify-content: center;
    margin-bottom: .5rem;
}

/* A logo é o caminho de volta pro storefront — o link envolve a imagem
   sem mudar o desenho da tela. */
.auth-logo__link {
    display: inline-flex;
    text-decoration: none;
    color: inherit;
}

.auth-logo img {
    max-height: 128px;
    max-width: 440px;
    object-fit: contain;
}

.auth-logo__texto {
    font-size: 1.25rem;
    font-weight: 700;
    color: #1a1b26;
}

.auth-legenda {
    text-align: center;
    font-size: .8rem;
    color: #9aa0a8;
    margin-bottom: 2rem;
}

/* Aviso de checkout: quem ignora esta linha entra sem conta e perde o
   carrinho. Vermelho, negrito e um grau maior que a legenda comum — o
   cinza .8rem passava batido. */
.auth-legenda--aviso {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    color: #dc3545;
    font-size: .9375rem;
    font-weight: 700;
    line-height: 1.35;
}

.auth-legenda--aviso box-icon {
    flex-shrink: 0;
}

.auth-field {
    position: relative;
    margin-bottom: 1.75rem;
}

.auth-field__label {
    display: block;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #9aa0a8;
    margin-bottom: .35rem;
}

.auth-field__input {
    display: block;
    width: 100%;
    border: none;
    border-bottom: 2px solid #e5e7eb;
    background: transparent;
    padding: .3rem 0 .55rem;
    font-size: 1.05rem;
    color: #1f2937;
    border-radius: 0;
}

.auth-field__input:focus {
    outline: none;
    border-bottom-color: var(--auth-accent, var(--tenant-theme-color, #0d6efd));
}

/* Espaço reservado pro botão mostrar/ocultar não empurrar o texto. */
.auth-field--senha .auth-field__input {
    padding-right: 3.5rem;
}

.auth-field__toggle {
    position: absolute;
    right: 0;
    bottom: .6rem;
    background: none;
    border: none;
    padding: 0;
    line-height: 1;
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--auth-accent, var(--tenant-theme-color, #0d6efd));
    cursor: pointer;
}

.auth-button {
    display: block;
    width: 100%;
    margin-top: .5rem;
    padding: .9rem 1rem;
    border: none;
    border-radius: 999px;
    background: var(--auth-accent, var(--tenant-theme-color, #0d6efd));
    color: #fff;
    font-weight: 700;
    font-size: .95rem;
    letter-spacing: .02em;
    text-transform: uppercase;
    cursor: pointer;
    transition: opacity .15s ease, transform .05s ease;
}

.auth-button:hover {
    opacity: .92;
}

.auth-button:active {
    transform: scale(.99);
}

.auth-links {
    text-align: center;
    font-size: .85rem;
    color: #6b7280;
    margin-top: 1.5rem;
    line-height: 1.9;
}

.auth-links a {
    color: var(--auth-accent, var(--tenant-theme-color, #0d6efd));
    font-weight: 600;
    text-decoration: none;
}
