/* Arte Pronta — site público.
   Sobrescreve a cor primaria padrao do Vuexy (roxo, definido em
   app-assets/css/bootstrap.min.css) para o teal da paleta do Arte Pronta.
   O admin NAO carrega este arquivo — mantem o roxo nativo (ver cores-admin.css),
   decisao que diferencia visualmente as duas areas.
   Fonte da paleta: docs/Arte Pronta/Referências/2026-07-13-inspiracao-visual.md */
:root {
    --bs-primary: #2BBFA0;
    --bs-primary-rgb: 43, 191, 160;

    /* Acento (badges de destaque/promocao no catalogo) */
    --arte-pronta-coral: #FF6F61;
    --arte-pronta-coral-rgb: 255, 111, 97;
}

/* Corrige colapso do layout publico em telas < 576px (Task 1, follow-up;
   revisitado na Fase 11 de responsividade mobile pra cobrir o banner de cookies).
   O bootstrap.min.css vendorizado (Bootstrap 5.1.0) define `.container{max-width:0}`
   incondicionalmente, so sobrescrito a partir de `@media (min-width:576px)`. O admin nao
   sofre com isso porque usa `.container-fluid` no wrapper de conteudo, mas o layout publico
   (resources/views/layouts/app.blade.php) envolve o conteudo em `.container` dentro de
   `.content`, o rodape (resources/views/partials/footer.blade.php) tambem usa `.container`,
   e o banner de consentimento de cookies (partials/cookie-consent.blade.php, fixed-bottom)
   igualmente — todos ficam com width ~0 abaixo do breakpoint sm (confirmado via Playwright:
   `.container` do banner de cookies media 28px de largura a 390px/320px, com o texto e o
   botao "Aceitar" vazando por cima do resto da pagina). Escopo restrito a esses wrappers
   do site publico para nao alterar `.container` em nenhum outro lugar do projeto.
   Ampliado em 2026-07-20 pra incluir `.navbar-container` (mesmo colapso confirmado via
   Playwright: 28px de largura a 375px, quando a classe "container" foi adicionada ao header
   pra centralizar as informacoes — ver navbar.blade.php e o "margin-left: auto" logo acima
   neste arquivo). */
@media (max-width: 575.98px) {
    .content .container,
    .footer .container,
    #aviso-cookies .container,
    .navbar-container.container {
        max-width: 100%;
    }
}

/* Rodape nao fica colado no fim da viewport em paginas com pouco conteudo (ex.:
   pedidos/{id}/confirmacao logo apos o pagamento — achado do usuario 2026-07-21,
   confirmado via Playwright simulando conteudo curto: o rodape parava em ~495px de altura
   mas a pagina continuava com ~405px de espaco em branco vazio abaixo dele). Causa: o
   Vuexy vendorizado ja define `body{min-height:100%}` (via html{height:100%} em
   components.min.css), o que faz a `<body>` esticar ate preencher a viewport quando o
   conteudo e curto — mas como a `<body>` continua em `display:block` (fluxo normal), nada
   dentro dela cresce para acompanhar esse esticamento: o rodape fica onde o conteudo
   termina, e a sobra de altura vira espaco vazio DEPOIS do rodape em vez do rodape descer
   ate o fim. O mecanismo nativo do Vuexy pra isso (".footer-static .content-area-wrapper"
   com altura calc(100vh - navbar - footer) em components.min.css) nao se aplica aqui: o
   layout publico (resources/views/layouts/app.blade.php) usa `.content-wrapper` puro, sem
   a classe `.content-area-wrapper` que esse calculo exige. Fix classico de sticky footer
   via flexbox na `<body>`, com a area de conteudo crescendo (`flex: 1 0 auto`) pra empurrar
   o rodape pro fim. Escopado a `body.footer-static` (classe presente no `<body>` do layout
   publico) — seguro mesmo que o admin use a mesma classe, pois cores-publico.css nao e
   carregado no admin (ver comentario no topo deste arquivo). */
body.footer-static {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
}
body.footer-static > .app-content.content {
    flex: 1 0 auto;
}
body.footer-static > .footer {
    flex-shrink: 0;
}

/* Logo do card de login/cadastro (Fase 11, responsividade mobile). A tag <img height="60">
   em resources/views/auth/{login,cadastro}.blade.php mantem o aspect ratio original do
   arquivo (846x150), rendendo ~338px de largura sempre que height=60 — largura fixa que
   independe do viewport. O .card-body de .auth-basic cabe essa largura em telas >= ~424px,
   mas abaixo disso (confirmado via Playwright em 390px e 320px) a imagem vaza pra fora do
   card (fica invisivel por causa do `body{overflow-x:hidden}` global, mas corta visualmente
   o final da palavra "Pronta"). Escopo restrito ao breakpoint sm pra nao alterar o tamanho
   da logo em telas maiores, onde ela ja cabe do jeito que foi desenhada (height=60 fixo). */
@media (max-width: 575.98px) {
    .auth-wrapper .brand-logo img {
        max-width: 100%;
        height: auto;
    }
}

