/*
 * Tema `moda` -- loja de roupa, calçado e acessório.
 *
 * **Este arquivo é a folha de estilo INTEIRA do tema.** O `style.css` do
 * clássico não carrega junto (ver views/partials/theme-assets.php): não há
 * herança, não há regra pra vencer, não há especificidade a contornar. O
 * que não estiver aqui não existe na tela.
 *
 * Isso é o oposto da primeira tentativa (2026-08-09, revertida): lá o tema
 * era um remendo por cima do clássico, e o resultado foi um tema que era o
 * clássico com outra fonte -- além de uma sequência de correções gastas
 * brigando com cascata em vez de desenhar.
 *
 * O que continua vindo de fora, porque não é desenho: os dados, o JS de
 * `scripts/features/**` e o contrato de DOM (`scripts/core/Contract.js`).
 * Nomes de classe e id do contrato aparecem aqui como GANCHO -- o estilo
 * que eles recebem é decisão deste arquivo, não do clássico.
 *
 * ## A linguagem
 *
 * Neutro de croma zero, canto reto, fio de 1px no lugar de sombra, uma
 * família só (Archivo) usando LARGURA e peso pra separar título de
 * interface, e a foto mandando. A cor de quem carrega o tema é a do
 * LOJISTA -- faixa do topo, rodapé, selo, CTA. O tema decide onde ela
 * aparece; não escolhe qual é.
 *
 * ### O que foi refeito em 2026-08-09, e por quê
 *
 * A primeira versão deste arquivo era Fraunces + Jost sobre off-white
 * quente, com um rótulo em caixa alta e espaçado acima de cada seção.
 * Cada peça se defendia sozinha; juntas, elas são o sotaque padrão de
 * página gerada por IA em 2026 -- serifada editorial, creme de fundo,
 * "eyebrow" como gramática. O cliente pediu loja de roupa que não pareça
 * as outras, e aquilo entregava exatamente o contrário.
 *
 * Trocado: fonte (§01), fundo (§01), e o rótulo virou exceção (§02).
 *
 * Sumário
 *   00. Reset
 *   01. Tokens
 *   02. Tipografia e utilitários
 *   03. Botões, campos e controles
 *   04. Cabeçalho
 *   05. Menu mobile e off-canvas
 *   06. Hero
 *   07. Seção e grade de produto
 *   08. Card de produto
 *   09. Página de produto
 *   10. Listagem e filtro
 *   11. Carrinho
 *   12. Checkout
 *   13. Conta
 *   13b. Entrar / criar conta
 *   13c. Informações da empresa
 *   14. Rodapé e barra inferior
 *   15. Componentes compartilhados (toast, modal, skeleton)
 *   16. Movimento
 */

/* =================================================
 * 00. Reset
 * ================================================= */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
}

img,
picture,
video,
svg {
    max-width: 100%;
    display: block;
}

button,
input,
select,
textarea {
    font: inherit;
    color: inherit;
}

button {
    background: none;
    border: 0;
    cursor: pointer;
}

ul,
ol {
    list-style: none;
}

a {
    color: inherit;
    text-decoration: none;
}

table {
    border-collapse: collapse;
    width: 100%;
}

/* =================================================
 * 01. Tokens
 * ================================================= */
:root {
    /* **Neutro de croma zero, não bege.** A primeira versão deste arquivo
       usava um off-white quente (#faf8f5) sob o nome `--paper`, com a
       justificativa de "devolver a borda da peça fotografada em fundo
       branco". A justificativa é real e a cor é errada mesmo assim: essa
       faixa exata (quase-branco morno) é o fundo padrão de página gerada
       por IA hoje, ao ponto de o nome do token já ser sintoma. Loja de
       roupa de verdade se distingue pela FOTO e pela cor da marca, não por
       um creme de fundo.

       Aqui o fundo é neutro puro e some; quem carrega calor é a paleta do
       lojista, logo abaixo. */
    --bg: #ffffff;
    --bg-sunk: #f4f4f4;
    --card: #ffffff;
    --ink: #111111;
    --ink-soft: #46464a;
    --ink-mute: #6e6e73;
    --line: #e3e3e5;
    --line-strong: #c6c6c9;

    /* A paleta da LOJA, injetada em runtime por scripts/core/ThemeColors.js
       a partir de company_preferences.

       **Ela carrega o tema, não decora.** Um tema white-label que usa a cor
       do lojista só no botão de comprar é um tema cinza com um botão
       colorido -- e loja nenhuma se reconhece nele. Aqui a cor da marca
       ocupa a faixa superior, o rodapé, o selo de promoção, o CTA e o
       estado ativo. É a estratégia "comprometida": um terço da superfície
       com a cor de quem é dono da loja. */
    --primary-color: #111111;
    --secondary-color: #111111;
    --secondary-dark-color: #111111;

    /* Texto sobre a cor da marca. Sem saber se ela é clara ou escura, o
       tema não pode cravar branco: `color-contrast()` ainda não é
       universal, então o valor vem de ThemeColors.js, que já conhece a cor
       e calcula. Branco é o padrão até ele responder. */
    --on-brand: #ffffff;

    --ok: #146c43;
    --warn: #8a5a00;
    --err: #a4262c;

    /* Uma família só, dois eixos variáveis. Título usa LARGURA (wdth) e
       peso; interface usa o peso normal. Contraste de verdade sem colocar
       duas famílias pra brigar -- e uma requisição de fonte em vez de
       duas. Ver views/themes/moda/head.php. */
    --font-display: 'Archivo', system-ui, sans-serif;
    --font-ui: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;

    --step--1: .75rem;
    --step-0: .9375rem;
    --step-1: 1.0625rem;
    --step-2: clamp(1.375rem, 2.2vw, 1.75rem);
    --step-3: clamp(1.75rem, 4vw, 2.75rem);
    --step-4: clamp(2.5rem, 7vw, 5rem);

    --tracking: .1em;

    --gap: 1rem;
    --gap-2: 1.5rem;
    --gap-3: 2.5rem;
    --gap-4: 4rem;

    --shell: 1440px;
    --pad: 1.25rem;

    --ease: cubic-bezier(.2, .6, .2, 1);
    --fast: .2s var(--ease);
    --slow: .5s var(--ease);

    --z-header: 50;
    --z-drawer: 90;
    --z-overlay: 80;
}

@media (min-width: 768px) {
    :root {
        --pad: 2.5rem;
    }
}

/* =================================================
 * 02. Tipografia e utilitários
 * ================================================= */
body {
    font-family: var(--font-ui);
    font-size: var(--step-0);
    font-weight: 400;
    line-height: 1.55;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

/* O contraste de título vem de LARGURA + PESO na mesma família. Archivo é
   variável nos dois eixos; `font-stretch: 108%` alarga a letra o
   suficiente pra o título ter presença sem virar outra fonte. */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 700;
    font-stretch: 108%;
    line-height: 1.05;
    letter-spacing: -.025em;
    text-wrap: balance;
}

h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }
h4 { font-size: var(--step-0); font-stretch: 100%; letter-spacing: -.01em; }

p { text-wrap: pretty; }
strong, b { font-weight: 600; }

/* **Rótulo em caixa alta é exceção, não gramática.**
 *
 * A primeira versão deste tema punha um `.md-eyebrow` acima de cada seção,
 * do título do produto, do seletor de tamanho e de cada bloco de filtro.
 * Isso é o andaime que denuncia página gerada: quando toda seção tem o
 * mesmo rótulo miúdo e espaçado em cima, ele deixa de informar e vira
 * decoração repetida.
 *
 * Sobrou em dois lugares, e os dois são CONTEÚDO, não moldura: o nome da
 * campanha que o lojista escreveu no banner, e o selo de promoção. Onde
 * era andaime, o peso do próprio título passou a fazer o trabalho. */
.md-eyebrow {
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.mini-text { font-size: var(--step--1); color: var(--ink-mute); }

.md-shell,
.container {
    width: 100%;
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: var(--pad);
}

/* `.hidden` vinha do style.css e é usada por JS compartilhado (banner de
   frete grátis, seções da conta). Sem ela aqui, tudo que o JS "escondia"
   aparecia -- o aviso de frete abria a página como uma faixa solta. */
.hidden,
.md-hidden { display: none !important; }

.mobile-hide { display: none; }
.desktop-hide { display: block; }

/* Blindagem dos utilitários (armadilha §6.7 do playbook, duas vezes neste
   arquivo): qualquer regra de área de toque com duas classes vence
   `.mobile-hide`/`.desktop-hide` (uma classe) e traz o elemento de volta na
   largura errada -- foi assim que o aviso de frete e o coração de favoritos
   apareceram no celular. O `!important` aqui é o mesmo contrato do
   `.hidden`: utilitário de esconder tem que vencer sempre. */
@media (max-width: 921px) {
    .mobile-hide { display: none !important; }
}

/* Aviso de frete grátis: faixa fina, mesma tinta do topo. */
.notification {
    background: var(--bg-sunk);
    border-bottom: 1px solid var(--line);
    text-align: center;
}
.notification-content { padding: .6rem var(--pad); }
.notification-title {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.notification progress,
.notification #progress { display: none; }

/* O carrossel do Swiper precisa das medidas dele; sem `style.css` por
   baixo, quem garante que o slide ocupa a largura toda é este bloco. */
.swiper { overflow: hidden; }
.swiper-wrapper { display: flex; }
.swiper-slide { flex: 0 0 100%; width: 100%; }

@media (min-width: 922px) {
    .mobile-hide { display: block; }
    .desktop-hide { display: none !important; }
}

.flexitem { display: flex; align-items: center; }
.flexcol { display: flex; flex-direction: column; }
.flexcenter { display: flex; align-items: center; justify-content: center; }
.flexwrap { display: flex; flex-wrap: wrap; }
.object-cover { overflow: hidden; }
/* O `<a>` que costuma envolver a foto é inline por padrão e quebra a
   corrente do `height: 100%` -- a imagem cai no tamanho natural dentro
   da caixa (foi assim no mini-carrinho). O bloco aqui vale pra todo
   consumidor do utilitário. */
.object-cover a { display: block; width: 100%; height: 100%; }
.object-cover img { width: 100%; height: 100%; object-fit: cover; }

/* Foco visível em tudo que recebe teclado. O clássico não tinha; aqui é
   requisito, não polimento. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

/* =================================================
 * 03. Botões, campos e controles
 * ================================================= */
.md-btn,
.primary-button,
.secondary-button,
.light-button,
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6em;
    font-family: var(--font-ui);
    font-size: var(--step--1);
    font-weight: 500;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    padding: 1.15em 2.4em;
    border: 1px solid var(--primary-color);
    background: var(--primary-color);
    color: var(--on-primary, #fff);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color var(--fast), color var(--fast), border-color var(--fast);
}

.md-btn:hover,
.primary-button:hover,
.btn:hover {
    background: transparent;    color: var(--primary-color);
}

/* `.btn-secondary` e `.btn-sm` vêm do JS da conta (`profile/index.js` monta
   "Ver detalhes" com as três classes juntas). Sem tratamento eles herdavam
   o botão primário e cada linha da lista de pedidos ganhava um bloco sólido
   na cor da marca -- oitenta pedidos, oitenta blocos, e o valor do pedido
   deixava de ser o que se lê primeiro. */
.md-btn--ghost,
.secondary-button,
.light-button,
.btn-secondary {
    background: transparent;
    color: var(--ink);
    border-color: var(--line-strong);
}
.btn-secondary:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn-sm {
    min-height: 36px;
    padding: 0 1em;
    font-size: var(--step--1);
    letter-spacing: .04em;
}
.md-btn--ghost:hover,
.secondary-button:hover,
.light-button:hover {
    background: var(--ink);
    color: var(--bg);
}

.md-btn--brand {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: #fff;
}
.md-btn--brand:hover {
    background: transparent;
    color: var(--primary-color);
}

.md-btn--wide,
.md-btn--block { width: 100%; }

.md-btn:disabled,
.primary-button:disabled,
.btn:disabled {
    opacity: .5;
    cursor: not-allowed;
}

.md-btn--link {
    background: none;
    border: 0;
    padding: 0;
    color: var(--ink);
    border-bottom: 1px solid currentColor;
    letter-spacing: var(--tracking);
}

input[type="text"],
input[type="email"],
input[type="mail"],
input[type="tel"],
input[type="search"],
input[type="password"],
input[type="number"],
select,
textarea {
    width: 100%;
    padding: .9em 1em;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 0;
    font-size: var(--step-0);
    transition: border-color var(--fast);
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--ink);
    outline: none;
}

label {
    display: block;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: .4em;
}

/* Stepper de quantidade -- mesmo componente no card, na página de produto
   e no carrinho. `.minus`/`.plus` em volta do input são contrato de JS. */
.qty-control,
.purchase-quantity {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--line);
    background: var(--card);
}
.qty-control button,
.purchase-quantity-btn {
    width: 2.6em;
    min-width: 32px;
    font-size: var(--step-0);
    color: var(--ink);
    transition: background-color var(--fast);
}
.qty-control button:hover,
.purchase-quantity-btn:hover { background: var(--bg-sunk); }
.qty-control input,
.purchase-quantity-input {
    width: 3em;
    border: 0;
    text-align: center;
    padding: .7em 0;
    background: none;
    -moz-appearance: textfield;
}
.purchase-quantity-input::-webkit-outer-spin-button,
.purchase-quantity-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* =================================================
 * 04. Cabeçalho
 * ================================================= */
