/* =============================================================
   Tema "Orvalho" (estrutura `alimentos`) — a folha INTEIRA.

   O `style.css` do clássico NÃO carrega junto (ver
   views/partials/theme-assets.php): este arquivo traz o próprio reset e o
   próprio tudo — inclusive os utilitários que o JS compartilhado assume
   existir (`.hidden`, `.mobile-hide`, `.skeleton`, `.toast-stack`…) e as
   classes que só nascem em runtime, montadas por JS, que não aparecem em
   partial nenhum para você ler (THEME_PLAYBOOK §4.6b).

   ## A referência, e o que ela decide

   Greenhub (tema Viola, Shopify). O que define a cara dela, e que este
   tema persegue:

   1. **Só a foto tem caixa.** Fundo branco de ponta a ponta; a foto mora
      numa moldura branca de fio finíssimo (`1px solid rgba(18,18,18,.1)`,
      raio de 13px, quadrado perfeito) e o texto embaixo NÃO tem caixa,
      fundo nem recuo lateral — encosta na borda esquerda da moldura. É o
      contrário do reflexo de "card = retângulo em volta de tudo", e é o
      que faz a grade respirar com 28px de vão em vez de virar parede.
   2. **A cor da loja em faixa, não em detalhe.** Utilidade no topo, barra
      de categorias, faixa de newsletter e rodapé inteiro. É o que faz
      duas lojas com primárias diferentes parecerem duas lojas. Sobre a
      mercadoria ela não aparece: nada de disco colorido no canto da foto.
   3. **Pílula em tudo que é controle.** Botão, campo, unidade de medida,
      aba, filtro escolhido, paginação. Conteúdo em canto macio — 8px na
      moldura e no painel, 13px no card, 6px no selo. O selo é a única
      peça da vitrine que NÃO é pílula, e é o que o faz ler como etiqueta
      colada na embalagem em vez de mais um controle.
   4. **Título folgado, não apertado.** `letter-spacing` ABRE (+.3px no
      título, +.5px no botão) e o peso fica em 500 — o oposto do "grande e
      justo" de revista. Com Lato, que é a família dela.
   5. **Nada acontece ao passar o mouse no produto**, além da segunda foto
      surgindo por opacidade. Sem camada de ações, sem botão que aparece.
   6. **Zero rolagem lateral.** O que não cabe anda por botão — no
      computador o trilho nem é contêiner de rolagem.

   As medidas deste arquivo (1170 de caixa, 15 de respiro, 28 de vão, 18px
   de nome de produto, 32px de título de seção) são LIDAS da referência com
   `getComputedStyle`, não estimadas de print.

   Ordem do arquivo (a mesma do §4.4 do playbook):
   reset · tokens · tipografia e utilitários · botões/campos/controles ·
   cabeçalho · menu do celular e gavetas · banner · seções, trilho e
   grade · card · página de produto · listagem e filtro · carrinho ·
   checkout · conta · entrar/criar conta · blocos de runtime ·
   toast/modal/esqueleto · responsivo.
   ============================================================= */

/* ============================== 1. RESET ============================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd, ul, ol {
    margin: 0;
    padding: 0;
}

ul, ol { list-style: none; }

/* Rede de segurança: sem o `style.css` embaixo, uma <img> sem regra
   assume o tamanho natural do arquivo — foi assim que a home de um tema
   irmão abriu com 36.000px de altura na primeira carga (§6.1). */
img, svg, video, canvas, iframe {
    display: block;
    max-width: 100%;
}
img { height: auto; }

button, input, select, textarea {
    font: inherit;
    color: inherit;
    margin: 0;
}

button { background: none; border: 0; cursor: pointer; }

a { color: inherit; text-decoration: none; }

table { border-collapse: collapse; width: 100%; }

/* ============================== 2. TOKENS ============================== */

:root {
    /* --- Paleta da loja (white-label) ---------------------------------
       `core/ThemeColors.js` sobrescreve estas cinco em `documentElement`
       assim que o bootstrap roda. Os valores aqui são o que a primeira
       pintura usa — verde de folha, que é o pior caso decente numa loja
       de alimento se o JS demorar. */
    --primary-color: #1f6b52;
    --secondary-color: #1f6b52;
    --secondary-dark-color: #124435;
    --on-primary: #ffffff;
    --on-brand: #ffffff;

    /* A cor da marca como TEXTO não passa contraste sozinha (§6.24): uma
       primária clara vira preço ilegível sobre papel. Faixa, botão e selo
       usam a primária crua com `--on-primary` calculado por cima; texto
       usa a variante escurecida. */
    --orv-marca-txt: color-mix(in srgb, var(--primary-color) 78%, #000);
    --orv-marca-fundo: color-mix(in srgb, var(--primary-color) 8%, #fff);
    --orv-marca-fio: color-mix(in srgb, var(--primary-color) 24%, #fff);
    --orv-marca-fundo-2: color-mix(in srgb, var(--primary-color) 84%, #000);

    /* --- Papel e tinta ------------------------------------------------
       Croma zero: a página tem faixas inteiras na cor da loja, e neutro
       tingido brigaria com toda primária que não fosse do mesmo matiz.

       A tinta é a da referência crua (`--color-base-text: 18,18,18`), e o
       fio é a MESMA tinta a 10% — que é como ela desenha toda borda
       (`1px solid rgba(18,18,18,.1)`). Escrito em rgba, e não no #e8e8e8
       equivalente, porque a borda também aparece sobre a seção alternada,
       onde um cinza opaco vira um retângulo mais claro que o fundo. */
    --orv-papel: #ffffff;
    --orv-bandeja: #f5f5f5;        /* fundo de miniatura sem moldura */
    --orv-corredor-fundo: #ebebeb; /* caixa de categoria: cena de gôndola */
    --orv-fundo: #f7f7f7;     /* seção alternada */
    --orv-tinta: #121212;
    --orv-tinta-2: #4a4a4a;
    /* 4.83:1 sobre papel e 4.57:1 sobre a bandeja, que é onde ele mais
       aparece. O cinza "bonito" de rótulo (#8b8b8b) dá 3.1:1 e reprova a
       varredura do §7.3 em 12px. */
    --orv-tinta-3: #666666;
    --orv-fio: rgba(18, 18, 18, .1);
    --orv-fio-2: rgba(18, 18, 18, .22);

    /* Semânticas de alimento: o verde de "em estoque/fresco" não segue a
       loja — é leitura de disponibilidade, não identidade. A variante
       escura existe para uso em TEXTO. */
    --orv-fresco: #2f8f4e;
    --orv-fresco-txt: #1e7a3c;
    --orv-fresco-fundo: #ecf6ef;

    /* Selos da referência: preto para "sem estoque", marrom de encarte
       para o desconto (o `#634e45` medido no card dela), verde para
       novidade. */
    --orv-off: #634e45;
    --orv-oferta: #c0392b;
    --orv-oferta-txt: #a5301f;
    --orv-oferta-fundo: #fbeeec;

    /* --- Medidas ------------------------------------------------------
       Tudo aqui é medido na referência, não estimado. A caixa dela tem
       1170px e respira 15px nas bordas; a grade abre 28px entre cards no
       computador e 14px no celular (`--grid-desktop-horizontal-spacing`).

       O raio vem em três degraus porque ela usa três: moldura de foto e
       painel em 8px (`--media-radius`), card e caixa grande em ~13px
       (`--card-corner-radius: .8rem`), selo em ~6px
       (`--badge-corner-radius: .4rem`). Controle é pílula em tudo. */
    --orv-largura: 1170px;
    --orv-gutter: 15px;
    --orv-gap: 28px;       /* entre cards, no computador */
    --orv-gap-cel: 14px;
    --orv-r: 8px;          /* moldura de foto, painel */
    --orv-r-g: 13px;       /* card, caixa grande */
    --orv-r-selo: 6px;
    --orv-pill: 999px;     /* controle */

    --orv-ease: cubic-bezier(.22, .61, .36, 1);

    /* Tokens do manifest (defaults se o head não imprimir) */
    --orv-cols: 5;
    --orv-units: flex;
    --orv-vistos: flex;
    --orv-servicos: flex;

    /* Altura do cabeçalho preso — lida pelo `top` dos painéis colados. */
    --orv-topo: 108px;

    --orv-sombra: 0 18px 40px -18px rgba(20, 20, 20, .28), 0 2px 6px rgba(20, 20, 20, .05);
    --orv-sombra-leve: 0 1px 2px rgba(20, 20, 20, .05);

    /* Camadas nomeadas — nada de 999 solto pelo arquivo. */
    --orv-z-preso: 100;
    --orv-z-mega: 120;
    --orv-z-vistos: 130;
    --orv-z-gaveta: 200;
    --orv-z-fundo-modal: 300;
    --orv-z-modal: 310;
    --orv-z-toast: 400;
}

/* ==================== 3. TIPOGRAFIA E UTILITÁRIOS ==================== */

body {
    background: var(--orv-papel);
    color: var(--orv-tinta);
    font-family: 'Lato', system-ui, -apple-system, 'Segoe UI', sans-serif;
    font-size: 14px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

/* Título NÃO é apertado neste tema. A referência abre `letter-spacing`
   em +.3px no título e em +.5px no botão — o oposto do reflexo de
   "grande e justo" que a maioria dos temas tem. É meia parte do porquê
   ela parece placa de corredor de mercado e não capa de revista; a outra
   meia é o peso, que fica em 500 (Lato resolve para o Regular) em vez do
   600/700 que gritaria ao lado de uma foto de embalagem. */
h1, h2, h3, h4 {
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: .3px;
    color: var(--orv-tinta);
    text-wrap: balance;
}

p { text-wrap: pretty; }
strong, b { font-weight: 700; }

.mini-text { font-size: 12px; line-height: 1.45; color: var(--orv-tinta-3); }

/* --- Estrutura ------------------------------------------------------- */

.container {
    width: 100%;
    max-width: var(--orv-largura);
    margin: 0 auto;
    padding: 0 var(--orv-gutter);
}

.wrapper { width: 100%; }

.flexitem { display: flex; align-items: center; }
.flexcol { display: flex; flex-direction: column; }
.flexwrap { display: flex; flex-wrap: wrap; }
.flexcenter { display: flex; align-items: center; justify-content: center; }

/* --- Utilitários que o JS compartilhado assume existir (§4.4) --------
   Sem eles a loja quebra em silêncio: o que o JS "esconde" aparece, o
   placeholder fica invisível, os slides deitam lado a lado. */

.hidden { display: none !important; }
[hidden] { display: none !important; }

/* NÃO existe regra de `display` para `.mobile-hide` fora do media query:
   `display: initial` vale `inline`, e uma faixa que deveria ser bloco
   vira caixa inline — o fundo pinta só atrás do texto (§6.26). O par é
   resolvido lá embaixo, no responsivo, junto com as áreas de toque. */
.desktop-hide { display: none; }

/* Swiper: banner e galeria usam, e o CSS da lib vem por CDN. Estas três
   são a rede de segurança para o instante entre o HTML e o JS. */
.swiper { overflow: hidden; position: relative; }
.swiper-wrapper { display: flex; }
.swiper-slide { flex: 0 0 100%; min-width: 0; }

/* Caixa de foto. O `a { display:block }` está aqui por causa do §6.18: um
   anchor inline entre a caixa e a foto faz `height:100%` resolver contra
   altura automática, e a imagem sai miúda dentro da moldura. */
.object-cover { position: relative; overflow: hidden; }
.object-cover a { display: block; width: 100%; height: 100%; }
.object-cover img { width: 100%; height: 100%; object-fit: cover; }

.icon-small { display: inline-flex; font-size: 17px; line-height: 1; }
.icon-large { position: relative; display: inline-flex; font-size: 21px; line-height: 1; }

/* Alvo de toque em link DENTRO de texto (§6.30): a caixa de um <a> inline
   é a métrica da fonte, e a varredura do §7.3 pede 22px. `min-height` não
   faz nada em inline; `padding-block` entra no retângulo de clique sem
   empurrar a linha de baixo nem quebrar o `-webkit-line-clamp`. */
.orv-card__nome a,
.breadcrumb a,
.orv-rodape__col a,
.mini-cart .item-content p a,
.toggle-form a,
.orv-estoque__cod a { padding-block: 4px; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--orv-marca-txt);
    outline-offset: 2px;
    border-radius: 4px;
}

@keyframes orv-sobe {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

@keyframes orv-gira { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
}

/* ================= 4. BOTÕES, CAMPOS E CONTROLES ==================
   Dois botões, como na referência: o cheio na cor da loja e o de
   contorno. `.btn`/`.btn-secondary`/`.btn-sm` entram na mesma regra
   porque `profile/index.js` os monta em runtime (§4.6b) — sem isso o
   "Ver detalhes" de um pedido nasce sem nada. */

.primary-button,
.secondary-button,
.light-button,
.btn,
button[type="submit"],
#applyCoupon,
#calculateFreight {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 26px;
    border: 1px solid transparent;
    border-radius: var(--orv-pill);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: .5px;
    text-align: center;
    cursor: pointer;
    transition: background-color .18s var(--orv-ease), color .18s var(--orv-ease),
                border-color .18s var(--orv-ease);
}

.primary-button,
.btn,
button[type="submit"],
#applyCoupon,
#calculateFreight {
    background: var(--primary-color);
    color: var(--on-primary);
}

.primary-button:hover,
.btn:hover,
button[type="submit"]:hover,
#applyCoupon:hover,
#calculateFreight:hover { background: var(--orv-marca-fundo-2); }

/* O contorno da referência é a TINTA cheia, não um cinza de fio: ela
   desenha o secundário com `box-shadow: 0 0 0 1.3px #000`. Um contorno
   claro é o erro clássico aqui — vira botão fantasma ao lado de uma foto
   de embalagem colorida, e o "Ver todos" some do lado do título. */
.secondary-button,
.btn-secondary,
.light-button {
    background: var(--orv-papel);
    color: var(--orv-tinta);
    border-color: var(--orv-tinta);
}

/* O contorno da referência ENCHE no hover, e é a única troca de cor de
   botão do tema. */
.secondary-button:hover,
.btn-secondary:hover,
.light-button:hover {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

.btn-sm { min-height: 34px; padding: 0 14px; font-size: 12.5px; }

.btn-danger,
.btn-modal-danger { background: var(--orv-oferta); color: #fff; border-color: transparent; }

button:disabled,
.primary-button:disabled,
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* --- Campos ---------------------------------------------------------- */

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="number"],
input[type="search"],
input[type="date"],
input[type="mail"],
select,
textarea {
    width: 100%;
    min-height: 46px;
    padding: 10px 18px;
    background: var(--orv-papel);
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    font-size: 14px;
    color: var(--orv-tinta);
    transition: border-color .18s var(--orv-ease), box-shadow .18s var(--orv-ease);
}

textarea { border-radius: var(--orv-r-g); min-height: 110px; resize: vertical; }

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--orv-marca-fundo);
}

/* Placeholder na tinta de rótulo: o cinza claro "elegante" reprova
   contraste e é o motivo mais comum de campo ilegível. */
::placeholder { color: var(--orv-tinta-3); opacity: 1; }

label { font-size: 13px; font-weight: 600; color: var(--orv-tinta-2); }

select {
    appearance: none;
    padding-right: 40px;
    background-image: linear-gradient(45deg, transparent 50%, var(--orv-tinta-2) 50%),
                      linear-gradient(135deg, var(--orv-tinta-2) 50%, transparent 50%);
    background-position: calc(100% - 21px) 21px, calc(100% - 16px) 21px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

input[type="checkbox"],
input[type="radio"] {
    width: 17px;
    height: 17px;
    min-height: 0;
    accent-color: var(--primary-color);
    cursor: pointer;
}

/* --- A pílula de unidade, o controle-assinatura ----------------------
   Mesma peça no card e na página de produto: o rádio some e o rótulo VIRA
   o alvo. O estado ativo é `:has(:checked)` — CSS puro, então a troca é
   instantânea mesmo antes de o módulo compartilhado carregar. */
.orv-un {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 28px;
    padding: 0 12px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    font-size: 12px;
    font-weight: 600;
    color: var(--orv-tinta-2);
    cursor: pointer;
    transition: border-color .16s var(--orv-ease), background-color .16s var(--orv-ease),
                color .16s var(--orv-ease);
}

.orv-un input { position: absolute; opacity: 0; pointer-events: none; }
.orv-un:hover { border-color: var(--orv-tinta-2); color: var(--orv-tinta); }

.orv-un:has(:checked) {
    background: var(--orv-tinta);
    border-color: var(--orv-tinta);
    color: #fff;
}

.orv-un--grande { min-height: 38px; padding: 0 18px; font-size: 13.5px; }
.orv-un__off { font-size: 11px; font-weight: 700; color: var(--orv-oferta-txt); }
.orv-un:has(:checked) .orv-un__off { color: #ffd9d2; }

/* --- Botão redondo de navegação (trilhos, banner, galeria) ------------ */
.orv-redondo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    color: var(--orv-tinta);
    font-size: 20px;
    line-height: 1;
    box-shadow: var(--orv-sombra-leve);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease),
                border-color .16s var(--orv-ease), opacity .16s var(--orv-ease);
}

.orv-redondo:hover {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

/* Fim de trilho: o botão fica no lugar (o layout não pula) e para de
   responder. */
.orv-redondo:disabled {
    opacity: .35;
    cursor: default;
    background: var(--orv-papel);
    border-color: var(--orv-fio);
    color: var(--orv-tinta-3);
}

/* ============================ 5. CABEÇALHO ============================
   Três linhas: utilidade (rola embora), papel com busca, e a faixa de
   categorias. As duas últimas ficam PRESAS e descem junto com a página —
   pedido explícito da referência. */

.header-top {
    background: var(--primary-color);
    color: var(--on-primary);
    font-size: 12.5px;
}

.header-top .wrapper { justify-content: space-between; gap: 16px; min-height: 40px; }
.header-top ul { gap: 22px; }

.header-top a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding-block: 10px;
    opacity: .9;
    transition: opacity .16s var(--orv-ease);
}

.header-top a:hover { opacity: 1; }
.orv-top__oi { font-weight: 600; }

.header-nav {
    position: sticky;
    top: 0;
    z-index: var(--orv-z-preso);
    background: var(--orv-papel);
}

/* A sombra só aparece depois que a página sai do topo: preso e no topo
   são estados diferentes, e a moldura permanente cansa. Quem marca é o JS
   do tema; sem ele o cabeçalho continua preso e só não ganha sombra. */
.header-nav.is-preso { box-shadow: 0 4px 20px -12px rgba(20, 20, 20, .35); }

.orv-head__linha .wrapper {
    justify-content: space-between;
    gap: 24px;
    min-height: 76px;
}

.header-nav .logo img { max-height: 42px; width: auto; object-fit: contain; }

/* Loja sem logotipo: o SiteChrome troca a <img> por um <span> com o nome
   da empresa. */
.header-nav .logo span { font-size: 21px; font-weight: 700; letter-spacing: -.02em; }

/* --- Busca: pílula com o botão encaixado dentro ---------------------- */

.orv-busca { flex: 1 1 auto; max-width: 620px; }

.orv-busca form.search {
    display: flex;
    align-items: center;
    padding: 4px 4px 4px 8px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    transition: border-color .16s var(--orv-ease), box-shadow .16s var(--orv-ease);
}

.orv-busca form.search:focus-within {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--orv-marca-fundo);
}

.orv-busca input[type="search"] {
    flex: 1;
    min-height: 40px;
    padding: 0 12px;
    border: 0;
    background: transparent;
    font-size: 14px;
}

.orv-busca input[type="search"]:focus { outline: none; box-shadow: none; }

/* Filho DIRETO de propósito (§6.27): o `HeaderSearch.js` pendura o menu
   de histórico DENTRO deste mesmo <form>, e um `.orv-busca button` solto
   pintaria cada item do histórico como botão da cor da loja. */
.orv-busca form.search > button[type="submit"] {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 0 26px;
}

/* --- Ações da direita ------------------------------------------------- */

.header-nav .right ul.secont-links { gap: 4px; }

.orv-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--orv-pill);
    transition: background-color .16s var(--orv-ease);
}