/* bootstrap.min.css grava .btn-primary/.btn-outline-primary/a{color} com um hex
   fixo em vez de referenciar var(--bs-primary) — redefinir a variavel acima nao
   e suficiente para essas classes. Overrides explicitos abaixo, incluindo
   hover/focus/active para nao "piscar" na interacao.
   !important e necessario: colors.min.css (carregado antes deste arquivo) ja
   declara .btn-primary/.btn-outline-primary com !important no hex roxo nativo,
   entao sem !important aqui o roxo do colors.min.css vence mesmo carregando
   por ultimo — !important sempre bate especificidade/ordem de cascata. */
.btn-primary,
.btn-primary:focus,
.btn-primary:hover {
    background-color: #2BBFA0 !important;
    border-color: #2BBFA0 !important;
    color: #FFF !important;
}
.btn-primary:hover {
    background-color: #23A88C !important;
    border-color: #1F9880 !important;
}
.btn-primary:focus,
.btn-check:checked + .btn-primary:focus,
.btn-check:focus + .btn-primary,
.btn-primary.active:focus,
.btn-primary:active:focus,
.show > .btn-primary.dropdown-toggle:focus {
    box-shadow: 0 0 0 .25rem rgba(var(--bs-primary-rgb), .5) !important;
}

.btn-outline-primary {
    color: #2BBFA0 !important;
    border-color: #2BBFA0 !important;
}
.btn-outline-primary:hover,
.btn-check:checked + .btn-outline-primary,
.btn-outline-primary.active,
.btn-outline-primary.dropdown-toggle.show,
.btn-outline-primary:active {
    color: #FFF !important;
    background-color: #2BBFA0 !important;
    border-color: #2BBFA0 !important;
}
.btn-outline-primary:focus,
.btn-check:checked + .btn-outline-primary:focus,
.btn-check:focus + .btn-outline-primary,
.btn-outline-primary.active:focus,
.btn-outline-primary.dropdown-toggle.show:focus,
.btn-outline-primary:active:focus,
.btn-outline-primary:focus {
    box-shadow: 0 0 0 .25rem rgba(var(--bs-primary-rgb), .5) !important;
}

/* Achado (Importante) do review cruzado de UX/acessibilidade (2026-07-22): navegação por
   teclado (Tab) não mostrava indicador de foco visível em botões/links fora do
   .btn-primary/.btn-outline-primary (ex: .btn-outline-secondary, .btn-outline-danger, os
   <a> do menu/rodapé) -- falha de WCAG 2.4.7. O Vuexy vendorizado zera outline/box-shadow
   sem repor nada; regra genérica via :focus-visible cobre o que os overrides acima (que
   já existiam só pro primary) não cobriam, sem alterar a aparência de mouse/toque (só
   dispara quando o foco vem do teclado). */
a:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
    outline: .15rem solid #2BBFA0 !important;
    outline-offset: .1rem;
}

a {
    color: #2BBFA0;
}

/* Rodape (spec backlog 2026-07-19): fundo alterado para cinza medio
   rgb(102,102,102), pedido do usuario. `.footer-light` do Vuexy e o `text-muted`/
   cor de link herdada do `a{color}` acima (teal, pensado pra fundo claro) ficam
   com contraste ruim nesse fundo escuro — overrides de texto/link em branco
   escopados a `.footer` abaixo substituem a regra teal que havia aqui antes
   (o `.footer .nav-link` tinha especificidade maior que `a` e vencia o roxo
   nativo do Vuexy; agora cumpre o mesmo papel de "vencer a cascata", so que em
   branco em vez de teal, e junto com `.footer a` cobre tambem os links fora do
   `<ul class="nav">`, como Termos/Privacidade e o credito "Desenvolvido por"). */
.footer {
    background-color: rgb(102, 102, 102);
}
.footer .nav-link,
.footer a {
    color: #FFF;
}
.footer .nav-link:hover,
.footer a:hover {
    color: rgba(255, 255, 255, .75);
}
.footer .text-muted {
    color: rgba(255, 255, 255, .85) !important;
}

/* Rodape quebrando em telas desktop menores (992px-1280px, achado do usuario 2026-07-21,
   confirmado via Playwright/getComputedStyle). Causa: partials/footer.blade.php usa a
   utility class "gap-3" do Bootstrap esperando o gap padrao (~1rem), mas o
   bootstrap.min.css vendorizado do Vuexy REDEFINE toda a escala gap-* pra valores bem
   maiores (".gap-3{gap:3rem!important}", junto com gap-0/1/2/4/5 tambem deslocados) —
   com o font-size base de 14px do tema (html{font-size:14px} em components.min.css),
   gap-3 vira 42px em vez dos ~16px esperados. A linha de navegacao do rodape (~677px) e o
   bloco de links legais/copyright (~541px) nao cabem lado a lado dentro do `.container`
   disponivel entre os breakpoints lg e xl (936px a 1184px uteis, contra os ~1234px
   necessarios) — o `flex-wrap` do rodape quebra a linha nesse intervalo (comportamento
   esperado/responsivo), mas o gap de 42px herdado do gap-3 contaminado cria um vao
   vertical grande demais entre as duas linhas, parecendo quebrado. Escopo restrito a
   `.footer` pra nao alterar gap-3 em nenhum outro lugar do site publico; !important
   necessario pra vencer o gap-3 do Vuexy, que ja carrega !important. */
.footer .gap-3 {
    gap: 1rem !important;
}