/* A faixa superior é o primeiro terço de superfície que a cor do lojista
   ocupa. Num tema white-label, marca que só aparece no botão de comprar
   não é marca -- é um botão colorido num tema cinza. */
.md-topbar {
    background: var(--secondary-dark-color);
    color: var(--on-brand);
}
.md-topbar .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    min-height: 38px;
}
/* `padding-block` nos links utilitários: a auditoria de alvo de toque
   pegou todos eles com ~18px de altura, que é a altura da linha do texto.
   O padding não muda nada visualmente (o fundo é o mesmo da faixa) e
   dobra a área clicável -- barato o bastante pra não ter desculpa. */
.md-topbar a,
.md-topbar span {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--bg);
}
.md-topbar a:hover { opacity: .7; }
.md-topbar ul { display: flex; gap: 1.5rem; }

.md-header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}
.md-header .container {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--gap);
    min-height: 64px;
}
/* O botão de menu do celular media 15x23 -- é o ícone puro, sem área.
   `display: none` no desktop precisa vir junto: a regra de área tinha
   especificidade maior que `.desktop-hide` e trazia o botão de volta na
   tela grande, virando uma quarta coluna num grid de três -- o cabeçalho
   inteiro quebrava em duas linhas. */
.md-header .trigger {
    display: none;
}
@media (max-width: 921px) {
    .md-header .trigger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        height: 40px;
        margin-left: -8px;
        font-size: 1.35rem;
    }
}

.md-header__logo img {
    max-height: 34px;
    width: auto;
}
.md-header__logo .logo-text {
    font-family: var(--font-display);
    font-size: var(--step-2);
}

.md-header__nav { display: none; }
@media (min-width: 922px) {
    .md-header .container { min-height: 80px; }
    .md-header__nav {
        display: flex;
        justify-content: center;
        gap: 2.25rem;
    }
    .md-header__nav > li > a {
        display: inline-flex;
        align-items: center;
        gap: .35em;
        font-size: var(--step--1);
        letter-spacing: var(--tracking);
        text-transform: uppercase;
        padding: .5rem 0;
    }
    /* Fio que cresce do centro -- o único enfeite de interação do
       cabeçalho. O resto responde só com opacidade. */
    .md-header__nav > li > a::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 1px;
        background: currentColor;
        transform: scaleX(0);
        transition: transform var(--fast);
    }
    /* O fio ancora no PRÓPRIO link; o `li` fica estático de propósito.
       Se o `li` for `position: relative`, o `.md-mega` (absoluto, left/right
       0) ancora nele e o "painel de largura total" vira uma coluna da
       largura do item, com o texto vazando pra fora do fundo branco. O
       ancestral posicionado que interessa é o `.md-header` (sticky conta
       como posicionado) -- é ele que dá a largura total. */
    .md-header__nav > li > a { position: relative; }
    .md-header__nav > li:hover > a::after { transform: scaleX(1); }
}

.md-header__tools {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1.1rem;
}
/* 40x40: o ícone tem 22px de largura, e a auditoria de alvo de toque
   pegou os três do cabeçalho abaixo do mínimo confortável. O quadrado
   maior é área clicável, não desenho -- o ícone continua do mesmo
   tamanho. */
/* `:not(.md-btn)` porque o mini-carrinho mora dentro deste bloco, e os
   botões dele são `.md-btn`. Sem a exclusão, `.md-header__tools a` (duas
   classes) vencia `.md-btn` (uma) e pintava "Finalizar compra" com a
   tinta do ícone: preto sobre o fundo da marca, 3.86:1. A auditoria de
   contraste pegou; a olho o botão parecia só um pouco escuro. */
.md-header__tools a:not(.md-btn),
.md-header__tools button:not(.md-btn) {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    font-size: 1.35rem;
    color: var(--ink);
}
.md-header__count,
.item-number {
    position: absolute;
    top: -6px;
    right: -9px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-ui);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0;
    background: var(--primary-color);
    color: #fff;
    border-radius: 999px;
}

/* Mega-menu de categoria: painel de largura total, sem borda arredondada,
   abrindo colado no fio do cabeçalho. */
.md-mega {
    /* `display: none` na base: o SiteChrome clona a navegação inteira
       (mega incluso) pra dentro do off-canvas, e lá o padrão
       opacity/visibility ocuparia espaço em branco no meio do menu. No
       desktop a media query abaixo troca pra `block` e anima com
       opacity+translate -- `display` não transiciona. */
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 24px -18px rgba(0, 0, 0, .4);
}
@media (min-width: 922px) {
    .md-header__nav .md-mega {
        display: block;
        opacity: 0;
        visibility: hidden;
        transform: translateY(10px);
        pointer-events: none;
        transition: opacity .25s var(--ease), transform .25s var(--ease), visibility .25s;
    }
    .md-header__nav > li:hover .md-mega,
    .md-header__nav > li:focus-within .md-mega {
        opacity: 1;
        visibility: visible;
        transform: none;
        pointer-events: auto;
    }
}
.md-mega .container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--gap-2);
    padding-block: var(--gap-3);
}
.md-mega h4 {
    font-family: var(--font-ui);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: .8rem;
}
.md-mega li + li { margin-top: .15rem; }
/* Linha inteira clicável -- os links do painel mediam 16px de altura. */
.md-mega li a {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
}
.md-mega a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* --- mini-carrinho --- */
.mini-cart {
    position: absolute;
    top: calc(100% + 12px);
    right: 0;
    width: min(380px, calc(100vw - 2rem));
    background: var(--card);
    border: 1px solid var(--line);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity var(--fast), transform var(--fast), visibility var(--fast);
    z-index: var(--z-header);
    text-align: left;
}
.mini-cart.show {
    opacity: 1;
    visibility: visible;
    transform: none;
}
.mini-cart .cart-head {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--line);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.mini-cart .cart-body {
    max-height: 46vh;
    overflow-y: auto;
}
.mini-cart .products.mini li {
    display: grid;
    grid-template-columns: 64px 1fr auto;
    gap: .85rem;
    align-items: center;
    padding: 1rem 1.25rem;
}
.mini-cart .products.mini li + li { border-top: 1px solid var(--line); }
.mini-cart .thumbnail {
    aspect-ratio: 3 / 4;
    background: var(--bg-sunk);
    overflow: hidden;
}
/* O markup é `.thumbnail > a > img`. O `<a>` inline quebrava a corrente
   de altura: `height: 100%` da imagem resolvia contra o anchor (altura
   auto) e a foto saía no tamanho natural, pequena dentro da caixa. */
.mini-cart .thumbnail a { display: block; width: 100%; height: 100%; }
.mini-cart .thumbnail img { width: 100%; height: 100%; object-fit: cover; }
/* `min-width: 0` na coluna do meio: numa grade `64px 1fr auto`, a coluna
   flexível tem largura mínima automática igual ao conteúdo, então um nome
   com variação junto ("Tênis de Corrida Leve | Tamanho 43 - Cor Preto")
   estoura a célula em vez de quebrar linha e invade o que está ao lado e
   abaixo. `overflow-wrap` cobre o caso do nome com um pedaço longo sem
   espaço (código, medida). */
.mini-cart .item-content { min-width: 0; overflow-wrap: anywhere; }
.mini-cart .item-content p { font-size: var(--step--1); text-transform: none; letter-spacing: 0; line-height: 1.35; }
.mini-cart .price { display: flex; flex-wrap: wrap; gap: .5rem; font-size: var(--step--1); color: var(--ink-mute); margin-top: .35rem; }
.mini-cart .item-remove { color: var(--ink-mute); font-size: 1.1rem; }
.mini-cart .item-remove:hover { color: var(--err); }
.mini-cart .cart-footer { padding: 1.25rem; border-top: 1px solid var(--line); }
.mini-cart .subtotal { display: flex; justify-content: space-between; margin-bottom: 1rem; }
.mini-cart .actions { display: grid; gap: .5rem; }
.mini-cart .actions a { width: 100%; }

/* --- Painel de busca (§04b) ---
   O partial compartilhado era `desktop-hide` e ficava fixo em cima do menu
   inferior; aqui o tema tem partial próprio (sem `desktop-hide`) e o painel
   desce colado ao topo em QUALQUER largura -- a lupa do cabeçalho e o
   "Buscar" da barra inferior alternam `.showsearch` no `.site`
   (SiteChrome). Esc e o X fecham. */
.search-bottom {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    z-index: calc(var(--z-drawer) + 5);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 1.5rem 0 1.75rem;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-16px);
    transition: opacity var(--fast), transform var(--fast), visibility var(--fast);
}
.showsearch .search-bottom {
    opacity: 1;
    visibility: visible;
    transform: none;
}
.search-bottom .search {
    display: flex;
    align-items: center;
    gap: .85rem;
    max-width: 720px;
    margin-inline: auto;
    border-bottom: 1px solid var(--ink);
    padding-bottom: .5rem;
}
.search-bottom .icon-large {
    font-size: 1.3rem;
    color: var(--ink-mute);
}
.search-bottom input[type="search"] {
    flex: 1;
    min-width: 0;
    border: 0;
    padding: .45em 0;
    font-size: var(--step-1);
    background: none;
}
.search-bottom input[type="search"]:focus { border: 0; }
/* O X de limpar nativo do WebKit sai azul e duplica o X de fechar do
   painel. O de fechar fica; o nativo some. */
.search-bottom input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
.search-bottom button[type="submit"] {
    font-size: var(--step--1);
    font-weight: 500;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    padding: .6em 0;
    white-space: nowrap;
    box-shadow: inset 0 -1px 0 currentColor;
}
.search-bottom .search-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    font-size: 1.3rem;
    color: var(--ink-mute);
}
.search-bottom .search-close:hover { color: var(--ink); }

/* Nas páginas de busca o painel deixa de ser overlay e vira BARRA da
   própria página, sempre visível -- o termo pesquisado fica na tela,
   editável, em vez de sumir atrás do toggle. Quem faz a mudança é o JS de
   apresentação do tema (scripts/themes/moda/pesquisa-produtos.js): ele
   MOVE o nó do fim do documento (onde o partial compartilhado o emite)
   pra baixo do cabeçalho da listagem e põe esta classe. Static no fim do
   DOM colocaria a barra no rodapé. O X sai: não há o que fechar. */
.search-bottom--inline {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    padding: 0 0 1.25rem;
    border-bottom: 0;
}
.search-bottom--inline .container { padding-inline: 0; }
.search-bottom--inline .search { max-width: 560px; margin-inline: 0; }
.search-bottom--inline .search-close { display: none; }

/* Dropdown de buscas recentes (`HeaderSearch.attachHistoryDropdown`).
   O componente é o `.select-box-menu` compartilhado -- sem estas regras
   os botões do histórico fluíam INLINE dentro do form, colados na linha
   do input. Fechado por padrão; `search-select-box-open` (posta no form
   no focus) abre. */
.search-select-box { position: relative; }
.select-box-menu {
    display: none;
    position: absolute;
    top: calc(100% + 1px);
    left: 0;
    right: 0;
    background: var(--card);
    border: 1px solid var(--line);
    box-shadow: 0 16px 28px -20px rgba(0, 0, 0, .35);
    z-index: 30;
}
.search-select-box-open .select-box-menu { display: block; }
.select-box-option {
    display: flex;
    align-items: center;
    gap: .6rem;
    width: 100%;
    padding: .7rem 1rem;
    text-align: left;
    font-size: var(--step-0);
    transition: background-color var(--fast);
}
.select-box-option:hover { background: var(--bg-sunk); }
.select-box-option .option-icon { color: var(--ink-mute); font-size: 1rem; }
.select-box-option .option-body { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.select-box-footer {
    display: flex;
    align-items: center;
    gap: .5em;
    width: 100%;
    padding: .7rem 1rem;
    border-top: 1px solid var(--line);
    font-size: var(--step--1);
    letter-spacing: .04em;
    color: var(--ink-mute);
    transition: color var(--fast), background-color var(--fast);
}
.select-box-footer:hover { background: var(--bg-sunk); color: var(--err); }

/* =================================================
 * 05. Menu mobile e off-canvas
 * ================================================= */
.md-drawer,
.off-canvas {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(88vw, 380px);
    background: var(--bg);
    border-right: 1px solid var(--line);
    transform: translateX(-102%);
    transition: transform var(--slow);
    z-index: var(--z-drawer);
    overflow-y: auto;
    padding: 1.5rem var(--pad) 3rem;
}
.site.showmenu .md-drawer,
.site.showmenu .off-canvas { transform: none; }

.md-overlay,
.overlay {
    position: fixed;
    inset: 0;
    background: rgba(20, 17, 15, .45);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--fast), visibility var(--fast);
    z-index: var(--z-overlay);
}
.site.showmenu .md-overlay,
.site.showmenu .overlay { opacity: 1; visibility: visible; }