.orv-icone:hover { background: var(--orv-bandeja); }

/* A sacola é o único alvo com fundo permanente: é a ação que fecha a
   compra, e na referência ela é a pílula escura do canto. */
.orv-sacola {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 18px 0 16px;
    border-radius: var(--orv-pill);
    background: var(--primary-color);
    color: var(--on-primary);
    transition: background-color .16s var(--orv-ease);
}

.orv-sacola:hover { background: var(--orv-marca-fundo-2); }
.orv-sacola .cart-total { font-size: 13.5px; font-weight: 700; }

/* O contador que o CartFx pulsa. O aninhamento `.fly-item > .item-number`
   é contrato: é onde a bolinha do produto aterrissa. */
.header-nav .fly-item { position: absolute; top: -8px; right: -10px; }

.header-nav .fly-item .item-number {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--orv-pill);
    background: var(--orv-tinta);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

.orv-sacola .fly-item .item-number { background: var(--orv-papel); color: var(--orv-tinta); }

/* --- Faixa de categorias --------------------------------------------- */

.orv-head__faixa {
    background: var(--primary-color);
    color: var(--on-primary);
}

.orv-head__faixa-in {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
}

.orv-head__faixa nav > ul { gap: 2px; flex-wrap: nowrap; }

/* `li` estático de propósito (§6.15): o painel do mega-menu tem
   `left: 0; right: 0` e ancora no ancestral posicionado mais próximo —
   com `position: relative` aqui ele mediria a largura do ITEM. Quem
   posiciona é o `.header-nav`, que é sticky (e sticky conta como
   posicionado). */
.orv-head__faixa li { position: static; }

.orv-head__faixa nav a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 14px 14px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--on-primary);
    opacity: .92;
    transition: opacity .16s var(--orv-ease);
}

.orv-head__faixa nav a:hover,
.orv-head__faixa .has-child:hover > a { opacity: 1; }

.orv-head__faixa .has-child:hover > a .icon-small { transform: rotate(180deg); }
.orv-head__faixa .icon-small { transition: transform .2s var(--orv-ease); font-size: 15px; }

.orv-head__servicos {
    display: var(--orv-servicos, flex);
    align-items: center;
    gap: 22px;
    font-size: 12.5px;
    white-space: nowrap;
}

.orv-head__servicos a,
.orv-head__servicos span {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding-block: 6px;
    opacity: .92;
}

.orv-head__servicos i { font-size: 16px; }

/* --- Mega-menu -------------------------------------------------------- */

.orv-head__faixa .mega {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: var(--orv-z-mega);
    background: var(--orv-papel);
    color: var(--orv-tinta);
    border-top: 1px solid var(--orv-fio);
    box-shadow: var(--orv-sombra);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity .18s var(--orv-ease), transform .18s var(--orv-ease), visibility .18s;
}

.orv-head__faixa .has-child:hover .mega,
.orv-head__faixa .has-child:focus-within .mega {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.orv-head__faixa .mega .wrapper {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 30px;
    padding: 28px 0 32px;
}

.orv-mega__col h4 { font-size: 14px; margin-bottom: 10px; }
.orv-mega__col h4 a { color: var(--orv-tinta); padding: 4px 0; }
.orv-mega__col ul { display: flex; flex-direction: column; gap: 2px; }

.orv-mega__col ul a {
    padding: 5px 0;
    font-size: 13px;
    font-weight: 400;
    color: var(--orv-tinta-2);
    opacity: 1;
}

.orv-mega__col ul a:hover { color: var(--orv-marca-txt); }

.orv-mega__foto {
    display: block;
    margin-top: 14px;
    border-radius: var(--orv-r);
    aspect-ratio: 16 / 10;
    background: var(--orv-bandeja);
}

.orv-mega__foto img { transition: transform .45s var(--orv-ease); }
.orv-mega__foto:hover img { transform: scale(1.04); }

/* =============== 6. MENU DO CELULAR, GAVETAS E OVERLAYS ===============
   O drawer recebe uma CÓPIA de `.header-nav nav` e de `.header-top
   .wrapper` (SiteChrome). Toda regra escrita para a navegação DO
   CABEÇALHO alcança o clone (§6.14) — por isso as regras coloridas acima
   são escopadas em `.orv-head__faixa`, que não existe lá dentro. */

.site-off {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(88vw, 350px);
    z-index: var(--orv-z-gaveta);
    transform: translateX(-102%);
    transition: transform .3s var(--orv-ease);
}

.site.showmenu .site-off { transform: none; }

.off-canvas {
    height: 100%;
    overflow-y: auto;
    background: var(--orv-papel);
    padding: 0 20px 28px;
    box-shadow: var(--orv-sombra);
}

.canvas-head {
    position: sticky;
    top: 0;
    z-index: 2;
    justify-content: flex-end;
    padding: 14px 0;
    background: var(--orv-papel);
}

.canvas-head .t-close {
    display: flex;
    width: 40px;
    height: 40px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    font-size: 20px;
}

/* `align-items: stretch` explícito: o `ul` clonado vem com `.flexitem` do
   cabeçalho, que é `align-items: center` — trocar só a direção deixava
   cada item encolhido e centralizado no meio da gaveta. */
.off-canvas nav > ul,
.off-canvas .thetop-nav ul {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
}

.off-canvas nav a,
.off-canvas .thetop-nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 48px;
    padding: 4px 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--orv-tinta);
    opacity: 1;
}

.off-canvas .thetop-nav {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--orv-fio);
}

/* Sem chevron para empurrar: no bloco de conta o `space-between` jogaria
   o texto para a direita, com o ícone sozinho na esquerda. */
.off-canvas .thetop-nav a { justify-content: flex-start; font-weight: 400; color: var(--orv-tinta-2); }

/* O acordeão do drawer. O `.mega` clonado é um <div>, não o <ul> do menu
   — por isso a regra mira nele diretamente (§6.14). */
.off-canvas .has-child > a > .icon-small {
    width: 34px;
    height: 34px;
    align-items: center;
    justify-content: center;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    transition: transform .2s var(--orv-ease);
}

.off-canvas .has-child .mega { display: none; padding: 2px 0 10px 12px; }
.off-canvas .has-child.expand .mega { display: block; }
.off-canvas .has-child.expand > a > .icon-small { transform: rotate(180deg); }

.off-canvas .mega .wrapper,
.off-canvas .mega .container { display: block; padding: 0; }
.off-canvas .mega h4 { font-size: 13px; margin: 10px 0 4px; }
.off-canvas .mega ul a { min-height: 40px; font-weight: 400; font-size: 14px; }
.off-canvas .orv-mega__foto { display: none; }

/* A cortina atrás da gaveta e da busca do celular. */
.overlay {
    position: fixed;
    inset: 0;
    z-index: calc(var(--orv-z-gaveta) - 1);
    background: rgba(20, 20, 20, .5);
    opacity: 0;
    visibility: hidden;
    transition: opacity .25s var(--orv-ease), visibility .25s;
}

.site.showmenu .overlay,
.site.showsearch .overlay { opacity: 1; visibility: visible; }

/* --- Busca do celular ------------------------------------------------- */

.search-bottom {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    z-index: var(--orv-z-gaveta);
    background: var(--orv-papel);
    padding: 14px 0;
    transform: translateY(-104%);
    transition: transform .28s var(--orv-ease);
    box-shadow: var(--orv-sombra);
}

.site.showsearch .search-bottom { transform: none; }

.search-bottom form.search { display: flex; align-items: center; gap: 8px; }
.search-bottom form.search input[type="search"] { flex: 1; }
.search-bottom form.search > button[type="submit"] { flex: 0 0 auto; }

.search-bottom .t-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    flex: 0 0 auto;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
}

/* --- Barra inferior --------------------------------------------------- */

.menu-bottom {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--orv-z-preso);
    background: var(--orv-papel);
    border-top: 1px solid var(--orv-fio);
    padding-bottom: env(safe-area-inset-bottom);
}

.menu-bottom ul { justify-content: space-around; }
.menu-bottom li { flex: 1; }

.menu-bottom a {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 58px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--orv-tinta-2);
}

.menu-bottom i { font-size: 20px; }
.menu-bottom .fly-item { position: absolute; top: 8px; right: calc(50% - 22px); }

.menu-bottom .fly-item .item-number {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: var(--orv-pill);
    background: var(--primary-color);
    color: var(--on-primary);
    font-size: 10px;
    font-weight: 700;
}

/* --- Gaveta do carrinho ----------------------------------------------
   A caixa externa NÃO sai da tela quando fechada — quem desliza é o
   painel de dentro. Guardar a caixa em `translateX(102%)` parece o óbvio
   e cobra caro: elemento à direita do viewport entra na área rolável do
   documento e a loja inteira ganha rolagem lateral (medido na varredura
   do §7.3; `overflow-x: clip` no <html> não resolve, porque `fixed`
   escapa do recorte do ancestral). */
.mini-cart {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(94vw, 420px);
    z-index: var(--orv-z-gaveta);
    visibility: hidden;
    overflow: hidden;
    transition: visibility .3s;
    text-align: left;
    color: var(--orv-tinta);
}

.mini-cart.show { visibility: visible; }

.mini-cart .content {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
    transform: translateX(102%);
    transition: transform .3s var(--orv-ease);
}

.mini-cart.show .content { transform: none; }

.orv-gaveta__topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 22px 12px;
}

.orv-gaveta__titulo { font-size: 17px; font-weight: 600; }

.orv-gaveta__x {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--orv-pill);
    font-size: 20px;
    color: var(--orv-tinta-2);
}

.orv-gaveta__x:hover { background: var(--orv-bandeja); color: var(--orv-tinta); }

.mini-cart .cart-head {
    flex: none;
    padding: 0 22px 12px;
    border-bottom: 1px solid var(--orv-fio);
    font-size: 12.5px;
    color: var(--orv-tinta-3);
}

.mini-cart .cart-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 22px;
}

/* `.products.mini` vive dentro do `.right` do cabeçalho: qualquer regra
   de descendente escrita para a navegação da direita alcançaria os itens
   do carrinho (§6.27). Por isso tudo aqui é escopado em `.mini-cart`. */
.mini-cart .products.mini { display: flex; flex-direction: column; }

.mini-cart .products.mini li.item {
    display: grid;
    grid-template-columns: 68px minmax(0, 1fr) 32px;
    align-items: center;
    gap: 12px;
    padding: 16px 0;
}

.mini-cart .products.mini li.item + li.item { border-top: 1px solid var(--orv-fio); }

/* `.products.mini`, e NÃO `.mini-cart`: a mesma lista de itens é montada
   em dois lugares — a gaveta do carrinho e o resumo do pedido no checkout
   (`.summary-order .products.mini`). Presa ao `.mini-cart`, a regra
   deixava a lista do checkout sem medida nenhuma, e ali a <img> assumia o
   tamanho natural do arquivo: 328px de largura dentro de uma coluna de
   350 (§6.1 outra vez, agora no checkout).

   A medida fica no EMBRULHO e a foto só preenche — mesmo par do
   `#cart-table`, pelo mesmo motivo (dar altura fixa aos dois estica a
   foto para fora da moldura). */
.products.mini .thumbnail {
    flex: 0 0 auto;
    width: 68px;
    height: 68px;
    padding: 6px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
}

.products.mini .thumbnail img { width: 100%; height: 100%; object-fit: contain; }

/* O resumo do checkout não tem o `.flexitem` que a gaveta tem no `<li>`,
   então foto e texto sairiam empilhados e colados. */
.summary-order .products.mini li.item { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
.summary-order .products.mini li.item + li.item { border-top: 1px solid var(--orv-fio); }
.summary-order .item-content { min-width: 0; }

.mini-cart .item-content {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}

.mini-cart .item-content p {
    font-size: 13.5px;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mini-cart .item-content .price {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    font-weight: 700;
}

.mini-cart .item-content .price .fly-item {
    position: static;
    font-size: 12px;
    font-weight: 600;
    color: var(--orv-tinta-3);
}

.item-unit-tag {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    color: var(--orv-tinta-2);
    font-size: 11px;
    font-weight: 600;
}

.mini-cart .item-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--orv-pill);
    color: var(--orv-tinta-3);
    font-size: 17px;
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.mini-cart .item-remove:hover { background: var(--orv-bandeja); color: var(--orv-oferta); }

.mini-cart .cart-footer {
    flex: none;
    padding: 16px 22px calc(16px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--orv-fio);
}

.mini-cart .subtotal {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 4px;
}

.mini-cart .subtotal p { font-size: 14px; color: var(--orv-tinta-2); }
.mini-cart .subtotal strong { font-size: 20px; color: var(--orv-tinta); }

.orv-gaveta__nota { font-size: 12px; color: var(--orv-tinta-3); margin-bottom: 14px; }

.mini-cart .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mini-cart .actions a { width: 100%; padding: 0 12px; font-size: 13.5px; }

/* Carrinho vazio: o `<ul>` fica sem filhos e a gaveta ficaria oca. */
.mini-cart .products.mini:empty::after {
    content: "Sua sacola está vazia.";
    display: block;
    padding: 44px 0;
    text-align: center;
    font-size: 14px;
    color: var(--orv-tinta-3);
}

/* --- Barra de frete grátis (gaveta e carrinho) ------------------------
   Montada pelo JS de apresentação a partir do subtotal que o módulo
   compartilhado escreve — o MiniCart não sabe que ela existe. */
.orv-frete { margin: 14px 0; }

.orv-frete__texto {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    color: var(--orv-tinta-2);
    margin-bottom: 8px;
}

.orv-frete__texto i { color: var(--orv-fresco-txt); font-size: 16px; }

.orv-frete__trilha {
    height: 6px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    overflow: hidden;
}

/* Cresce por `scaleX`, não por `width`: a barra é sólida, o resultado na
   tela é idêntico e a animação sai do caminho do layout. */
.orv-frete__barra {
    display: block;
    height: 100%;
    width: 100%;
    border-radius: var(--orv-pill);
    background: var(--orv-fresco);
    transform: scaleX(var(--orv-frete-p, 0));
    transform-origin: left center;
    transition: transform .45s var(--orv-ease);
}

.orv-frete--ganhou .orv-frete__texto { color: var(--orv-fresco-txt); font-weight: 600; }

/* ============================== 7. BANNER ==============================
   A faixa da referência NÃO é uma foto de fundo com texto por cima: é um
   fundo claro de papel com o texto à esquerda e a foto recortada à
   direita, ocupando pouco mais da metade. A diferença é estrutural, e é
   ela que dá a leitura leve — a primeira versão deste tema cobria a faixa
   inteira com a foto e punha um véu branco sobre o texto, o que deixava a
   primeira dobra escura e pesada.

   O rendilhado de legumes ao fundo é a mesma ideia do papel de parede da
   referência: traço fino, quase invisível, só para o vazio da esquerda
   não ser um retângulo liso. É SVG embutido — nada de arquivo, nada de
   requisição. */

.orv-banner {
    position: relative;
    background: #f6f4ef;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='220' viewBox='0 0 260 220'%3E%3Cg fill='none' stroke='%23dcd6c8' stroke-width='1.4' stroke-linecap='round'%3E%3Ccircle cx='48' cy='52' r='22'/%3E%3Cpath d='M48 30c3-7 9-9 14-8-1 6-5 10-11 10'/%3E%3Cpath d='M150 44c14 0 22 10 22 22s-9 20-22 20-22-8-22-20 8-22 22-22z'/%3E%3Cpath d='M150 40v-9'/%3E%3Cpath d='M62 150c16-10 30-6 38 4-12 12-30 12-38-4z'/%3E%3Cpath d='M100 154c8-2 14 1 18 6'/%3E%3Cpath d='M196 140c0 16-8 26-18 26s-18-10-18-26 8-22 18-22 18 6 18 22z'/%3E%3Cpath d='M178 118v-10'/%3E%3C/g%3E%3C/svg%3E");
    background-repeat: repeat;
    background-size: 300px 250px;
}

.orv-banner__slider { position: relative; }

/* Cada slide RECORTA o que é seu.
   A foto sangra para fora do container com margem negativa (ver
   `.orv-banner__foto`), e o `overflow: hidden` do `.swiper` só recorta na
   borda do slider — não na borda de cada slide. Resultado: a foto do
   slide vizinho, que está encostado fora da tela, entrava 281px pela
   ESQUERDA e passava por cima do rótulo do slide ativo. Na tela parecia
   um retalho de outra foto colado na margem, e o rótulo aparecia cortado.
   Medido no Chrome: slide ativo em 0..1343, foto do anterior chegando a
   +281.

   Recortar no slide não tira o efeito de sangria: o slide tem a largura
   da viewport, que é exatamente até onde a foto deve ir. */
.orv-banner__slider .swiper-slide { overflow: hidden; }

.orv-banner__in {
    display: grid;
    grid-template-columns: minmax(0, 46fr) minmax(0, 54fr);
    align-items: center;
    gap: clamp(16px, 3vw, 40px);
    min-height: clamp(360px, 38vw, 470px);
}

.orv-banner__texto { padding: 40px 0 56px; }

/* O rótulo pequeno em vermelho de encarte — na referência é ele que
   nomeia a campanha acima do título ("Fresh Grocery Items"). */
.orv-banner__rotulo {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--orv-oferta-txt);
    margin-bottom: 12px;
}