/* Paginacao (Laravel ->links(), usada em /produtos, /blog e /pedidos): o
   estado ativo vem roxo de bootstrap-extended.min.css (.page-item.active
   .page-link com o roxo nativo no background, sem !important, mas nada no
   publico o sobrescrevia antes disso). */
.page-item.active .page-link {
    background-color: #2BBFA0 !important;
    border-color: #2BBFA0 !important;
    color: #FFF !important;
}
.page-item:not(.active) .page-link:hover,
.page-item:not(.active) .page-link:focus {
    color: #2BBFA0 !important;
}
.page-item.active .page-link:hover,
.page-item.active .page-link:focus {
    background-color: #23A88C !important;
    border-color: #1F9880 !important;
    color: #FFF !important;
}

/* Preco PIX em destaque (card de catalogo/home, carrinho e detalhe de
   produto): app-ecommerce.min.css na verdade define isso com um seletor
   composto de alta especificidade (`.ecommerce-application .list-view
   .ecommerce-card .item-options .item-wrapper .item-cost .item-price`),
   nao o `.item-price` isolado — !important necessario pra vencer sem ter
   que replicar a cadeia inteira de ancestrais em cada template. */
.item-price {
    color: #2BBFA0 !important;
}

/* Radio/checkbox marcados (ex.: forma de pagamento PIX/Cartao no checkout):
   colors.min.css define .form-check-input:checked com o roxo nativo como
   border-color/background-color. */
.form-check-input:checked {
    background-color: #2BBFA0;
    border-color: #2BBFA0;
}

/* alert-info (avisos.blade.php: mensagens de status neutro, ex. "pagamento em
   andamento", revalidacao de itens do carrinho) usa por padrao o ciano generico
   do Vuexy (colors.min.css), destoando do teal da marca que ja rebate botoes,
   links, preco e paginacao neste arquivo. alert-success/alert-danger nao mudam
   aqui: verde/vermelho sao cores semanticas universais (sucesso/erro), so o
   "info" neutro faz sentido herdar a cor primaria da marca.
   Receita de bg/texto espelha o que o Vuexy ja usa em .alert-danger (fundo em
   rgba da cor solida a 12% de opacidade + texto na cor solida). */
.alert-info {
    background-color: rgba(43, 191, 160, .12) !important;
    color: #1F9880 !important;
}

/* Contador do carrinho no header: o botao do icone (.btn-icon, Vuexy) tem
   overflow:hidden, e o badge de contagem usa a classe .badge-up posicionada
   fora da caixa do botao (top:-11px/right:-9px) para ficar "flutuando" no
   canto — o overflow:hidden corta o numero, deixando so uma lasca vermelha
   visivel. Unico uso de .btn-icon no site publico e este carrinho (navbar.blade.php). */
.header-navbar .btn-icon.position-relative {
    overflow: visible;
}

/* Header sticky (spec 2026-07-19-header-busca-redesign): o tema Vuexy fixa
   `html body { height: 100% }` (components.min.css) pensando no layout de
   dashboard admin, onde um wrapper interno com overflow:auto rola o
   conteudo — o site publico nao tem esse wrapper, quem rola e a propria
   janela. Como o box de "body" fica travado na altura do viewport mesmo com
   overflow:visible, o "position: sticky" do header so acompanha o scroll
   dentro dessa altura e depois se solta. Mesma especificidade do seletor
   original (html body), ganha por ordem de carga (este arquivo vem depois
   de components.min.css). */
html body {
    height: auto;
    min-height: 100%;
}

/* Fase 5 (Home): `.app-content.content` (layouts/app.blade.php) recebe do Vuexy vendorizado
   (components.min.css) `padding: calc(2rem + 4.45rem + 1.3rem) 2rem 0` — pensado pra compensar
   um navbar `fixed-top` do template admin original. O navbar publico (partials/navbar.blade.php)
   e `sticky-top`, nao `fixed-top`, entao nao precisa dessa reserva de espaco: sobrava um respiro
   grande demais no topo de toda pagina publica, e o padding lateral de 2rem tambem brigava com o
   banner full-bleed abaixo (ele ignora o padding por usar 100vw, mas o resto do conteudo da pagina
   ficava com gutters inconsistentes ao lado de um banner que vai borda a borda). Reduzido pra um
   respiro vertical pequeno e zero horizontal (o `.container` interno already cuida do gutter do
   conteudo normal).
   Achado real (2026-07-20, revisao pos-deploy): a primeira tentativa desse override usava o
   seletor `.app-content.content` (especificidade 0,2,0), mas a regra do Vuexy vendorizado e
   `html .content.app-content` (0,2,1, por causa do prefixo `html`) — mais especifica, entao
   vencia independente da ordem de carregamento do CSS. O padding gigante nunca sumiu de verdade.
   Corrigido igualando o prefixo `html` pra ter a mesma especificidade e a ordem de carga (este
   arquivo carrega depois) decidir.
   Segundo ajuste (2026-07-20): usuario pediu pra zerar de vez o respiro vertical, deixando o
   banner "praticamente embaixo" da navbar — sem padding-top nenhum aqui, a navbar sticky-top
   (que tem sua propria altura/sombra) ja cria a separacao visual necessaria. */
html .content.app-content {
    padding: 0;
}