/* O SiteChrome clona o `ul.md-header__nav` inteiro pra dentro do drawer --
   e a regra base `.md-header__nav { display: none }` (que só vira flex no
   desktop) escondia o clone junto. No drawer a lista sempre aparece, um
   item por linha. */
.md-drawer .md-header__nav,
.off-canvas .md-header__nav { display: block; }

.md-drawer nav > ul > li > a,
.off-canvas nav > ul > li > a {
    display: block;
    padding: .9rem 0;
    border-bottom: 1px solid var(--line);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.md-drawer .has-child > ul,
.off-canvas .has-child > ul { display: none; padding: .25rem 0 .75rem 1rem; }
.md-drawer .has-child.expand > ul,
.off-canvas .has-child.expand > ul { display: block; }
/* No cabeçalho o submenu é o `.md-mega` (um div de painel, não um `ul`) --
   clonado pro drawer, ele vira o conteúdo do acordeão: estático, sem
   sombra, uma coluna. Sem estas regras o chevron alternava `.expand` e
   nada aparecia. */
.md-drawer .has-child.expand .md-mega,
.off-canvas .has-child.expand .md-mega {
    display: block;
    position: static;
    border: 0;
    box-shadow: none;
}
.md-drawer .md-mega .container,
.off-canvas .md-mega .container {
    display: block;
    padding: .25rem 0 .75rem 1rem;
}
.md-drawer .md-mega h4,
.off-canvas .md-mega h4 { margin: .75rem 0 .35rem; }
.md-drawer .md-mega li a,
.off-canvas .md-mega li a { min-height: 34px; }
.md-drawer .has-child .icon-small,
.off-canvas .has-child .icon-small {
    float: right;
    padding: .9rem 0;
    cursor: pointer;
}
.t-close {
    display: inline-flex;
    font-size: 1.5rem;
    margin-bottom: 1rem;
}

/* =================================================
 * 06. Hero
 * ================================================= */
.md-hero {
    position: relative;
    background: var(--bg-sunk);
}
.md-hero__slide {
    position: relative;
    height: var(--md-hero-h, 68vh);
    min-height: 420px;
    max-height: 820px;
}
.md-hero--medio { --md-hero-h: 54vh; }
.md-hero--alto  { --md-hero-h: 68vh; }
.md-hero--cheio { --md-hero-h: calc(100vh - 64px); }

.md-hero__image { position: absolute; inset: 0; }
.md-hero__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Foto de campanha quase sempre tem rosto no terço superior --
       centralizar corta a cabeça nas telas mais baixas. */
    object-position: 50% 28%;
}

/* O gradiente resolve o problema real do banner enviado pelo lojista: não
   dá pra saber se a foto é clara ou escura atrás do texto. Sem ele metade
   das lojas fica com o título ilegível, e a culpa cai no tema. */
.md-hero__text {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding-bottom: clamp(2rem, 7vh, 5rem);
    background: linear-gradient(to top, rgba(0, 0, 0, .6) 0%, rgba(0, 0, 0, .25) 40%, rgba(0, 0, 0, 0) 70%);
}
.md-hero__text .container {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.1rem;
    width: 100%;
}
.md-hero .md-eyebrow {
    background: var(--bg);
    color: var(--ink);
    padding: .5em 1em;
}
.md-hero__headline {
    font-family: var(--font-display);
    font-size: var(--step-4);
    line-height: 1.03;
    color: #fff;
    max-width: 15ch;
    text-shadow: 0 2px 24px rgba(0, 0, 0, .35);
}
.md-hero__headline span { display: block; color: #fff; }
/* Segunda linha em peso e largura menores, não em itálico: o link de
   fonte não traz o eixo itálico do Archivo, e o navegador sintetizava um
   oblíquo inclinando a letra à força -- fica torto, não fica itálico. */
.md-hero__headline-alt {
    font-weight: 400;
    font-stretch: 100%;
    opacity: .92;
}
.md-hero .md-btn {
    background: var(--bg);
    border-color: var(--bg);
    color: var(--ink);
}
.md-hero .md-btn:hover { background: transparent; color: var(--bg); }

.md-hero__dots {
    --swiper-pagination-color: #fff;
    --swiper-pagination-bullet-inactive-color: #fff;
    --swiper-pagination-bullet-inactive-opacity: .45;
    bottom: 1.25rem !important;
}

/* =================================================
 * 07. Seção e grade de produto
 * ================================================= */
main > div,
main > section { margin-bottom: var(--gap-4); }

.sectop {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap);
    padding-bottom: 1rem;
    margin-bottom: var(--gap-2);
    border-bottom: 1px solid var(--line);
}
.sectop h2 { font-size: var(--step-2); }
.sectop .circle { display: none; }
.sectop .view-all,
.view-all {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    box-shadow: inset 0 -1px 0 currentColor;
    white-space: nowrap;
}

/* 2 colunas no celular é regra, não consequência: uma coluna dá um card
   gigante e obriga a rolar demais pra comparar peças -- que é exatamente
   o que se faz numa loja de roupa. */
.products.main,
.md-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem .75rem;
}
@media (min-width: 768px) {
    .products.main,
    .md-grid {
        grid-template-columns: repeat(var(--md-grid-colunas, 3), minmax(0, 1fr));
        gap: 3rem 1.5rem;
    }
}

/* Categorias como porta: foto grande, nome por cima, um clique. */
.md-cats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem;
}
@media (min-width: 768px) {
    .md-cats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; }
}
.md-cat {
    position: relative;
    display: block;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background: var(--bg-sunk);
}
.md-cat__media,
.md-cat__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.md-cat__media img { transition: transform 1.1s var(--ease); }
.md-cat:hover .md-cat__media img { transform: scale(1.05); }
.md-cat__name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.5rem 1rem 1rem;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, .6), rgba(0, 0, 0, 0));
}

/* Rede de segurança: qualquer imagem dentro de bloco de produto que este
   tema ainda não tenha estilizado nominalmente fica contida no lugar dela.
   Sem o `style.css` por baixo, uma foto sem regra assume o tamanho natural
   do arquivo -- foi assim que a home abriu com 36.000px de altura na
   primeira carga do tema standalone. */
.products img,
.banners img,
.brands img {
    max-width: 100%;
    height: auto;
}

/* =================================================
 * 08. Card de produto
 * ================================================= */
.products.main .item,
.md-card {
    display: flex;
    flex-direction: column;
    position: relative;
}

.md-card__media,
.products.main .media {
    position: relative;
    aspect-ratio: var(--md-ratio-foto, 3 / 4);
    background: var(--bg-sunk);
    overflow: hidden;
}
.md-card__thumb,
.md-card__thumb a,
.products.main .thumbnail {
    display: block;
    width: 100%;
    height: 100%;
}
.md-card__thumb img,
.products.main .thumbnail img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 1.1s var(--ease);
}
.md-card:hover .md-card__thumb img { transform: scale(1.04); }

.md-card__tags {
    position: absolute;
    top: .6rem;
    left: .6rem;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .35rem;
    z-index: 2;
}
.md-tag {
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    padding: .4em .7em;
    background: var(--bg);
    color: var(--ink);
}
.md-tag--sale { background: var(--primary-color); color: var(--on-brand); }
.md-tag--shipping { background: var(--ink); color: #fff; }

/* Sempre visível, nunca atrás de :hover -- metade do tráfego é celular, e
   lá `:hover` não existe.
   Escopado no card de propósito: `.favorite-btn` também é a classe do link
   "Favoritos" da página de produto (partials/product/actions.php). Solto,
   o posicionamento absoluto arrancava aquele link do lugar dele e o
   grudava no canto do primeiro ancestral posicionado. */
.md-card__fav {
    position: absolute;
    top: .5rem;
    right: .5rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: rgba(250, 248, 245, .92);
    color: var(--ink);
    font-size: 1.05rem;
    cursor: pointer;
    transition: background-color var(--fast), color var(--fast);
}
.md-card__fav:hover,
.md-card__fav.is-active { background: var(--ink); color: var(--bg); }

.md-card__body,
.products.main .content {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding-top: .9rem;
    flex: 1;
}
.md-card__title,
.products.main .content h3 {
    font-family: var(--font-ui);
    font-size: var(--step-0);
    font-weight: 400;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* O link do título media 16px de altura (a linha do texto) -- a auditoria
   de alvo de toque pegou em toda grade. Block ocupa o h3 inteiro. */
.md-card__title a,
.products.main .content h3 a { display: block; padding-block: 2px; }
.md-card__title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.md-card__price,
.products.main .price {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin-top: .15rem;
}
.md-card__price .current,
.products .price .current {
    font-size: var(--step-1);
    font-weight: 500;
    color: var(--ink);
}
.md-card__price .normal,
.products .price .normal {
    text-decoration: line-through;
    color: var(--ink-mute);
    font-size: var(--step--1);
}
/* Bloco `.mini-links` da oferta -- lista de links de subcategoria que
   media 16px de altura por link. */
.mini-links li a {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
}
.login-required {
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
}
.md-card__meta,
.md-card__rating { font-size: var(--step--1); color: var(--ink-mute); }
.md-card__summary { font-size: var(--step--1); color: var(--ink-mute); }

/* Empilhado no celular. Em duas colunas o card tem ~178px, e o stepper
   (~90px) mais o botão com `white-space: nowrap` e padding de 2.4em
   somavam 231px -- o botão vazava a tela e criava rolagem horizontal na
   home inteira. Achado pela auditoria de overflow, não a olho: o card
   ficava visualmente quase certo. */
.purchase-section,
.md-card__buy {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: .5rem;
    margin-top: auto;
    padding-top: .9rem;
}
.purchase-section .purchase-quantity { align-self: flex-start; }
.purchase-section .purchase-btn {
    width: 100%;
    padding: .95em 1rem;
    letter-spacing: .06em;
}

@media (min-width: 768px) {
    .purchase-section,
    .md-card__buy { flex-direction: row; align-items: center; }
    .purchase-section .purchase-btn { flex: 1; width: auto; }
}

@media (min-width: 768px) {
    /* Botão de compra entra no hover no desktop, onde há hover de verdade.
       No celular fica sempre visível (regra base acima) -- lá não há como
       revelá-lo. */
    .purchase-section,
    .md-card__buy {
        opacity: 0;
        transform: translateY(4px);
        transition: opacity var(--fast), transform var(--fast);
    }
    .md-card:hover .purchase-section,
    .md-card:focus-within .purchase-section,
    .md-card:hover .md-card__buy,
    .md-card:focus-within .md-card__buy {
        opacity: 1;
        transform: none;
    }
}

.stock-danger { color: var(--err); }
.free-shipping { color: var(--ok); }
.cashback-badge {
    display: inline-block;
    font-size: 10px;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    padding: .35em .6em;
    background: var(--bg-sunk);
    color: var(--ink-soft);
}

/* =================================================
 * 09. Página de produto
 * ================================================= */
.md-pdp { padding-top: 1.25rem; }
.md-pdp__back {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    gap: .5em;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: 1.5rem;
}
.md-pdp__back:hover { color: var(--ink); }

.md-pdp__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2rem;
    align-items: start;
}
@media (min-width: 922px) {
    .md-pdp__grid {
        grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
        gap: 4rem;
    }
}

.md-pdp__stack {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 88%;
    gap: .5rem;
    overflow: auto hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}
.md-pdp__stack::-webkit-scrollbar { display: none; }
/* Sem `max-height`: com `aspect-ratio` junto, o quadro virava paisagem e o
   `contain` devolvia a peça pequena entre duas faixas vazias -- o oposto
   do que a galeria existe pra fazer. Quem controla o tamanho aqui é a
   largura da coluna, e a altura acompanha a proporção. */
.md-pdp__shot {
    scroll-snap-align: center;
    width: 100%;
    aspect-ratio: var(--md-ratio-foto, 3 / 4);
    overflow: hidden;
    background: var(--bg-sunk);
}
.md-pdp__shot a { display: block; height: 100%; }
/* `contain` na página, `cover` no card: o tema não sabe se o lojista subiu
   foto de modelo ou peça recortada em fundo branco. Num card de 300px o
   corte custa pouco; numa foto de 780px ele corta cabeça e pés. */
.md-pdp__shot img { width: 100%; height: 100%; object-fit: contain; }

@media (min-width: 922px) {
    .md-pdp__stack {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, 1fr);
        overflow: visible;
    }
    /* Mosaico uniforme, sem foto destacada. Dar a linha inteira à primeira
       fazia ela chegar a mais de 1000px de altura numa coluna de 780 --
       e a tentativa de conter isso com `max-height` foi o que deformou o
       quadro. Uniforme é previsível e é como catálogo de moda se organiza.
       Com uma foto só, a coluna vira única e a peça ocupa tudo. */
    .md-pdp__stack:not(:has(.md-pdp__shot:nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
    .md-pdp__buy { position: sticky; top: 100px; }
}

.md-pdp__kicker { margin-bottom: .4rem; font-size: var(--step--1); color: var(--ink-mute); }
.md-pdp__title { font-size: var(--step-3); margin-bottom: 1rem; }
.md-pdp .price .current { font-size: var(--step-3); font-family: var(--font-ui); font-weight: 500; }
.md-pdp .stock-sku,
.md-pdp .rating { margin-top: 1rem; font-size: var(--step--1); color: var(--ink-mute); }
/* "Adicione sua avaliação" e "Entrar na minha conta" mediam 14px de altura. */
.md-pdp .rating a,
.md-pdp .add-review,
.reviews a {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
}

/* Contagem regressiva da oferta (`partials/product/countdown` e o bloco de
   destaque da home). O markup é `ul#countdown > li#days…#seconds` -- os ids
   são contrato com Countdown.js. Sem regra os quatro números saíam colados
   ("0000"), parecendo lixo de template. Rótulo de unidade via ::after:
   o JS só escreve o número. */
.offer {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 1.25rem 0;
}
.offer p {
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
}
#countdown { display: inline-flex; gap: .4rem; }
#countdown li {
    min-width: 3em;
    padding: .4em .45em .35em;
    border: 1px solid var(--line-strong);
    text-align: center;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}
#countdown li::after {
    display: block;
    font-size: 9px;
    font-weight: 400;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-mute);
}
#days::after { content: 'dias'; }
#hours::after { content: 'horas'; }
#minutes::after { content: 'min'; }
#seconds::after { content: 'seg'; }