.orv-banner__titulo {
    font-size: clamp(1.9rem, 4vw, 3rem);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.03em;
}

.orv-banner__titulo span { display: block; }
.orv-banner__titulo-2 { color: var(--orv-tinta-2); font-weight: 400; }

.orv-banner__cta { margin-top: 26px; }

/* A foto sangra para a direita e para baixo, como na referência: ela toca
   a borda da faixa em vez de flutuar num cartão. `contain` porque
   embalagem e sacola de feira são fotografadas inteiras. */
/* A foto sangra até a borda direita da tela, como na referência — parar
   na margem do container faria a faixa parecer um cartão, não um cenário.
   `calc(-50vw + 50%)` é a metade que falta entre o container e o
   viewport; com a largura máxima batida, ela vale a própria goteira. */
.orv-banner__foto {
    align-self: stretch;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    min-width: 0;
    margin-right: calc(-50vw + 50%);
}

.orv-banner__foto img {
    width: 100%;
    height: 100%;
    max-height: clamp(360px, 38vw, 470px);
    object-fit: contain;
    object-position: bottom center;
}

/* A entrada em sequência: rótulo, título e botão sobem um depois do outro
   quando o slide vira o ativo. Com um banner só (`--unico`), roda uma vez
   na carga — mesmo efeito, sem slider. */
.orv-banner__slider--unico .orv-banner__texto > *,
.swiper-slide-active .orv-banner__texto > * {
    animation: orv-sobe .6s var(--orv-ease) both;
}

.swiper-slide-active .orv-banner__titulo,
.orv-banner__slider--unico .orv-banner__titulo { animation-delay: .12s; }
.swiper-slide-active .orv-banner__cta,
.orv-banner__slider--unico .orv-banner__cta { animation-delay: .24s; }

/* SEM caixa. A referência põe os controles direto sobre a faixa do
   banner — nada de pílula translúcida com desfoque atrás deles, que é
   linguagem de player de vídeo e some com o fundo claro do banner. Os
   botões são só o ícone num alvo de 44px, na tinta cheia. */
.orv-banner__controles {
    position: absolute;
    left: 50%;
    bottom: 14px;
    z-index: 2;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
}

.orv-banner__seta,
.orv-banner__pausa {
    /* `flex: 0 0 auto` porque o container é estreito e o flex encolhia os
       botões para 34px, abaixo do alvo de toque. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: var(--orv-tinta);
    font-size: 22px;
    transition: opacity .16s var(--orv-ease);
}

.orv-banner__seta:hover,
.orv-banner__pausa:hover { opacity: .6; }

.orv-banner__pontos { display: flex; align-items: center; gap: 11px; padding: 0 11px; }

/* 12px com fio de 1px: cheio no ativo, vazado nos outros. O tamanho é o
   dobro do "ponto discreto" de praxe, e é de propósito — na referência a
   bolinha é alvo de clique, não enfeite. */
.orv-banner__ponto {
    width: 12px;
    height: 12px;
    border-radius: var(--orv-pill);
    border: 1px solid var(--orv-tinta);
    cursor: pointer;
    transition: background-color .18s var(--orv-ease);
}

.orv-banner__ponto--on { background: var(--orv-tinta); }

.orv-banner__risco { width: 1px; height: 20px; background: var(--orv-tinta); opacity: .35; margin: 0 8px; }

/* Os dois ícones da pausa moram no mesmo botão; a classe decide qual
   aparece. A regra mira a classe do <i>, não a tag, porque biblioteca de
   ícone troca o nó (§6.31). */
.orv-banner__pausa .ri-play-mini-fill { display: none; }
.orv-banner__pausa--pausado .ri-pause-mini-fill { display: none; }
.orv-banner__pausa--pausado .ri-play-mini-fill { display: inline-flex; }

/* ==================== 8. SEÇÕES, TRILHO E GRADE ====================
   Toda seção tem a mesma anatomia: título à esquerda, ação à direita,
   conteúdo embaixo. O que muda entre elas é o fundo. */

.orv-sec { padding: clamp(38px, 5vw, 64px) 0; }
.orv-sec--fundo { background: var(--orv-fundo); }

.orv-sec__topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
}

/* 32px é o tamanho medido no "Browse All Categories" da referência, e o
   peso e o espacejamento seguem a regra geral do §3: 500 e +.3px. */
.orv-sec__titulo {
    font-size: clamp(1.4rem, 2.6vw, 2rem);
    font-weight: 500;
    letter-spacing: .3px;
}

/* "Ver todos" é o secundário da referência inteiro: pílula de contorno na
   tinta, 40px de altura, com o espacejamento aberto do §3. */
.orv-vertodos {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 24px;
    border: 1px solid var(--orv-tinta);
    border-radius: var(--orv-pill);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: .5px;
    white-space: nowrap;
    transition: background-color .16s var(--orv-ease), border-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.orv-vertodos:hover {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

/* --- Grade de produtos ------------------------------------------------
   As colunas do computador vêm do manifest, impressas pelo head.php
   DENTRO de media query (§6.33). Celular é sempre 2. */
.orv-grade {
    display: grid;
    grid-template-columns: repeat(var(--orv-cols, 5), minmax(0, 1fr));
    gap: var(--orv-gap);
}

.orv-grade__cel { display: contents; }

/* A aba escondida some com o card inteiro. `display: contents` no
   embrulho faz o card participar da grade como se o wrapper não
   existisse; quando ele é escondido, some junto — sem buraco na grade. */
.orv-grade__cel[hidden] { display: none; }

/* --- Trilho horizontal ------------------------------------------------
   No computador o trilho NÃO é contêiner de rolagem: ele anda por
   `transform` e a caixa recorta. Sem barra, sem arrasto, e sem o atalho
   de duas dedadas do trackpad levando a página para o lado. No toque, a
   rolagem nativa com scroll-snap funciona com o dedo mesmo sem JS. */

.orv-trilho { position: relative; }
.orv-trilho__caixa { overflow: hidden; }

.orv-trilho__fita {
    display: flex;
    gap: var(--orv-gap);
    transition: transform .45s var(--orv-ease);
}

/* As setas ficam SOBRE as bordas da tira, como na referência. */
.orv-trilho__seta {
    position: absolute;
    top: 50%;
    z-index: 2;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    color: var(--orv-tinta);
    font-size: 20px;
    box-shadow: var(--orv-sombra-leve);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease), opacity .16s var(--orv-ease);
}

.orv-trilho__seta:hover { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }
.orv-trilho__seta:disabled { opacity: .3; cursor: default; background: var(--orv-papel); color: var(--orv-tinta-3); }
.orv-trilho__seta--esq { left: -14px; }
.orv-trilho__seta--dir { right: -14px; }

/* --- Corredores (categorias) ------------------------------------------ */

.orv-corredor {
    flex: 0 0 auto;
    width: 166px;   /* 6 colunas de 1170 com 28 de vão, como na referência */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    text-align: center;
}

/* Mesmo canto de 13px do card — é essa repetição que faz a home parecer
   uma prateleira só em vez de três seções empilhadas. O que muda é o
   fundo: cinza cheio em vez do fio.

   Cinza, e não a moldura branca do card, porque foto de CORREDOR é cena
   de gôndola (fundo cheio, sem recorte) e não packshot em fundo branco:
   sobre papel ela flutuaria sem borda visível. E o fio some junto — sobre
   #ebebeb um traço de tinta a 10% não aparece, só suja o canto. */
.orv-corredor__foto {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--orv-r-g);
    background: var(--orv-corredor-fundo);
    transition: background-color .2s var(--orv-ease);
}

.orv-corredor:hover .orv-corredor__foto { background: #e2e2e2; }

/* `contain` com respiro: o cinza precisa APARECER em volta da foto, senão
   a caixa some atrás dela e o token não pinta nada. */
.orv-corredor__foto img { object-fit: contain; padding: 12px; transition: transform .45s var(--orv-ease); }
.orv-corredor:hover .orv-corredor__foto img { transform: scale(1.06); }
.orv-corredor__inicial { font-size: 38px; font-weight: 700; color: var(--orv-tinta-3); }
.orv-corredor__nome { font-size: 15px; font-weight: 500; line-height: 1.3; letter-spacing: .3px; }

/* --- Selos / marcas ---------------------------------------------------- */

.orv-selos { background: var(--orv-fundo); padding: 30px 0; }

.orv-selos__fita {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: clamp(24px, 5vw, 64px);
}

.orv-selos__fita img {
    max-height: 56px;
    width: auto;
    object-fit: contain;
    filter: grayscale(1);
    opacity: .6;
    transition: filter .2s var(--orv-ease), opacity .2s var(--orv-ease);
}

.orv-selos__fita a:hover img { filter: none; opacity: 1; }

/* --- Abas da vitrine --------------------------------------------------- */

.orv-abas { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }

.orv-aba {
    min-height: 36px;
    padding: 0 20px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    font-size: 13px;
    font-weight: 600;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease), border-color .16s var(--orv-ease);
}