/* Achado do usuario (2026-07-20): a regra acima so cobria desktop — existe uma SEGUNDA regra
   vendorizada, so ativa em `@media (max-width: 767.98px)`, com um seletor diferente
   (`html body .app-content`, nao `html .content.app-content`) e `!important`:
   `padding: calc(2rem - .8rem + 4.45rem + 1.3rem) calc(2rem - .8rem) 0 !important`. Sem
   `!important` e sem cobrir esse seletor especifico, o respiro gigante do topo voltava em
   qualquer tela abaixo de 768px (confirmado com CDP getMatchedStylesForNode, nao so leitura
   de CSS — a inspecao visual por si so nao mostra qual regra especifica esta vencendo). */
html body .app-content {
    padding: 0 !important;
}

/* Banner carrossel full-bleed (Fase 5, Home): a tecnica de "quebra de container" via 100vw deixa
   sobrar uma fatia horizontal quando ha barra de rolagem vertical (100vw inclui a largura da
   barra, mas o viewport "util" — clientWidth — nao).
   Achado do usuario (2026-07-25, bug no mobile: header "andava" e ficava cortado no scroll):
   essa regra estava em `body { overflow-x: hidden }` (comentario antigo dizia, errado, que
   isso "nao afeta o sticky-top do header"). Na verdade afeta: pela spec de CSS Overflow, se um
   eixo (aqui overflow-x) recebe um valor diferente de "visible", o OUTRO eixo (overflow-y, que
   a gente nunca declarava) e computado como "auto" em vez de "visible" — mesmo se voce tentar
   forcar "overflow-y: visible" explicitamente, a spec ainda converte pra "auto" nesse caso.
   Isso faz o <body> virar um scroll container de verdade (confirmado via Playwright,
   getComputedStyle(body).overflowY === "auto"), e "position: sticky" no header passa a colar
   relativo a ESSE scroll container em vez da janela — na pratica, um offset constante (~24px
   no teste com viewport 390x844) entre onde o sticky "deveria" estar e onde fica, cortando uma
   fatia do header durante o scroll. Corrigido aplicando o overflow-x:hidden num elemento mais
   especifico (`.app-content.content`, que nao e ancestral do <nav> sticky) em vez do <body> —
   contem a mesma fatia horizontal do banner sem tornar o <body> um scroll container. Confirmado
   sem regressao: scrollWidth === clientWidth em mobile (390px) e desktop (1440px) nos dois
   casos, antes e depois. */
.app-content.content {
    overflow-x: hidden;
}

/* Banner carrossel full-bleed: quebra o container pai (.container dentro de .content-body,
   ver layouts/app.blade.php) pra ocupar 100% da largura do viewport, borda a borda — em vez de
   ficar limitado a largura do `.container` como o resto do conteudo da pagina. */
#carrossel-banners {
    width: 100vw;
    position: relative;
    left: 50%;
    right: 50%;
    margin-left: -50vw;
    margin-right: -50vw;
}

/* Swiper de Destaques (Fase 5, Home): o vendor CSS/JS deste projeto e Swiper 6.7.0, cuja classe
   de container esperada e `.swiper-container` (overflow:hidden, position:relative etc. — ver
   app-assets/vendors/css/extensions/swiper.min.css). A partir do Swiper 7 a lib passou a usar
   apenas `.swiper` como classe de container, e foi essa convencao mais nova que o markup daqui
   (home.blade.php) usava (`class="swiper swiper-destaques"`), sem a classe antiga. Resultado:
   o container nunca recebia overflow:hidden, os 8 slides ficavam todos lado a lado sem corte
   (visiveis muito alem da largura do card), causando o "aparece uma imagem que deveria estar
   oculta" — e essa mesma falta de clip empurrava a largura de toda a pagina, contribuindo pro
   scroll horizontal. Resolvido no proprio home.blade.php adicionando a classe `swiper-container`
   junto (mudanca de markup, nao de CSS) — regra abaixo e so uma rede de seguranca caso outro
   swiper apareca no site publico sem essa classe. */
.swiper-destaques:not(.swiper-container) {
    overflow: hidden;
    position: relative;
}

/* Banner de consentimento de cookies (partials/cookie-consent.blade.php): pedido do usuario
   (2026-07-20) pra usar a cor primaria do site em vez do cinza padrao do Bootstrap
   (`alert-dark`, removido do markup). Texto branco e botao "Aceitar" em branco (o inverso do
   fundo) garantem contraste — um botao .btn-primary aqui "sumiria" contra um fundo da mesma
   cor teal. */
#aviso-cookies {
    background-color: #2BBFA0;
}
#aviso-cookies .btn-light {
    color: #2BBFA0;
}
#aviso-cookies .btn-light:hover {
    color: #22987F;
}

/* Catálogo (/produtos): achado do usuário (2026-07-20) — cards de produto ficavam colados
   verticalmente. `.grid-view` (app-ecommerce.min.css) só define `column-gap: 2rem` (gap
   horizontal), sem `row-gap` — e nenhum outro lugar do vendor CSS compensa com margin-bottom
   no `.ecommerce-card`, então linhas diferentes da grade não tinham respiro nenhum entre si. */
.grid-view {
    row-gap: 2rem;
}

/* Navbar pública (partials/navbar.blade.php): substitui o utilitário "bg-white" por essa
   classe própria — ver comentário no blade sobre o `[class*="bg-"]` do Vuexy que forçava
   texto branco sobre fundo branco nos links do header (achado do usuário, 2026-07-20:
   "Produtos"/Blog/FAQ ficavam invisíveis). */