.md-picker { margin: 1.75rem 0; }
.md-picker__label { margin-bottom: .6rem; font-weight: 600; font-size: var(--step-0); }
.md-picker__grid { display: flex; flex-wrap: wrap; gap: .5rem; }
.md-picker__opt {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    width: auto;
    min-width: 3.4em;
    margin: 0;
    padding: .75em 1.1em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: .04em;
    text-transform: none;
    color: var(--ink);
    cursor: pointer;
    transition: border-color var(--fast), background-color var(--fast), color var(--fast);
}
.md-picker__opt input { position: absolute; opacity: 0; pointer-events: none; }
.md-picker__thumb { width: 22px; height: 22px; object-fit: cover; }
.md-picker__opt:hover { border-color: var(--ink); }
.md-picker__opt:has(input:checked) { background: var(--ink); border-color: var(--ink); color: var(--bg); }
/* Esgotado é AVISO, não bloqueio: loja que não quebra estoque por variação
   manda zero em tudo, e travar aqui deixaria essas lojas sem nenhum
   tamanho clicável só neste tema. */
.md-picker__opt.is-out { color: var(--ink-mute); background: var(--bg-sunk); }
.md-picker__opt.is-out .label { text-decoration: line-through; }
.md-picker__out { font-size: 10px; letter-spacing: var(--tracking); text-transform: uppercase; }

.actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    margin-top: 1.75rem;
}
.actions .qty-control { align-self: flex-start; }
.actions .button-cart,
.actions .button-cart .primary-button { width: 100%; }
.wish-share ul { display: flex; gap: 1.75rem; }
.wish-share a { display: inline-flex; align-items: center; min-height: 32px; gap: .5em; font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; cursor: pointer; }
.wish-share .icon-large { font-size: 1.15rem; }

.buy-together,
.upsell,
.quantity-tiers {
    margin-top: 1.75rem;
    padding: 1.25rem;
    border: 1px solid var(--line);
    background: var(--card);
}
.buy-together-title,
.upsell-title,
.quantity-tiers-title {
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: 1rem;
}
/* Trilho horizontal, sem quebra: com `flex-wrap` o "+" separador órfão
   ficava colado na borda direita e o card seguinte caía sozinho na linha
   de baixo -- parecia conteúdo vazando. Kit de N itens rola de lado, como
   o resto do catálogo. */
.buy-together-items {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: .25rem;
    scrollbar-width: thin;
}
.buy-together-plus {
    flex: none;
    align-self: center;
    color: var(--ink-mute);
}
.buy-together-card { flex: none; width: 92px; }
.buy-together-price { font-size: var(--step--1); font-weight: 600; }
.buy-together-price .normal {
    font-weight: 400;
    color: var(--ink-mute);
    text-decoration: line-through;
    margin-left: .35em;
}
.buy-together-card .thumbnail { aspect-ratio: 3/4; background: var(--bg-sunk); overflow: hidden; }
.buy-together-name {
    font-size: var(--step--1);
    line-height: 1.3;
    margin-top: .4rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.buy-together-footer { display: flex; flex-direction: column; gap: .75rem; margin-top: 1rem; }
.upsell-items { display: grid; gap: 1rem; }
.upsell-card { display: grid; grid-template-columns: 64px 1fr auto; gap: .75rem; align-items: center; }
.upsell-card .thumbnail { aspect-ratio: 3/4; background: var(--bg-sunk); overflow: hidden; }
.quantity-tiers li { display: flex; justify-content: space-between; padding: .4rem 0; border-bottom: 1px solid var(--line); font-size: var(--step--1); }

/* Faixa de leitura -- descrição, informações e avaliações em largura total,
   fora da coluna de compra. Texto numa coluna de 380px ninguém lê. */
.md-pdp__info {
    padding: var(--gap-4) 0;
    background: var(--bg-sunk);
    border-top: 1px solid var(--line);
}
.md-pdp__info .container { max-width: 900px; }
.collapse .has-child > a {
    display: block;
    padding: 1.1rem 0 1.1rem 1.75rem;
    border-bottom: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    position: relative;
}
.collapse .has-child > a::before {
    content: '+';
    position: absolute;
    left: 0;
    font-size: var(--step-1);
    line-height: 1;
}
.collapse .expand > a::before { content: '–'; }
.collapse .content { display: none; padding: 1.25rem 0 1.75rem; }
.collapse .expand > .content,
.collapse .expand > ul.content { display: block; }
.collapse .content li { display: flex; justify-content: space-between; gap: 1rem; padding: .4rem 0; border-bottom: 1px solid var(--line); }
.collapse table th,
.collapse table td { padding: .5rem .75rem; border: 1px solid var(--line); text-align: left; font-size: var(--step--1); }
.reviews h4 { font-family: var(--font-display); margin-bottom: 1rem; }
.review-block-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.rate-sum { font-family: var(--font-display); font-size: var(--step-3); }
.review-block-body li { display: block; padding: 1.25rem 0; border-bottom: 1px solid var(--line); }
.review-form p { margin-bottom: 1rem; }
.rate-this { display: inline-flex; flex-direction: row-reverse; gap: .25rem; }
.rate-this input { display: none; }
.rate-this label { font-size: 1.3rem; color: var(--line-strong); cursor: pointer; margin: 0; }
.rate-this input:checked ~ label,
.rate-this label:hover,
.rate-this label:hover ~ label { color: var(--ink); }
.stars { display: inline-flex; gap: 2px; color: var(--ink); }

.breadcrumb ul { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.breadcrumb li + li::before { content: '/'; margin-right: .5rem; color: var(--ink-mute); }
.breadcrumb,
.breadcrumb a { font-size: var(--step--1); color: var(--ink-mute); }
/* Trilha clicável com área de toque de verdade -- os links mediam 14px. */
.breadcrumb a { display: inline-flex; align-items: center; min-height: 28px; }
.breadcrumb a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* =================================================
 * 10. Listagem e filtro
 * ================================================= */
.md-plp { padding-top: 1.5rem; }
.md-plp__head { margin-bottom: var(--gap-2); }
.md-plp__head .breadcrumb { margin-bottom: .75rem; }
.md-plp__head h1 { font-size: var(--step-3); }

.md-plp__grid { display: grid; grid-template-columns: 1fr; gap: var(--gap-3); align-items: start; }
@media (min-width: 922px) {
    .md-plp__grid { grid-template-columns: 220px minmax(0, 1fr); }
}

/* No celular o painel de filtro fica escondido até o botão "Filtrar"
   abrir. Quem alterna é `Filters.js`, e ele põe `.show` no `.filter` --
   não no `aside`. Escrevi `.is-open` no aside primeiro e o botão não fazia
   nada; é o tipo de coisa que só aparece lendo o módulo, e por isso o
   contrato precisa dizer QUAL elemento recebe a classe. */
.filter { display: none; }
.filter.show {
    display: block;
    position: fixed;
    inset: auto 0 0 0;
    max-height: 78vh;
    overflow-y: auto;
    z-index: var(--z-drawer);
    padding: 1.25rem var(--pad) 2rem;
    background: var(--bg);
    border-top: 1px solid var(--line-strong);
}
@media (min-width: 922px) {
    .filter { display: block; }
    .filter.show { position: static; max-height: none; padding: 0; background: none; border: 0; }
}

.filter-block { padding: 1.25rem 0; border-bottom: 1px solid var(--line); }
.filter-block:first-child { padding-top: 0; }
.filter-block h4,
.filter-trigger {
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    margin-bottom: .75rem;
}
/* O gatilho "Filtrar" do celular é um link -- media 74x14. Vira botão de
   fio com área de toque real. */
a.filter-trigger {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    min-height: 40px;
    padding: 0 1em;
    border: 1px solid var(--line-strong);
    margin-bottom: 0;
}
.md-filter__row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .55rem;
    padding: .28rem 0;
}
.md-filter__row label {
    display: flex;
    align-items: center;
    margin: 0;
    font-size: var(--step-0);
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink);
    cursor: pointer;
}
.md-filter__row .checked { display: none; }
.md-filter__row .count { font-size: var(--step--1); color: var(--ink-mute); }
.md-filter__row input:checked + label { font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
.md-filter__empty { font-size: var(--step--1); color: var(--ink-mute); }
.byprice .range-track { padding: .5rem 0; }
.price-range { display: flex; gap: .4rem; font-size: var(--step--1); color: var(--ink-mute); }

.md-plp__bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding-bottom: 1rem;
    margin-bottom: var(--gap-2);
    border-bottom: 1px solid var(--line);
}
.md-plp__chips { flex: 1; min-width: 0; }
.md-plp__chips #selectedFilters { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.md-plp__chips h4 { font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; color: var(--ink-mute); font-family: var(--font-ui); }
#selectedFiltersList { display: flex; gap: .4rem; flex-wrap: wrap; }
#selectedFiltersList > * {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    padding: .35em .7em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
}
.md-plp__sorts { display: flex; align-items: center; gap: 1.25rem; margin-left: auto; }
.item-sortir,
.item-perpage,
.item-options { position: relative; }
.item-sortir .label,
.item-perpage .label,
.item-options .label {
    display: inline-flex;
    align-items: center;
    gap: .35em;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    cursor: pointer;
    margin: 0;
    color: var(--ink);
}
.item-sortir ul,
.item-options ul {
    display: none;
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    min-width: 160px;
    background: var(--card);
    border: 1px solid var(--line);
    z-index: 20;
}
.item-sortir.open ul,
.item-options.open ul,
.item-sortir:hover ul,
.item-options:hover ul { display: block; }
.item-sortir li,
.item-options li { padding: .6rem .9rem; font-size: var(--step--1); cursor: pointer; }
.item-sortir li:hover,
.item-options li:hover,
.item-sortir li.active { background: var(--bg-sunk); }
.load-more { display: flex; justify-content: center; margin-top: var(--gap-3); }
/* A paginação da busca é montada por `ProductController::renderProductCards`:
   `.pagination > button.btn1 + ul > li.link/.ellipsis + button.btn2` -- não
   há `<a>` nenhum. As regras antigas (`.pagination li a`) não casavam com
   nada e a paginação saía como texto solto. */
.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    flex-wrap: wrap;
}
.pagination ul { display: flex; gap: .35rem; flex-wrap: wrap; justify-content: center; }
.pagination li.link,
.pagination li a,
.pagination li span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    border: 1px solid var(--line);
    font-size: var(--step--1);
    cursor: pointer;
    transition: background-color var(--fast), color var(--fast), border-color var(--fast);
}
.pagination li.ellipsis {
    display: inline-flex;
    align-items: flex-end;
    padding-bottom: .4rem;
    color: var(--ink-mute);
}
.pagination .btn1,
.pagination .btn2 {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    border: 1px solid var(--line-strong);
    font-size: 1.1rem;
    transition: background-color var(--fast), color var(--fast), border-color var(--fast);
}
.pagination li.active,
.pagination li.link:hover,
.pagination li.active a,
.pagination li a:hover,
.pagination .btn1:hover,
.pagination .btn2:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }

/* =================================================
 * 11. Carrinho
 * ================================================= */
.products.cart .flexwrap { display: grid; grid-template-columns: 1fr; gap: var(--gap-3); align-items: start; }
@media (min-width: 922px) {
    .products.cart .flexwrap { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}
/* **A tabela do carrinho é markup GERADO por JS compartilhado.**
   `features/cart/CartTable.js` monta `<tr>/<td>` e injeta em
   `#cart-table tbody` a cada mutação. Um tema não troca isso por lista de
   cards sem mexer no JS -- e mexer no JS mudaria o carrinho de todo tema.
   Então aqui o tema faz o que lhe cabe: estiliza. No celular as células
   viram blocos (`display: block` + rótulo por `::before`), que é como
   tabela de 5 colunas cabe numa tela de 390px sem rolagem lateral. */
#cart-table th {
    text-align: left;
    padding: 0 0 .75rem;
    border-bottom: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    font-weight: 500;
    color: var(--ink-mute);
}
#cart-table td { padding: 1.25rem 0; border-bottom: 1px solid var(--line); vertical-align: middle; }
#cart-table td.flexitem { display: flex; align-items: center; gap: 1rem; }
#cart-table .thumbnail { flex: 0 0 76px; width: 76px; aspect-ratio: 3/4; background: var(--bg-sunk); overflow: hidden; }
#cart-table .content strong { display: block; font-weight: 400; }
#cart-table .content p,
.item-unit-tag { font-size: var(--step--1); color: var(--ink-mute); }
.item-remove-grid { color: var(--ink-mute); font-size: 1.2rem; }
.item-remove-grid:hover { color: var(--err); }
.cart-empty { padding: 3rem 0; text-align: center; color: var(--ink-mute); }