.orv-aba:hover { border-color: var(--orv-tinta-2); color: var(--orv-tinta); }
.orv-aba.is-on { background: var(--orv-tinta); border-color: var(--orv-tinta); color: #fff; }

/* --- Faixa de campanha (a oferta com relógio) --------------------------
   Foto cheia, texto centrado em branco e o relógio em quatro círculos —
   o "BIG SALE" da referência. */

/* A faixa de campanha da referência é uma FOTO de ambiente com o texto
   por cima. A loja não tem foto de ambiente: tem o packshot do produto em
   fundo branco, e esticar um packshot para 1360px de largura dá aquele
   borrão claro com texto ilegível em cima.

   Então a faixa inverte: fundo na cor da loja, texto à esquerda e o
   produto recortado à direita, dentro de um círculo de papel. Mesma
   função (uma faixa de campanha que corta a página em duas), mesma
   presença, e usando a foto que a loja realmente tem. */
.orv-campanha {
    position: relative;
    background: var(--primary-color);
    color: var(--on-brand);
    overflow: hidden;
}

.orv-campanha > .container {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
    align-items: center;
    gap: clamp(24px, 4vw, 56px);
}

.orv-campanha__foto {
    order: 2;
    justify-self: center;
    width: min(320px, 74vw);
    aspect-ratio: 1 / 1;
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    margin: 30px 0;
}

/* `cover` dentro do círculo: o catálogo de hortifruti é fotografado em
   quadro cheio, e `contain` deixaria um retângulo flutuando dentro de uma
   moldura redonda. */
.orv-campanha__foto img { object-fit: cover; }

.orv-campanha__texto { padding: clamp(34px, 5vw, 60px) 0; }

.orv-campanha__chapeu {
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    opacity: .9;
}

.orv-campanha h2 {
    margin: 12px 0 8px;
    color: inherit;
    font-size: clamp(1.7rem, 3.6vw, 2.6rem);
    font-weight: 700;
}

.orv-campanha__preco { font-size: 16px; opacity: .92; }
.orv-campanha__preco strong { font-size: 20px; }

/* O relógio: quatro círculos brancos, o rótulo saindo do `::after` para o
   markup continuar sendo os quatro <li> que o Countdown.js escreve. */
.orv-relogio ul { gap: 12px; margin: 26px 0; justify-content: flex-start; }

.orv-relogio li {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 74px;
    height: 74px;
    border-radius: var(--orv-pill);
    background: #fff;
    color: var(--orv-tinta);
    font-size: 22px;
    font-weight: 700;
    line-height: 1;
}

.orv-relogio li::after {
    font-size: 10.5px;
    font-weight: 600;
    color: var(--orv-tinta-3);
    margin-top: 4px;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.orv-relogio #days::after { content: "dias"; }
.orv-relogio #hours::after { content: "horas"; }
.orv-relogio #minutes::after { content: "min"; }
.orv-relogio #seconds::after { content: "seg"; }

.orv-campanha__cta {
    display: inline-flex;
    align-items: center;
    min-height: 46px;
    padding: 0 30px;
    border: 1px solid currentColor;
    border-radius: var(--orv-pill);
    font-size: 14px;
    font-weight: 600;
    color: inherit;
    transition: background-color .18s var(--orv-ease), color .18s var(--orv-ease);
}

.orv-campanha__cta:hover { background: var(--orv-papel); color: var(--orv-tinta); border-color: var(--orv-papel); }

/* ============================== 9. CARD ==============================
   A anatomia é a da referência, medida nela: SÓ a moldura da foto tem
   caixa — fio de 1px na tinta a 10%, raio de ~13px, quadrado perfeito. O
   texto embaixo não tem caixa, não tem fundo e não tem recuo lateral;
   encosta na borda da foto e sobe alinhado à esquerda.

   Isso é o contrário do reflexo de "card = retângulo com borda em volta
   de tudo", e é o que faz a grade dela respirar com 28px de vão em vez de
   virar uma parede de molduras. Selos empilhados no canto superior
   esquerdo, favorito no oposto, e o botão de contorno no pé.

   Nenhuma camada de ações no hover: a única resposta é a segunda foto
   surgindo. */

.orv-card {
    display: flex;
    flex-direction: column;
}

/* A moldura vive na FOTO, não no card. `overflow: hidden` fica aqui
   porque é ela que recorta a segunda foto e o zoom. */
.orv-card__foto {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
    transition: border-color .2s var(--orv-ease);
}

.orv-card:hover .orv-card__foto { border-color: var(--orv-fio-2); }
.orv-card__foto .thumbnail { aspect-ratio: 1 / 1; }

/* `contain`, e não o `cover` que a referência usa: as fotos dela são
   packshot quadrado de estúdio, onde os dois dão o mesmo resultado; as
   nossas vêm do catálogo do lojista em proporção qualquer, e `cover`
   cortaria a tampa da embalagem. Com a moldura branca em volta, o efeito
   na tela é o mesmo dela. */
.orv-card__foto img { object-fit: contain; padding: 12px; }

/* A troca de foto: a segunda fica por cima com opacidade 0 e sobe no
   hover — nada de trocar `src`, que pisca enquanto a segunda baixa. Só
   existe quando o produto TEM segunda foto diferente da capa. */
.orv-card__foto2 {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity .45s var(--orv-ease);
}

.orv-card__foto--dupla:hover .orv-card__foto2,
.orv-card:focus-within .orv-card__foto2 { opacity: 1; }

.orv-card__selos {
    position: absolute;
    top: 12px;
    left: 12px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
    pointer-events: none;
}

/* Retângulo de canto macio, e não pílula: na referência o selo é a única
   coisa da vitrine que NÃO é pílula (`--badge-corner-radius: .4rem`) — é
   o que o faz ler como etiqueta colada na embalagem em vez de mais um
   controle. Peso normal, corpo 12: ele informa, não grita. */
.orv-selo {
    display: inline-flex;
    padding: 2px 10px;
    border-radius: var(--orv-r-selo);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.5;
    color: #fff;
}

.orv-selo--fora { background: var(--orv-tinta); }
.orv-selo--off { background: var(--orv-off); }
.orv-selo--volta { background: var(--primary-color); color: var(--on-primary); }

/* `.favorite-btn` é o coração do card E o link "Favoritos" da página de
   produto (§6.6): o posicionamento absoluto mora na classe DO TEMA, senão
   ele arranca o link da outra tela e gruda no canto.

   Papel com fio, e não o disco na cor da loja que estava aqui: dentro de
   uma moldura branca de 200px o disco colorido era o objeto mais forte do
   card e competia com a própria mercadoria. A referência não põe NADA de
   cor permanente sobre a foto — o botão dela ("Quick view") é neutro e só
   a cor da loja no hover. */
/* Os dois botões da foto empilhados no canto oposto aos selos. Uma pilha,
   e não dois `position: absolute` com `top` calculado na mão — assim
   entrar um terceiro botão não obriga a recontar deslocamento. */
.orv-card__cantos {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.orv-card__fav,
.orv-card__qv {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    color: var(--orv-tinta-2);
    font-size: 17px;
    cursor: pointer;
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease),
                border-color .16s var(--orv-ease);
}

.orv-card__fav:hover,
.orv-card__qv:hover {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

.orv-card__fav .ri-heart-3-fill { color: var(--orv-oferta); }
.orv-card__fav:hover .ri-heart-3-fill { color: #ffd2cc; }

/* `15px 0 0`: o texto encosta na borda ESQUERDA da foto. Sem recuo
   lateral e sem fundo — é a diferença entre a vitrine da referência e um
   mural de fichas. */
.orv-card__corpo {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 15px 0 0;
    flex: 1;
}

/* Rótulo de categoria em corpo normal, sem versalete: a referência põe o
   fornecedor logo abaixo do nome com o mesmo 14px do texto corrido. O
   versalete de 11px que estava aqui é linguagem de moda, não de
   mercearia. */
.orv-card__cat {
    font-size: 14px;
    color: var(--orv-tinta-3);
}

/* 18px em peso normal. É o número medido no card dela, e é grande: o nome
   do produto é o que se varre numa vitrine de mercado, não o preço. */
/* `min-height` de DUAS linhas: o nome é recortado em 2 (`line-clamp`
   abaixo), mas quem tem só uma deixava a linha seguinte — a categoria —
   subir 22px. Numa fileira de cinco cards em que dois nomes quebram e
   três não, a categoria e o preço saem do prumo e a grade fica serrilhada
   (visto no Chrome: categoria em y=219 em três cards e y=241 no vizinho).
   Reservar a altura das duas linhas alinha a fileira inteira sem depender
   do tamanho do nome, que vem do catálogo do lojista.

   Os 8px do fim da conta são o `padding-block: 4px` que o <a> de dentro
   recebe pela regra de alvo de toque (§6.30) — sem somá-los, o card de
   nome curto fica 8px mais baixo que o de nome longo e o serrilhado
   continua, só que menor. */
.orv-card__nome {
    font-size: 18px;
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: .3px;
    min-height: calc(18px * 1.2 * 2 + 8px);
}

.orv-card__nome a {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.orv-card__preco {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: auto;
}

/* 18px em 500 para o preço vigente e 14px normal para o riscado — os dois
   números da referência. O 700 que estava aqui empatava com o nome em
   força visual; em 500 o par nome/preço lê como uma coisa só. */
.orv-card__preco .current { font-size: 18px; font-weight: 500; }
.orv-card__preco .normal { font-size: 14px; color: var(--orv-tinta-3); text-decoration: line-through; }
.orv-card__preco .login-required { font-size: 14px; font-weight: 500; color: var(--orv-marca-txt); }

/* O `display` vem de custom property porque o interruptor do manifest é
   impresso pelo head.php: este card é renderizado também pela busca, com
   uma lista fixa de parâmetros, sem as preferências da loja dentro. */
.orv-card__unidades { display: var(--orv-units, flex); flex-wrap: wrap; gap: 5px; }

.orv-card__linha {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 13px;
    color: var(--orv-tinta-3);
}

.orv-card__frete { display: inline-flex; align-items: center; gap: 4px; color: var(--orv-fresco-txt); font-weight: 700; }

.orv-card__obs {
    font-size: 13px;
    color: var(--orv-tinta-3);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* A linha QUEBRA sozinha quando o botão não cabe ao lado do stepper.
   Sem breakpoint: o card tem largura diferente em cada tela (206px na
   home, 149px no explorar, que perde espaço pro filtro), e um limiar
   fixo erraria em uma das duas.

   Quem decide é o `flex-basis` do botão: 96px é a largura de que
   "Adicionar" precisa. Cabendo o stepper (84) + o vão (8) + esses 96,
   ficam lado a lado; não cabendo, o botão vai para a linha de baixo com
   a largura inteira do card. `min-width: 0` sozinho não resolvia — ele
   deixa o botão ENCOLHER, mas o texto dentro não encolhe junto e
   vazava para fora da pílula (achado ao vivo no explorar). */
.orv-card__acao { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 4px; }

/* Altura FIXA de 40, a mesma do "Adicionar". Sem ela a caixa mede o
   conteúdo (40) MAIS o próprio fio de 1px em cima e embaixo, e sobra um
   degrau de 2px no pé de todo card da grade. */
.purchase-quantity {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    height: 40px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    overflow: hidden;
}

/* 40px, a MESMA altura do "Adicionar" ao lado: os dois formam uma linha
   só, e qualquer diferença aqui aparece como degrau no pé de todo card da
   grade. */
.purchase-quantity-btn {
    flex: 0 0 auto;
    width: 26px;
    height: 40px;
    font-size: 15px;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease);
}

.purchase-quantity-btn:hover { background: var(--orv-bandeja); }

/* A seta do input numérico rouba 16px de uma caixa de 36 — e o stepper ao
   lado faz o mesmo trabalho. */
/* `input.` no seletor NÃO é enfeite: o campo genérico do §4 é
   `input[type="number"]`, que pesa 0,1,1 — mais que a classe sozinha
   (0,1,0). Sem o qualificador, quem mandava aqui era a regra genérica, e
   o campo do stepper ficava com os 46px de altura e os 18px de recuo
   lateral de um campo de formulário: a caixa saía com 124px de largura e
   48 de altura ao lado de um botão de 40, empurrando o "Adicionar" para
   fora do card. */
input.purchase-quantity-input {
    flex: 0 0 auto;
    width: 30px;
    min-height: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 0;
    text-align: center;
    font-size: 14px;
    font-weight: 500;
    -moz-appearance: textfield;
}

.purchase-quantity-input::-webkit-outer-spin-button,
.purchase-quantity-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* O botão do card é o de CONTORNO da referência, e ele enche no hover. */
/* `min-width: 0` é o que impede o estouro: item de flex não encolhe
   abaixo do próprio conteúdo por padrão, então "Adicionar" + 14px de
   recuo de cada lado formavam um piso e o botão VAZAVA para fora do card
   em vez de espremer. */
.orv-card__acao .purchase-btn {
    flex: 1 1 96px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    padding: 0 10px;
    border: 1px solid var(--orv-tinta);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: .5px;
    color: var(--orv-tinta);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease), border-color .16s var(--orv-ease);
}

.orv-card__acao .purchase-btn:hover:not(:disabled) {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

/* ======================== 10. PÁGINA DE PRODUTO ======================== */

.orv-produto { padding: 20px 0 clamp(34px, 5vw, 60px); }

.breadcrumb ul {
    flex-wrap: wrap;
    gap: 8px;
    padding: 6px 0 20px;
    font-size: 12.5px;
    color: var(--orv-tinta-3);
}

.breadcrumb li + li::before { content: "/"; margin-right: 8px; color: var(--orv-fio-2); }
.breadcrumb a { color: var(--orv-tinta-3); }
.breadcrumb a:hover { color: var(--orv-tinta); }

.orv-produto__grade {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(24px, 4vw, 60px);
    align-items: start;
}

/* --- Galeria ---------------------------------------------------------- */

.orv-galeria__palco {
    position: relative;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    overflow: hidden;
}

.orv-galeria__palco .image-show {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
}

.orv-galeria__palco .image-show a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 26px;
}

/* Altura definida e largura mandando: `aspect-ratio` com largura
   automática faz o navegador ESTREITAR a caixa para manter a proporção
   (§6.8). */
.orv-galeria__palco img { max-height: 100%; width: auto; object-fit: contain; }

.orv-galeria__seta {
    position: absolute;
    top: 50%;
    z-index: 2;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    cursor: pointer;
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease), opacity .16s var(--orv-ease);
}

.orv-galeria__seta:hover { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }
.orv-galeria__palco .swiper-button-prev { left: 14px; }
.orv-galeria__palco .swiper-button-next { right: 14px; }

.orv-galeria__palco .swiper-button-prev::after,
.orv-galeria__palco .swiper-button-next::after {
    font-family: swiper-icons;
    font-size: 14px;
    font-weight: 700;
}

.orv-galeria__palco .swiper-button-prev::after { content: "prev"; }
.orv-galeria__palco .swiper-button-next::after { content: "next"; }
.orv-galeria__palco .swiper-button-disabled { opacity: 0; pointer-events: none; }

.orv-galeria__fita { margin-top: 14px; }
.orv-galeria__fita ul { display: flex; gap: 12px; }

.orv-galeria__fita li {
    flex: 0 0 auto;
    width: 88px;
    height: 88px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    overflow: hidden;
    cursor: pointer;
    transition: border-color .16s var(--orv-ease);
}

.orv-galeria__fita li img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.orv-galeria__fita li:hover { border-color: var(--orv-fio-2); }

/* A miniatura ativa é marcada pelo Swiper de miniaturas, que o
   ProductGallery liga. */
.orv-galeria__fita .swiper-slide-thumb-active { border-color: var(--primary-color); }

/* --- Coluna de compra -------------------------------------------------- */

.orv-compra__marca {
    display: inline-flex;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--orv-tinta-3);
    margin-bottom: 8px;
}

.orv-compra h1 { font-size: clamp(1.5rem, 3vw, 2.15rem); letter-spacing: -.025em; }

.orv-compra .content { display: flex; flex-direction: column; gap: 20px; margin-top: 16px; }

.orv-compra .rating { display: flex; align-items: center; gap: 12px; font-size: 12.5px; }
.orv-compra .rating a { color: var(--orv-tinta-3); text-decoration: underline; padding-block: 4px; }
.orv-compra .rating a:hover { color: var(--orv-tinta); }

/* As estrelas são desenhadas pelo JS compartilhado a partir de
   `data-rating`; sem regra viram uma linha de texto solta. */
.stars { display: inline-flex; gap: 2px; color: #e0a12a; font-size: 14px; }

.orv-compra .price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 12px; }

.orv-compra .price .current {
    font-size: clamp(1.6rem, 3vw, 2.1rem);
    font-weight: 700;
    letter-spacing: -.03em;
}

.orv-compra .price .normal { font-size: 15px; color: var(--orv-tinta-3); text-decoration: line-through; }
.orv-compra .price .login-required { font-size: 15px; font-weight: 600; color: var(--orv-marca-txt); }

/* O selo de oferta que na referência fica colado no preço. Ele é montado
   pelo partial de preço compartilhado como `.cashback-badge`; o de
   desconto propriamente dito sai da galeria (ver o partial). */
.cashback-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 11px;
    border-radius: var(--orv-pill);
    background: var(--orv-marca-fundo);
    color: var(--orv-marca-txt);
    font-size: 11.5px;
    font-weight: 700;
}

/* --- Unidades ---------------------------------------------------------- */

.orv-unidades__rotulo { font-size: 13.5px; color: var(--orv-tinta-2); margin-bottom: 10px; }
.orv-unidades__rotulo strong { color: var(--orv-tinta); }
.orv-unidades__fila { display: flex; flex-wrap: wrap; gap: 8px; }

/* A mensagem de economia nasce escondida e só aparece com `.visible` —
   quem põe a classe é `features/product/index.js`, que decide quando a
   conversão compensa. */
.orv-unidades__economia {
    display: none;
    align-items: center;
    gap: 7px;
    margin-top: 12px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--orv-fresco-txt);
}

.orv-unidades__economia.visible { display: flex; }

/* --- Variação (dropdown do clássico, com a pele daqui) ----------------- */

.sizes p { font-size: 13.5px; color: var(--orv-tinta-2); margin-bottom: 10px; }

.select { position: relative; max-width: 340px; }

.select .select-button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    min-height: 46px;
    padding: 0 18px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    font-size: 14px;
    cursor: pointer;
}

.select .select-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: var(--orv-z-mega);
    max-height: 260px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
}

.select .select-dropdown li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px;
    border-radius: var(--orv-r);
    font-size: 13.5px;
    cursor: pointer;
}

.select .select-dropdown li:hover { background: var(--orv-bandeja); }

/* `i, svg` sempre: a lib de ícone troca a TAG depois de carregar, e uma
   regra que mire só o <i> deixa de casar — o tique passaria a aparecer em
   TODAS as variações (§6.31). */
.select .select-dropdown li i,
.select .select-dropdown li svg { opacity: 0; width: 15px; height: 15px; }
.select .select-dropdown li.selected i,
.select .select-dropdown li.selected svg { opacity: 1; }

/* --- Disponibilidade com barra ----------------------------------------- */

.orv-estoque {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 18px;
    border-top: 1px solid var(--orv-fio);
}

.orv-estoque__linha { font-size: 13.5px; color: var(--orv-tinta-2); }
.orv-estoque__linha .available { color: var(--orv-fresco-txt); font-weight: 700; }
.orv-estoque__linha--fora { color: var(--orv-oferta-txt); font-weight: 600; }

.orv-estoque__trilha {
    height: 4px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    overflow: hidden;
}

/* Cresce da esquerda ao carregar. `scaleX` e não `width`: fica fora do
   caminho do layout, e a proporção chega como custom property inline
   porque é DADO — o estoque daquele produto. */
.orv-estoque__barra {
    display: block;
    height: 100%;
    width: 100%;
    border-radius: var(--orv-pill);
    background: var(--orv-fresco);
    transform-origin: left center;
    animation: orv-estoque .9s var(--orv-ease) both;
}

@keyframes orv-estoque {
    from { transform: scaleX(0); }
    to   { transform: scaleX(var(--orv-estoque-p, 0)); }
}

.orv-estoque__cod { font-size: 11.5px; color: var(--orv-tinta-3); }
.orv-estoque__frete { color: var(--orv-fresco-txt); font-weight: 600; }

/* --- Ações ------------------------------------------------------------- */

.orv-acoes { display: flex; flex-direction: column; gap: 16px; }
.orv-acoes__qtd { display: flex; align-items: center; gap: 16px; }
.orv-acoes__rotulo { font-size: 13.5px; color: var(--orv-tinta-2); }

.qty-control { border: 1px solid var(--orv-fio-2); border-radius: var(--orv-pill); overflow: hidden; }

.qty-control button {
    width: 42px;
    height: 46px;
    font-size: 17px;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease);
}

.qty-control button:hover { background: var(--orv-bandeja); }

.qty-control input {
    width: 56px;
    min-height: 46px;
    padding: 0;
    border: 0;
    border-radius: 0;
    text-align: center;
    font-size: 14px;
    font-weight: 700;
}

.qty-control input:focus { box-shadow: none; }

.orv-acoes__botoes { display: flex; flex-direction: column; gap: 10px; }
.orv-acoes__botoes button { width: 100%; min-height: 52px; font-size: 15px; }

.orv-acoes__extras ul { gap: 24px; }

.orv-acoes__extras a {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: 34px;
    padding-block: 4px;
    font-size: 13px;
    color: var(--orv-tinta-2);
    cursor: pointer;
}

.orv-acoes__extras a:hover { color: var(--orv-tinta); }
.orv-acoes__extras .icon-large { font-size: 18px; }
.orv-acoes__extras .ri-heart-3-fill { color: var(--orv-oferta); }

/* --- Ficha (vendedor/categoria) ---------------------------------------- */

.orv-ficha { display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; }
.orv-ficha > div { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 12px; }
.orv-ficha dt { color: var(--orv-tinta-3); }
.orv-ficha dd { font-weight: 600; }

/* --- Faixa por quantidade ---------------------------------------------- */

.quantity-tiers { padding: 16px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r); background: var(--orv-fundo); }
.quantity-tiers-title { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.quantity-tiers ul, .quantity-tiers .tier-list { display: flex; flex-wrap: wrap; gap: 8px; }

.quantity-tiers li,
.quantity-tiers .tier {
    flex: 1 1 120px;
    padding: 10px 12px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    font-size: 12.5px;
    line-height: 1.35;
}

/* `.active` é a classe que `QuantityTierPricing.js` aplica na faixa que
   vale para a quantidade digitada — conferida no módulo (§6.5). */
.quantity-tiers li.active,
.quantity-tiers .tier.active { border-color: var(--primary-color); background: var(--orv-marca-fundo); }

/* --- Contagem regressiva do produto ------------------------------------ */

.orv-compra .offer {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-radius: var(--orv-r);
    background: var(--orv-oferta-fundo);
}

.orv-compra .offer p { font-size: 12.5px; font-weight: 700; color: var(--orv-oferta-txt); }
.orv-compra .offer ul { display: flex; gap: 6px; }

.orv-compra .offer li {
    min-width: 42px;
    padding: 6px 8px;
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    font-size: 14px;
    font-weight: 700;
    text-align: center;
}

/* --- Compre junto e upsell ---------------------------------------------- */

.buy-together,
.upsell { padding-top: 20px; border-top: 1px solid var(--orv-fio); }

.buy-together-title,
.upsell-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; margin-bottom: 14px; }

.buy-together-items,
.upsell-items { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* `max-width` porque a lista é flex: com UM complementar o cartão
   esticaria para a coluna inteira e a foto viraria o assunto da página. */
.buy-together-card,
.upsell-card {
    flex: 1 1 140px;
    min-width: 0;
    max-width: 220px;
    padding: 12px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    text-align: center;
}

.buy-together-card .thumbnail,
.upsell-card .thumbnail {
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--orv-r);
    background: var(--orv-bandeja);
    margin-bottom: 10px;
}

.buy-together-card .thumbnail img,
.upsell-card .thumbnail img { object-fit: contain; padding: 8px; }

/* O nome é <a> inline (no upsell a classe está no próprio anchor):
   `padding-block` leva o alvo de 17px para os 22 do §7.3. */
a.upsell-name,
.buy-together-name a { display: inline-block; padding-block: 3px; }

.buy-together-name,
.upsell-name {
    font-size: 12.5px;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.buy-together-price,
.upsell-price { display: inline-flex; align-items: baseline; gap: 6px; margin-top: 6px; font-size: 13.5px; font-weight: 700; }
.buy-together-price .normal,
.upsell-price .normal { font-weight: 400; font-size: 11.5px; color: var(--orv-tinta-3); text-decoration: line-through; }

.buy-together-plus {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    font-size: 15px;
}

.buy-together-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.buy-together-total { font-size: 13.5px; }

/* --- Acordeão de detalhes ------------------------------------------------
   `.description.collapse > ul > li.has-child` com o `<a class="icon-small">`
   de cabeçalho. Quem alterna é o SiteChrome, pondo `.expand` no `li` — e
   ele usa o MESMO seletor da navegação, então o cabeçalho aqui precisa
   continuar sendo um `.icon-small`. */

.description.collapse { margin-top: 4px; border-top: 1px solid var(--orv-fio); }
.description.collapse > ul > li.has-child { border-bottom: 1px solid var(--orv-fio); }

.description.collapse > ul > li.has-child > a.icon-small {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 18px 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--orv-tinta);
    cursor: pointer;
}

.description.collapse > ul > li.has-child > a.icon-small::after {
    content: "\ea4e";
    font-family: remixicon;
    font-size: 20px;
    color: var(--orv-tinta-3);
    transition: transform .22s var(--orv-ease);
}

.description.collapse > ul > li.has-child.expand > a.icon-small::after { transform: rotate(180deg); }
.description.collapse > ul > li.has-child > .content { display: none; }
.description.collapse > ul > li.has-child.expand > .content { display: block; padding-bottom: 20px; }
.description.collapse .content p { font-size: 14px; color: var(--orv-tinta-2); }

.description.collapse ul.content > li {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 10px 0;
    border-bottom: 1px solid var(--orv-fio);
    font-size: 13.5px;
}

.description.collapse ul.content > li:last-child { border-bottom: 0; }
.description.collapse ul.content > li span:first-child { color: var(--orv-tinta-3); }
.description.collapse ul.content > li span:last-child { font-weight: 600; text-align: right; }