.navbar-fundo-branco {
    background-color: #FFF;
}

/* Pedido do usuário (2026-07-20): centralizar as informações do header, alinhadas com o
   mesmo bloco centralizado que o resto do site usa (partials/navbar.blade.php ganhou a
   classe "container" no <div class="navbar-container">). Confirmado via
   getBoundingClientRect que isso sozinho não bastava: o Vuexy vendorizado tem
   ".header-navbar .navbar-container { margin-left: 0 }", mais específico (2 classes) que o
   "margin-left: auto" do Bootstrap ".container" (1 classe) — o header ficava com a LARGURA
   certa (batendo com o container da página), mas grudado na esquerda em vez de centralizado. */
.header-navbar .navbar-container.container {
    margin-left: auto !important;
    margin-right: auto !important;
}

/* Submenus de Tipos/Categorias dentro do dropdown "Produtos" (partials/navbar.blade.php,
   pedido do usuário 2026-07-20): Bootstrap 5 não tem suporte nativo a dropdown aninhado —
   sem isso, o submenu abriria embaixo do item pai, ocupando a largura toda e ficando confuso
   junto com o menu pai. Abre pro lado (like um menu de contexto de desktop), com pequeno
   ajuste de posição vertical (-.5rem) pra alinhar com o item que o abriu. Em telas < lg
   (menu mobile, sem espaço lateral) cai pro padrão empilhado do Bootstrap.
   Achado do usuário (2026-07-20, revisão visual): o submenu aparecia bem abaixo de
   "Categorias", desconectado — o Vuexy vendorizado tem
   ".vertical-layout .header-navbar .navbar-container ul.navbar-nav li.dropdown .dropdown-menu
   { top: 41px !important }" pensada pro dropdown de nível único (41px = altura da navbar), mas
   o seletor descendente casa com QUALQUER .dropdown-menu dentro de um li.dropdown, inclusive o
   submenu aninhado (que também mora dentro do <li class="nav-item dropdown"> externo).
   !important sozinho não bastou: a regra do Vuexy tem a MESMA especificidade que
   ".dropdown-submenu > .dropdown-menu" (6 classes + 2 elementos cada) — com !important dos
   dois lados, empate de especificidade é resolvido por ordem de carga, e mesmo carregando
   depois a regra local perdia (confirmado via CDP getMatchedStylesForNode mostrando "top: 41px
   !important" ainda vencendo). Repetir a cadeia de ancestrais do Vuexy + a classe própria
   deixa o seletor local estritamente mais específico. */
.dropdown-submenu {
    position: relative;
}
@media (min-width: 992px) {
    .vertical-layout .header-navbar .navbar-container ul.navbar-nav li.dropdown .dropdown-submenu > .dropdown-menu {
        top: -.5rem !important;
        left: 100% !important;
        margin-left: .1rem;
        /* Achado do usuário (2026-07-20, revisão visual): nomes mais longos ("Arte para Redes
           Sociais", "Datas Comemorativas") apareciam cortados/vazando pra fora da caixa do
           submenu. Causa (confirmada via getBoundingClientRect: scrollWidth > clientWidth nos
           itens mais longos): o Bootstrap só define min-width: 10rem pro .dropdown-menu (aqui
           140px, porque o Vuexy usa 14px de font-size base em vez dos 16px padrão) e não
           encolhe/cresce pra caber o conteúdo mais largo de verdade — a caixa ficava travada
           exatamente nesse mínimo em vez de se ajustar ao item mais comprido. width:max-content
           força a caixa a medir o item mais largo de fato; max-width evita que um nome futuro
           absurdamente longo estoure pra fora da tela. */
        width: max-content;
        max-width: 280px;
    }
}

/* Achado do usuário (2026-07-20, "no mobile essa experiência é ainda pior"): reaproveitar
   esse MESMO dropdown pro mobile (só trocando position via media query) gerou uma sequência
   de bugs um atrás do outro — dropdown flutuando por cima da busca (Vuexy tem
   ".header-navbar .navbar-nav .dropdown-menu { position: absolute }" em
   "@media (max-width: 991.98px)", pensada pro dropdown pequeno de admin do Vuexy, não pra
   uma lista alta de taxonomia pública), depois submenu invisível — sinal de que era o
   componente errado pro mobile, não mais um ajuste pontual de CSS. Resolvido em
   partials/navbar.blade.php: o <li> do dropdown acima agora é "d-none d-lg-block" (só existe
   visualmente no desktop) e o mobile tem seu próprio <li class="d-lg-none"> com um acordeão
   "collapse" do Bootstrap — componente diferente, sem position:absolute nenhum e sem nada em
   comum com .dropdown-menu, então não há CSS do Vuexy pra brigar aqui. */

/* Achado do usuário (2026-07-20, mesma revisão): confirmado via CDP
   (CSS.getMatchedStylesForNode em ul.navbar-nav, viewport mobile) que "Produtos"/"Blog"/"FAQ"
   ficavam lado a lado em vez de empilhados por causa de outra regra vendorizada do Vuexy —
   ".header-navbar .navbar-nav { flex-direction: row; flex-wrap: wrap }" dentro de
   "@media (max-width: 991.98px)" — pensada pro layout horizontal com scroll da navbar de
   admin do Vuexy, não pro menu público. Nada relacionado ao dropdown/acordeão acima: essa
   regra afeta o <ul> pai inteiro e bate em qualquer item de menu, não só em "Produtos". */