@media (max-width: 767px) {
    #cart-table thead { display: none; }
    #cart-table tr {
        display: grid;
        grid-template-columns: 1fr auto;
        gap: .25rem 1rem;
        padding: 1.25rem 0;
        border-bottom: 1px solid var(--line);
    }
    #cart-table td { display: block; padding: 0; border: 0; }
    #cart-table td.flexitem { grid-column: 1 / -1; }
    #cart-table td:nth-child(2)::before { content: 'Unitário '; color: var(--ink-mute); }
    #cart-table td:nth-child(4)::before { content: 'Total '; color: var(--ink-mute); }
    #cart-table td:nth-child(3) { grid-column: 1; margin-top: .5rem; }
    #cart-table td:nth-child(5) { grid-row: 1; grid-column: 2; text-align: right; }
}
.cart-summary {
    padding: 1.5rem;
    background: var(--card);
    border: 1px solid var(--line);
}

/* --- Barra de frete grátis ---
   Aparece no topo do resumo do carrinho e dentro da gaveta do
   mini-carrinho (`--mini`), montada por scripts/themes/moda/carrinho.js e
   minicart-frete.js. Só desenho: quem sabe o mínimo é o servidor e quem
   sabe o subtotal são os módulos compartilhados de carrinho.

   No `moda` a barra segue a gramática do tema -- rótulo em versalete com
   tracking, canto reto, fio fino. A trilha é de 3px em vez dos 6px que um
   tema de raio arredondado usaria: aqui ela precisa ler como uma REGRA
   grossa, não como uma pílula. */
.md-frete { display: flex; flex-direction: column; gap: .55rem; margin-bottom: 1.5rem; }

.md-frete__texto {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
}

.md-frete__texto strong { color: var(--ink); font-weight: 600; }
.md-frete__texto i { font-size: 1.05rem; letter-spacing: 0; color: var(--ink); }
.md-frete--ganhou .md-frete__texto i,
.md-frete--ganhou .md-frete__texto strong { color: var(--ok); }

.md-frete__trilha { height: 3px; background: var(--bg-sunk); }

.md-frete__barra {
    display: block;
    height: 100%;
    width: 0;
    background: var(--ink);
    transition: width .5s var(--ease, ease);
}

.md-frete--ganhou .md-frete__barra { background: var(--ok); }

/* Na gaveta, a barra fica acima do subtotal com o fio separando do resto
   do rodapé. */
.md-frete--mini {
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line);
}

.coupon { display: flex; gap: .5rem; margin-bottom: 1.5rem; }
.coupon input { flex: 1; }
.coupon button { padding: 0 1.25rem; background: var(--ink); color: var(--bg); font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; }
.cart-total th { text-align: left; padding: .5rem 0; font-weight: 400; color: var(--ink-mute); }
.cart-total td { text-align: right; padding: .5rem 0; }
.cart-total .grand-total th,
.cart-total .grand-total td {
    padding-top: 1rem;
    border-top: 1px solid var(--line-strong);
    font-size: var(--step-1);
    color: var(--ink);
}
.cart-total .secondary-button { width: 100%; margin-top: 1.25rem; }
.cart-upsell { display: grid; grid-template-columns: 64px 1fr auto; gap: .75rem; align-items: center; margin-top: 1.5rem; padding: 1rem; border: 1px solid var(--line); }
.cart-upsell .thumbnail { aspect-ratio: 3/4; background: var(--bg-sunk); overflow: hidden; }
.shipping-rate { margin-bottom: 1.5rem; }
/* Respiro entre um campo e o rótulo do próximo -- "PAÍS" colava no select
   de cima. */
.shipping-rate label { margin-top: .9rem; }
/* `#calculateFreight` é um `<button>` sem classe nenhuma no partial
   compartilhado. Sem `style.css` por baixo ele renderiza como texto solto
   -- "Calcular Frete" parecia um parágrafo. Estilizar pelo id aqui é o
   caminho certo: mudar o markup do partial mexeria no clássico junto. */
#calculateFreight {
    width: 100%;
    margin-top: .75rem;
    padding: .95em 1.5em;
    background: var(--ink);
    color: var(--bg);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
#calculateFreight:hover { background: var(--ink-soft); }
.shipping-rate .has-child > a {
    display: block;
    padding: .9rem 0;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.rate-options label { display: flex; align-items: center; gap: .5rem; text-transform: none; letter-spacing: 0; color: var(--ink); }
.freight-error { color: var(--err); font-size: var(--step--1); }

/* Título e trilha das páginas internas: o clássico dava o respiro, e sem
   ele o H1 colava na trilha. */
.page-title { margin: .5rem 0 var(--gap-2); }
.page-title h1 { font-size: var(--step-3); }
.single-cart .breadcrumb,
.single-cart .page-title { padding-top: 0; }
.single-cart { padding-top: 1.5rem; }

/* =================================================
 * 12. Checkout
 * ================================================= */
.checkout { display: grid; grid-template-columns: 1fr; gap: var(--gap-3); align-items: start; }
@media (min-width: 922px) {
    .checkout { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
    .summary-order { position: sticky; top: 100px; }
}
.wizard-stepper { display: flex; align-items: center; gap: .5rem; margin-bottom: 2rem; }
.wz-step { display: flex; align-items: center; gap: .5rem; }
.wz-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    font-size: var(--step--1);
}
/* O dígito do passo fica SEMPRE visível: até 2026-08-10 o `Wizard.js`
   apagava o número do passo concluído (o clássico desenha um `✓` por
   `::before` e os dois se sobreporiam), e este tema, que não tem `✓`,
   ficava com o círculo cheio e vazio — na tela do Pix, onde os três
   passos ficam concluídos, o cabeçalho inteiro sem número. Agora o
   apagamento saiu do módulo e quem separa "atual" de "concluído" é o
   anel abaixo. */
.wz-step.active .wz-dot { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.wz-step.active .wz-dot { box-shadow: 0 0 0 3px rgba(17, 17, 17, .16); }
.wz-label { font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; }
.wz-line { flex: 1; height: 1px; background: var(--line-strong); }
.wizard-pane { display: none; }
.wizard-pane.on { display: block; }
.wizard-pane h1 { font-size: var(--step-2); margin-bottom: .5rem; }
.wz-sub { color: var(--ink-mute); margin-bottom: 1.5rem; }
.wizard-actions { display: flex; gap: .75rem; margin-top: 2rem; }
.wz-full { width: 100%; }

.addr-card,
.pay-item,
.benefits-box,
.summary-order,
.card-inline-form,
.pix-inline,
.guest-register {
    border: 1px solid var(--line);
    background: var(--card);
}
.guest-register,
.benefits-box,
.card-inline-form,
.pix-inline { padding: 1.5rem; }
.guest-register-hint { margin-bottom: 1.25rem; color: var(--ink-mute); }
.guest-register-login { margin-top: 1rem; font-size: var(--step--1); }
.guest-register-login a { display: inline-flex; align-items: center; min-height: 28px; box-shadow: inset 0 -1px 0 currentColor; }
.guest-register .form-grid { margin-bottom: 1.25rem; }
.address-cards { display: grid; gap: .75rem; }
.addr-card { padding: 1rem; cursor: pointer; }
/* `.selected` é a classe que o AddressInline.js realmente aplica (o
   `.active` ficou por leitura errada do módulo -- armadilha §6.5). Os dois
   entram: custa uma linha e cobre regressão de nome. */
.addr-card.active,
.addr-card.selected,
.pay-item.on,
.address-option.active,
.address-option.selected { border-color: var(--ink); background: var(--bg-sunk); }

/* --- Cartão de endereço: ícone | texto | lápis, numa linha. ---
   O markup é `i.option-icon + .option-body + button.option-edit`; sem
   grade o ícone flutuava em cima, o lápis caía embaixo e o texto ficava
   espremido entre os dois. */
.addr-card {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: center;
    transition: border-color var(--fast), background-color var(--fast);
}
.addr-card:hover { border-color: var(--line-strong); }
.addr-card .option-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: var(--bg-sunk);
    font-size: 1.15rem;
    color: var(--ink-soft);
}
.addr-card .option-body {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}
.addr-card .option-body strong { font-weight: 600; }
.addr-card .option-body > span { color: var(--ink-soft); overflow-wrap: anywhere; }
.addr-card .option-tag {
    font-size: var(--step--1);
    font-weight: 400;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-left: .35em;
}
.addr-card .option-edit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--line);
    color: var(--ink-soft);
    transition: border-color var(--fast), color var(--fast);
}
.addr-card .option-edit:hover { border-color: var(--ink); color: var(--ink); }

.addr-add {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    min-height: 42px;
    margin-top: .75rem;
    padding: 0 1.25em;
    border: 1px solid var(--ink);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    transition: background-color var(--fast), color var(--fast);
}
.addr-add:hover { background: var(--ink); color: #fff; }
.empty-address {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1.5rem;
    border: 1px dashed var(--line-strong);
    color: var(--ink-mute);
}
/* Formulário inline de endereço do checkout (AddressInline.js mostra ao
   clicar em "Adicionar novo endereço"). */
.addr-inline-form {
    margin-top: 1rem;
    padding: 1.5rem;
    border: 1px solid var(--line);
    background: var(--card);
}
.addr-inline-form h3 { margin-bottom: 1rem; }
.addr-cep-row { display: flex; gap: .5rem; }
.addr-cep-row input { flex: 1; }
.addr-cep-row button { width: 46px; flex: none; padding: 0; }
.form-field label { margin-bottom: .4em; }

/* --- Modo de envio: linhas selecionáveis, logo CONTIDO. ---
   `FreightCalculator.js` monta `.freight-pills > .freight-pill` com a
   logomarca da transportadora em `img.option-icon-img`. Sem regra a
   imagem assumia o tamanho natural do arquivo -- o BUSLOG abria na
   largura da coluna inteira e a lista virava um mural de logotipos. A
   logo aqui é ícone: caixa fixa, `object-fit: contain`. */
#shipping-method { margin-top: var(--gap-2); }
#shipping-method h2 {
    font-size: var(--step-1);
    padding-bottom: .75rem;
    margin-bottom: .75rem;
    border-bottom: 1px solid var(--line);
}
.freight-pills { display: grid; gap: .5rem; }
.freight-pill {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: center;
    padding: .85rem 1rem;
    border: 1px solid var(--line);
    background: var(--card);
    cursor: pointer;
    transition: border-color var(--fast), background-color var(--fast);
}
.freight-pill:hover { border-color: var(--line-strong); }
.freight-pill.selected { border-color: var(--ink); background: var(--bg-sunk); }
.freight-pill .option-icon-img {
    width: 56px;
    height: 28px;
    object-fit: contain;
    object-position: left center;
}
.freight-pill .option-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 28px;
    font-size: 1.25rem;
    color: var(--ink-soft);
}
.freight-pill .option-body {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}
.freight-pill .option-body strong { font-weight: 600; font-size: var(--step-0); }
.freight-pill .option-body span { font-size: var(--step--1); color: var(--ink-mute); }
.freight-pill .option-price { font-weight: 600; white-space: nowrap; }
.freight-pill .option-price.free { color: var(--ok); }
.freight-error {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--line);
    color: var(--err);
    font-size: var(--step-0);
}

/* --- Resumo do pedido: item com miniatura, não com pôster. ---
   A lista é `ul.products.mini` -- mesma anatomia do mini-carrinho, mas
   fora dele o seletor `.mini-cart .products.mini` não alcançava e a foto
   do produto abria na largura da coluna. */
.summary-order .products.mini { margin-top: 1.25rem; border-top: 1px solid var(--line); }
.summary-order .products.mini li {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr);
    gap: .85rem;
    align-items: center;
    padding: .85rem 0;
}
.summary-order .products.mini li + li { border-top: 1px solid var(--line); }
.summary-order .products.mini .thumbnail {
    width: 48px;
    aspect-ratio: 3 / 4;
    background: var(--bg-sunk);
    overflow: hidden;
}
.summary-order .products.mini .item-content p { font-size: var(--step--1); line-height: 1.35; }
.summary-order .products.mini .price {
    display: flex;
    gap: .5rem;
    font-size: var(--step--1);
    color: var(--ink-mute);
    margin-top: .25rem;
}

/* Linha de frete dos totais -- o FreightCalculator injeta a logo da
   transportadora escolhida ali também. */