.description.collapse table th,
.description.collapse table td { padding: 10px; border-bottom: 1px solid var(--orv-fio); font-size: 13px; text-align: left; }
.description.collapse table th { color: var(--orv-tinta-3); font-weight: 600; }

/* --- Avaliações ----------------------------------------------------------
   `.review-block` é ESTA caixa E a linha rótulo|valor da revisão do
   checkout (§6.22): tudo aqui é escopado em `.reviews`. */

.reviews h4 { font-size: 15px; margin-bottom: 14px; }

.reviews .review-block-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 16px;
    border-radius: var(--orv-r);
    background: var(--orv-fundo);
}

.reviews .rate-sum { font-size: 28px; font-weight: 700; line-height: 1; margin-right: 8px; }
.reviews .review-block-body ul { display: flex; flex-direction: column; gap: 16px; margin-top: 18px; }
.reviews .review-block-body li.item { padding-bottom: 16px; border-bottom: 1px solid var(--orv-fio); }
.reviews .person { font-size: 13.5px; font-weight: 600; }
.reviews .review-title { font-weight: 600; margin-top: 6px; font-size: 13.5px; }
.reviews .review-text { font-size: 13.5px; color: var(--orv-tinta-2); }
.reviews .review-form { margin-top: 18px; }
.reviews .review-form textarea,
.reviews .review-form input[type="text"] { margin-top: 8px; }

/* Estrelas clicáveis: input escondido, label com o ícone. A ordem no
   markup é invertida (star5 primeiro), então o realce vai do marcado para
   os irmãos SEGUINTES. */
.reviews .rate-this { display: inline-flex; flex-direction: row-reverse; justify-content: flex-end; gap: 4px; }
.reviews .rate-this input { position: absolute; opacity: 0; pointer-events: none; }
.reviews .rate-this label { font-size: 22px; color: var(--orv-fio-2); cursor: pointer; transition: color .15s var(--orv-ease); }
.reviews .rate-this input:checked ~ label,
.reviews .rate-this label:hover,
.reviews .rate-this label:hover ~ label { color: #e0a12a; }

.reviews .view-all { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; padding-block: 5px; font-size: 13px; font-weight: 600; color: var(--orv-marca-txt); }

.mobile-return-button { display: none; }

/* ==================== 11. LISTAGEM, FILTRO E BUSCA ==================== */

.orv-busca-pag { padding: 20px 0 clamp(34px, 5vw, 60px); }

.orv-busca-pag__topo { text-align: center; margin-bottom: 30px; }
.orv-busca-pag__topo h1 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin-bottom: 18px; }

/* O campo centrado da referência, com a lupa dentro. */
.orv-busca-pag__campo {
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 520px;
    margin: 0 auto;
    padding: 4px 6px 4px 10px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
}

.orv-busca-pag__campo input[type="search"] { flex: 1; min-height: 40px; border: 0; padding: 0 8px; }
.orv-busca-pag__campo input[type="search"]:focus { outline: none; box-shadow: none; }

.orv-busca-pag__campo > button[type="submit"] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    min-height: 0;
    padding: 0;
    border-radius: var(--orv-pill);
    font-size: 18px;
}

.orv-busca-pag__grade {
    display: grid;
    grid-template-columns: 244px minmax(0, 1fr);
    gap: clamp(20px, 3vw, 40px);
    align-items: start;
}

.filter { position: sticky; top: calc(var(--orv-topo) + 14px); max-height: calc(100vh - var(--orv-topo) - 28px); overflow-y: auto; padding-right: 4px; }

/* SEM `display` aqui: `.orv-filtro__topo` é `.desktop-hide`, e uma regra
   de display escrita fora do media query vence o utilitário por ordem de
   cascata — o cabeçalho "Filtrar ✕" aparecia no computador, onde não há
   painel para fechar (§6.7). O display mora no media query do celular. */
.orv-filtro__topo { align-items: center; justify-content: space-between; padding-bottom: 12px; }
.orv-filtro__topo strong { font-size: 15px; }

.filter-block { padding: 18px 0; border-bottom: 1px solid var(--orv-fio); }
.filter-block:first-of-type { padding-top: 0; }

.filter-block h4 {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--orv-tinta-3);
    margin-bottom: 12px;
}

.filter-block ul { display: flex; flex-direction: column; gap: 2px; max-height: 240px; overflow-y: auto; }

.filter-block li { display: flex; align-items: center; gap: 8px; min-height: 32px; font-size: 13.5px; color: var(--orv-tinta-2); }
.filter-block label { display: flex; align-items: center; gap: 8px; font-weight: 400; cursor: pointer; }
.filter-block .count { margin-left: auto; font-size: 11.5px; color: var(--orv-tinta-3); }
.filter-block .checked { display: none; }
.orv-filtro__vazio { font-size: 12.5px; color: var(--orv-tinta-3); }

.byprice input[type="range"] { width: 100%; accent-color: var(--primary-color); }
.price-range { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: 13px; font-weight: 600; }
.price-separator { color: var(--orv-tinta-3); font-weight: 400; }

/* Chips do filtro escolhido. O `Filters.js` mostra o bloco LIMPANDO o
   estilo inline (`display = ''`), então um `display: none` fixo na folha
   venceria para sempre e o chip nunca apareceria (§6.28) — a decisão é
   por CONTEÚDO. */
#selectedFilters { display: none; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
#selectedFilters:has(#selectedFiltersList *) { display: flex; }
#selectedFilters h4 { font-size: 12.5px; color: var(--orv-tinta-3); font-weight: 600; }
#selectedFiltersList { display: flex; flex-wrap: wrap; gap: 6px; }

#selectedFiltersList > * {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: var(--orv-pill);
    background: var(--orv-marca-fundo);
    color: var(--orv-marca-txt);
    font-size: 12px;
    font-weight: 600;
}

#selectedFiltersList .remove { cursor: pointer; opacity: .7; }
#selectedFiltersList .remove:hover { opacity: 1; }

.cat-navigation {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 0 18px;
    border-bottom: 1px solid var(--orv-fio);
    margin-bottom: 20px;
}

.item-sortir, .item-perpage, .item-options, .item-filter { position: relative; }

.item-sortir .label,
.item-options .label,
.item-filter .label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 38px;
    padding: 0 16px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.item-sortir ul,
.item-options ul {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: var(--orv-z-mega);
    min-width: 210px;
    padding: 6px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
    opacity: 0;
    visibility: hidden;
    transition: opacity .16s var(--orv-ease), visibility .16s;
}

.item-sortir:hover ul, .item-sortir:focus-within ul,
.item-options:hover ul, .item-options:focus-within ul { opacity: 1; visibility: visible; }

.item-sortir li, .item-options li { padding: 9px 10px; border-radius: var(--orv-r); font-size: 13px; cursor: pointer; }
.item-sortir li:hover, .item-options li:hover { background: var(--orv-bandeja); }

.load-more { margin-top: 30px; }

.pagination { display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; }
.pagination ul { display: flex; gap: 4px; }

.pagination button,
.page-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    height: 38px;
    padding: 0 10px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
    font-size: 13px;
    font-weight: 600;
    transition: background-color .16s var(--orv-ease), border-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.pagination button:hover:not(:disabled),
.page-btn:hover:not(:disabled) { border-color: var(--orv-tinta); }

.pagination .active,
.page-btn.active { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }
.pagination button:disabled, .page-btn:disabled { opacity: .4; cursor: default; }

.search-empty,
.empty-state {
    grid-column: 1 / -1;
    padding: 48px 20px;
    text-align: center;
    color: var(--orv-tinta-3);
    font-size: 14px;
}

/* ============================= 12. CARRINHO =============================
   `cart/CartTable.js` monta `<tr>/<td>` a cada mutação e injeta em
   `#cart-table tbody` — o tema ESTILIZA, não substitui (§6.3). No celular
   as células viram blocos com rótulo pelo `::before`. */

.single-cart { padding: 24px 0 clamp(34px, 5vw, 60px); }
.single-cart .page-title h1 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin-bottom: 20px; }

/* O miolo é `.products.one.cart > .flexwrap`, com a tabela dentro de um
   `form.form-cart` e o resumo num `.cart-summary.styled` ao lado: a grade
   mora no `.flexwrap`, que é quem tem os dois filhos. */
.products.one.cart .flexwrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 350px;
    gap: clamp(20px, 3vw, 40px);
    align-items: start;
}

.cart-summary.styled { position: sticky; top: calc(var(--orv-topo) + 14px); }

#cart-table thead th {
    padding: 0 10px 12px;
    border-bottom: 1px solid var(--orv-fio);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--orv-tinta-3);
    text-align: left;
}

#cart-table tbody td { padding: 16px 10px; border-bottom: 1px solid var(--orv-fio); font-size: 13.5px; vertical-align: middle; }

/* A moldura é do EMBRULHO; a foto só preenche.

   Antes as duas coisas estavam na mesma regra (`.thumbnail, img`), e o
   resultado era a caixa com 72px e 6px de recuo — sobrando 60 de conteúdo
   — enquanto a <img> dentro recebia 72 de altura pela MESMA regra. Ela
   vazava 12px para fora do próprio embrulho e saía esticada (§6.18: o
   `<a>` no meio já resolve `height:100%` contra altura automática; dar
   medida fixa aos dois é o que quebra). */
#cart-table .thumbnail {
    flex: 0 0 auto;
    width: 72px;
    height: 72px;
    padding: 6px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
}

#cart-table .thumbnail img { width: 100%; height: 100%; object-fit: contain; }

/* A célula da esquerda é foto + texto lado a lado, e sem isto os dois
   ficam colados: `.flexitem` só liga o flex, não dá vão nenhum. */
#cart-table td.flexitem { display: flex; align-items: center; gap: 14px; }
#cart-table .content { min-width: 0; }
#cart-table .content strong,
#cart-table .content a { font-weight: 500; }
#cart-table .qty-control { width: max-content; }

.item-remove-grid {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--orv-pill);
    color: var(--orv-tinta-3);
    font-size: 18px;
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.item-remove-grid:hover { background: var(--orv-bandeja); color: var(--orv-oferta); }
.cart-empty { padding: 48px 20px; text-align: center; color: var(--orv-tinta-3); }

.cart-summary,
.coupon,
.shipping-rate {
    padding: 20px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
}

.cart-summary + .coupon,
.coupon + .shipping-rate,
.cart-summary + .shipping-rate { margin-top: 14px; }

.cart-summary h3, .coupon h3, .shipping-rate h3 { font-size: 15px; margin-bottom: 14px; }

.cart-total tbody td { padding: 8px 0; font-size: 13.5px; }
.cart-total tbody tr:last-child td { padding-top: 14px; border-top: 1px solid var(--orv-fio); font-size: 18px; font-weight: 700; }

/* O botão que fecha o carrinho vem com `.secondary-button` no markup
   compartilhado. Aqui ele é a ação principal da tela e precisa pesar como
   tal — é pele: destino e id continuam os mesmos. */
.cart-total .secondary-button {
    width: 100%;
    margin-top: 16px;
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary);
}

.cart-total .secondary-button:hover { background: var(--orv-marca-fundo-2); border-color: var(--orv-marca-fundo-2); }

.coupon form, .shipping-rate form { display: flex; gap: 8px; flex-wrap: wrap; }
.coupon input, .shipping-rate input { flex: 1; min-width: 0; }
.coupon button, #calculateFreight { flex: 0 0 auto; }

.freight-options, .delivery-options { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }

.delivery-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-r);
    font-size: 13px;
    cursor: pointer;
    transition: border-color .16s var(--orv-ease), background-color .16s var(--orv-ease);
}

.delivery-option:hover { border-color: var(--orv-tinta-2); }
.delivery-option:has(input:checked) { border-color: var(--primary-color); background: var(--orv-marca-fundo); }

/* Logo de transportadora SEM caixa abre no tamanho natural do arquivo e
   estoura a linha (§4.6b). */
.delivery-image,
img.option-icon-img,
img.summary-carrier-logo { width: 44px; height: 28px; object-fit: contain; flex: 0 0 auto; }

.freight-error { margin-top: 10px; font-size: 12.5px; color: var(--orv-oferta-txt); }

/* A LINHA é o `.cart-upsell`, não o `.cart-upsell-content`: o markup do
   `CartUpsell.js` é `.cart-upsell > [.thumbnail, .cart-upsell-content,
   button]`, e o `-content` é só a coluna de texto do meio. Com a moldura
   e o flex na peça errada, a foto ficava sem medida e abria no tamanho
   natural do arquivo, empurrando o botão para fora. */
.cart-upsell {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 22px;
    padding: 14px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
}

.cart-upsell .thumbnail {
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    padding: 5px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
}

.cart-upsell .thumbnail img { width: 100%; height: 100%; object-fit: contain; }

.cart-upsell-content { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.cart-upsell-label { font-size: 12px; color: var(--orv-tinta-3); }
.cart-upsell-name { font-size: 14px; font-weight: 500; }
.cart-upsell-price { font-size: 16px; font-weight: 500; }
.cart-upsell-add-btn { flex: 0 0 auto; }

/* ============================= 13. CHECKOUT =============================
   Pele, nunca fluxo: os três passos, os ids do SDK e a ordem continuam os
   do wizard compartilhado (playbook §8). As classes de estado são todas
   `.selected` — lidas nos módulos, não adivinhadas. */

.page-checkout .checkout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 370px;
    gap: clamp(20px, 3vw, 40px);
    align-items: start;
    padding: 24px 0 clamp(38px, 5vw, 64px);
}

.wizard-stepper { display: flex; align-items: center; gap: 8px; margin-bottom: 26px; }
.wz-step { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--orv-tinta-3); }

.wz-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--orv-pill);
    border: 1px solid var(--orv-fio-2);
    background: var(--orv-papel);
    font-size: 12px;
    font-weight: 700;
}

.wz-step.active { color: var(--orv-tinta); font-weight: 700; }
.wz-step.active .wz-dot,
.wz-step.done .wz-dot { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }

.wz-line { flex: 1; height: 1px; background: var(--orv-fio-2); min-width: 12px; }
.wz-line.done { background: var(--primary-color); }

/* 320px existe (§6.25): abaixo de 400px só o passo ATIVO mantém o nome,
   ou o stepper vaza e a página inteira ganha rolagem lateral. */
@media (max-width: 400px) {
    .wz-step .wz-label, .wz-step .wz-sub { display: none; }
    .wz-step.active .wz-label { display: inline; }
}

.wizard-pane { display: none; }
.wizard-pane.on { display: block; }
.wizard-pane h3 { font-size: 16px; margin-bottom: 16px; }

.wizard-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 24px; }

.address-cards { display: flex; flex-direction: column; gap: 10px; }

.address-option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 16px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-r);
    font-size: 13.5px;
    cursor: pointer;
    transition: border-color .16s var(--orv-ease), background-color .16s var(--orv-ease);
}

.address-option:hover { border-color: var(--orv-tinta-2); }
.address-option.selected { border-color: var(--primary-color); background: var(--orv-marca-fundo); }
.option-edit { margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--orv-marca-txt); }

.addr-add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 46px;
    padding: 0 18px;
    border: 1px dashed var(--orv-fio-2);
    border-radius: var(--orv-r);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--orv-tinta-2);
}

.addr-add:hover { border-color: var(--primary-color); color: var(--orv-marca-txt); }

.addr-inline-form,
.card-inline-form,
.guest-register { padding: 18px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r); background: var(--orv-fundo); margin-top: 14px; }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }

/* `1 / -1` e nunca `span 2`: numa grade de uma coluna, `span 2` INVENTA
   uma segunda coluna implícita e o campo seguinte nasce com largura zero
   (§6.21, medido a 328px no formulário de cartão). */
.form-group-full, .span-2, .form-field.span-2 { grid-column: 1 / -1; }
.form-group, .form-field { display: flex; flex-direction: column; gap: 6px; }

/* --- Formulário de endereço -------------------------------------------
   Duas regras que faltavam SÓ nesta estrutura (as outras três já tinham),
   e que sozinhas explicam o formulário torto:

   1. `.addr-cep-row` sem flex: a lupa de buscar CEP é irmã do input, e
      sem a linha ela caía sozinha na linha de baixo, com a largura de um
      botão inteiro. Parecia um controle órfão no meio do formulário.
   2. `.checkset` sem nada: a caixa de seleção encostava no rótulo, sem
      respiro e sem alinhar com ele. */

.addr-cep-row { display: flex; gap: 8px; }
.addr-cep-row input { flex: 1; min-width: 0; }
.addr-cep-row .light-button { flex: 0 0 auto; width: 46px; min-height: 46px; padding: 0; }

.checkset { display: flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 400; color: var(--orv-tinta-2); cursor: pointer; }
.checkset input[type="checkbox"] { flex: 0 0 auto; }

/* Grade PRÓPRIA do endereço, em 6 colunas, no lugar do `auto-fit` genérico.
   O `auto-fit` dava a mesma largura a tudo — e "UF", que tem dois
   caracteres, ficava do tamanho de "Complemento". Aqui cada campo recebe
   a largura do que ele guarda, que é o que faz um formulário parecer
   pensado em vez de gerado.

   O alvo é o EMBRULHO (`.form-field`) e não o input, por isso o `:has()`:
   os campos não têm classe própria, só o id no `<input>` de dentro.

   Linhas: CEP+Apelido · Rua · Número+Complemento+Bairro · Cidade+UF. */
.addr-inline-form .form-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.addr-inline-form .form-field { grid-column: span 3; }
.addr-inline-form .form-field.span-2 { grid-column: 1 / -1; }