@media (max-width: 991.98px) {
    .header-navbar .navbar-nav {
        flex-direction: column !important;
    }
}

/* Achado via CDP (mesma revisão, viewport mobile): os links dentro do acordeão de
   "Produtos" (#produtosMobileMenu) apareciam bem mais claros/apagados que os itens irmãos
   ("Blog", "FAQ") — cor rgb(184,194,204) contra rgb(110,107,123). Causa: o Vuexy tem
   ".header-navbar .navbar-container ul.navbar-nav li > a.nav-link { color: #6E6B7B }" (a cor
   escura, legível) usando o combinador de filho direto "li > a.nav-link" — só bate em links
   que são filho DIRETO do <li>. Os links de "Blog"/"FAQ" são filhos diretos, mas os links
   dentro do acordeão ficam um nível mais fundo (li > div.collapse > a.nav-link), então caem
   na regra genérica ".navbar-light .navbar-container .navbar-nav .nav-link { color: #B8C2CC }"
   (@media max-width: 767.98px), pensada pra ficar apagada até o usuário interagir. */
#produtosMobileMenu .nav-link {
    color: #6E6B7B !important;
}

/* Banner da home colado no header (pedido do usuário, 2026-07-20): mesmo com
   html.content.app-content zerado (achados anteriores desta sessão), o banner ainda tinha um
   respiro visível porque continua dentro do `.container.py-2` do layout — o padding-top desse
   container empurrava o banner mesmo com ele sendo full-bleed na horizontal. :has() zera esse
   padding só quando o container tem o banner dentro (não afeta o padding-top de nenhuma outra
   página — catálogo, checkout etc. continuam com o respiro normal antes do título).
   !important necessário: `.py-2` do Vuexy vendorizado já é `padding-top: 1.5rem !important`
   (confirmado via CDP getMatchedStylesForNode) — sem !important aqui, a regra nunca vence
   independente de especificidade/ordem de carga (mesma classe de achado já documentada acima
   pro override de .btn-primary). */
.container:has(> #carrossel-banners) {
    padding-top: 0 !important;
}

/* Pedido do usuário (2026-07-22): no desktop (>= lg), o menu ficava colado na logo e os
   itens ("Produtos", "Blog", "Perguntas Frequentes") colados entre si. Escopado a >= 992px
   pra não afetar o acordeão mobile (que já usa "flex-direction: column" acima, onde
   column-gap não se aplica, e onde a proximidade com a logo não é o mesmo problema — o
   menu mobile fica dentro do collapse recolhível, abaixo do header). */
@media (min-width: 992px) {
    .header-navbar .navbar-collapse {
        margin-left: 2.5rem;
    }

    .header-navbar .navbar-nav {
        column-gap: 1.5rem;
    }
}

/* Achado do usuário (2026-07-22, catálogo/produtos no mobile): o campo de busca só tinha
   `.ecommerce-searchbar .input-group { box-shadow: 0 2px 8px 0 rgba(34,41,47,.14) }`
   (app-ecommerce.min.css) pra se destacar — sombra sutil demais pra funcionar como
   affordance de campo de busca, o box acaba parecendo sem contorno nenhum contra o fundo
   branco do card. Borda leve reforça o contorno sem remover a sombra existente. */
.ecommerce-searchbar .input-group {
    border: 1px solid #d8d6de;
}

/* Acordeão de filtros do catálogo (produtos/index.blade.php, mesmo pedido acima): o
   toggle e o "collapse" só existem/importam no mobile (o botão já é "d-lg-none"). No
   desktop o painel de filtros precisa continuar sempre visível, independente do estado
   JS do collapse (que nem chega a ser acionado, já que o toggle nem renderiza) — força
   "display" a vencer as classes/estilos inline que o Bootstrap aplica ao "collapse". */
@media (min-width: 992px) {
    #filtros-produtos {
        display: block !important;
        height: auto !important;
    }
}

/* Achado do usuário (2026-07-22): título/subtítulo do banner (carousel-caption) usa texto
   branco puro do Bootstrap, sem nenhum fundo — em banners com imagem clara (céu, praia,
   fundo estourado etc.) o texto ficava ilegível, sem contraste nenhum contra a própria
   foto. Degradê escurece só a metade de baixo da imagem (onde a legenda mora), sem
   escurecer a imagem inteira. Escopado a ":has(.carousel-caption)" -- só entra quando o
   banner tem subtítulo (home.blade.php só renderiza .carousel-caption nesse caso); banner
   sem subtítulo continua sem nenhum overlay. z-index explícito garante a ordem de
   empilhamento (degradê acima da foto, legenda acima do degradê) independente da ordem no
   DOM. */
.carousel-item:has(.carousel-caption)::before {
    content: '';
    position: absolute;
    inset: 0;
    /* Achado (Menor) do review cruzado de UX (2026-07-22): medido ~2,74:1 de contraste no
       título, no mobile, num banner com imagem clara -- a faixa de baixo do banner (onde a
       legenda mora no mobile, banner mais curto que desktop) caía dentro dos 70% já
       transparentes do degradê. Estendido: ainda mais escuro perto do fundo (.8 em vez de
       .75) e só fica transparente perto do topo (90%, era 70%), cobrindo com folga a área
       onde o texto renderiza em qualquer viewport. */
    background: linear-gradient(to top, rgba(0, 0, 0, .8) 0%, rgba(0, 0, 0, .4) 55%, transparent 90%);
    border-radius: inherit;
    z-index: 1;
    pointer-events: none;
}