.summary-shipping-label { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.summary-carrier { display: inline-flex; align-items: center; gap: .45rem; }
.summary-carrier-logo { max-height: 18px; max-width: 48px; object-fit: contain; }
.summary-carrier-info b { font-weight: 500; }
.summary-carrier-info em { font-style: normal; color: var(--ink-mute); margin-left: .35em; }

/* Benefícios (cashback/fidelidade) no resumo. */
.benefits-box { margin-bottom: 1.25rem; }
.benefits-box h3 {
    display: flex;
    align-items: center;
    gap: .5em;
    font-size: var(--step-0);
    margin-bottom: .75rem;
}
.benefit-toggle {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .5rem 0;
    font-size: var(--step-0);
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink);
    cursor: pointer;
}
.benefit-toggle input { width: auto; margin-top: .25em; accent-color: var(--primary-color); }
.benefit-toggle small { display: block; color: var(--ink-mute); }
/* --- Pagamento: acordeão de métodos. ---
   `PaymentAccordion.js` aplica `.selected` no `.pay-item` (não `.on` --
   armadilha §6.5; o `.on` fica de cinto e suspensório). O cabeçalho é
   `ico | texto | selo | seta`; sem a grade, o `<strong>` e o `<small>`
   inline saíam colados ("PixAprovação na hora"). */
.pay-accordion { display: grid; gap: .5rem; }
.pay-head {
    display: flex;
    align-items: center;
    gap: .85rem;
    width: 100%;
    padding: 1rem 1.1rem;
    cursor: pointer;
    text-align: left;
}
.pay-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: none;
    background: var(--bg-sunk);
    font-size: 1.2rem;
    color: var(--ink-soft);
}
.pay-txt {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
    flex: 1;
}
.pay-txt strong { font-weight: 600; }
.pay-txt small { font-size: var(--step--1); color: var(--ink-mute); }
.pay-badge {
    flex: none;
    padding: .3em .7em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: .04em;
    color: var(--ink-soft);
    white-space: nowrap;
}
.pay-arrow {
    flex: none;
    font-size: 1.2rem;
    color: var(--ink-mute);
    transition: transform var(--fast);
}
.pay-item {
    border: 1px solid var(--line);
    background: var(--card);
    transition: border-color var(--fast);
}
.pay-item:hover { border-color: var(--line-strong); }
.pay-item.selected,
.pay-item.on { border-color: var(--ink); }
.pay-item.selected .pay-arrow,
.pay-item.on .pay-arrow { transform: rotate(90deg); }
.pay-body { display: none; padding: 0 1.1rem 1.25rem; }
.pay-item.selected .pay-body,
.pay-item.on .pay-body { display: block; animation: md-rise .3s var(--ease); }
.pay-hint {
    display: flex;
    align-items: flex-start;
    gap: .5em;
    font-size: var(--step--1);
    color: var(--ink-mute);
    margin-top: .75rem;
}

/* Alternador crédito/débito (`CardPayment.js` alterna `.active`). */
.card-type-toggle {
    display: inline-flex;
    border: 1px solid var(--line-strong);
    margin-bottom: 1.25rem;
}
.card-type-option {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    min-height: 42px;
    padding: 0 1.25em;
    font-size: var(--step--1);
    letter-spacing: .04em;
    color: var(--ink-soft);
    transition: background-color var(--fast), color var(--fast);
}
.card-type-option.active { background: var(--ink); color: var(--bg); }

/* Caixas onde o SDK do Mercado Pago injeta os iframes de campo -- sem
   altura e borda elas somem e o formulário parece faltar pedaço. */
.container-checkout {
    height: 46px;
    padding: 0 .5em;
    background: var(--card);
    border: 1px solid var(--line);
}
/* O SDK do Mercado Pago injeta um <iframe> dentro da caixa; sem regra ele
   assume os 150px padrão de iframe e cada campo virava um painel. */
.container-checkout iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}
.card-inline-form { border: 0; padding: 0; }
.card-inline-form .progress-bar { width: 100%; margin-top: 1rem; }

/* Revisão do CHECKOUT: rótulo | valor por linha.
 *
 * Escopado em `.wizard-pane` de propósito. `.review-block` é nome de classe
 * REPETIDO no projeto: além destes quatro resumos, é também o contêiner do
 * bloco "Avaliações de clientes" da página de produto
 * (views/partials/product/details.php). Sem o escopo, esta regra — que vem
 * depois no arquivo — vencia lá também e espremia as avaliações numa coluna
 * de 110px: a nota "5.0" quebrava em três linhas e o aviso de login virava
 * uma tira de uma palavra por linha (relatado com print, 2026-08-11). */
.wizard-pane .review-block {
    display: grid;
    grid-template-columns: 110px minmax(0, 1fr);
    gap: 1rem;
    padding: .9rem 0;
    border-bottom: 1px solid var(--line);
}
.wizard-pane .review-block b { font-weight: 600; }
.wizard-pane .review-block span { color: var(--ink-soft); overflow-wrap: anywhere; }

/* Stepper: passo concluído e linha percorrida ficam de tinta. */
.wz-step.done .wz-dot { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.wz-line.done { background: var(--ink); }
.summary-order { padding: 1.5rem; }
.summary-totals li { display: flex; justify-content: space-between; padding: .4rem 0; }
.summary-totals li:last-child { padding-top: 1rem; margin-top: .5rem; border-top: 1px solid var(--line-strong); font-size: var(--step-1); }
/* Duas colunas fixas a partir de 640px, não `auto-fit`. Com `auto-fit` numa
   coluna de 970px o formulário abria quatro campos por linha e "Primeiro
   nome" ficava do tamanho de "Nº" -- a largura do campo deixa de sugerir
   o tamanho do que se digita nele. */
.form-grid { display: grid; grid-template-columns: 1fr; gap: 1rem 1.25rem; }
@media (min-width: 640px) {
    .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.span-2 { grid-column: span 2; }
.pix-qr { max-width: 260px; margin: 0 auto 1rem; }
/* `#qrCodeImage` nasce com `src=""` e só é preenchido quando o cliente
   escolhe Pix -- até lá o navegador desenha o ícone de imagem quebrada.
   Escondo enquanto está vazia; o markup é compartilhado e mudá-lo mexeria
   no clássico junto. */
.pix-qr img[src=""] { visibility: hidden; }

/* --- Overlay do "Concluir compra" (#loader1). ---
   O markup existe em pages/checkout.php e o `CheckoutForm.finalizarCompra`
   liga com `display: flex` enquanto o pedido é criado na API -- mas o
   estilo morava só no style.css do clássico. Aqui ele era INVISÍVEL: o
   cliente clicava, nada na tela mudava por segundos, e a compra parecia
   travada. Véu claro, barra de progresso indeterminada e texto dizendo o
   que está acontecendo -- os textos vêm por pseudo-elemento de propósito,
   pra não mexer no markup compartilhado (o clássico tem o desenho dele). */
#loader1 {
    position: fixed;
    inset: 0;
    z-index: 6000;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    padding: 2rem;
    background: rgba(255, 255, 255, .93);
    text-align: center;
}
#loader1::before {
    content: 'Criando seu pedido…';
    font-family: var(--font-display);
    font-size: var(--step-2);
    font-weight: 700;
    font-stretch: 108%;
    letter-spacing: -.025em;
    color: var(--ink);
}
#loader1::after {
    content: 'Estamos confirmando os itens e preparando o pagamento. Leva só alguns segundos — não feche a página.';
    max-width: 42ch;
    font-size: var(--step-0);
    line-height: 1.55;
    color: var(--ink-soft);
}
/* O círculo do clássico vira barra de progresso indeterminada. */
.loader-circle1 {
    position: relative;
    width: min(320px, 70vw);
    height: 3px;
    background: var(--line);
    overflow: hidden;
    order: 1;
}
#loader1::after { order: 2; }
.loader-circle1::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 40%;
    background: var(--ink);
    animation: md-progress 1.2s var(--ease) infinite;
}
@keyframes md-progress {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* --- Copia-e-cola do Pix (`form.pix-copy`) e a espera da confirmação. ---
   O form reaproveita a classe `.search`, que neste tema não tem regra
   solta -- o código saía num input cru com "Copiar" como texto solto. */
.pix-inline { text-align: center; }
.pix-inline .wz-sub { margin-inline: auto; max-width: 52ch; }
.pix-qr { border: 1px solid var(--line); padding: .75rem; background: #fff; }
.pix-copy {
    display: flex;
    align-items: stretch;
    gap: 0;
    max-width: 480px;
    margin: 1.5rem auto 0;
    text-align: left;
}
.pix-copy .icon-large {
    display: inline-flex;
    align-items: center;
    padding: 0 .8rem;
    border: 1px solid var(--line);
    border-right: 0;
    background: var(--bg-sunk);
    color: var(--ink-mute);
    font-size: 1.1rem;
}
.pix-copy input {
    flex: 1;
    min-width: 0;
    border: 1px solid var(--line);
    padding: .8em .9em;
    font-size: var(--step--1);
    font-variant-ligatures: none;
    text-overflow: ellipsis;
    color: var(--ink-soft);
}
.pix-copy input:focus { border-color: var(--ink); }
.pix-copy button {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: .5em;
    padding: 0 1.5em;
    background: var(--primary-color);
    border: 1px solid var(--primary-color);
    color: var(--on-primary, #fff);
    font-size: var(--step--1);
    font-weight: 500;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    white-space: nowrap;
    transition: background-color var(--fast), color var(--fast);
}
.pix-copy button:hover { background: transparent; color: var(--primary-color); }
.pix-waiting {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    margin-top: 1.5rem;
    font-size: var(--step--1);
    color: var(--ink-mute);
}
.pix-spinner {
    width: 16px;
    height: 16px;
    flex: none;
    border: 2px solid var(--line);
    border-top-color: var(--ink);
    border-radius: 50%;
    animation: md-spin 1s linear infinite;
}
@keyframes md-spin {
    to { transform: rotate(360deg); }
}
.item-remove,
.item-remove-grid { min-width: 32px; min-height: 32px; display: inline-flex; align-items: center; justify-content: center; }
.card-status { padding: 2rem; text-align: center; }

/* =================================================
 * 13. Conta
 * ================================================= */
.profile-header { padding: var(--gap-3) 0; border-bottom: 1px solid var(--line); }
.profile-content { display: grid; grid-template-columns: 1fr; gap: var(--gap-3); padding: var(--gap-3) 0; align-items: start; }
@media (min-width: 922px) {
    .profile-content { grid-template-columns: 240px minmax(0, 1fr); }
}
.nav-menu li + li { margin-top: .25rem; }
.nav-menu a {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .7rem .9rem;
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    border: 1px solid transparent;
}
.nav-menu a.active,
.nav-menu a:hover { border-color: var(--line); background: var(--card); }
.profile-header { display: flex; flex-wrap: wrap; gap: var(--gap-2); align-items: center; justify-content: space-between; }
.profile-info { display: flex; align-items: center; gap: 1rem; }
.profile-image { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; background: var(--bg-sunk); }
.profile-details h1 { font-size: var(--step-2); }
.profile-details p { color: var(--ink-mute); }
.identity-chips { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: .5rem; }
.identity-chips .chip { display: inline-flex; align-items: center; gap: .35em; font-size: var(--step--1); color: var(--ink-mute); }
.profile-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.profile-actions a,
.profile-actions button {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    min-height: 40px;
    padding: 0 1.1em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
}
.profile-actions a:hover,
.profile-actions button:hover { border-color: var(--ink); }

.wallet-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .75rem; margin-top: var(--gap-2); }
/* Os três textos do cartão (`small`/`b`/`em`) são inline no markup
   compartilhado -- sem `display:block` eles saíam grudados
   ("Cashback disponívelR$ 42,50usar no próximo pedido"). O partial é do
   clássico; quem separa aqui é o tema. */
.wallet-card {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: 1rem;
    border: 1px solid var(--line);
    background: var(--card);
    text-align: left;
    transition: border-color var(--fast);
}
.wallet-card:hover { border-color: var(--ink); }
.wallet-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: none;
    background: var(--bg-sunk);
    font-size: 1.1rem;
}
.wallet-card small,
.wallet-card b,
.wallet-card em { display: block; }
.wallet-card small { font-size: var(--step--1); color: var(--ink-mute); }
.wallet-card b { font-size: var(--step-1); font-weight: 600; line-height: 1.2; }
.wallet-card em { font-size: var(--step--1); font-style: normal; color: var(--ink-mute); }
.overview-panel,
.address-card,
.order-card,
.referral-panel { padding: 1.5rem; border: 1px solid var(--line); background: var(--card); margin-bottom: 1rem; }
.overview-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 1rem;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid var(--line);
}
.overview-head h2 { font-size: var(--step-1); }

/* "Editar" é ação secundária ao lado do título do painel -- com o
   tratamento de botão primário (preto, sólido, caixa alta grande) ela
   competia com o título e virava a coisa mais forte do painel. */