.addr-inline-form .form-field:has(#addrNumber) { grid-column: span 1; }
.addr-inline-form .form-field:has(#addrComplement) { grid-column: span 2; }
.addr-inline-form .form-field:has(#addrNeighborhood) { grid-column: span 3; }
.addr-inline-form .form-field:has(#addrCity) { grid-column: span 5; }
.addr-inline-form .form-field:has(#addrState) { grid-column: span 1; }

/* No celular a grade cai para TRÊS colunas, e não duas: com duas, "UF"
   sobrava sozinho numa linha inteira de 322px para guardar dois
   caracteres (medido a 390px). Com três, ele divide a linha com "Cidade"
   como no computador, e "Número" divide com "Complemento".

   Os `span` são reescritos um a um porque `span 5` numa grade de 3
   inventaria colunas implícitas (§6.21). */
@media (max-width: 720px) {
    .addr-inline-form .form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .addr-inline-form .form-field,
    .addr-inline-form .form-field:has(#addrNeighborhood) { grid-column: 1 / -1; }
    .addr-inline-form .form-field:has(#addrNumber),
    .addr-inline-form .form-field:has(#addrState) { grid-column: span 1; }
    .addr-inline-form .form-field:has(#addrComplement),
    .addr-inline-form .form-field:has(#addrCity) { grid-column: span 2; }
}

.freight-pills { display: flex; flex-direction: column; gap: 8px; }

.freight-pill {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-r);
    font-size: 13.5px;
    cursor: pointer;
    transition: border-color .16s var(--orv-ease), background-color .16s var(--orv-ease);
}

.freight-pill:hover { border-color: var(--orv-tinta-2); }
.freight-pill.selected { border-color: var(--primary-color); background: var(--orv-marca-fundo); }
.option-body { flex: 1; min-width: 0; }
.option-price { font-weight: 700; }
.option-price.free { color: var(--orv-fresco-txt); }
.option-tag { font-size: 11.5px; color: var(--orv-tinta-3); }
.skeleton-freight { height: 60px; border-radius: var(--orv-r); }

.pay-accordion { display: flex; flex-direction: column; gap: 10px; }
.pay-item { border: 1px solid var(--orv-fio-2); border-radius: var(--orv-r); overflow: hidden; transition: border-color .16s var(--orv-ease); }

/* `.selected`, não `.on` nem `.active`: é a classe que o
   `PaymentAccordion.js` aplica — escrever a errada faz o clique parecer
   não fazer nada (§6.5). */
.pay-item.selected { border-color: var(--primary-color); }

.pay-head { display: flex; align-items: center; gap: 12px; padding: 16px; cursor: pointer; }

.pay-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--orv-r);
    background: var(--orv-bandeja);
    font-size: 18px;
}

/* Coluna, não linha. O markup é `<strong>Pix</strong><small>Aprovação na
   hora</small>` dentro do mesmo `<span>`: sem empilhar, os dois correm um
   atrás do outro e saem grudados na tela — "PixAprovação na hora",
   "Cartão de crédito ou débitoInsira os dados do cartão". O `min-width: 0`
   é para o nome longo do cartão poder encolher em vez de empurrar o selo.
   Os outros três temas já faziam assim; este ficou para trás. */
.pay-txt {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    font-size: 14px;
    /* O cabeçalho é um <button>, e botão centraliza texto por herança do
       agente de usuário — sem isto "Pix" e "Dinheiro" saem centralizados
       sobre a legenda, que é larga, e a coluna fica torta. */
    text-align: left;
}

.pay-txt strong { font-weight: 500; }
.pay-txt small { font-size: 12.5px; color: var(--orv-tinta-3); }
.pay-badge { padding: 3px 10px; border-radius: var(--orv-pill); background: var(--orv-fresco-fundo); color: var(--orv-fresco-txt); font-size: 11px; font-weight: 700; }
.pay-arrow { color: var(--orv-tinta-3); transition: transform .2s var(--orv-ease); }
.pay-item.selected .pay-arrow { transform: rotate(180deg); }
/* FECHADO por padrão. Sem o `display: none` todo corpo de acordeão nasce
   aberto ao mesmo tempo — na prática o formulário de cartão ficava
   permanentemente estendido embaixo do Pix, com o par Crédito/Débito e os
   campos do MP à mostra sem ninguém ter escolhido cartão. Quem abre é a
   classe `.selected`/`.on` que o `PaymentAccordion.js` põe no item. */
.pay-body { display: none; padding: 0 16px 18px; }

.pay-item.selected .pay-body,
.pay-item.on .pay-body { display: block; }
.pay-hint { font-size: 12.5px; color: var(--orv-tinta-3); }

.card-type-toggle { display: flex; gap: 8px; margin-bottom: 14px; }

.card-type-option {
    flex: 1;
    min-height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.card-type-option.active { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }

/* O SDK do Mercado Pago injeta um <iframe> aqui dentro, e iframe sem
   altura vale 150px — cada campo do cartão viraria um painel (§6.19). */
.container-checkout {
    display: flex;
    align-items: center;
    min-height: 46px;
    height: 46px;
    padding: 0 16px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    background: var(--orv-papel);
}

.container-checkout iframe { width: 100%; height: 100%; border: 0; }

.card-status { margin-top: 10px; font-size: 12.5px; }
.card-status.is-error { color: var(--orv-oferta-txt); }
.card-status.is-success { color: var(--orv-fresco-txt); }

.benefits-box { display: flex; flex-direction: column; gap: 8px; }
.benefit-toggle { display: flex; align-items: center; gap: 10px; padding: 14px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r); font-size: 13px; }

.summary-order {
    position: sticky;
    top: calc(var(--orv-topo) + 14px);
    padding: 20px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
}

.summary-totals ul { display: flex; flex-direction: column; gap: 8px; }
.summary-totals li { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13.5px; }
.summary-totals li:last-child { padding-top: 14px; border-top: 1px solid var(--orv-fio); font-size: 18px; font-weight: 700; }
.summary-carrier-info { display: flex; align-items: center; gap: 8px; }
.summary-shipping-label { color: var(--orv-tinta-2); }

/* A revisão do checkout e o bloco de avaliações do produto compartilham
   `.review-block` (§6.22) — a grade rótulo|valor é escopada no painel do
   wizard, e não na classe solta. */
.wizard-pane .review-block {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr);
    gap: 6px 12px;
    font-size: 13.5px;
    padding: 12px 0;
    border-bottom: 1px solid var(--orv-fio);
}

.wizard-pane .review-block span:first-child { color: var(--orv-tinta-3); }

/* Overlay do "Concluir compra". O markup existe em pages/checkout.php e o
   estilo morava só no clássico: sem regra ele é invisível e a compra
   parece travada (§4.6b). */
#loader1 {
    position: fixed;
    inset: 0;
    z-index: var(--orv-z-toast);
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 18px;
    background: rgba(255, 255, 255, .94);
}

#loader1::after { content: "Estamos concluindo sua compra…"; font-size: 14px; font-weight: 600; color: var(--orv-tinta-2); }

.loader-circle1 {
    width: 48px;
    height: 48px;
    border: 3px solid var(--orv-fio-2);
    border-top-color: var(--primary-color);
    border-radius: var(--orv-pill);
    animation: orv-gira .9s linear infinite;
}

.pix-inline {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 24px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    text-align: center;
}

.pix-qr { padding: 12px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r); background: var(--orv-papel); }
.pix-qr img { width: 190px; height: 190px; object-fit: contain; }

/* `.pix-copy` reusa a classe `.search` do markup compartilhado — não dá
   para contar com ela ter estilo (§4.6b). */
.pix-copy { display: flex; gap: 8px; width: 100%; max-width: 400px; }
.pix-copy input { flex: 1; min-width: 0; font-size: 12.5px; }
.pix-copy button { flex: 0 0 auto; }

.pix-waiting { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--orv-tinta-2); }

.pix-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--orv-fio-2);
    border-top-color: var(--primary-color);
    border-radius: var(--orv-pill);
    animation: orv-gira .8s linear infinite;
}

.guest-register-hint { font-size: 12.5px; color: var(--orv-tinta-3); }
.guest-register-login { margin-top: 12px; font-size: 13px; }
.guest-register-login a { padding-block: 5px; color: var(--orv-marca-txt); font-weight: 600; }

/* ============================== 14. CONTA ==============================
   A anatomia real desta página, conferida na sessão logada e não deduzida:

     .container
       .profile-header.identity-card
         .profile-info  →  img.profile-image + .profile-details (nome,
                           e-mail, .identity-chips)
         .profile-actions
       .wallet-strip  →  button.wallet-card > span.wallet-icon + span >
                         (small, b)
       .profile-content
         .sidebar > nav > ul.nav-menu
         .main-content > #overviewSection … #referralSection

   **`.profile-details` é o bloco de NOME E E-MAIL**, não o wrapper de duas
   colunas — quem faz a coluna lateral é `.profile-content`. Escrever a
   grade no elemento errado (o palpite óbvio, vindo do nome) quebrava o
   cabeçalho da conta em duas colunas e deixava o resto da página num rio
   só. Foi exatamente o que a §7.6 pegou: a bancada de render mostra o
   esqueleto, mas quem mostra a TELA é a sessão real.

   Quase tudo dentro de `.main-content` é montado por `profile/index.js`
   em runtime (§4.6b): card de pedido, endereço, favorito, paginação e o
   conteúdo dos modais. */

.container:has(.profile-content) { padding-top: 26px; padding-bottom: clamp(34px, 5vw, 60px); }

.profile-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    padding: 22px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    margin-bottom: 16px;
}

.profile-info { display: flex; align-items: center; gap: 18px; }

.profile-image {
    width: 64px;
    height: 64px;
    flex: 0 0 auto;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    object-fit: cover;
    cursor: pointer;
}

/* O input de troca de foto é acionado pelo próprio avatar. */
.profile-info > input[type="file"] { display: none; }

.profile-details h1 { font-size: clamp(1.2rem, 2.4vw, 1.6rem); }
.profile-details > p { font-size: 13.5px; color: var(--orv-tinta-3); margin-top: 2px; }

.identity-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.chip, .facts-ok {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--orv-tinta-2);
}

.profile-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.profile-actions a,
.profile-actions button,
.wa-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: 38px;
    padding: 0 14px;
    border-radius: var(--orv-pill);
    font-size: 13px;
    font-weight: 600;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.profile-actions a:hover,
.profile-actions button:hover { background: var(--orv-bandeja); color: var(--orv-tinta); }

#logoutBtn { color: var(--orv-oferta-txt); }

/* --- A tira de atalhos (pedidos, favoritos, carteira, pontos) ---------
   Cada cartão é `<button><span.wallet-icon/><span><small>rótulo</small>
   <b>valor</b></span></button>`. Sem `display` no span interno, rótulo e
   valor saem colados — "Pedidos0" foi como a sessão real os mostrou. */

.wallet-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}

.wallet-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
    text-align: left;
    transition: border-color .16s var(--orv-ease), background-color .16s var(--orv-ease);
}

.wallet-card:hover { border-color: var(--orv-fio-2); background: var(--orv-fundo); }

.wallet-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: var(--orv-pill);
    background: var(--orv-marca-fundo);
    color: var(--orv-marca-txt);
    font-size: 19px;
}

.wallet-card > span:last-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.wallet-card small { font-size: 12px; color: var(--orv-tinta-3); }
.wallet-card b { font-size: 18px; font-weight: 700; }
.wallet-hint { font-size: 11.5px; color: var(--orv-tinta-3); }

/* --- Duas colunas: menu e conteúdo ------------------------------------ */

.profile-content {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: clamp(16px, 2.4vw, 28px);
    align-items: start;
}

.sidebar nav { padding: 10px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r-g); }
.nav-menu { display: flex; flex-direction: column; gap: 2px; }

.nav-menu a {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 14px;
    border-radius: var(--orv-pill);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.nav-menu a:hover { background: var(--orv-bandeja); color: var(--orv-tinta); }
.nav-menu a.active { background: var(--orv-marca-fundo); color: var(--orv-marca-txt); }
.nav-menu #mobileLogoutBtn { color: var(--orv-oferta-txt); }

.main-content > div { display: flex; flex-direction: column; gap: 14px; }

.overview-panel, .order-item, .address-item, .favorite-item,
.referral-panel, #referralPanel, .order-details {
    padding: 20px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
}

.overview-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.overview-head h3 { font-size: 15px; }

dl.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px 18px; font-size: 13.5px; }
dl.facts dt { font-size: 12px; color: var(--orv-tinta-3); }
dl.facts dd { font-weight: 600; margin-top: 2px; }

.orders, .address-list, .favorites-list, .overview-orders, .overview-addresses { display: flex; flex-direction: column; gap: 12px; }

.overview-order, .overview-address {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    font-size: 13px;
}

.overview-order:hover, .overview-address:hover { border-color: var(--orv-fio-2); }
.overview-order-info { flex: 1; min-width: 0; }
.overview-order-total { font-weight: 700; }
.overview-address-tag { padding: 2px 9px; border-radius: var(--orv-pill); background: var(--orv-marca-fundo); color: var(--orv-marca-txt); font-size: 11px; font-weight: 700; }

.order-info { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.order-meta { font-size: 12.5px; color: var(--orv-tinta-3); }
.order-amount { font-weight: 700; margin-left: auto; }
.order-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

.order-status { display: inline-flex; align-items: center; padding: 3px 11px; border-radius: var(--orv-pill); font-size: 11.5px; font-weight: 700; }
.status-pending { background: #fdf3e2; color: #8a5a00; }
.status-processing { background: var(--orv-marca-fundo); color: var(--orv-marca-txt); }
.status-completed, .status-delivered { background: var(--orv-fresco-fundo); color: var(--orv-fresco-txt); }
.status-canceled, .status-refunded { background: var(--orv-oferta-fundo); color: var(--orv-oferta-txt); }
.status-undefined { background: var(--orv-bandeja); color: var(--orv-tinta-3); }

.order-item-detail { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--orv-fio); }
.order-item-image { width: 50px; height: 50px; object-fit: contain; border-radius: var(--orv-r); background: var(--orv-bandeja); padding: 4px; }
.order-summary-row { display: flex; justify-content: space-between; font-size: 13.5px; padding: 5px 0; }
.order-summary-total { font-weight: 700; border-top: 1px solid var(--orv-fio); padding-top: 10px; }

.address-item-content { font-size: 13.5px; }
.address-item-actions { display: flex; gap: 8px; margin-top: 14px; }

.favorite-item { display: flex; align-items: center; gap: 12px; }
.favorite-info { flex: 1; min-width: 0; font-size: 13.5px; }
.favorite-price { font-weight: 700; }
.favorite-stock-warning { font-size: 12px; color: var(--orv-oferta-txt); }

.empty-address, .empty-state { color: var(--orv-tinta-3); font-size: 13.5px; }

/* --- Formulário da conta ---------------------------------------------- */

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; }
.form-subgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.form-group-inline { display: flex; align-items: center; gap: 10px; }
.form-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; }

/* O interruptor de "isento de inscrição": o input fica escondido e a
   pista é o `.slider` irmão. */
.switch { position: relative; display: inline-flex; width: 44px; height: 24px; flex: 0 0 auto; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }

/* ESCOPADO em `.switch` de propósito. `.slider` solto é a pista do
   interruptor E a classe do bloco do banner da home (`section.slider`,
   que vem do partial compartilhado): sem o escopo, o hero inteiro virava
   um cilindro cinza de 999px de raio posicionado sobre a página — §6.22
   na prática, e desta vez cobrando de mim mesmo. */
.switch .slider {
    position: absolute;
    inset: 0;
    border-radius: var(--orv-pill);
    background: var(--orv-fio-2);
    transition: background-color .18s var(--orv-ease);
    pointer-events: none;
}

.switch .slider::before {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: var(--orv-pill);
    background: #fff;
    transition: transform .18s var(--orv-ease);
}

.switch input:checked + .slider { background: var(--primary-color); }
.switch input:checked + .slider::before { transform: translateX(20px); }

#paginationControls { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 18px; }
#paginationControls button { min-width: 36px; height: 36px; padding: 0 12px; border: 1px solid var(--orv-fio-2); border-radius: var(--orv-pill); font-size: 13px; font-weight: 600; }
#paginationControls button:disabled { opacity: .4; }
#pageIndicator, #pageIndicatorOrders, #pageIndicatorFavorites, #pageFavIndicator { font-size: 13px; color: var(--orv-tinta-3); }

.referral-link-row { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.referral-stats { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.referral-stat { flex: 1 1 120px; padding: 14px; border-radius: var(--orv-r); background: var(--orv-fundo); font-size: 13px; }
.referral-explainer { font-size: 13px; color: var(--orv-tinta-2); }

.timeline { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.timeline-step { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--orv-tinta-3); }
.timeline-step.active { color: var(--orv-tinta); font-weight: 600; }
.timeline-icon { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--orv-pill); background: var(--orv-bandeja); font-size: 14px; }
.timeline-step.active .timeline-icon { background: var(--primary-color); color: var(--on-primary); }
.tracking-info { margin-top: 12px; font-size: 13px; }
.tracking-info-label { color: var(--orv-tinta-3); }

.skeleton-card { height: 74px; border-radius: var(--orv-r-g); }

/* ====================== 15. ENTRAR / CRIAR CONTA ======================
   Dois cartões lado a lado sob um título centrado, como na referência —
   mas UM formulário só: quem alterna entre entrar e criar conta é o
   AuthForm, e o cartão da esquerda apenas dispara o mesmo link. */

body:has(#authForm) { background: var(--orv-fundo); }

.orv-auth { padding: clamp(30px, 6vh, 64px) var(--orv-gutter) clamp(40px, 8vh, 80px); }
.orv-auth__titulo {
    text-align: center;
    font-size: clamp(1.6rem, 3.2vw, 2.3rem);
    font-weight: 600;
    letter-spacing: -.02em;
    margin-bottom: 30px;
}

.orv-auth__grade {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
    max-width: 960px;
    margin: 0 auto;
    align-items: start;
}

.orv-auth__cartao {
    padding: clamp(22px, 3vw, 34px);
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
}

.orv-auth__cartao h2 { font-size: 19px; margin-bottom: 12px; }
.orv-auth__cartao--convite p { font-size: 13.5px; color: var(--orv-tinta-2); }

.orv-auth__lista { display: flex; flex-direction: column; gap: 8px; margin: 18px 0 22px; font-size: 13.5px; color: var(--orv-tinta-2); }
.orv-auth__lista li { display: flex; align-items: center; gap: 8px; }
.orv-auth__lista i { color: var(--orv-fresco-txt); }

#authForm .form-group { margin-bottom: 16px; }
#authForm button[type="submit"] { width: 100%; margin-top: 4px; }

.toggle-form { margin-top: 12px; font-size: 13px; color: var(--orv-tinta-3); }
.toggle-form a { color: var(--orv-marca-txt); font-weight: 600; }
.orv-auth__esqueci { text-align: right; margin-top: -6px; }
.orv-auth__troca { text-align: center; }

/* ============ 16. BLOCOS DE RUNTIME (compartilhados, sem partial) ============ */

.variation-picker { display: flex; flex-direction: column; gap: 10px; }
.variation-body { display: flex; flex-wrap: wrap; gap: 8px; }

.variation-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    border: 1px solid var(--orv-fio-2);
    border-radius: var(--orv-pill);
    font-size: 13px;
    cursor: pointer;
}

.variation-option:hover { border-color: var(--orv-tinta-2); }
.variation-option.selected { border-color: var(--primary-color); background: var(--orv-marca-fundo); }
.variation-price { font-weight: 700; }
.variation-hint { font-size: 12.5px; color: var(--orv-tinta-3); }

.share-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; }
.share-item { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 6px; border: 1px solid var(--orv-fio); border-radius: var(--orv-r); font-size: 12px; }
.share-item i { font-size: 20px; }
.share-item:hover { border-color: var(--orv-tinta-2); }
.share-copy { display: flex; gap: 8px; margin-top: 14px; }
.share-copy input { flex: 1; min-width: 0; font-size: 12.5px; }