.carousel-item .carousel-caption {
    z-index: 2;
}

/* Achado via debug (2026-07-22, mesma revisão): o título dentro da legenda usava <h2
   class="h4"> — o "color: #fff" do Bootstrap fica só no .carousel-caption, e a Vuexy tem
   uma regra própria de elemento (h1..h6 { color: #5E5873 }) que NÃO é herdada, é um valor
   explícito no próprio h2, então vence a herança do pai e pinta o título cinza-arroxeado
   sobre a foto escura — quase ilegível, mesmo com o degradê. Só o subtítulo (<p>, sem
   regra de cor própria da Vuexy) herdava o branco corretamente. */
.carousel-caption h2 {
    color: #fff;
}

/* Feedback visual de "Adicionar ao carrinho" (pedido do usuário, 2026-07-22, ver
   adicionar-ao-carrinho.js): pulso no badge de contagem do ícone de carrinho no header
   toda vez que um item é adicionado. animation-fill-mode não é necessário — a classe é
   removida via JS depois de disparar, o estado final já é o normal (sem transform). */
@keyframes pulso-badge-carrinho {
    0% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.35);
    }
    100% {
        transform: scale(1);
    }
}

.badge-carrinho-pulso {
    animation: pulso-badge-carrinho .4s ease;
}

/* Achado do PageSpeed Insights (2026-07-26, auditoria mobile): "as áreas de toque não têm
   tamanho ou espaçamento suficiente" -- os dois botões só-ícone sempre visíveis no header
   mobile (hamburger e carrinho) tinham hitbox abaixo do recomendado (~44px):
   .navbar-toggler vem do Bootstrap com padding vertical de só .25rem (4px); .btn-icon
   (Vuexy) tem .8rem (12.8px) nos 4 lados, ficando perto do limite mas ainda curto quando
   somado ao ícone (14px, feather.replace no layout). Aumenta só o padding (a área
   clicável/toque) em telas <= 991.98px (mesmo breakpoint mobile já usado neste arquivo) --
   não muda o tamanho visual do ícone em si, só a folga ao redor dele. */
@media (max-width: 991.98px) {
    .header-navbar .navbar-toggler {
        padding: .65rem .75rem;
    }

    .header-navbar .btn-icon {
        padding: 1rem;
    }
}

/* Achado do PageSpeed Insights (2026-07-26, mesma auditoria mobile): "as cores de primeiro
   e segundo plano não têm uma taxa de contraste suficiente" -- vários utilitários do
   Vuexy/Bootstrap usados no site público ficam abaixo de 4.5:1 sobre fundo branco/claro:
   .text-muted (#B9B9C3, ~1.9:1 -- preço riscado, data do post), .text-success (#28C76F,
   ~2.2:1 -- preço PIX em destaque), .badge.bg-light-success (mesmo verde, ~2.2:1 no fundo
   claro -- badge "X% OFF") e .badge.bg-light-secondary/.text-secondary (#82868B, ~3.2:1 --
   badge de tipo do produto). Reaproveita o cinza escuro já usado no menu mobile (#6E6B7B,
   ver #produtosMobileMenu acima) e escurece verde/cinza na mesma família de cor (não troca
   verde por teal nem cinza por preto), todos com contraste >= 4.5:1 medido contra branco.
   !important necessário pelo mesmo motivo dos outros overrides deste arquivo: as regras
   originais (colors.min.css/bootstrap.min.css) já declaram essas classes com !important. */
.text-muted {
    color: #6E6B7B !important;
}
.text-success {
    color: #0F5132 !important;
}
.badge.bg-light-success {
    color: #0F5132 !important;
}
.badge.bg-light-secondary,
.text-secondary {
    color: #495057 !important;
}

/* Achado do PageSpeed Insights (2026-07-26, mesma auditoria mobile): os botões
   indicadores do carrossel de banners (Banner 1/2/3) ficam abaixo do tamanho de
   toque recomendado. O Bootstrap vendorizado da 3px de indicador + 10px de borda
   transparente em cima/embaixo (23px de altura de toque real) e só 3px de margem
   lateral (6px de vão entre indicadores vizinhos) -- por baixo do minimo de 24px
   recomendado. Aumenta só a borda transparente (area de toque, sem mudar o
   tamanho visual dos 3px do indicador) e o vão lateral, restrito ao mobile (mesmo
   breakpoint já usado nas demais áreas de toque deste arquivo). */
@media (max-width: 991.98px) {
    #carrossel-banners .carousel-indicators [data-bs-target] {
        border-top-width: 12px;
        border-bottom-width: 12px;
        margin-left: 6px;
        margin-right: 6px;
    }
}