.overview-head .btn,
.overview-head .btn-secondary {
    padding: .55em 1em;
    background: transparent;
    color: var(--ink);
    border-color: var(--line-strong);
    font-size: var(--step--1);
}
.overview-head .btn:hover { background: var(--ink); color: #fff; border-color: var(--ink); }

/* `dl` de dados: rótulo e valor lado a lado, pares separados por fio. O
   markup é `div > dt + dd`, então a linha é a `div`. */
.facts { display: grid; gap: 0; }
.facts > div {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: 1rem;
    padding: .7rem 0;
    border-bottom: 1px solid var(--line);
}
.facts > div:last-child { border-bottom: 0; }
.facts dt { color: var(--ink-mute); font-size: var(--step--1); }
.facts dd { display: flex; align-items: center; gap: .4em; }
.facts-ok { color: var(--ok); }

.overview-addresses,
.overview-orders { display: grid; gap: .75rem; }
.form-actions { margin-top: 1.5rem; }
.form-group { margin-bottom: 1rem; }
.form-group-full { grid-column: 1 / -1; }
.form-subgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; grid-column: 1 / -1; }

/* --- Listas geradas por JS dentro da conta ---
   `features/profile/index.js` e `AddressModal.js` montam estes itens em
   runtime, com classes próprias. Nada disso aparece na bancada de render
   (que não tem sessão nem API), e nada disso existia no theme.css: pedido,
   endereço e favorito saíam empilhados sem card e sem espaçamento. É o
   tipo de buraco que só a tela real, logada e com dado, revela. */

.order-item,
.address-item,
.favorite-item {
    display: grid;
    gap: 1rem;
    align-items: center;
    padding: 1.25rem;
    border: 1px solid var(--line);
    background: var(--card);
    transition: border-color var(--fast);
}
.order-item + .order-item,
.address-item + .address-item,
.favorite-item + .favorite-item { margin-top: .75rem; }
.order-item:hover,
.address-item:hover,
.favorite-item:hover { border-color: var(--line-strong); }

/* Pedido: identificação, estado e valor. Três colunas no desktop porque a
   comparação entre pedidos se faz na vertical -- valores alinhados numa
   coluna se leem de relance; empilhados, não. */
.order-item { grid-template-columns: 1fr; }
@media (min-width: 768px) {
    .order-item { grid-template-columns: minmax(0, 1fr) auto auto; gap: 1.5rem; }
}
.order-info h3 { font-size: var(--step-0); font-stretch: 100%; letter-spacing: 0; margin-bottom: .3rem; }
.order-meta { display: flex; flex-wrap: wrap; gap: 1rem; font-size: var(--step--1); color: var(--ink-mute); }
.order-meta span { display: inline-flex; align-items: center; gap: .35em; }
.order-amount { font-size: var(--step-1); font-weight: 600; white-space: nowrap; }
.order-actions { display: flex; align-items: center; gap: 1rem; }
@media (min-width: 768px) {
    .order-actions { justify-content: flex-end; }
}

/* Estado do pedido como pastilha de fio, não de preenchimento: são até
   cinco estados numa lista longa, e cinco blocos sólidos coloridos
   competiriam com o valor, que é o que a pessoa procura. */
.order-status {
    justify-self: start;
    padding: .3em .75em;
    border: 1px solid currentColor;
    font-size: var(--step--1);
    letter-spacing: .04em;
    white-space: nowrap;
    color: var(--ink-soft);
}
.status-pending    { color: var(--warn); }
.status-processing { color: var(--ink-soft); }
.status-shipping   { color: var(--ink); }
.status-delivered  { color: var(--ok); }
.status-canceled,
.status-cancelled  { color: var(--err); }

/* Endereço: o texto é `strong` + `<br>` cru vindo do JS, então quem dá o
   ritmo é o `line-height`. O `strong` fica INLINE de propósito -- com
   `display: block` ele soma com o `<br>` que vem logo depois e abre uma
   linha vazia no meio do endereço. */
.address-item { grid-template-columns: minmax(0, 1fr) auto; }
.address-item-content { line-height: 1.6; font-size: var(--step-0); }
.address-item-content strong { font-weight: 600; }
.address-item-actions { display: flex; gap: .5rem; }
/* Os botões vêm com ícone E texto do JS ("✎ Editar"). Fixar 38x38 fazia o
   rótulo vazar por cima do card vizinho -- largura automática, e o mínimo
   só garante a área de toque. */
.address-item-actions button {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    min-height: 38px;
    padding: 0 .9em;
    border: 1px solid var(--line);
    color: var(--ink-soft);
    font-size: var(--step--1);
    letter-spacing: .04em;
    white-space: nowrap;
    transition: border-color var(--fast), color var(--fast);
}
.address-item-actions button:hover { border-color: var(--ink); color: var(--ink); }
.address-item-actions .delete:hover { border-color: var(--err); color: var(--err); }

#addAddressBtn {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    min-height: 42px;
    margin-bottom: 1.25rem;
    padding: 0 1.25em;
    border: 1px solid var(--ink);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    transition: background-color var(--fast), color var(--fast);
}
#addAddressBtn:hover { background: var(--ink); color: #fff; }

/* Favorito: a foto manda, como no resto do tema. */
.favorite-item { grid-template-columns: 72px minmax(0, 1fr) auto; }
.favorite-item img { width: 72px; aspect-ratio: 3 / 4; object-fit: cover; background: var(--bg-sunk); }
.favorite-info h3 { font-size: var(--step-0); font-stretch: 100%; letter-spacing: 0; }
.favorite-price { font-size: var(--step-1); font-weight: 600; margin-top: .2rem; }
.favorite-stock-warning { font-size: var(--step--1); color: var(--err); margin-top: .2rem; }

/* Paginação das seções: os botões vêm sem classe do JS, então o seletor é
   pelo contêiner. */
#paginationControls,
.favorites-list + .pagination,
#favoritesSection .pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1.5rem;
}
#paginationControls button,
#favoritesSection .pagination button,
.page-btn {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    min-height: 38px;
    padding: 0 1em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: .04em;
    transition: border-color var(--fast), background-color var(--fast), color var(--fast);
}
#paginationControls button:hover:not(:disabled),
#favoritesSection .pagination button:hover:not(:disabled),
.page-btn:hover:not(:disabled) { background: var(--ink); border-color: var(--ink); color: #fff; }
#paginationControls button:disabled,
.page-btn:disabled { opacity: .4; cursor: not-allowed; }
#pageIndicatorOrders,
#pageIndicatorFavorites { font-size: var(--step--1); color: var(--ink-mute); }

/* Formulário de endereço -- clonado do `<template>` para dentro do modal
   compartilhado (`core/Modal.js`). */
.address-form-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.address-form-body .form-group { margin-bottom: 0; }
.address-form-body .form-group-full { grid-column: 1 / -1; }
.cep-group { display: flex; gap: .5rem; }
.cep-group input { flex: 1; }
.cep-group button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    flex: none;
    border: 1px solid var(--line);
    color: var(--ink);
}
.cep-group button:hover { border-color: var(--ink); background: var(--ink); color: #fff; }
.form-group-inline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.form-group-inline label { margin: 0; }

/* Interruptor: `input` escondido, `.slider` é o desenho. */
.switch { position: relative; display: inline-flex; width: 44px; height: 24px; flex: none; margin: 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .slider {
    position: absolute;
    inset: 0;
    background: var(--line-strong);
    border-radius: 999px;
    transition: background-color var(--fast);
}
.switch .slider::before {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    background: #fff;
    border-radius: 50%;
    transition: transform var(--fast);
}
.switch input:checked + .slider { background: var(--primary-color); }
.switch input:checked + .slider::before { transform: translateX(20px); }
.switch input:focus-visible + .slider { outline: 2px solid var(--ink); outline-offset: 2px; }

.empty-state {
    padding: 2.5rem 1.25rem;
    border: 1px dashed var(--line-strong);
    text-align: center;
    color: var(--ink-mute);
}
#accountSection h2,
#addressesSection h2,
#ordersSection h2,
#favoritesSection h2,
#referralSection h2 { font-size: var(--step-2); margin-bottom: 1.25rem; }

/* =================================================
 * 13b. Entrar / criar conta
 * -------------------------------------------------
 * `login.php` não carrega o `style.css` nem o `style-login.css` (ver
 * theme-assets.php), então TODO o estilo desta tela sai daqui. Antes desta
 * seção existir, a página renderizava crua: título colado no topo, campos
 * de largura total e o "Entrar" como texto, porque o reset zera `button`.
 * ================================================= */
.md-auth {
    display: grid;
    grid-template-columns: 1fr;
    min-height: 100vh;
}
@media (min-width: 922px) {
    .md-auth { grid-template-columns: 1.1fr 1fr; }
    .md-auth--sem-capa { grid-template-columns: 1fr; }
}

.md-auth__capa {
    display: none;
    position: relative;
    background: var(--bg-sunk);
}
@media (min-width: 922px) {
    .md-auth__capa { display: block; }
}
.md-auth__capa img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 35%;
}
.md-auth__frase {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 6rem 3rem 3rem;
    font-family: var(--font-display);
    font-size: var(--step-3);
    font-weight: 700;
    font-stretch: 108%;
    letter-spacing: -.025em;
    line-height: 1.05;
    color: #fff;
    background: linear-gradient(to top, rgba(0, 0, 0, .6), rgba(0, 0, 0, 0));
}

.md-auth__painel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--gap-3) var(--pad);
}
/* 30rem e não `max-width: 100%`: campo de formulário largo demais é mais
   difícil de ler e de mirar, e esta coluna tem metade da tela sobrando. */
.md-auth__caixa { width: min(30rem, 100%); }

.md-auth__marca {
    display: inline-flex;
    align-items: center;
    margin-bottom: var(--gap-3);
}
.md-auth__marca img { max-height: 32px; width: auto; }
.md-auth__marca span { font-family: var(--font-display); font-weight: 700; font-size: var(--step-2); }

.md-auth h1 { font-size: var(--step-3); margin-bottom: var(--gap-2); }
.md-auth .form-group { margin-bottom: 1.1rem; }
.md-auth__esqueci { margin: -.35rem 0 1.5rem; }
.md-auth__esqueci a,
.md-auth__alternar a {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    font-size: var(--step--1);
    box-shadow: inset 0 -1px 0 currentColor;
}
.md-auth__alternar {
    margin-top: 1rem;
    font-size: var(--step--1);
    color: var(--ink-mute);
}
.md-auth__alternar a { color: var(--ink); margin-left: .35em; }

/* =================================================
 * 13c. Informações da empresa
 * -------------------------------------------------
 * Página institucional (`enterprise-info.php`). O markup é compartilhado
 * (`views/pages/enterprise-info.php`) e as classes vinham do style.css do
 * clássico -- sem regra aqui a ficha renderizava crua: ícones soltos,
 * rótulo e valor na mesma linha, mapa do tamanho de um selo.
 * ================================================= */
.enterprise-info-box {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--gap-2);
    align-items: stretch;
    margin-bottom: var(--gap-4);
}
@media (min-width: 922px) {
    .enterprise-info-box { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
    .enterprise-info-box.no-map { grid-template-columns: minmax(0, 760px); }
}
.info-section,
.map-section {
    border: 1px solid var(--line);
    background: var(--card);
    display: flex;
    flex-direction: column;
}
.info-section-head,
.map-head {
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--line);
}
.info-section-head h3,
.map-head h3 {
    display: flex;
    align-items: center;
    gap: .6em;
    font-size: var(--step-1);
}
.info-section-head i,
.map-head i { color: var(--ink-mute); }
.company-info-list { padding: .5rem 1.5rem; }
.company-info-list li {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr);
    gap: 1rem;
    align-items: center;
    padding: .9rem 0;
}
.company-info-list li + li { border-top: 1px solid var(--line); }
.info-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: var(--bg-sunk);
    font-size: 1.15rem;
    color: var(--ink-soft);
}
.info-content {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}
.info-content strong {
    font-size: var(--step--1);
    font-weight: 500;
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    color: var(--ink-mute);
}
.info-content span { overflow-wrap: anywhere; }
.info-content a { display: inline-flex; align-items: center; min-height: 28px; }
.info-content a:hover { text-decoration: underline; text-underline-offset: 3px; }
.status-badge {
    align-self: flex-start;
    padding: .25em .75em;
    border: 1px solid currentColor;
    font-size: var(--step--1);
    letter-spacing: .04em;
}
.status-badge.active { color: var(--ok); }
.status-badge.inactive { color: var(--err); }
/* O iframe do mapa preenche a seção; `min-height` garante mapa útil mesmo
   quando a ficha ao lado é curta. */
.map-frame { flex: 1; min-height: 340px; }
.map-frame iframe {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 340px;
}

/* =================================================
 * 14. Rodapé e barra inferior
 * ================================================= */
.newsletter { background: var(--secondary-dark-color); color: var(--on-brand); padding: var(--gap-3) 0; }
.newsletter .box { display: grid; gap: 1.5rem; align-items: center; }
@media (min-width: 768px) {
    .newsletter .box { grid-template-columns: 1fr auto; }
}
.newsletter h3 { font-size: var(--step-2); color: var(--on-brand); }
.newsletter p { color: var(--on-brand); opacity: .75; }
.newsletter form { display: flex; min-width: min(420px, 100%); }
.newsletter .icon-large { display: none; }
.newsletter input { border-color: transparent; }
.newsletter button { padding: 0 1.5rem; background: var(--on-brand); color: var(--secondary-dark-color); font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; }