#resultMessage { margin-top: 10px; font-size: 13px; }
#resultMessage.is-error { color: var(--orv-oferta-txt); }
#resultMessage.is-success { color: var(--orv-fresco-txt); }

/* Histórico de busca: o `HeaderSearch.js` pendura o menu DENTRO do
   <form> (§6.27) — sem estas regras os botões fluem inline no meio do
   campo de busca. */
.search-select-box { position: relative; }

.select-box-menu {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    z-index: var(--orv-z-mega);
    display: none;
    flex-direction: column;
    padding: 6px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
}

.search-select-box-open .select-box-menu { display: flex; }

.select-box-option, .select-box-footer {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 38px;
    padding: 0 12px;
    border-radius: var(--orv-r);
    background: transparent;
    color: var(--orv-tinta-2);
    font-size: 13px;
    text-align: left;
}

.select-box-option:hover, .select-box-footer:hover { background: var(--orv-bandeja); color: var(--orv-tinta); }
.select-box-footer { margin-top: 4px; border-top: 1px solid var(--orv-fio); border-radius: 0; font-size: 12px; color: var(--orv-tinta-3); }

/* --- Vistos recentemente ----------------------------------------------
   O relógio preso à direita da tela, como na referência. `display` vem de
   custom property: o revendedor desliga no manifest e o head imprime
   `none`. */
.orv-vistos {
    display: var(--orv-vistos, flex);
    position: fixed;
    top: 50%;
    right: 0;
    z-index: var(--orv-z-vistos);
    transform: translateY(-50%);
    align-items: flex-start;
    justify-content: flex-end;
}

/* A ABA. Ela é o cabeçalho do painel, não um botão que flutua ao lado
   dele: fechada, só a orelha de 42px sobra para fora da folha; aberta, a
   mesma peça vira a faixa de título do painel, e a orelha continua ali
   como o ícone à esquerda do título. É por isso que os dois moram na
   MESMA linha de flex em vez de o painel ser `position: absolute`.
   Arredondada só do lado de dentro (`40px 0 0 40px`), que é o que a faz
   ler como aba puxada da borda e não como cartão solto. */
.orv-vistos__btn {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border: 1px solid var(--orv-fio);
    border-right: 0;
    border-radius: var(--orv-pill) 0 0 var(--orv-pill);
    background: var(--orv-papel);
    color: var(--orv-tinta);
    font-size: 20px;
    box-shadow: var(--orv-sombra-leve);
    transition: color .16s var(--orv-ease), background-color .16s var(--orv-ease);
}

.orv-vistos__btn:hover { color: var(--orv-tinta); background: var(--orv-bandeja); }

/* Aberta, a orelha perde o canto de baixo e encosta no painel — os dois
   viram uma peça só. */
.orv-vistos.is-open .orv-vistos__btn {
    border-bottom-left-radius: 0;
    border-bottom: 0;
    box-shadow: none;
}

/* O painel cresce do lado direito da aba: largura 0 fechado, 270px
   aberto. Anima a LARGURA, e não `transform`, porque a aba tem de andar
   junto — com o painel deslocado por transform ela ficaria parada e o
   conjunto se separaria no meio da animação. */
.orv-vistos__painel {
    flex: 0 0 auto;
    width: 0;
    overflow: hidden;
    border: 1px solid var(--orv-fio);
    border-right: 0;
    border-radius: var(--orv-r) 0 0 var(--orv-r);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
    opacity: 0;
    visibility: hidden;
    transition: width .26s var(--orv-ease), opacity .2s var(--orv-ease), visibility .26s;
}

.orv-vistos.is-open .orv-vistos__painel {
    width: 270px;
    opacity: 1;
    visibility: visible;
}

/* Larguras fixas nos filhos: com o pai indo de 0 a 270 o conteúdo
   refluiria a cada quadro da animação, e o texto ficaria pulando. */
.orv-vistos__titulo,
.orv-vistos__lista,
.orv-vistos__vazio { width: 270px; }

.orv-vistos__titulo {
    display: flex;
    align-items: center;
    min-height: 42px;
    padding: 0 14px;
    border-bottom: 1px solid var(--orv-fio);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: .3px;
    color: var(--orv-tinta);
}

.orv-vistos__lista {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    max-height: 46vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Cada item é um card de fio, como na referência — lista de linhas soltas
   dentro de um painel estreito vira parede de texto. */
.rv-item a {
    display: grid;
    grid-template-columns: 54px minmax(0, 1fr);
    align-items: center;
    gap: 10px;
    padding: 8px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    transition: border-color .16s var(--orv-ease);
}

.rv-item a:hover { border-color: var(--orv-fio-2); }
.rv-item img { width: 54px; height: 54px; object-fit: contain; border-radius: var(--orv-r); background: var(--orv-corredor-fundo); padding: 4px; }
.rv-item p { font-size: 14px; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.rv-item span { font-size: 14px; font-weight: 500; }
.orv-vistos__vazio { padding: 14px; }

/* Estado vazio decidido por CONTEÚDO: cobre o instante entre abrir e a
   resposta chegar sem piscar a frase. */
.orv-vistos__vazio { display: none; font-size: 12.5px; color: var(--orv-tinta-3); }
.orv-vistos__lista:empty { display: none; }
.orv-vistos__lista:empty + .orv-vistos__vazio { display: block; }

/* ==================== 17. TOAST, MODAL E ESQUELETO ==================== */

.toast-stack {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: var(--orv-z-toast);
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: min(92vw, 370px);
}

/* `.toast-visible` é o ESTADO, e o `core/Toast.js` conta com ele: o toast
   nasce sem a classe, ganha no rAF seguinte e a perde ao sair — e o
   módulo espera o `transitionend` para tirar o nó do DOM. Sem o par
   estado inicial + transição, o toast aparecia no HTML e não na tela
   (achado na sessão logada da §7.6), e sem transição alguma o `detach`
   dependeria só do timer de segurança. */
.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
    font-size: 13.5px;
    cursor: pointer;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity .22s var(--orv-ease), transform .22s var(--orv-ease);
}

.toast-visible { opacity: 1; transform: none; }

.toast i { font-size: 18px; }

.toast-success { border-color: var(--orv-fresco); color: var(--orv-fresco-txt); }
.toast-error { border-color: var(--orv-oferta); color: var(--orv-oferta-txt); }

.app-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: var(--orv-z-fundo-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px;
    background: rgba(20, 20, 20, .5);
}

.modal-dialog {
    position: relative;
    z-index: var(--orv-z-modal);
    width: min(96vw, 540px);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
    box-shadow: var(--orv-sombra);
    overflow: hidden;
}

.modal-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--orv-fio); }
.modal-title { font-size: 15px; font-weight: 700; }
.modal-body { flex: 1; min-height: 0; overflow-y: auto; padding: 20px; font-size: 13.5px; }

/* Sem `gap` os dois botões saem colados ("CancelarSalvar") — um dos sete
   blocos sem estilo achados na primeira sessão real de um tema irmão. */
.modal-footer { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 16px 20px; border-top: 1px solid var(--orv-fio); }

.btn-modal { min-height: 42px; padding: 0 20px; border-radius: var(--orv-pill); border: 1px solid var(--orv-fio-2); background: var(--orv-papel); font-size: 13.5px; font-weight: 600; }
.btn-modal-primary { background: var(--primary-color); border-color: var(--primary-color); color: var(--on-primary); }
.btn-modal-secondary { color: var(--orv-tinta-2); }
.btn-modal-danger { background: var(--orv-oferta); border-color: var(--orv-oferta); color: #fff; }

.skeleton {
    background: linear-gradient(90deg, var(--orv-bandeja) 25%, #ececec 37%, var(--orv-bandeja) 63%);
    background-size: 400% 100%;
    border-radius: var(--orv-r);
    animation: orv-esqueleto 1.3s ease-in-out infinite;
}

@keyframes orv-esqueleto {
    from { background-position: 100% 50%; }
    to { background-position: 0 50%; }
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ======================= 18. RODAPÉ E NEWSLETTER =======================
   O bloco inteiro na cor da loja: newsletter, colunas e a barra final.
   `--on-brand` é calculado por `core/ThemeColors.js` a partir da
   luminância real da primária. */

.orv-rodape { background: var(--primary-color); color: var(--on-brand); margin-top: 70px; }

.orv-news { border-bottom: 1px solid rgba(255, 255, 255, .16); }

.orv-news__in { display: flex; align-items: center; justify-content: space-between; gap: 30px; flex-wrap: wrap; padding: 36px 0; }
.orv-news h3 { font-size: clamp(1.2rem, 2.2vw, 1.6rem); color: inherit; max-width: 22ch; }
.orv-news p { margin-top: 6px; font-size: 13.5px; opacity: .85; max-width: 48ch; }

.orv-news__form { display: flex; align-items: center; gap: 10px; flex: 1 1 350px; max-width: 470px; }
.orv-news__form input { flex: 1; background: var(--orv-papel); border-color: transparent; color: var(--orv-tinta); }

/* O botão da newsletter vive sobre a cor da loja: o primário sumiria
   dentro dela. Inverte — papel com tinta. */
.orv-news__form button[type="submit"] { flex: 0 0 auto; background: var(--orv-papel); color: var(--orv-tinta); }
.orv-news__form button[type="submit"]:hover { background: var(--orv-bandeja); }

.orv-rodape__grade { display: grid; grid-template-columns: 1.5fr repeat(3, 1fr); gap: 34px; padding: 44px 0; }

.orv-rodape__col h4 { font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase; color: inherit; opacity: .8; margin-bottom: 14px; }
.orv-rodape__col ul { display: flex; flex-direction: column; gap: 2px; }
.orv-rodape__col a { display: inline-flex; font-size: 14px; opacity: .9; transition: opacity .16s var(--orv-ease); }
.orv-rodape__col a:hover { opacity: 1; text-decoration: underline; }
.orv-rodape__col span { font-size: 13.5px; opacity: .8; }

.orv-rodape__marca .logo img { max-height: 48px; width: auto; object-fit: contain; }
.orv-rodape__marca p { margin-top: 14px; font-size: 14px; opacity: .85; max-width: 34ch; }

.orv-rodape__wa {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 18px;
    min-height: 42px;
    padding: 0 20px;
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: var(--orv-pill);
    font-size: 13.5px;
    font-weight: 600;
}

.orv-rodape__wa:hover { background: rgba(255, 255, 255, .12); }

.orv-rodape__barra { border-top: 1px solid rgba(255, 255, 255, .16); }
.orv-rodape__barra-in { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 18px 0; }
.orv-rodape__barra .mini-text { color: inherit; opacity: .8; }

.orv-rodape__barra .socials ul { display: flex; gap: 8px; }

.orv-rodape__barra .socials a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--orv-pill);
    border: 1px solid rgba(255, 255, 255, .3);
    font-size: 17px;
    transition: background-color .16s var(--orv-ease);
}

.orv-rodape__barra .socials a:hover { background: rgba(255, 255, 255, .14); }

.orv-bandeiras { display: flex; align-items: center; gap: 8px; }

.orv-bandeiras li {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 30px;
    border-radius: 4px;
    background: rgba(255, 255, 255, .14);
}

.orv-bandeiras svg { fill: none; stroke: #fff; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }

/* ==================== 18b. CONVITE DE NEWSLETTER ====================
   A janela que abre sozinha, na anatomia da referência: duas metades
   iguais (cena à esquerda, texto à direita), canto de 8px, véu preto a
   30% e nada de sombra — a caixa se destaca pelo véu, não por elevação.

   Ela só existe no HTML quando o interruptor do manifest está ligado
   (ver `partials/footer.php`), então aqui não há regra de "desligado".
   O `[hidden]` do bloco é o estado FECHADO, que o `.np--aberto`
   destrava — e a regra global de `[hidden]` lá em cima já é
   `display: none !important`, então a janela nasce fora da tela mesmo se
   este trecho nunca carregar. */

/* `.np[hidden]` EXPLÍCITO, e não a regra do navegador.

   `[hidden]` do agente de usuário é `display: none` com especificidade de
   seletor de tipo — qualquer `display` que a folha declare para `.np`
   VENCE. O resultado é uma janela que fica permanentemente "aberta" e
   invisível (o véu com opacidade 0) cobrindo a página inteira: os cliques
   caem nela, e o sintoma é a loja parecer morta — menu não navega, filtro
   não filtra, botão de comprar não responde.

   O tema `alimentos` escapou por acaso, porque o reset dele traz
   `[hidden] { display: none !important }`. Depender disso numa peça
   compartilhada é o mesmo bug esperando o próximo tema. */
.np[hidden] { display: none; }

.np {
    position: fixed;
    inset: 0;
    z-index: var(--orv-z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--orv-gutter);
}

.np__veu {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .3);
    animation: np-veu .25s var(--orv-ease) both;
}

.np__caixa {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: min(710px, 100%);
    max-height: calc(100vh - var(--orv-gutter) * 2);
    overflow: hidden auto;
    border-radius: var(--orv-r);
    background: var(--orv-papel);
    animation: np-entra .3s var(--orv-ease) both;
}

/* O mesmo padrão de frutas do banner, sobre a cor da loja bem diluída: é
   a peça que amarra a janela ao resto do tema sem depender de foto. */
.np__cena {
    background-color: var(--orv-marca-fundo);
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='220' viewBox='0 0 260 220'%3E%3Cg fill='none' stroke='%23dcd6c8' stroke-width='1.4' stroke-linecap='round'%3E%3Ccircle cx='48' cy='52' r='22'/%3E%3Cpath d='M48 30c3-7 9-9 14-8-1 6-5 10-11 10'/%3E%3Cpath d='M150 44c14 0 22 10 22 22s-9 20-22 20-22-8-22-20 8-22 22-22z'/%3E%3Cpath d='M150 40v-9'/%3E%3Cpath d='M62 150c16-10 30-6 38 4-12 12-30 12-38-4z'/%3E%3Cpath d='M100 154c8-2 14 1 18 6'/%3E%3Cpath d='M196 140c0 16-8 26-18 26s-18-10-18-26 8-22 18-22 18 6 18 22z'/%3E%3Cpath d='M178 118v-10'/%3E%3C/g%3E%3C/svg%3E");
    background-position: center;
}

/* Com foto do banner, a cena vira só a moldura dela: `cover` porque a
   metade é alta e estreita, e uma foto de banca contida ali deixaria duas
   faixas de fundo em cima e embaixo. */
.np__cena--foto { background-image: none; }
.np__cena--foto img { width: 100%; height: 100%; object-fit: cover; }

.np__corpo {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 34px 27px;
    text-align: center;
}

.np__x {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--orv-pill);
    font-size: 20px;
    color: var(--orv-tinta-2);
    transition: background-color .16s var(--orv-ease), color .16s var(--orv-ease);
}

.np__x:hover { background: var(--orv-bandeja); color: var(--orv-tinta); }

.np__titulo { font-size: 24px; }
.np__texto { font-size: 14px; color: var(--orv-tinta-2); max-width: 32ch; }

.np__form { width: 100%; }
.np__form form { display: flex; flex-direction: column; gap: 10px; }
.np__form button[type="submit"] { width: 100%; }

/* "Agora não" existe porque o "x" de 34px no canto é um alvo pequeno para
   a única saída de uma janela que a pessoa não pediu — e porque recusar
   em palavras é mais claro do que caçar o fechar. */
.np__depois {
    font-size: 13px;
    color: var(--orv-tinta-3);
    text-decoration: underline;
    text-underline-offset: 3px;
    padding-block: 4px;
}

.np__depois:hover { color: var(--orv-tinta); }

/* --- Espiar (quick view) ----------------------------------------------
   Mesma casca do convite (`.np`), outro miolo: caixa branca de 8px,
   duas colunas — foto à esquerda, ficha à direita — e o "x" no canto,
   que é exatamente a anatomia da janela da referência (900px de teto,
   15px de recuo). O conteúdo é CLONADO do card, então tudo que aparece
   aqui já estava na vitrine. */

.npqv__caixa { width: min(900px, 100%); grid-template-columns: 1fr 1fr; }

.npqv__foto {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    margin: 15px 0 15px 15px;
    overflow: hidden;
}

.npqv__foto img { width: 100%; height: 100%; object-fit: contain; padding: 16px; }

.npqv__corpo {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 26px;
    text-align: left;
    align-items: flex-start;
}

.npqv__cat { font-size: 14px; color: var(--orv-tinta-3); }
.npqv__nome { font-size: 24px; }
.npqv__corpo .orv-card__preco .current { font-size: 22px; }
.npqv__corpo .purchase-section { display: flex; align-items: center; gap: 10px; width: 100%; }
.npqv__corpo .purchase-btn { flex: 1; }

.npqv__link {
    font-size: 14px;
    color: var(--orv-marca-txt);
    text-decoration: underline;
    text-underline-offset: 3px;
    padding-block: 4px;
}

@keyframes np-veu { from { opacity: 0; } to { opacity: 1; } }