/* Achado do usuário (2026-07-26): mais destaque e padronização dos controles de
   navegação de imagem em todos os carrosséis do site (spec
   2026-07-26-destaque-navegacao-carrosseis). Estilo aprovado via companion visual
   (opção B): botão circular branco, ícone na cor da marca, sombra leve -- em vez do
   ícone SVG padrão do Bootstrap (sem fundo, opacity:.5, pouco contraste em fotos claras).
   Compartilhado entre o carrossel de banners da home e o carrossel de fotos do produto
   no mobile -- os dois usam as mesmas classes .carousel-control-prev/next do Bootstrap,
   só o container pai muda (#carrossel-banners vs #carrosselProduto). */
#carrossel-banners .carousel-control-prev,
#carrossel-banners .carousel-control-next,
#carrosselProduto .carousel-control-prev,
#carrosselProduto .carousel-control-next {
    top: 50%;
    bottom: auto;
    width: 44px;
    height: 44px;
    transform: translateY(-50%);
    border-radius: 50%;
    /* Pedido do usuário (2026-07-27): leve transparência no fundo branco do botão --
       deixa um pouco da imagem por trás aparecer, em vez de um branco 100% opaco. */
    background-color: rgba(255, 255, 255, .85);
    color: #2BBFA0;
    opacity: 1;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}
#carrossel-banners .carousel-control-prev,
#carrosselProduto .carousel-control-prev {
    left: 12px;
}
#carrossel-banners .carousel-control-next,
#carrosselProduto .carousel-control-next {
    right: 12px;
}
#carrossel-banners .carousel-control-prev:hover,
#carrossel-banners .carousel-control-next:hover,
#carrosselProduto .carousel-control-prev:hover,
#carrosselProduto .carousel-control-next:hover {
    color: #23A88C;
}

/* Feather icons (gerados por feather.replace() em tempo de execução, conversão de
   <i data-feather> em <svg> inline) precisam de tamanho maior pra não ficar perdidos
   dentro do botão circular de 44px. O padrão global de feather.replace() em
   layouts/app.blade.php:142 é 14px (width: 14, height: 14), muito pequeno pro contexto
   de um ícone de navegação dentro de um botão destacado. Precedente no codebase:
   carrinho/index.blade.php:28 usa inline style="width: 3rem; height: 3rem;" pra
   ícone de carrinho. Aqui, 20px oferece espaçamento confortável em todas as direções
   dentro do círculo de 44px. */
#carrossel-banners .carousel-control-prev svg,
#carrossel-banners .carousel-control-next svg,
#carrosselProduto .carousel-control-prev svg,
#carrosselProduto .carousel-control-next svg {
    width: 20px;
    height: 20px;
}

/* Indicadores (bolinhas) dos mesmos dois carrosséis: o Vuexy vendorizado já recolore o
   padrão branco do Bootstrap pra um cinza escuro (#22292F) -- sobrescreve de volta pra
   branco (inativo) e teal sólido (ativo), sem tocar nas bordas transparentes que dão a
   área de toque maior (achado do PageSpeed, regra já existente logo acima neste
   arquivo) -- só a cor do miolo visível (background-color) muda. */
#carrossel-banners .carousel-indicators [data-bs-target],
#carrosselProduto .carousel-indicators [data-bs-target] {
    background-color: #fff;
    opacity: .6;
    border-left: 1px solid #2BBFA0;
    border-right: 1px solid #2BBFA0;
}
#carrossel-banners .carousel-indicators .active,
#carrosselProduto .carousel-indicators .active {
    background-color: #2BBFA0;
    opacity: 1;
}

/* Destaques (Swiper, achado do usuário 2026-07-26): mesmo tratamento visual dos outros
   dois carrosséis (círculo branco, ícone teal) -- só o container do botão, o glifo da
   seta continua sendo o próprio ícone do Swiper (font-family: swiper-icons), não um
   ícone Feather, já que a lib gera o ícone via CSS (:after), não markup HTML próprio.
   --swiper-navigation-color recolore esse ícone gerado; sem adicionar
   .swiper-pagination (bolinhas) -- decisão explícita da spec, Destaques mostra vários
   cards por vez e desliza em grupo, não é um slide de imagem cheia por vez. */
.swiper-destaques {
    --swiper-navigation-color: #2BBFA0;
}
.swiper-destaques .swiper-button-prev,
.swiper-destaques .swiper-button-next {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    /* Mesma leve transparência dos outros dois carrosséis (pedido do usuário, 2026-07-27). */
    background-color: rgba(255, 255, 255, .85);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}
/* Achado do usuário (2026-07-27): o glifo da seta (gerado via :after, font-family:
   swiper-icons) usa font-size: var(--swiper-navigation-size), que continua no padrão
   do Swiper (44px) -- o MESMO tamanho do botão inteiro. Dentro do círculo de 44px (acima),
   o glifo estourava pra fora da borda, virando uma mancha em vez de uma seta. Corrigido
   direto no font-size do próprio pseudo-elemento (sem tocar --swiper-navigation-size, que
   também controla o margin-top de centralização vertical do botão via calc() do Swiper --
   mudar essa variável desalinharia o botão verticalmente). 20px é o mesmo tamanho usado
   nos ícones Feather dos outros dois carrosséis, dentro do mesmo círculo de 44px. */
.swiper-destaques .swiper-button-prev::after,
.swiper-destaques .swiper-button-next::after {
    font-size: 20px;
}
.swiper-destaques .swiper-button-prev:hover,
.swiper-destaques .swiper-button-next:hover {
    --swiper-navigation-color: #23A88C;
}