.widgets { padding: var(--gap-3) 0; }
.widgets .flexwrap { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--gap-2); }
.widgets h4 { font-family: var(--font-ui); font-size: var(--step--1); letter-spacing: var(--tracking); text-transform: uppercase; color: var(--ink-mute); margin-bottom: .9rem; }
/* Lista de link do rodapé: `inline-flex` com altura mínima em vez de
   margem entre itens -- a área clicável passa a ser a linha inteira, e a
   auditoria de alvo parava de acusar 21px de altura em toda página. */
.widgets li a {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    color: var(--ink-soft);
}
.widgets a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

.footer-info { padding: var(--gap-2) 0 calc(6rem + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.footer-info .wrapper { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; }
.footer-info .logo img { max-height: 30px; width: auto; }
.socials ul { display: flex; gap: 1rem; font-size: 1.2rem; }
@media (min-width: 922px) {
    .footer-info { padding-bottom: var(--gap-2); }
}

/* Barra inferior do celular. Fica fora do fluxo, então o rodapé reserva
   espaço acima (o `padding-bottom: 6rem` do .footer-info). */
.menu-bottom {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-header);
    display: flex;
    background: var(--bg);
    border-top: 1px solid var(--line);
}
/* O flex tem que estar no `ul`: o filho direto do `nav.menu-bottom` é a
   lista, não os `li`. Sem esta regra os cinco destinos empilhavam na
   vertical e a barra "fixa" virava um painel cobrindo meia tela. */
.menu-bottom ul {
    display: flex;
    width: 100%;
}
.menu-bottom li { flex: 1; }
.menu-bottom a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: .55rem 0 .7rem;
    font-size: 10px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ink-soft);
}
.menu-bottom i { font-size: 1.25rem; }
/* O contador da sacola: o `.item-number` global é absoluto e ancora no
   ancestral posicionado -- sem isto ele fugia pro canto da barra inteira.
   Ancorado no `a` e deslocado pra junto do ícone. */
.menu-bottom a { position: relative; }
.menu-bottom .fly-item .item-number {
    top: 2px;
    right: auto;
    left: calc(50% + 6px);
}
@media (min-width: 922px) {
    .menu-bottom { display: none; }
}

/* =================================================
 * 15. Componentes compartilhados
 * ================================================= */
#preloader {
    position: fixed;
    inset: 0;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg);
}

.skeleton {
    background: linear-gradient(90deg, var(--bg-sunk) 25%, var(--line) 37%, var(--bg-sunk) 63%);
    background-size: 400% 100%;
    animation: md-shimmer 1.4s ease infinite;
}
.skeleton-card { aspect-ratio: 3 / 4; }
/* O JS da conta usa `.skeleton-card` também nas LISTAS (pedidos, endereços,
   favoritos) -- lá a proporção 3/4 vira um bloco de coluna inteira. Nesses
   contêineres o placeholder tem a altura do item que vai chegar. */
#ordersList .skeleton-card,
#addressList .skeleton-card,
#address-select .skeleton-card { aspect-ratio: auto; height: 92px; }
#favoritesList .skeleton-card { aspect-ratio: auto; height: 108px; }
#ordersList .skeleton-card + .skeleton-card,
#addressList .skeleton-card + .skeleton-card,
#address-select .skeleton-card + .skeleton-card,
#favoritesList .skeleton-card + .skeleton-card { margin-top: .75rem; }
/* `FreightCalculator` injeta `.skeleton-freight` enquanto a API responde --
   a classe não existia e o "carregando" era invisível. */
.skeleton-freight { height: 44px; }
.skeleton-freight + .skeleton-freight { margin-top: .5rem; }
@keyframes md-shimmer {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

.toast-stack { position: fixed; top: 1rem; right: 1rem; z-index: 3000; display: grid; gap: .5rem; }
.toast { padding: .9rem 1.1rem; background: var(--ink); color: var(--bg); font-size: var(--step--1); display: flex; align-items: center; gap: .6rem; }
.toast-error { background: var(--err); }
.toast-success { background: var(--ok); }

/* Modal compartilhado (`core/Modal.js`). Ele monta
   `.modal-header`/`.modal-body`/`.modal-footer` e os botões
   `.btn-modal-primary`/`.btn-modal-secondary` -- nomes próprios, que não
   batem com `.btn` nem com `.md-btn`. Sem tratamento, "Cancelar" e
   "Salvar" saíam como dois textos colados no rodapé do modal. */
.app-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 4000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(17, 17, 17, .45);
}
.modal-dialog {
    display: flex;
    flex-direction: column;
    width: min(620px, 100%);
    max-height: 86vh;
    background: var(--card);
    border: 1px solid var(--line);
}
.modal-header {
    padding: 1.5rem 1.75rem 1rem;
    border-bottom: 1px solid var(--line);
}
.modal-title { font-size: var(--step-2); }
.modal-body { padding: 1.75rem; overflow-y: auto; }
.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: .75rem;
    padding: 1.25rem 1.75rem;
    border-top: 1px solid var(--line);
}
.btn-modal {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 1.6em;
    border: 1px solid var(--line-strong);
    font-size: var(--step--1);
    letter-spacing: var(--tracking);
    text-transform: uppercase;
    transition: background-color var(--fast), color var(--fast), border-color var(--fast);
}
.btn-modal-secondary:hover { border-color: var(--ink); }
.btn-modal-primary {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-primary, #fff);
}
.btn-modal-primary:hover { background: transparent; color: var(--primary-color); }
.btn-modal-danger {
    background: var(--err);
    border-color: var(--err);
    color: #fff;
}
.btn-modal-danger:hover { background: transparent; color: var(--err); }

/* Modal "Selecione uma variação" (`features/cart/VariationModal.js`).
   Markup 100% de runtime: não existe em partial nenhum, então sem estas
   regras a foto da variação abre no tamanho natural do arquivo dentro do
   modal e as opções viram texto corrido. O estado `.selected` é escrito
   pelo módulo no clique. */
.variation-picker { display: flex; flex-direction: column; gap: .5rem; }
.variation-hint { margin-bottom: .5rem; color: var(--ink-mute); }

.variation-option {
    display: grid;
    grid-template-columns: 52px minmax(0, 1fr) auto;
    align-items: center;
    gap: 1rem;
    padding: .6rem .75rem;
    /* `.variation-option` é um <label>, então a regra base de rótulo do
       tema pega nele: a versalete com tracking fica (é a voz deste tema),
       mas a margem de rótulo brigava com o `gap` da lista. */
    margin-bottom: 0;
    border: 1px solid var(--line);
    cursor: pointer;
    transition: border-color var(--fast), background-color var(--fast);
}

.variation-option:hover { border-color: var(--line-strong); }

.variation-option.selected {
    border-color: var(--ink);
    background: var(--bg-sunk);
}

/* Retrato, como toda foto deste tema (o card e o mini-carrinho usam a
   mesma proporção) — quadrado aqui destoaria da grade da loja. */
.variation-option img {
    width: 52px;
    aspect-ratio: 3 / 4;
    height: auto;
    object-fit: cover;
    background: var(--bg-sunk);
}

.variation-body { min-width: 0; }
/* Sem isto, o texto herda o `--ink-mute` da regra base de <label> — fraco
   demais para o dado principal da linha. */
.variation-body strong { color: var(--ink); font-weight: 600; }
.variation-price { color: var(--ink); font-weight: 600; white-space: nowrap; }

/* =================================================
 * 16. Movimento
 * -------------------------------------------------
 * Keyframes puros, sem classe de gatilho: rodam na carga e o conteúdo
 * nunca fica refém de JS pra aparecer. `backwards` cobre o delay.
 * ================================================= */
@keyframes md-rise {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
}
@keyframes md-fade {
    from { opacity: 0; }
}
@keyframes md-sheet {
    from { opacity: .4; transform: translateY(24px); }
}

/* Entrada do hero: título sobe primeiro, selo e CTA acompanham. Um
   escalonamento só, no elemento que abre a página -- não é gramática de
   seção. */
.md-hero__text .container > * { animation: md-rise .7s var(--ease) backwards; }
.md-hero__text .container > :nth-child(2) { animation-delay: .08s; }
.md-hero__text .container > :nth-child(3) { animation-delay: .16s; }

/* Troca de passo do checkout. */
.wizard-pane.on { animation: md-rise .35s var(--ease); }

/* Folha de filtro subindo no celular. */
@media (max-width: 921px) {
    .filter.show { animation: md-sheet .35s var(--ease); }

    /* A gaveta da sacola vira FOLHA ancorada no rodapé da tela.
       No computador ela é um balão pendurado no ícone do cabeçalho
       (`position: absolute; top: 100%`), e isso funciona porque o gatilho é
       aquele ícone. No celular quem abre é a barra inferior — e o balão
       continuava medido a partir do cabeçalho, que já rolou para fora:
       abria com `top: -478px`, quase toda acima da área visível. Dava a
       impressão de que o tema não tinha mini-carrinho no celular
       (relatado 2026-08-11). */
    .mini-cart {
        position: fixed;
        top: auto;
        right: 0;
        left: 0;
        bottom: 0;
        width: auto;
        max-height: 80vh;
        display: flex;
        flex-direction: column;
        border-inline: 0;
        border-bottom: 0;
        transform: translateY(12px);
        /* Acima da barra inferior, que também é `position: fixed`. */
        z-index: calc(var(--z-header) + 2);
        box-shadow: 0 -12px 36px rgb(0 0 0 / 18%);
        padding-bottom: env(safe-area-inset-bottom);
    }

    .mini-cart .cart-body { max-height: none; flex: 1 1 auto; }

    /* Sem isto a folha cobre a página inteira sem dar pista de que a
       página continua atrás — e o clique-fora que fecha vira adivinhação. */
    .mini-cart.show { transform: none; }
}

/* Toast e modal chegam, não aparecem. */
.toast { animation: md-rise .3s var(--ease); }
.app-modal-backdrop { animation: md-fade .25s var(--ease); }
.modal-dialog { animation: md-rise .3s var(--ease); }

/* Respeita quem pediu menos movimento -- o zoom da foto e o autoplay do
   hero são enfeite, não informação. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}


/* ================== CONVITE DE NEWSLETTER (compartilhado) ==================
   A janela que abre sozinha. O markup vem de
   `views/partials/newsletter-popup.php` e o comportamento de
   `scripts/shared/NewsletterForm.js` — os dois iguais em todos os temas.
   O que muda de tema para tema é SÓ esta pele, e por isso o bloco começa
   ligando as classes neutras `np*` aos tokens desta folha.

   Duas metades: cena à esquerda (a foto do primeiro banner da loja, ou o
   fundo rebaixado quando não há foto) e o texto à direita. O `[hidden]` do
   bloco é o estado fechado — e como `[hidden]` já é `display:none` no
   reset, a janela nasce fora da tela mesmo se esta pele não 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 {
    --np-paper: var(--card);
    --np-sunk: var(--bg-sunk);
    --np-ink: var(--ink);
    --np-ink-2: var(--ink-soft);
    --np-ink-3: var(--ink-mute);
    position: fixed;
    inset: 0;
    z-index: 400;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.np__veu {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .3);
    animation: np-veu .25s ease both;
}

.np__caixa {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: min(710px, 100%);
    max-height: calc(100vh - 32px);
    overflow: hidden auto;
    border-radius: 8px;
    background: var(--np-paper);
    animation: np-entra .3s ease both;
}

.np__cena { background: var(--np-sunk); }
.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: 0;
    border-radius: 999px;
    background: none;
    color: var(--np-ink-2);
    font-size: 20px;
    cursor: pointer;
    transition: background-color .16s ease, color .16s ease;
}

.np__x:hover { background: var(--np-sunk); color: var(--np-ink); }

.np__titulo { font-size: 24px; color: var(--np-ink); }
.np__texto { font-size: 14px; color: var(--np-ink-2); max-width: 32ch; }

.np__form { width: 100%; }
.np__form form { display: flex; flex-direction: column; gap: 10px; }
.np__form input { width: 100%; }
/* O botão vem da cor da LOJA, e não do estilo que cada tema dá ao
   `.newsletter button` do rodapé: vários pintam esse botão de branco
   porque a faixa do rodapé é escura, e dentro da janela branca ele
   sumiria. Aqui o fundo é sempre a primária, com `--on-brand` (calculado
   por `core/ThemeColors.js` a partir da luminância real) por cima. */
.np__form button[type="submit"] {
    width: 100%;
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--on-brand, #fff);
}

/* "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 {
    border: 0;
    background: none;
    cursor: pointer;
    font-size: 13px;
    color: var(--np-ink-3);
    text-decoration: underline;
    text-underline-offset: 3px;
    padding-block: 4px;
}

.np__depois:hover { color: var(--np-ink); }

@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; }
}

/* 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. */
@media (max-width: 860px) {
    .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; }
}


/* ============ 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(--card);
    border: 1px solid var(--line);
    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(--ok) !important;
    border-color: var(--ok) !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;
}

/* ---------------------------------------------------------------
 * 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;
}