@keyframes np-entra {
    from { opacity: 0; transform: translateY(14px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

/* ============================ 19. RESPONSIVO ============================ */

@media (max-width: 1199px) {
    .orv-produto__grade { gap: 30px; }
    .page-checkout .checkout,
    .products.one.cart .flexwrap { grid-template-columns: minmax(0, 1fr); }
    .summary-order, .cart-summary.styled { position: static; }
}

@media (max-width: 1023px) {
    .orv-busca-pag__grade { grid-template-columns: minmax(0, 1fr); }
    .profile-content { grid-template-columns: minmax(0, 1fr); }

    /* O painel de filtros do celular. A classe de aberto é `.show` NO
       `.filter` — quem alterna é `search/Filters.js`. */
    .single-category .sidebar { position: fixed; inset: 0; z-index: var(--orv-z-gaveta); pointer-events: none; }

    .filter {
        position: absolute;
        inset: 0 auto 0 0;
        width: min(88vw, 340px);
        max-height: none;
        padding: 18px;
        background: var(--orv-papel);
        box-shadow: var(--orv-sombra);
        transform: translateX(-102%);
        transition: transform .28s var(--orv-ease);
        pointer-events: auto;
    }

    .filter.show { transform: none; }
    .orv-filtro__topo { display: flex; }

    /* O "x" que fecha o painel é um `<a>` com só um ícone dentro: sem
       caixa própria ele fica com 18px de altura, abaixo do alvo do §7.3. */
    .orv-filtro__topo .filter-trigger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 38px;
        height: 38px;
        margin-right: -8px;
        border-radius: var(--orv-pill);
        font-size: 20px;
        color: var(--orv-tinta-2);
    }
}

@media (max-width: 860px) {
    /* Mesma especificidade do bloco de utilitários lá em cima, e DEPOIS
       dele: é assim que o par mobile-hide/desktop-hide funciona sem
       `!important` (§6.26). A regra de área de toque entra aqui dentro, o
       que resolve o §6.7 de graça. */
    .mobile-hide { display: none; }
    .desktop-hide { display: revert; }

    .trigger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        margin-left: -8px;
        border-radius: var(--orv-pill);
    }

    .orv-head__linha .wrapper { min-height: 60px; gap: 10px; }
    .header-nav .logo img { max-height: 32px; }
    .orv-sacola { padding: 0 12px; }

    .orv-grade { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--orv-gap-cel); }
    .orv-trilho__fita { gap: var(--orv-gap-cel); }
    .orv-card__corpo { padding: 12px 0 0; gap: 5px; }
    .orv-card__nome { font-size: 15px; }
    .orv-card__preco .current { font-size: 16px; }

    /* O empilhamento no celular NÃO precisa de regra própria: o card tem
       ~164px de largura útil em duas colunas, o `flex-basis: 96px` do
       botão não cabe ao lado do stepper (84 + 8 de vão), e a linha quebra
       sozinha — o mesmo mecanismo que resolve o explorar.

       A versão anterior forçava `flex-direction: column` aqui, e isso
       QUEBROU quando o botão ganhou base: em coluna o `flex-basis` vale
       para a ALTURA, e o "Adicionar" virou um oval de 96px de alto. */
    .orv-card__acao { gap: 6px; }
    .orv-card__acao .purchase-btn { font-size: 13px; padding: 0 10px; }

    .orv-produto__grade { grid-template-columns: minmax(0, 1fr); }
    .orv-corredor { width: 128px; }

    /* No celular as duas colunas viram duas linhas: foto em cima, texto
       embaixo — empilhar mantém a foto inteira, que é o ponto dela. */
    .orv-banner__in { grid-template-columns: minmax(0, 1fr); min-height: 0; gap: 0; }
    .orv-banner__foto { order: -1; padding-top: 24px; margin-right: 0; justify-content: center; }
    .orv-banner__foto img { max-height: 46vw; }
    .orv-banner__texto { padding: 20px 0 60px; }

    .orv-rodape { margin-top: 44px; }
    .orv-rodape__grade { grid-template-columns: 1fr 1fr; gap: 28px; padding: 32px 0; }
    .orv-news__in { padding: 28px 0; }

    .mobile-return-button { display: block; padding: 12px 0 0; }

    .mobile-return-button a {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 42px;
        height: 42px;
        margin-left: var(--orv-gutter);
        border-radius: var(--orv-pill);
        background: var(--orv-bandeja);
        font-size: 19px;
    }

    .orv-galeria__fita li { width: 68px; height: 68px; }

    /* No celular a cena vira uma faixa em cima: as duas metades lado a
       lado dariam 160px de largura para o campo de e-mail. */
    .np__caixa { grid-template-columns: minmax(0, 1fr); width: min(420px, 100%); }
    .np__cena { height: 96px; }
    .np__corpo { padding: 26px 20px; }
    .np__titulo { font-size: 21px; }

    .npqv__caixa { width: min(420px, 100%); }
    .npqv__foto { margin: 15px 15px 0; }
    .npqv__corpo { padding: 20px; }
    .npqv__nome { font-size: 19px; }

    /* A tabela do carrinho vira lista de blocos com o rótulo saindo do
       `::before` — o markup é montado por JS e não pode ser trocado. */
    #cart-table thead { display: none; }
    #cart-table tbody tr { display: grid; grid-template-columns: 80px minmax(0, 1fr); gap: 4px 12px; padding: 16px 0; border-bottom: 1px solid var(--orv-fio); }
    #cart-table tbody td { border: 0; padding: 0; }
    #cart-table tbody td:first-child { grid-row: span 4; }
    #cart-table tbody td[data-label]::before { content: attr(data-label) ": "; color: var(--orv-tinta-3); font-size: 11.5px; }

    .toast-stack { right: 12px; left: 12px; bottom: 76px; max-width: none; }
    .modal-dialog { width: 96vw; }

    /* A barra inferior fixa cobre o fim da página. */
    /* O `env(safe-area-inset-bottom)` NÃO é detalhe: a barra inferior soma a
       faixa da barra de gestos à própria altura, e uma reserva de número fixo
       deixa de cobri-la em qualquer aparelho que tenha essa faixa (34px no
       iPhone). O que fica embaixo dela é justamente o fim da página — o botão
       de fechar o pedido. */
    body { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }

    /* No celular a aba desce para o canto, acima da barra fixa. O painel
       aberto encolhe junto — 270px numa tela de 360 não deixa nada da
       página aparecer atrás. */
    .orv-vistos { top: auto; bottom: calc(74px + env(safe-area-inset-bottom)); transform: none; }
    .orv-vistos.is-open .orv-vistos__painel { width: min(74vw, 270px); }
    .orv-vistos__titulo,
    .orv-vistos__lista,
    .orv-vistos__vazio { width: min(74vw, 270px); }

    /* O painel de ordenação abre ancorado à esquerda do controle, que no
       celular já está colado na borda direita — ancorado à direita ele
       cresce para dentro. */
    .item-sortir ul, .item-options ul { left: auto; right: 0; min-width: min(210px, 76vw); }
}

@media (max-width: 560px) {
    .orv-rodape__grade { grid-template-columns: 1fr; }
    .orv-rodape__marca p { max-width: none; }
    .orv-relogio li { width: 62px; height: 62px; font-size: 18px; }
    .mini-cart .actions { grid-template-columns: 1fr; }
}

/* A faixa de campanha empilha no celular: foto primeiro, texto embaixo. */
@media (max-width: 860px) {
    .orv-campanha > .container { grid-template-columns: minmax(0, 1fr); text-align: center; }
    .orv-campanha__foto { order: -1; width: min(240px, 60vw); margin: 26px 0 0; }
    .orv-campanha__texto { padding: 20px 0 34px; }
    .orv-relogio ul { justify-content: center; }
}

/* --- Alvo de toque: a última passada da varredura ---------------------
   Todos abaixo vêm de markup COMPARTILHADO e são `<a>` inline dentro de
   texto — a caixa deles é a métrica da fonte (17px em texto de 13), e o
   §7.3 pede 22. `padding-block` entra no retângulo de clique sem empurrar
   a linha seguinte (§6.30); a regra mira a classe do partial, não uma
   classe do tema, porque é lá que o markup mora. */
.banners .product-categories a,
.shipping-rate .icon-small,
.reviews .review-form p a,
.guest-register-login a,
.orv-vertodos + .view-all,
.view-all { padding-block: 5px; }

/* A foto do favorito é uma `<img>` NUA dentro do card — o
   `features/favorites/index.js` monta `img + .favorite-info`, sem caixa.
   Sem regra ela abre no tamanho natural do arquivo e o cartão vira uma
   coluna de 500px (§6.1, agora dentro de um bloco de runtime). Achado na
   sessão logada da §7.6. */
.favorite-item {
    display: grid;
    grid-template-columns: 76px minmax(0, 1fr);
    align-items: center;
    gap: 14px;
    cursor: pointer;
    transition: border-color .16s var(--orv-ease);
}

.favorite-item:hover { border-color: var(--orv-fio-2); }

.favorite-item > img {
    width: 76px;
    height: 76px;
    object-fit: contain;
    border-radius: var(--orv-r);
    background: var(--orv-bandeja);
    padding: 6px;
}

.favorite-info h3 { font-size: 14px; font-weight: 600; }
.favorite-info .favorite-price { margin-top: 4px; font-size: 15px; font-weight: 700; }

/* --- Preloader ---------------------------------------------------------
   `views/partials/preloader.php` sai em TODA página e o `#page` nasce com
   `display:none` atrás dele; o `shared/Preloader.js` põe `.is-done` e
   depois esconde. Sem regra nenhuma aqui, a marca e a barra apareciam
   cruas no topo do documento no primeiro instante de cada carga — e a
   transição de saída não existia, então o `transitionend` que o módulo
   espera só chegava pelo timer de segurança. */
#preloader {
    position: fixed;
    inset: 0;
    z-index: var(--orv-z-toast);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--orv-papel);
    opacity: 1;
    transition: opacity .3s var(--orv-ease);
}

#preloader.is-done { opacity: 0; }

.preloader-inner { display: flex; flex-direction: column; align-items: center; gap: 16px; }

.preloader-name {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--orv-tinta);
}

.preloader-bar {
    display: block;
    width: 160px;
    height: 3px;
    border-radius: var(--orv-pill);
    background: var(--orv-bandeja);
    overflow: hidden;
}

.preloader-bar > span {
    display: block;
    width: 40%;
    height: 100%;
    border-radius: var(--orv-pill);
    background: var(--primary-color);
    animation: orv-carrega 1.1s var(--orv-ease) infinite;
}

@keyframes orv-carrega {
    from { transform: translateX(-110%); }
    to   { transform: translateX(260%); }
}


/* ============ FEEDBACK DE "ADICIONADO" (shared/CartFx.js) ============
   Três peças que o módulo compartilhado ATIVA por classe mas não
   estiliza — sem estas regras, adicionar ao carrinho não dá retorno
   nenhum na tela: a bolinha nasce sem `position` e fica parada num
   canto, o contador não pulsa e o botão não pisca. O carrinho enche em
   silêncio e a pessoa clica de novo achando que falhou.

   O aninhamento `.fly-item > .item-number` e os nomes `cart-fly-dot`,
   `bump` e `btn-added` são CONTRATO do módulo (§4.6b): nascem em runtime
   e não aparecem em partial nenhum para ler.

   O alvo do voo é `.iscart .icon-large` (ou `.cart-trigger`), então o
   cabeçalho do tema precisa de um dos dois. */

.cart-fly-dot {
    position: fixed;
    z-index: 900;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--orv-papel);
    border: 1px solid var(--orv-fio);
    box-shadow: 0 8px 24px -8px rgba(0, 0, 0, .35);
    pointer-events: none;
    transition: transform .7s ease, opacity .7s ease;
}

.cart-fly-dot img { width: 100%; height: 100%; object-fit: cover; }

.item-number.bump { animation: cartfx-bump .42s ease; }

@keyframes cartfx-bump {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.45); }
    100% { transform: scale(1); }
}

/* `!important` porque o botão de compra de cada tema já declara fundo e
   cor com especificidade maior que uma classe solta, e este estado é
   momentâneo (o módulo tira a classe sozinho). */
.btn-added {
    background: var(--orv-fresco) !important;
    border-color: var(--orv-fresco) !important;
    color: #fff !important;
    animation: cartfx-pop .5s ease;
}

@keyframes cartfx-pop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.12); }
    100% { transform: scale(1); }
}


/* ========== NOME LONGO NO CARRINHO (defesa de catálogo) ==========
   Descrição de produto vem do catálogo do lojista e pode ser qualquer
   coisa — inclusive uma palavra de 60 caracteres sem espaço (código,
   nome colado). Duas regras seguram isso, e faltando UMA já quebra:

   1. `min-width: 0` — item de flex/grid tem `min-width: auto`, que
      significa "não encolha abaixo do seu conteúdo". A célula do nome
      então CRESCE para caber a palavra, empurra as vizinhas e a linha
      passa a encavalar; a página ganha rolagem lateral junto.
   2. `overflow-wrap: anywhere` — sem isto a palavra não quebra em lugar
      nenhum, e o `min-width: 0` sozinho só troca "empurrar a vizinha"
      por "vazar por cima dela".

   Medido no `moda` com um nome de 57 caracteres: `.content` ia a 474px
   dentro de uma célula de 350 e o documento a 586 numa tela de 390.

   Vale para as três listas que mostram nome de produto: a tabela do
   carrinho, a gaveta do mini-carrinho e o resumo do checkout. */

#cart-table td.flexitem,
#cart-table .content,
.products.mini .item-content,
.summary-order .item-content {
    min-width: 0;
}

#cart-table .content,
#cart-table .content a,
.products.mini .item-content,
.summary-order .item-content {
    overflow-wrap: anywhere;
}


/* ============ INFORMAÇÕES DA EMPRESA (enterprise-info) ============
   Esta estrutura NÃO tinha uma linha para esta página: o markup vem do
   `views/pages/enterprise-info.php` compartilhado, e sem regra nenhuma a
   página abria como HTML cru — lista com marcador, ícone do tamanho do
   texto, nenhuma caixa. Tema standalone não herda o `style.css`, então
   "o clássico estiliza" não vale de nada aqui (§4.4).

   Anatomia: uma ou duas colunas (dados da empresa + mapa, e `no-map`
   quando a loja não tem endereço), cada uma num painel de fio com
   cabeçalho, e dentro a lista rótulo/valor com o ícone num quadrado. */

.enterprise-info-box {
    display: flex;
    flex-direction: column;
    gap: 20px;
    margin-bottom: 32px;
}

@media (min-width: 861px) {
    .enterprise-info-box { flex-direction: row; align-items: flex-start; }
    .enterprise-info-box .info-section { flex: 3; }
    .enterprise-info-box .map-section { flex: 2; position: sticky; top: calc(var(--orv-topo) + 14px); }
    .enterprise-info-box.no-map .info-section { flex: 1; }
}

.info-section,
.map-section {
    min-width: 0;
    border: 1px solid var(--orv-fio);
    border-radius: var(--orv-r-g);
    background: var(--orv-papel);
    overflow: hidden;
}

.info-section-head,
.map-head {
    padding: 16px 20px;
    border-bottom: 1px solid var(--orv-fio);
}

.info-section-head h3,
.map-head h3 {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    color: var(--orv-tinta);
}

.info-section-head h3 i,
.map-head h3 i { color: var(--primary-color); font-size: 18px; }

.company-info-list { padding: 0 20px; }

.company-info-list li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--orv-fio);
}

.company-info-list li:last-child { border-bottom: 0; }

.info-icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--orv-r);
    background: var(--orv-corredor-fundo);
    color: var(--orv-tinta);
    font-size: 17px;
}

/* `min-width: 0` porque e-mail longo é uma palavra só e estouraria a
   coluna — o mesmo caso do nome de produto no carrinho. */
.info-content { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.info-content strong {
    font-size: 12px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--orv-tinta-3);
}

.info-content > span { color: var(--orv-tinta); overflow-wrap: anywhere; }
.info-content a:hover { text-decoration: underline; }

.map-section iframe,
.map-section img { width: 100%; border: 0; display: block; }

/* ---------------------------------------------------------------
 * Pedido mínimo (migration 081) — aviso + botão travado.
 *
 * Regra de compra, não enfeite: por isso o bloco se repete em TODO
 * tema (aqui e em styles/themes/**), ao contrário da barra de frete
 * grátis, que cada tema desenha do seu jeito. Um tema sem este bloco
 * mostraria o botão de fechar pedido com aparência de clicável mesmo
 * bloqueado — ver scripts/shared/MinimumOrder.js.
 * --------------------------------------------------------------- */
.minimum-order-notice {
    margin: 0 0 0.75em;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--danger-color, #c0392b);
}
.minimum-order-notice strong {
    font-weight: 700;
}
.is-blocked-minimum {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: auto;
}

/* ---------------------------------------------------------------
 * Retirada na loja (migration 081) — escolha no passo 1 do checkout.
 *
 * Repetido em todo tema pelo mesmo motivo do pedido mínimo: o passo 1
 * vem do partial compartilhado, e sem estes estilos o tema mostraria
 * dois radios crus e um painel sem separação nenhuma. Ver
 * scripts/features/checkout/PickupOption.js.
 * --------------------------------------------------------------- */
.delivery-mode {
    display: flex;
    gap: 0.75em;
    flex-wrap: wrap;
    margin-bottom: 1.25em;
}
.delivery-mode-option {
    display: flex;
    align-items: center;
    gap: 0.5em;
    flex: 1 1 12em;
    padding: 0.9em 1em;
    border: 1px solid var(--border-color, #e2e2e2);
    border-radius: var(--radius, 8px);
    cursor: pointer;
}
.delivery-mode-option input {
    accent-color: var(--primary-color, #5ac782);
}
.delivery-mode-option.is-active {
    border-color: var(--primary-color, #5ac782);
}
.pickup-panel {
    display: flex;
    flex-direction: column;
    gap: 0.35em;
    padding: 1.25em;
    margin-bottom: 1.25em;
    border: 1px solid var(--border-color, #e2e2e2);
    border-radius: var(--radius, 8px);
}
.pickup-instructions {
    margin: 0.5em 0 0;
    line-height: 1.5;
}
/* Some com endereço/frete enquanto a retirada estiver escolhida. */
.hidden-by-pickup {
    display: none !important;
}
