/* =================================================================
   style.css - folha de estilos principal do site público AcheiCasas.com
   ================================================================= */

/* =================================================================
   1. Variáveis globais
   ================================================================= */
:root {
    --cor-primaria: #333333;
    --cor-secundaria: #1C1C1C;
    --cor-destaque: #14B8A6;
    --cor-destaque-hover: #2dd4bf;
    --cor-destaque-suave: #ecfdf9;
    --cor-destaque-suave-texto: #6B6B6B;
    --cor-fundo: #F6F6F4;
    --cor-texto-muted: #6B6B6B;
    --cor-branco: #ffffff;
    --cor-preto-transparente: rgba(0, 0, 0, 0.6);
    --font-principal: 'Inter', sans-serif;
    --font-titulo: 'Space Grotesk', sans-serif;
    --raio-borda-padrao: 8px;
    /* Linguagem Visual 2.0: raio maior pra superfícies grandes (fotos,
       cards, painéis) - --raio-borda-padrao continua valendo só pra
       controles pequenos (inputs, badges, botões pequenos). Espelha
       --radius-surface do tailwind-input.css (mesmo valor, sistema de
       variáveis paralelo já existente no projeto). */
    --raio-surface: 22px;
    --sombra-surface: 0 2px 8px rgba(28, 28, 28, .06);
    --sombra-surface-flutuante: 0 8px 24px rgba(28, 28, 28, .08), 0 2px 6px rgba(28, 28, 28, .05);
}

/* =================================================================
   2. Estilos globais e resets
   ================================================================= */
body {
    background-color: var(--cor-fundo);
    font-family: var(--font-principal);
    font-size: 0.95rem;
    /* Sem isso, blocos full-bleed (.faixa-marcas, .cta-final-vendas) causam
       scroll horizontal: eles usam width:100vw pra escapar do container, mas
       100vw conta a barra de rolagem, então sempre sobra um pouco de largura
       além da viewport visível. */
    overflow-x: hidden;
}
h1, h2, h3, h4,
.fw-titulo,
.card .card-title,
.preco-destaque {
    font-family: var(--font-titulo);
}

/* Link sem classe própria usa o amarelo de destaque em vez do azul padrão.
   Fica em @layer base (não solto) de propósito: assim qualquer utility de
   cor do Tailwind (text-brand-secundaria num botão, text-brand-primaria num
   link "Ver todos", text-brand-secundaria na página ativa da paginação...)
   vence, já que a camada utilities está acima de base. Solto/unlayered essa
   regra ganhava de TODA utility de cor em <a>, deixando texto amarelo em
   cima de botão amarelo (invisível). Links de conteúdo, sem utility própria,
   continuam pegando o amarelo daqui. */
@layer base {
    a {
        color: var(--cor-destaque);
    }
    a:hover {
        color: var(--cor-destaque-hover);
    }
}

/* 2.1. Alertas - paleta própria em cima das custom properties que o
   Bootstrap 5.3 já lê por trás de .alert-* (o azul padrão de .alert-info
   destoava do resto do site, então cada variante ganhou cor coerente). */
.alert {
    position: relative;
    overflow: hidden;
    border-radius: var(--raio-borda-padrao);
    border-left-width: 4px;
    padding-right: 3.25rem;
}
/* Ícone grande e translúcido no canto, só pra dar textura sem competir
   com o texto do alerta. */
.alert::after {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    position: absolute;
    right: -0.4rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 3.25rem;
    opacity: 0.12;
    pointer-events: none;
}
.alert-success {
    --bs-alert-color: #1f7a4d;
    --bs-alert-bg: #eaf7ef;
    --bs-alert-border-color: #cdebd9;
    border-left-color: #1f7a4d;
}
.alert-success::after {
    content: "\f058";
    color: #1f7a4d;
}
.alert-danger {
    --bs-alert-color: #b3261e;
    --bs-alert-bg: #fdecea;
    --bs-alert-border-color: #f6cbc6;
    border-left-color: #b3261e;
}
.alert-danger::after {
    content: "\f071";
    color: #b3261e;
}
.alert-warning {
    --bs-alert-color: #7a5c00;
    --bs-alert-bg: var(--cor-destaque-suave);
    --bs-alert-border-color: #f3e3ad;
    border-left-color: #c9a02e;
}
.alert-warning::after {
    content: "\f3ed";
    color: #c9a02e;
}
.alert-info {
    --bs-alert-color: #4a4a47;
    --bs-alert-bg: #f1f0ec;
    --bs-alert-border-color: #e1dfd8;
    border-left-color: #8a8a86;
}
.alert-info::after {
    content: "\f05a";
    color: #8a8a86;
}

/* 2.2. Formulários e botões - visual "soft": borda quase invisível (sombra
   leve em vez de uma linha cinza dura) e foco na cor de destaque do site. */
.form-control,
.form-select {
    font-size: 0.9rem;
    color: var(--cor-secundaria);
    border: 1px solid #ebebe8;
    border-radius: var(--raio-borda-padrao);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}
.form-control::placeholder {
    color: var(--cor-texto-muted);
    opacity: 0.8;
}
.form-control:focus,
.form-select:focus {
    border-color: var(--cor-destaque);
    box-shadow: 0 0 0 0.2rem rgba(20, 184, 166, 0.15);
}
.form-label {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--cor-secundaria);
}

.btn {
    border-radius: var(--raio-borda-padrao);
}
.btn-outline-secondary {
    border-color: transparent;
    background-color: var(--cor-fundo);
    color: var(--cor-texto-muted);
}
.btn-outline-secondary:hover {
    background-color: #ececea;
    border-color: transparent;
    color: var(--cor-primaria);
}
.btn-secondary {
    border-color: transparent;
    background-color: var(--cor-fundo);
    color: var(--cor-texto-muted);
}
.btn-secondary:hover {
    background-color: #ececea;
    border-color: transparent;
    color: var(--cor-primaria);
}

/* =================================================================
   3. Componentes da interface
   ================================================================= */

/* 3.2. Hero de busca (fundo amarelo refinado, gerado via CSS) */
.hero-section {
    position: relative;
    overflow: hidden;
    padding: 5rem 0 5.5rem;
    background-color: var(--cor-destaque);
    background-image:
        radial-gradient(circle at 12% 18%, rgba(255, 255, 255, 0.5) 0%, transparent 42%),
        radial-gradient(circle at 88% 82%, rgba(255, 255, 255, 0.28) 0%, transparent 42%),
        linear-gradient(135deg, var(--cor-destaque) 0%, var(--cor-destaque-hover) 100%);
    color: var(--cor-primaria);
}
/* Grade sutil de fundo, com as bordas esmaecidas (mask radial) pra não
   competir com o card de busca no centro. */
.hero-section::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(14, 14, 14, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(14, 14, 14, 0.05) 1px, transparent 1px);
    background-size: 46px 46px;
    -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 25%, transparent 80%);
    mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 25%, transparent 80%);
}

.hero-vendedor-img {
    position: absolute;
    right: 0;
    bottom: 0;
    height: 100%;
    max-height: 420px;
    width: auto;
    z-index: 1;
    opacity: 0.92;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to left, black 52%, transparent 92%);
    mask-image: linear-gradient(to left, black 52%, transparent 92%);
}
@media (max-width: 991.98px) {
    .hero-vendedor-img {
        display: none;
    }
}

/* Selo acima do título */
.hero-selo {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.9rem;
    border-radius: 999px;
    background-color: rgba(28, 28, 28, 0.08);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.2px;
    color: var(--cor-secundaria);
}
.hero-titulo {
    margin-top: 1rem;
    font-family: var(--font-titulo);
    font-size: clamp(2rem, 5vw, 3.25rem);
    font-weight: 700;
    line-height: 1.1;
    color: var(--cor-secundaria);
}
.hero-subtitulo {
    margin: 0.9rem auto 0;
    max-width: 40rem;
    font-size: 1.05rem;
    color: rgba(28, 28, 28, 0.72);
}

/* Card de busca: branco sólido, estreito, centralizado */
.hero-busca-card {
    margin: 2rem auto 0;
    max-width: 620px;
    padding: 0.9rem;
    border-radius: var(--raio-surface);
    background-color: #fff;
    box-shadow: 0 18px 45px -12px rgba(0, 0, 0, 0.28);
}

/* Abas em pílula segmentada (JS troca .active via data-tab-target) */
.hero-tabs {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.25rem;
    border-radius: 999px;
    background-color: var(--cor-fundo);
}
.hero-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.5rem 1.35rem;
    border: none;
    border-radius: 999px;
    background: transparent;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--cor-texto-muted);
    cursor: pointer;
    transition: background-color 0.2s, color 0.2s;
}
.hero-tab.active {
    background-color: var(--cor-primaria);
    color: #fff;
}
.hero-tab:hover:not(.active) {
    color: var(--cor-primaria);
}

/* Barra de busca unificada (pílula): empilha no mobile, vira linha com
   botão redondo (só a lupa) a partir de 640px. */
.hero-busca {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.4rem;
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 1rem;
}
.hero-busca-campo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 1;
    min-width: 0;
    padding: 0.15rem 0.85rem;
}
.hero-busca-icone {
    flex-shrink: 0;
    font-size: 0.9rem;
    color: var(--cor-texto-muted);
}
.hero-busca-input,
.hero-busca-select {
    width: 100%;
    min-width: 0;
    padding: 0.55rem 0;
    border: none;
    background: transparent;
    font-size: 0.92rem;
    color: var(--cor-primaria);
}
.hero-busca-input:focus,
.hero-busca-select:focus {
    outline: none;
}
.hero-busca-input::placeholder {
    color: var(--cor-texto-muted);
}
.hero-busca-select {
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236B6B6B' stroke-width='1.6'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 0.85rem;
    padding-right: 1.35rem;
}
.hero-busca-divisor {
    display: none;
}
.hero-busca-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 46px;
    border: none;
    border-radius: 999px;
    background-color: var(--cor-destaque);
    color: var(--cor-secundaria);
    font-size: 0.92rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color 0.2s, transform 0.1s;
}
.hero-busca-submit:hover {
    background-color: var(--cor-destaque-hover);
}
.hero-busca-submit:active {
    transform: scale(0.97);
}
@media (min-width: 640px) {
    .hero-busca {
        flex-direction: row;
        align-items: center;
        gap: 0;
        padding: 0.35rem 0.35rem 0.35rem 0.4rem;
        border-radius: 999px;
    }
    .hero-busca-divisor {
        display: block;
        align-self: stretch;
        width: 1px;
        margin: 0.4rem 0;
        background-color: rgba(0, 0, 0, 0.1);
    }
    .hero-busca-submit {
        flex-shrink: 0;
        width: 46px;
    }
    .hero-busca-submit-texto {
        display: none;
    }
}

.carousel-indicators {
    bottom: 15px;
}
.carousel-indicators [data-bs-target] {
    background-color: rgba(255, 255, 255, 0.85);
}

/* 3.3. Títulos de seção */
.section-title {
    text-align: center;
    margin-bottom: 3rem;
}
.section-title h1,
.section-title h2 {
    font-weight: bold;
    position: relative;
    padding-bottom: 0.5rem;
    display: inline-block;
}
.section-title h1::after,
.section-title h2::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    height: 4px;
    width: 80px;
    background-color: var(--cor-destaque);
    border-radius: 2px;
}
.section-title p {
    color: var(--cor-texto-muted);
    margin-top: 1rem;
    max-width: 600px;
    margin-left: auto;
    margin-right: auto;
}

/* 3.4. Botões */
.btn-custom-accent {
    background-color: var(--cor-destaque);
    border-color: var(--cor-destaque);
    color: var(--cor-branco);
    border-radius: var(--raio-borda-padrao);
    font-weight: 500;
    transition: background-color 0.2s;
}
.btn-custom-accent:hover {
    background-color: var(--cor-destaque-hover);
    border-color: var(--cor-destaque-hover);
    color: var(--cor-branco);
}
.btn-outline-light:hover {
    background-color: var(--cor-branco);
    color: var(--cor-secundaria);
}

/* 3.5. Cards */
.card {
    border: none;
    transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
    position: relative;
    border-radius: var(--raio-borda-padrao);
}
.card .card-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-transform: uppercase;
 }
.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
}
.card .card-img-top-cover {
    height: 200px;
    width: 100%;
    object-fit: cover;
    border-radius: var(--raio-borda-padrao) var(--raio-borda-padrao) 0 0;
    transition: transform 0.4s ease;
}
.featured-ad-card {
    margin: 3px;
    border-radius: var(--raio-borda-padrao);
}
.featured-ad-card .card-img-top-cover {
    height: 100%;
}
.preco-destaque {
    font-size: 1.25rem;
}
.city-info {
    font-size: 0.8rem;
    color: var(--cor-texto-muted);
    margin-top: 0.5rem;
}
.city-info i {
    margin-right: 0.25rem;
}

/* 3.5.1. Card inteiro clicável (stretched-link) + zoom suave na foto no
   hover, somado ao translateY(-5px) que o .card:hover já aplica. O
   .card-img-wrapper tem overflow:hidden, então o zoom fica recortado certo. */
.card:hover .card-img-top-cover {
    transform: scale(1.06);
}
/* Mantém elementos clicáveis (favorito, badge) acima do stretched-link. */
.card .acima-do-link {
    position: relative;
    z-index: 2;
}

/* 3.5.2. Card com capa + logo em avatar (estilo "perfil") usado por revenda
   e serviço. O avatar fica fora da capa, como irmão, pra não ser recortado
   pelo overflow dela: sobrepõe metade na capa, metade no corpo. */
.card-capa {
    position: relative;
    height: 130px;
    overflow: hidden;
    border-radius: var(--raio-borda-padrao) var(--raio-borda-padrao) 0 0;
    background: var(--cor-fundo-suave, #e9ecef);
}
.card-capa img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s ease;
}
.card:hover .card-capa img {
    transform: scale(1.06);
}
.card-logo-avatar {
    position: absolute;
    right: 16px;
    top: 102px; /* 130 (capa) menos 28 (metade do avatar) = sobrepõe 50/50 */
    width: 56px;
    height: 56px;
    border-radius: 8px;
    background: #fff;
    color: var(--cor-texto-muted);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    object-fit: contain;
    padding: 5px;
    font-size: 1.2rem;
    z-index: 3;
}
.card.tem-capa .card-body {
    padding-top: 2.2rem;
}
.card.tem-capa .card-title {
    padding-right: 64px; /* não corre por baixo do avatar */
}
/* Card "enxuto" (sem capa personalizada) usado por imobiliária/serviço -
   logo pequena e inline ao lado do nome, em vez do avatar sobreposto à
   capa. Menos poluição visual, mais previsível (nem toda empresa manda
   uma capa de qualidade, e a capa custava espaço vertical sem entregar
   informação nova). Hoje é um .painel-surface (raio/sombra novos), então
   não precisa mais de padding-top próprio - o .painel-surface já dá
   padding em tudo. */
.card-logo-avatar-inline {
    position: static;
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background: #fff;
    border: 1px solid var(--cor-borda, #e9ecef);
    object-fit: contain;
    padding: 4px;
    box-shadow: none;
}
.revenda-rodape {
    color: var(--cor-texto-muted);
    font-size: 0.9rem;
    /* O padding do .painel-surface é simétrico (20px), mas o rodapé colava
       no endereço - 4px no card de serviço - e sobravam 20px embaixo dele.
       Era isso que fazia a base parecer folgada demais em relação ao topo:
       não o padding, e sim o conteúdo empurrado pra baixo. 14px é a mesma
       medida que .painel-surface já usa entre título e corpo. */
    margin-top: 14px;
}
.revenda-ver-loja {
    color: var(--cor-destaque);
    font-weight: 600;
    text-decoration: none;
}

/* Padding simétrico nos cards enxutos. O selo de destaque não empurra o
   conteúdo (é absoluto), então não há por que reservar espaço vertical pra
   ele: ele sobe pro cantinho e encosta de leve no topo do logo, que é como
   estava antes e não atrapalha a leitura. */
.painel-surface.service-card,
.painel-surface.revenda-card-enxuta {
    padding: 22px;
}

/* Dentro de uma coluna de grid a margem do próprio card sobra: o .col é
   flex, então essa margem entra na altura da coluna e o card estica 16px
   além do conteúdo - o que aparecia como um vão extra embaixo, somado ao
   padding. Quem separa os cards ali é o gap do grid, não a margem. */
.col > .painel-surface {
    margin-bottom: 0;
}

/* Cabeçalho do card enxuto (logo + nome), travado na altura do próprio
   logo. Sem isso o bloco crescia junto com o nome - duas, três linhas - e
   o logo, centralizado, descia junto: dois cards lado a lado ficavam com
   logo e nome em alturas diferentes. Duas coisas inflavam o bloco: o
   número de linhas do nome e os 14px de margem que .painel-surface h5
   aplica (e que vencem o mb-0 do markup, por estar fora de @layer). O
   nome fica limitado a duas linhas, que é o que cabe nos 48px. */
.card-enxuto-topo {
    height: 48px;
    align-items: center;
}
.card-enxuto-topo h5 {
    margin-bottom: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 3.5.3. "Ver empresa" e links de contato dos serviços em destaque */
.ver-empresa-link {
    color: var(--cor-destaque);
    font-weight: 600;
}
.link-whatsapp {
    color: #25d366;
    font-size: 1.5rem;
    line-height: 1;
    text-decoration: none;
    transition: transform 0.15s ease;
    display: inline-flex;
    background: none;
    border: 0;
    padding: 0;
}
.link-whatsapp-texto {
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    text-align: left;
}
.link-whatsapp-texto:hover {
    color: #25d366;
}
.link-ligamos {
    color: var(--cor-destaque-hover);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    background: none;
    border: 0;
    padding: 0;
}
.link-ligamos:hover {
    text-decoration: underline;
}
.link-whatsapp:hover {
    color: #1da851;
    transform: scale(1.1);
}
.link-ligacao-icone {
    color: var(--cor-destaque-hover);
    font-size: 1.3rem;
    line-height: 1;
    text-decoration: none;
    transition: transform 0.15s ease;
    display: inline-flex;
    background: none;
    border: 0;
    padding: 0;
}
.link-ligacao-icone:hover {
    color: var(--cor-destaque);
    transform: scale(1.1);
}
/* Avatar de iniciais pra equipe de vendas sem foto cadastrada. */
.avatar-iniciais {
    width: 46px;
    height: 46px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--cor-destaque-suave);
    color: var(--cor-destaque-suave-texto);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.95rem;
}

/* 3.6. Tags, badges e menu mobile */
.tag {
    position: absolute;
    top: 10px; left: 10px;
    background-color: var(--cor-primaria);
    color: var(--cor-branco);
    padding: 4px 8px;
    font-size: 0.75rem;
    border-radius: 4px;
    font-weight: bold;
    white-space: nowrap;
    z-index: 10;
}
/* A .tag continua flutuando (absoluta) também no card enxuto: pôr ela no
   fluxo empurrava o conteúdo, e aí card com destaque e card sem destaque
   ficavam com logo e nome em alturas diferentes na mesma fileira. Em vez
   disso ela sobe pro cantinho e encolhe - o seletor duplo é necessário
   porque .tag.tag-featured tem a mesma especificidade e vem depois no
   arquivo, então venceria e o selo não encolheria. */
.painel-surface > .tag,
.painel-surface > .tag.tag-featured {
    top: 6px;
    left: 22px;
    /* Menor que o selo sobre foto de capa: aqui ele divide espaço com o
       conteúdo em vez de flutuar sobre uma imagem, e cada pixel a menos é
       um pixel a menos de sobreposição no topo do logo. */
    padding: 0.2em 0.6em;
    font-size: 0.7rem;
}

.tag.tag-featured {
    background-color: var(--cor-destaque-suave);
    color: var(--cor-destaque-suave-texto);
    padding: 0.35em 0.65em;
    border-radius: 50rem;
    font-size: 0.75em;
}
.brand-tag {
    position: absolute;
    top: 10px; right: 10px;
    background-color: var(--cor-preto-transparente);
    color: var(--cor-branco);
    padding: 4px 8px;
    font-size: 0.75rem;
    border-radius: 4px;
    font-weight: bold;
    text-transform: uppercase;
    z-index: 10;
}
/* 3.6.1. Ícones circulares do menu (Favoritos, Painel) */
.btn-icon-circle {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--cor-destaque);
    color: var(--cor-destaque);
    text-decoration: none;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.95rem;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.btn-icon-circle:hover {
    text-decoration: none;
    background-color: var(--cor-destaque);
    color: var(--cor-branco);
}
/* Contador de favoritos: badge pequeno no canto do ícone de coração do
   header, com versão inline pro menu mobile. Fica escondido por padrão
   (.d-none) - favoritos.js só remove a classe quando há pelo menos 1 salvo. */
.badge-favoritos-contador {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 50%;
    background-color: #b3261e;
    color: var(--cor-branco);
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}
.badge-favoritos-inline {
    position: static;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    margin-left: 0.25rem;
}
.badge-favoritos-inline.d-none {
    display: none !important;
}

/* 3.6.2. Menu mobile (offcanvas), mesmo esquema visual do header */
.offcanvas-custom {
    background-color: var(--cor-branco);
    color: var(--cor-primaria);
}
.offcanvas-custom .nav-link {
    color: var(--cor-primaria);
    border-radius: var(--raio-borda-padrao);
    padding: 0.5rem 0.75rem;
    font-size: 1rem !important;
    font-weight: 600;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.offcanvas-custom .nav-link:hover,
.offcanvas-custom .nav-link:focus {
    background-color: var(--cor-destaque-suave);
    color: var(--cor-destaque-hover);
}

/* 3.6.3. Botão de favorito (coração no canto da foto) */
.card-img-wrapper {
    position: relative;
    overflow: hidden;
    border-radius: var(--raio-borda-padrao) var(--raio-borda-padrao) 0 0;
}
.btn-favorito {
    position: absolute;
    bottom: 10px;
    right: 10px;
    z-index: 10;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background-color: var(--cor-preto-transparente);
    color: var(--cor-branco);
    border: none;
    outline: none;
    box-shadow: none;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    cursor: pointer;
    transition: transform 0.15s ease, color 0.15s ease;
}
.btn-favorito:hover {
    transform: scale(1.1);
}
.btn-favorito.favorito-ativo {
    color: var(--cor-destaque);
}
/* Variante pra usar fora do card-img-wrapper (ex.: ao lado do título em
   anuncio-detalhes.php) - mesmo botão, mas no fluxo normal em vez de
   absoluto, com cores neutras (a versão escura só faz sentido sobre foto). */
.btn-favorito-inline {
    position: static;
    flex-shrink: 0;
    background-color: var(--cor-fundo);
    color: var(--cor-texto-muted);
}
.btn-favorito-inline.favorito-ativo {
    background-color: var(--cor-destaque-suave);
    color: var(--cor-destaque-hover);
}

.bg-destaque-light {
    background-color: var(--cor-destaque-suave) !important;
    color: var(--cor-destaque-suave-texto) !important;
}


/* 3.7. Breadcrumb */
nav[aria-label="breadcrumb"] {
    padding-bottom: 0.85rem;
    border-bottom: 1px solid #e9ecef;
}
.breadcrumb {
    --bs-breadcrumb-divider: '>';
    margin-bottom: 0;
}
.breadcrumb-item a {
    color: var(--cor-texto-muted);
    text-decoration: none;
}
.breadcrumb-item a:hover {
    color: var(--cor-destaque-hover);
}
.breadcrumb-item.active {
    color: var(--cor-primaria);
    font-weight: 500;
}
.post-header nav[aria-label="breadcrumb"] {
    border-bottom: none;
    padding-bottom: 0;
}
.post-header .breadcrumb a {
    color: rgba(255, 255, 255, 0.8);
}
.post-header .breadcrumb-item.active {
    color: var(--cor-branco);
}


/* 3.8. Rodapé */
footer {
    background: var(--cor-secundaria);
    font-size: 0.85rem;
}
.footer-link {
    transition: color 0.15s ease;
}
.footer-link:hover {
    color: var(--cor-destaque) !important;
}
.footer-accent-line {
    height: 3px;
    background-color: var(--cor-destaque);
    width: 100px;
    margin: 0 auto 1.5rem auto;
    border-radius: 2px;
}
.social-icon {
    transition: transform 0.2s, color 0.2s;
}
.social-icon:hover {
    color: var(--cor-destaque) !important;
    transform: scale(1.1);
}


/* =================================================================
   4. Páginas de listagem e detalhe
   ================================================================= */

/* 4.1. Página de anúncios */
.filter-sidebar {
    background-color: var(--cor-branco);
    position: sticky;
    top: 20px;
}
/* .filter-sidebar também virou .painel-surface (raio novo, ver seção
   13) - e .painel-surface tem seu próprio position:relative (pros
   badges .tag se posicionarem), definido bem depois neste arquivo.
   Mesma especificidade (uma classe cada), então quem vem depois no
   arquivo vencia: o sticky nunca aplicava de verdade (virava
   position:relative, mas o top:20px continuava valendo - por isso o
   filtro não só não flutuava, como ainda ficava 20px desalinhado em
   relação ao painel ao lado). Seletor composto = especificidade maior,
   não depende mais de ordem no arquivo. */
.filter-sidebar.painel-surface {
    position: sticky;
    top: 20px;
}
/* position:sticky só "viaja" dentro dos limites do seu próprio pai
   direto (containing block) - e no desktop o pai direto do formulário
   é [data-drawer-painel], que por sua vez está dentro de
   .filtros-drawer[data-drawer] (o mecanismo de drawer mobile, virado
   estático no desktop). Nenhum dos dois herda a altura esticada que o
   <aside> ganha do grid (align-items:stretch é só no filho direto do
   grid, não se propaga sozinho pros netos) - os dois ficavam com
   altura igual à do próprio formulário, sem sobra nenhuma pro sticky
   "andar" enquanto rola. Resultado: o filtro nunca flutuava, saía de
   tela junto com o resto. 100% aqui repassa a altura do <aside> (que
   conta como "definida" por ser item de grid esticado) até o pai
   direto do formulário. */
@media (min-width: 1024px) {
    .filtros-drawer,
    .filtros-drawer [data-drawer-painel] {
        height: 100%;
    }
}
.sort-bar {
    background-color: var(--cor-branco);
}
.pagination {
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 0.5rem;
    max-width: 100%;
}
@media (max-width: 575.98px) {
    .pagination .page-item .page-link {
        padding: 0.375rem 0.65rem;
        font-size: 0.85rem;
    }
}
.pagination .page-item .page-link {
    color: var(--cor-primaria);
    border-color: #e9ecef;
    border-radius: var(--raio-borda-padrao);
    font-weight: 500;
}
.pagination .page-item.active .page-link {
    background-color: var(--cor-destaque);
    border-color: var(--cor-destaque);
    color: var(--cor-branco);
    font-weight: bold;
}
.pagination .page-item:not(.active):not(.disabled) .page-link:hover {
    background-color: var(--cor-destaque-suave);
    border-color: var(--cor-destaque);
    color: var(--cor-primaria);
}
.pagination .page-item.disabled .page-link {
    color: var(--cor-texto-muted) !important;
    background-color: var(--cor-fundo) !important;
    border-color: #e9ecef !important;
}

/* 4.2. Página de revendas (listagem) */
.revenda-card .card-header {
    border-bottom: 1px solid #eee;
}
.revenda-logo {
    max-height: 60px;
    width: auto;
    object-fit: contain;
}

/* 4.3. Página da revenda (estoque) */
.revenda-header {
    height: 350px;
    background-size: cover;
    background-position: center;
    background-color: var(--cor-primaria);
    position: relative;
}
/* Revenda sem capa cadastrada: gradiente sólido no lugar do placeholder. */
.revenda-header.sem-capa {
    background: linear-gradient(135deg, var(--cor-primaria), #495057);
}
.revenda-header-overlay {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0.2));
    display: flex;
    align-items: flex-end;
}
.revenda-header-overlay > .container {
    padding-bottom: 2rem;
}
.revenda-header-info {
    display: flex;
    align-items: center;
    gap: 1.5rem;
}
.revenda-header-texto {
    color: var(--cor-branco);
    min-width: 0;
}
.revenda-header-texto h1 {
    overflow-wrap: anywhere;
}
.revenda-header-texto p {
    color: rgba(255, 255, 255, 0.75);
}
.revenda-page-logo {
    max-height: 90px;
    width: auto;
    flex-shrink: 0;
    object-fit: contain;
    background-color: rgba(255, 255, 255, 0.95);
    padding: 10px;
    border-radius: var(--raio-borda-padrao);
    border: 2px solid var(--cor-branco);
}
.info-sidebar {
    position: sticky;
    top: 100px;
}
#mapa-revenda {
    /* O Leaflet usa z-index internos altos nos próprios panes/controles
       (400 a 1000+) - sem isolar um novo contexto de empilhamento aqui,
       eles "vazam" pra cima de elementos com z-index bem mais baixo no
       resto da página, como o drawer do menu mobile (z-60 em
       tailwind-input.css). isolation:isolate contém tudo isso dentro do
       próprio mapa. */
    position: relative;
    isolation: isolate;
}
.conteudo-formatado ul,
.conteudo-formatado ol {
    padding-left: 1.25rem;
    margin-bottom: 0.75rem;
}
.conteudo-formatado ul {
    list-style: disc;
}
.conteudo-formatado ol {
    list-style: decimal;
}
.conteudo-formatado li {
    margin-bottom: 0.25rem;
}
.conteudo-formatado p {
    margin-bottom: 0.75rem;
}
.conteudo-formatado p:last-child,
.conteudo-formatado ul:last-child,
.conteudo-formatado ol:last-child {
    margin-bottom: 0;
}
.conteudo-formatado h1,
.conteudo-formatado h2,
.conteudo-formatado h3,
.conteudo-formatado h4,
.conteudo-formatado h5,
.conteudo-formatado h6 {
    font-weight: 600;
    margin-bottom: 0.5rem;
}
.conteudo-formatado blockquote {
    border-left: 3px solid var(--cor-destaque);
    padding-left: 0.75rem;
    margin: 0 0 0.75rem;
    color: var(--cor-texto-muted);
}
.social-icon-revenda {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    background-color: #f1f1f1;
    color: var(--cor-texto-muted);
    border-radius: 50%;
    transition: background-color 0.2s, color 0.2s;
    text-decoration: none;
}
.social-icon-revenda:hover {
    background-color: var(--cor-destaque);
    color: var(--cor-branco);
}
.grid-botoes-contato {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}
.botao-contato-revenda {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    width: 68px;
    background: none;
    border: 0;
    padding: 0;
    text-decoration: none;
    color: var(--cor-texto-muted);
}
.botao-contato-icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    background-color: #f1f1f1;
    color: var(--cor-texto-muted);
    border-radius: 50%;
    transition: background-color 0.2s, color 0.2s;
    font-size: 1.1rem;
}
.botao-contato-revenda:hover .botao-contato-icone {
    background-color: var(--cor-destaque);
    color: var(--cor-branco);
}
.botao-contato-texto {
    font-size: 0.72rem;
    text-align: center;
    line-height: 1.1;
}
.equipe-vendas li {
    padding-bottom: 0.75rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid #f0f2f5;
}
.equipe-vendas li:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}
.equipe-vendas h6 {
    font-weight: 500;
    margin-bottom: 2px;
}

/* 4.4. Página de detalhes do anúncio (galeria e sidebar) - carrossel
   de fotos, ver seção 13 (Linguagem Visual 2.0) pra marcação e estilo
   atuais (.galeria-carrossel-*) - substituiu #main-photo/.thumbnail-*
   (foto única + tira de miniaturas com setas), que não combinava mais
   com o resto do site já migrado. */
.price-card-main {
    background-color: #1f7a4d;
    border: none;
}
.preco-destaque-principal {
    font-size: 2.4rem;
    color: #ffffff;
}
.fipe-link-abaixo {
    color: rgba(255, 255, 255, 0.85);
    font-weight: 400;
    font-size: 0.75rem;
    text-decoration: none;
}
.fipe-link-abaixo:hover {
    color: #ffffff;
}
/* Carrossel de banners da home: o fundo (a section inteira) fica full-bleed
   como separador visual entre as seções, no mesmo espírito da .faixa-marcas
   logo abaixo - só o banner em si (dentro do .container, ver
   paginas/bloco-banners.php) respeita a largura do conteúdo. */
.hero-carousel {
    background-color: #e4e2dd;
    padding: 3rem 0;
}

/* Faixa de marcas em destaque, full-bleed, usada em mais de uma página -
   logo opaca por padrão, ganha destaque no hover. */
.faixa-marcas {
    background-color: #e4e2dd;
    padding: 3rem 0;
    margin-top: 3rem;
}
/* "Pesquisas populares" reaproveita a .faixa-marcas (mesma faixa mais
   escura), mas é a última seção da home, direto antes do footer - dois
   ajustes por causa disso:
   1) Acima do título: a .faixa-marcas original soma margin-top(3rem) +
      padding-top(3rem) = 96px, o dobro do respiro que "Últimos
      anúncios"/"Últimas do blog" têm (mt-5 do .container + mb-6 do
      título ≈ 44px) - aqui reduz pra bater com o mesmo padrão.
   2) Abaixo dos chips: padding-bottom simétrico ao padding-top (só
      respiro interno da faixa, não é o que gerava o espaço reportado)
      - o espaço indevido vinha do footer.php somando seu próprio mt-5
      *depois* do padding-bottom daqui. footer.php agora lê
      $footer_colado (setado só quando esta seção existe, ver
      paginas/home.php) e omite o mt-5 nesse caso - a faixa encosta
      direto no footer, sem nenhum respiro entre os dois (pedido
      explícito: "a faixa tem que encostar no footer"). */
.faixa-pesquisas-populares {
    margin-top: 1.25rem;
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
}
.faixa-marcas-lista {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 2.5rem;
}
.faixa-marcas-item {
    display: inline-flex;
    align-items: center;
    opacity: 0.85;
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.faixa-marcas-item:hover {
    opacity: 1;
    transform: scale(1.08);
}
.faixa-marcas-item img {
    height: 52px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
}
@media (max-width: 575.98px) {
    .faixa-marcas-lista {
        gap: 2rem;
    }
    .faixa-marcas-item img {
        height: 38px;
    }
}

/* Faixa de tipos de imóvel na home: mesma faixa acima, mas cada item é um
   mini card com ícone (não tem "logo" de tipo de imóvel como marca de carro).
   Visual discreto de propósito: ícone na mesma cor do texto, quase como uma
   sombra, pra não competir visualmente com os cards de anúncio da página. */
.faixa-tipos-item {
    flex-direction: column;
    justify-content: center;
    gap: 0.6rem;
    width: 130px;
    padding: 1.5rem 1rem;
    border-radius: var(--raio-borda-padrao, 10px);
    background-color: #ffffff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    opacity: 1;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.faixa-tipos-item:hover {
    opacity: 1;
    transform: translateY(-2px);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.08);
}
.faixa-tipos-icone {
    font-size: 1.75rem;
    line-height: 1;
    color: var(--cor-primaria);
    opacity: 0.28;
    transition: opacity 0.2s ease, color 0.2s ease;
}
.faixa-tipos-item:hover .faixa-tipos-icone {
    opacity: 0.55;
    color: var(--cor-destaque);
}
.faixa-tipos-label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--cor-primaria);
}
@media (max-width: 575.98px) {
    .faixa-tipos-item {
        width: 104px;
        padding: 1.1rem 0.75rem;
    }
    .faixa-tipos-icone {
        font-size: 1.4rem;
    }
}

/* ===== Landing "Anuncie": hero amarelo (mesmo fundo do hero da home)
   englobando o breadcrumb + título + âncoras; os 3 diferenciais viram
   cards brancos que sobem sobre a borda inferior do hero. ===== */
.anuncie-hero {
    position: relative;
    overflow: hidden;
    padding: 3.5rem 0 6rem;
    background-color: var(--cor-destaque);
    background-image:
        radial-gradient(circle at 12% 18%, rgba(255, 255, 255, 0.5) 0%, transparent 42%),
        radial-gradient(circle at 88% 82%, rgba(255, 255, 255, 0.28) 0%, transparent 42%),
        linear-gradient(135deg, var(--cor-destaque) 0%, var(--cor-destaque-hover) 100%);
    color: var(--cor-secundaria);
}
.anuncie-hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(14, 14, 14, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(14, 14, 14, 0.05) 1px, transparent 1px);
    background-size: 46px 46px;
    -webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 35%, #000 25%, transparent 82%);
    mask-image: radial-gradient(ellipse 85% 75% at 50% 35%, #000 25%, transparent 82%);
}
.anuncie-hero-crumb {
    display: flex;
    margin-bottom: 1.5rem;
}
.anuncie-hero-crumb nav[aria-label="breadcrumb"] {
    border-bottom: none;
    padding-bottom: 0;
}
.anuncie-hero-titulo {
    margin-top: 1rem;
    font-family: var(--font-titulo);
    font-size: clamp(1.9rem, 4.5vw, 3rem);
    font-weight: 700;
    line-height: 1.12;
    color: var(--cor-secundaria);
}
.anuncie-hero-sub {
    margin: 1rem auto 0;
    max-width: 44rem;
    font-size: 1.05rem;
    color: rgba(28, 28, 28, 0.75);
}
.anuncie-features {
    position: relative;
    z-index: 10;
    margin-top: -3.25rem;
    margin-bottom: 3rem;
}
.anuncie-feature-card {
    height: 100%;
    padding: 1.75rem;
    border-radius: 1rem;
    background-color: var(--cor-branco);
    box-shadow: 0 18px 45px -14px rgba(0, 0, 0, 0.2);
    text-align: center;
}
.anuncie-feature-icon {
    width: 60px;
    height: 60px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    background-color: var(--cor-destaque);
    color: var(--cor-secundaria);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    box-shadow: 0 6px 16px rgba(20, 184, 166, 0.45);
}
.features-list { column-count: 2; column-gap: 2rem; }
.tech-specs-list .list-group-item {
    padding-left: 0;
    padding-right: 0;
    background-color: transparent;
    border-color: #f0f2f5;
}

/* 4.5. Página guia de serviços */
.service-icon,
.service-card .service-icon {
    width: 70px;
    height: 70px;
    margin: 0 auto 1rem auto;
    background-color: var(--cor-fundo);
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.service-icon i,
.service-card .service-icon i {
    color: var(--cor-destaque-hover);
    font-size: 2rem;
}
.service-card .service-logo {
    max-height: 70px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
    margin: 0 auto 1rem auto;
}


/* 4.6. Páginas do blog */
.painel-post-destaque {
    border-radius: var(--raio-surface);
    box-shadow: var(--sombra-surface);
    background: #fff;
}
.post-header {
    height: 400px;
    background-size: cover;
    background-position: center;
    position: relative;
}
.post-header-overlay {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0.3));
}
.post-content p {
    line-height: 1.8;
    color: #495057;
    margin-bottom: 1rem;
}
.post-content p.lead {
    font-size: 1.15rem;
    color: #333;
    line-height: 1.9;
    font-weight: 400;
    margin-bottom: 1.5rem;
}
.post-content h2 {
    font-size: 1.55rem;
    font-weight: 700;
    color: #1c1c1c;
    margin: 2.2rem 0 1rem;
    padding-bottom: .4rem;
    border-bottom: 3px solid var(--cor-destaque);
}
.post-content h3 {
    font-size: 1.2rem;
    font-weight: 600;
    color: #1c1c1c;
    margin: 1.75rem 0 .6rem;
}
.post-content h4 {
    font-size: 1rem;
    font-weight: 600;
    color: #495057;
    margin: 1.5rem 0 .4rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}
.post-content ul {
    list-style: disc;
    padding-left: 1.5rem;
    margin-bottom: 1rem;
}
.post-content ol {
    list-style: decimal;
    padding-left: 1.5rem;
    margin-bottom: 1rem;
}
.post-content li {
    margin-bottom: .4rem;
    line-height: 1.8;
    color: #495057;
}
.post-content blockquote {
    border-left: 4px solid var(--cor-destaque);
    padding: .9rem 1.4rem;
    margin: 1.75rem 0;
    background: #f8f9fa;
    border-radius: 0 6px 6px 0;
    font-style: italic;
    color: #6c757d;
    font-size: 1.05rem;
}
.post-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
    font-size: .95rem;
}
.post-content table th,
.post-content table td {
    padding: .55rem .85rem;
    border: 1px solid #dee2e6;
    vertical-align: top;
}
.post-content table th {
    background: #f1f3f5;
    font-weight: 600;
    color: #1c1c1c;
    width: 40%;
}
.post-content table tr:nth-child(even) td {
    background: #f8f9fa;
}
.post-content hr {
    border: none;
    border-top: 2px solid #f0f0f0;
    margin: 2.5rem 0;
}
.post-content img {
    max-width: 100%;
    border-radius: 8px;
    margin: 1rem 0;
    height: auto;
}
.post-content .callout {
    background: #fff8e1;
    border-left: 4px solid var(--cor-destaque);
    padding: 1rem 1.25rem;
    border-radius: 0 6px 6px 0;
    margin: 1.75rem 0;
}
.post-content .callout strong {
    display: block;
    margin-bottom: .3rem;
    color: #1c1c1c;
}
.post-content .post-gallery img {
    transition: transform 0.2s ease-in-out;
}
.post-content .post-gallery img:hover {
    transform: scale(1.05);
}
.category-filters .btn-check:checked+.btn, .category-filters .btn.active {
    background-color: var(--cor-destaque);
    border-color: var(--cor-destaque);
    color: var(--cor-branco);
}

/* 4.7. Página anuncie conosco */

/* Navegação rápida (âncoras) pros 3 públicos da página - só os grupos de
   plano que existem de fato no banco ganham um link. */
.anuncie-quicknav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1.5rem;
}
.anuncie-quicknav-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1rem;
    border-radius: 50rem;
    border: 1px solid #e4e2dd;
    background-color: var(--cor-branco);
    color: var(--cor-primaria);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.anuncie-quicknav-item:hover {
    background-color: var(--cor-destaque-suave);
    border-color: var(--cor-destaque);
    color: var(--cor-destaque-hover);
}
/* Compensa a altura do header fixo, pra clicar num link da navegação
   rápida não esconder o título da seção atrás dele. */
.anuncie-secao {
    scroll-margin-top: 110px;
}
/* Linha curta e centralizada (mesma receita do .footer-accent-line) pra
   separar visualmente os 3 escopos de plano. */
.anuncie-divisor {
    height: 3px;
    width: 100px;
    background-color: var(--cor-destaque);
    border-radius: 2px;
    margin: 3rem auto;
}
/* Etiqueta pequena acima do título de cada bloco, indicando pra quem é.
   display:block força a quebra de linha antes do H2 - sem isso, o H2 da
   .section-title é inline-block e sobe pro lado da etiqueta. */
.anuncie-scope-badge {
    display: block;
    width: fit-content;
    margin: 0 auto 0.5rem;
    background-color: var(--cor-fundo);
    color: var(--cor-texto-muted);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    padding: 0.35em 0.9em;
}
/* Selo de tipo do plano (Particular/Revenda/Serviço) em cada card -
   discreto por padrão; ganha contraste em cards destacados, onde o
   cabeçalho vira um degradê amarelo com texto branco. */
.badge-tipo-plano {
    background-color: var(--cor-fundo);
    color: var(--cor-texto-muted);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
}
.pricing-card.featured .badge-tipo-plano {
    background-color: rgba(255, 255, 255, 0.25);
    color: var(--cor-branco);
}

.accordion-button:not(.collapsed) {
    color: var(--cor-destaque-hover);
    background-color: var(--cor-fundo);
}
.accordion-button:focus {
    border-color: var(--cor-destaque);
    box-shadow: 0 0 0 0.25rem rgba(20, 184, 166, 0.25);
}
.pricing-card {
    border: none;
    background-color: var(--cor-branco);
}
.pricing-card .card-header {
    background-color: transparent;
    border-bottom: 1px solid #dee2e6;
}
.pricing-card.featured {
    border: 2px solid var(--cor-destaque);
}
.pricing-card.featured .card-header {
    background: linear-gradient(90deg, var(--cor-destaque) 0%, var(--cor-destaque-hover) 100%);
    color: var(--cor-branco);
    border-color: var(--cor-destaque);
}

/* 4.8. Página de erro 404 */
.error-icon-container {
    width: 150px;
    height: 150px;
    margin: 0 auto;
    background-color: var(--cor-fundo);
    border: 5px solid var(--cor-destaque);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}
.error-icon-container i {
    font-size: 5rem;
    color: var(--cor-destaque-hover);
}

/* 4.9. Página FIPE */
.loader-container {
    display: flex;
    justify-content: center;
    padding: 2rem;
}
.fipe-result-card {
    background-color: var(--cor-fundo);
    border: 1px solid #dee2e6;
    border-radius: var(--raio-borda-padrao);
    padding: 2rem;
    text-align: center;
}


/* =================================================================
   6. Botões de ação flutuantes (FAB)
   ================================================================= */
.fab-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    /* 1000 é exatamente o teto que o Leaflet já usa internamente
       (zoom/atribuição) - empatava e às vezes perdia. Mesmo tier de
       .tabbar-mobile/.contato-fixo-mobile (ver seção 13). */
    z-index: 1025;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.fab-button {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: var(--cor-destaque);
    color: var(--cor-branco);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    text-decoration: none;
    border: 0;
    padding: 0;
    box-shadow: 0 4px 10px rgba(0,0,0,0.2);
    transition: transform 0.2s ease-in-out, background-color 0.2s;
}
.fab-button:hover {
    transform: scale(1.1);
    background-color: var(--cor-destaque-hover);
    color: var(--cor-branco);
}
.fab-button.whatsapp-btn {
    background-color: #25D366;
}
.fab-button.whatsapp-btn:hover {
    background-color: #128C7E;
}
/* Anel pulsante no botão de filtro (mobile, /anuncios) - só pra chamar
   atenção pro recurso, ::before fica atrás do próprio botão (z-index
   -1) e expande/desaparece em loop; o botão em si não anima, só o anel. */
.fab-filtros-wrapper .fab-button {
    position: relative;
}
.fab-filtros-wrapper .fab-button::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--cor-destaque);
    z-index: -1;
    animation: fab-filtro-pulso 2.4s ease-out infinite;
}
@keyframes fab-filtro-pulso {
    0% { transform: scale(1); opacity: .55; }
    100% { transform: scale(1.7); opacity: 0; }
}
.back-to-top-btn {
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity 0.3s, visibility 0.3s, transform 0.3s;
}
.back-to-top-btn.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

/* =================================================================
   7. Banner de cookies
   ================================================================= */
.cookie-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: var(--cor-secundaria);
    color: rgba(255, 255, 255, 0.9);
    z-index: 1050;
    transform: translateY(100%);
    transition: transform 0.5s ease-in-out;
    box-shadow: 0 -2px 10px rgba(0,0,0,0.2);
    padding: 1rem 0;
}
.cookie-banner.show {
    transform: translateY(0);
}
.cookie-banner p a {
    color: var(--cor-destaque);
    text-decoration: underline;
    font-weight: 500;
}
@media (max-width: 575.98px) {
    .cookie-banner .container {
        text-align: center;
    }
}


/* =================================================================
   8. Media queries e responsividade
   ================================================================= */
@media (max-width: 991.98px) {
    .info-sidebar {
        position: static;
        margin-top: 2rem;
    }
}

@media (max-width: 767.98px) {
    .revenda-header {
        height: auto;
        min-height: 240px;
    }
    .revenda-header-overlay > .container {
        padding-top: 2rem;
    }
    /* Empilha logo e texto centralizados pra não disputarem espaço. */
    .revenda-header-info {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 0.75rem;
    }
    .revenda-header-texto h1 {
        font-size: 1.6rem;
        line-height: 1.2;
    }
    .revenda-page-logo {
        max-height: 70px;
    }
}

@media (max-width: 575.98px) { 
    .sort-bar {
        flex-direction: column;
        align-items: flex-start !important;
        gap: 0.75rem;
    }
    .sort-bar .form-control {
        width: 100% !important;
    }
    .features-list {
        column-count: 1;
    }
}

/* =================================================================
   9. Animação de scroll (reveal)
   Aplique a classe "reveal" em qualquer bloco pra ele aparecer com
   fade-in e leve deslocamento ao entrar na tela. As classes
   "reveal-delay-1" a "reveal-delay-3" escalonam elementos próximos,
   como os cards de uma mesma grade.
   ================================================================= */
.reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
}
.reveal-delay-1.is-visible { transition-delay: 0.1s; }
.reveal-delay-2.is-visible { transition-delay: 0.2s; }
.reveal-delay-3.is-visible { transition-delay: 0.3s; }

@media (prefers-reduced-motion: reduce) {
    .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* =================================================================
   10. Faixa full-bleed de separação entre seções (usado em /anuncie)
   Mesmo padrão do .hero-carousel da home: fundo cinza ocupando 100% da
   tela, servindo de divisor visual entre planos - só funciona como filho
   direto de <main>, nunca aninhado dentro de um .container (a matemática
   do width:100vw/margin negativa parte do viewport, não do container pai).
   ================================================================= */
.anuncie-faixa {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    background-color: #e4e2dd;
    padding: 3rem 0;
}
/* Quando a última faixa (FAQ) é o bloco final antes do rodapé, zera a
   margem padrão do rodapé (footer tem "mt-5" global) - sem isso sobra uma
   tira branca entre o fundo cinza da faixa e o rodapé escuro. */
main:has(> .anuncie-faixa:last-child) + footer {
    margin-top: 0 !important;
}

/* =================================================================
   12. Modal de captura de lead (partials/modal-lead.php e
   bloco-modal.php reaproveitam este mesmo seletor de intenção)
   Abas "Ver número" / "Me liguem" mostradas quando o gatilho é do tipo
   ver_numero - as outras origens (whatsapp, ligação direta) pulam
   direto pro formulário, sem esse seletor. Pílula segmentada (raio
   999px, fundo bg-brand-fundo com a opção ativa em branco) em vez do
   antigo estilo "aba sublinhada" - mesmo espírito do alternador
   grade/lista da busca (.btn-modo-exibicao), puxando a Linguagem
   Visual 2.0 (seção 13) pra dentro do modal também. */
.intencao-selector {
    display: flex;
    gap: 4px;
    background: var(--cor-fundo);
    border-radius: 999px;
    padding: 4px;
    margin-bottom: 1rem;
}
.intencao-btn {
    flex: 1;
    background: none;
    border: none;
    border-radius: 999px;
    padding: .55rem 1rem;
    font-size: .85rem;
    color: var(--cor-texto-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    transition: color .15s, background-color .15s;
}
.intencao-btn:hover {
    color: #333;
}
.intencao-btn.active {
    background: #fff;
    color: var(--cor-primaria);
    font-weight: 600;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}

/* Modal de lead - mesmo raio de "sheet" (--raio-surface) usado em
   cards/fotos/painéis na Linguagem Visual 2.0 (seção 13), em vez do
   raio de controle (rounded-padrao, 8px, pensado pra input/botão) que
   o [data-modal-conteudo] genérico usa por padrão. Só #modal-lead -
   não mexe no bloco-modal.php (banner), que continua com o raio
   genérico. No mobile vira bottom-sheet (ancorado embaixo, desliza de
   baixo pra cima) em vez do diálogo centralizado - lê mais "app",
   menos "popup de formulário de desktop espremido no celular". */
#modal-lead [data-modal-conteudo] {
    border-radius: var(--raio-surface);
}
.modal-lead-grabber {
    display: none;
}
@media (max-width: 639.98px) {
    #modal-lead [data-modal-painel] {
        align-items: flex-end;
        padding: 0;
    }
    #modal-lead [data-modal-conteudo] {
        width: 100%;
        max-width: none;
        max-height: 88vh;
        overflow-y: auto;
        border-radius: var(--raio-surface) var(--raio-surface) 0 0;
        /* Vence o scale-95 do [data-modal-conteudo] genérico (mesma
           convenção do projeto: CSS sem @layer já ganha de utility) -
           começa deslocado pra baixo e desliza até 0 na abertura. */
        transform: translateY(24px);
    }
    #modal-lead.is-open [data-modal-conteudo] {
        transform: translateY(0);
    }
    .modal-lead-grabber {
        display: block;
        width: 36px;
        height: 4px;
        border-radius: 999px;
        background: rgba(28, 28, 28, .15);
        margin: 10px auto 0;
    }
}

/* =================================================================
   13. Linguagem Visual 2.0
   Sistema de raio em 3 camadas (--raio-borda-padrao 8px pra controles
   finos, inalterado; --raio-surface 22px novo pra superfícies grandes;
   pílula/rounded-circle já existentes pro resto) + navegação inferior
   fixa no mobile (substitui o menu hambúrguer) + composição de card
   edge-to-edge com preço flutuante. Validado em protótipo antes da
   implementação (ver roadmap no cofre Obsidian).
   ================================================================= */

/* ---- linha flutuante sobre a foto (compartilhar/favoritar à
   direita - o "voltar" saiu, redundante com o botão nativo de voltar
   do navegador/breadcrumb) - só no mobile; a partir de 1024px o
   header real já cobre esse espaço, então some. Vira
   position:absolute (não fixed) e mora DENTRO do
   .galeria-carrossel-wrapper (paginas/anuncio-detalhes.php), que já é
   o position:relative que ancora as setas/contador do carrossel -
   assim fica sempre exatamente sobre a foto, sem depender de nenhum
   número mágico de offset pra descontar altura de header/breadcrumb
   (que variam com o tamanho do título de cada anúncio - um top fixo
   em px já quebrou 2x por causa disso) e rola junto com a página/foto
   em vez de ficar grudada na tela pra sempre (fixed cobria o header
   quando esse número mágico não acertava, relatado como "os ícones
   ficaram no meio da tela"). z-index:2 é o mesmo tier das outras
   camadas flutuantes desse wrapper (setas, contador) - não precisa
   mais brigar com o header (z-index:50), já que não compete de forma
   nenhuma com ele agora. */
.topo-flutuante-mobile {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
    display: flex;
    justify-content: flex-end;
    padding: 16px;
    pointer-events: none;
}
.topo-flutuante-mobile > * {
    pointer-events: auto;
}
.topo-flutuante-mobile .tfm-direita {
    display: flex;
    gap: 8px;
}
/* .btn-favorito "puro" (seção 3) nasce position:absolute (pensado pro
   canto de uma foto de card) - aqui, dentro do flex do .tfm-direita,
   isso escapava do layout e ficava flutuando por cima do botão de
   compartilhar (mesma posição, os dois amontoados e praticamente
   impossíveis de clicar certo). .card-imovel-v2 .btn-favorito já
   reseta isso pro contexto do card; aqui reseta pro contexto da barra
   flutuante. */
.topo-flutuante-mobile .btn-favorito {
    position: static;
}
/* Anúncio sem foto nenhuma - não tem sobre o que flutuar (não existe
   .galeria-carrossel-wrapper pra ancorar), então essa variante (mesma
   marcação, vinda de fora do wrapper) vira só uma linha normal no
   fluxo do documento, acima do título. */
.topo-flutuante-mobile--sem-foto {
    position: static;
    padding: 0;
    margin-bottom: 12px;
}
@media (min-width: 1024px) {
    .topo-flutuante-mobile {
        display: none !important;
    }
}

/* ---- ícone flutuante sobre foto (voltar/compartilhar/favoritar no
   topo do anúncio no mobile) - mesma pílula do .btn-icon-circle, mas
   com fundo branco sólido pra ficar legível em cima de qualquer foto. */
.btn-icon-flutuante {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 0;
    background: rgba(255, 255, 255, .92);
    box-shadow: var(--sombra-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--cor-secundaria);
    cursor: pointer;
}

/* ---- galeria edge-to-edge (substitui a foto dentro de .card com
   padding) - sem moldura no mobile, com raio-surface + sombra a partir
   de 1024px onde volta a ter respiro em volta. */
/* Carrossel de prévia do anúncio (arrasta com o dedo) - "espiada": a
   foto atual ocupa a maior parte da largura, com um pedacinho da
   próxima já visível na lateral (padrão comum em site de imóveis
   grande, ex. ZAP - sinaliza sozinho que dá pra arrastar, sem
   precisar só das setas). Mesmo mecanismo scroll-snap já estabelecido
   pelo .carrossel-banners/.carrossel-destaques (tailwind-input.css),
   só que com slide < 100% em vez de full-bleed. Fotos normalizadas
   via object-fit aqui é intencional - é só a prévia; a íntegra sem
   cortar mora na aba Mídias (.midias-grid, mais abaixo). */
/* Full-bleed (estoura o .container, vai de fora a fora igual o hero/
   .anuncie-faixa) - mesma técnica já usada em .anuncie-faixa (ver
   seção 12): width:100vw + margem negativa igual a metade da
   diferença entre viewport e o 50% do próprio containing block, que
   cancela algebricamente desde que o .container ancestral esteja
   centralizado (é, via margin:0 auto) - funciona mesmo aninhado
   dentro do .container (diferente do aviso antigo da .anuncie-faixa,
   que é sobre outro detalhe: essa nasce direto em <main>, sem
   ancestral nenhum no meio). position:relative continua necessário
   pras setas/contador (absolute) se posicionarem em cima do próprio
   carrossel, não da tela toda. */
.galeria-carrossel-wrapper {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
}
.galeria-carrossel {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}
/* Item invisível no fim do trilho, do mesmo tamanho de um slide (10%
   no mobile, 50% no desktop) - sem ele a ÚLTIMA foto não consegue
   encostar na borda esquerda ao rolar até o fim (o scroll para mais
   cedo, sobra uma faixa vazia). Achava que isso era só padding-right
   no container (10%/50%), mas padding percentual encolhe o content-box
   do próprio flex container - e como os slides do desktop também usam
   flex-basis em %, ficavam sendo calculados em cima dessa largura já
   encolhida pelo padding (50% de padding vira 50% de UM content-box
   que já é só 50% da largura real = slides de 25%, "4 por vez" em vez
   de 2). Um item de verdade no fim (via ::after) não mexe no
   content-box, só ocupa espaço como qualquer outro item do flex. */
.galeria-carrossel::after {
    content: '';
    flex: 0 0 10%;
}
.galeria-carrossel::-webkit-scrollbar {
    display: none;
}
/* Sem raio/sombra de propósito, diferente de todo outro card do site
   - esse carrossel é full-bleed (a primeira foto encosta na borda
   real da tela), então um cantinho arredondado ali ficaria estranho;
   pedido explícito do usuário, exclusivo desse carrossel. */
.galeria-carrossel-slide {
    flex: 0 0 90%;
    scroll-snap-align: start;
    cursor: pointer;
}
/* Altura via clamp em vez de valor fixo: um valor fixo (ex: 420px)
   com o slide ocupando 90% de telas muito largas (monitor grande)
   virava uma foto bem mais "faixa panorâmica" que foto de imóvel,
   feio principalmente com só 1 foto no anúncio (nada de variedade
   pra disfarçar o corte esquisito). Cresce com a largura da tela
   (25vw) mas sobe devagar e para de crescer depois de 640px. */
.galeria-carrossel-slide img {
    width: 100%;
    height: clamp(320px, 25vw, 640px);
    object-fit: cover;
    display: block;
}
/* Desktop: 2 fotos por vez (não mais 1 só ocupando a tela toda) - uma
   única foto full-width em monitor comum (1280-1440px) ficava tão alta
   (clamp de 48vw) que precisava rolar a página só pra ver o resto do
   anúncio, mesmo já sem a "espiada" da próxima. Com 2 por vez, cada
   slide ocupa metade da largura - pra manter a mesma proporção ~2:1 de
   antes (meio-termo bom pra foto vertical e horizontal), a altura
   também cai pela metade (24vw em vez de 48vw). Sem "espiada" de uma
   3ª foto continua valendo (o pedacinho cortado ficava desalinhado com
   só 1 foto no anúncio); o ::after acima cresce pra 50% aqui, mesma
   lógica de folga do mobile (10%) só que do tamanho de 1 slide inteiro
   agora que cada slide é metade da largura. */
@media (min-width: 1024px) {
    .galeria-carrossel::after {
        flex-basis: 50%;
    }
    .galeria-carrossel-slide {
        flex: 0 0 calc(50% - 4px);
    }
    .galeria-carrossel-slide img {
        height: clamp(280px, 24vw, 400px);
    }
}
/* Setas - mesmo botão redondo branco do .btn-expandir-mapa (ver seção
   do mapa em tela cheia), padrão mais recente da sessão. Só faz
   sentido em telas sem toque, mas fica visível em toda largura -
   convive bem com o arrasto por dedo (quem tem os dois usa o que
   preferir). */
.galeria-carrossel-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 38px;
    height: 38px;
    border-radius: 999px;
    background: #fff;
    border: 0;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--cor-primaria);
    cursor: pointer;
    font-size: .9rem;
}
.galeria-carrossel-nav.prev { left: 12px; }
.galeria-carrossel-nav.next { right: 12px; }
.galeria-carrossel-contador {
    position: absolute;
    bottom: 12px;
    right: 12px;
    z-index: 2;
    background: rgba(28, 28, 28, .7);
    color: #fff;
    font-size: .75rem;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
}

/* ---- preço em pílula flutuante (sobre a foto, ou dentro do card de
   listagem) - troca o antigo .price-card-main como bloco à parte. */
.preco-pill {
    font-family: var(--font-titulo);
    font-weight: 700;
    background: #fff;
    border-radius: 999px;
    box-shadow: var(--sombra-surface-flutuante);
    padding: 8px 16px;
    display: inline-block;
}
/* Variante sem "flutuar" - pro preço em destaque dentro de um
   .painel-surface já branco (ex.: sidebar do anúncio), onde a pílula
   branca com sombra do .preco-pill ficava sem contraste nenhum (branco
   sobre branco). Aqui o preço é o próprio conteúdo do painel, grande e
   direto, sem pretender ser um elemento flutuando sobre uma foto. */
.preco-destaque-surface {
    font-family: var(--font-titulo);
    font-weight: 700;
    font-size: 1.75rem;
    color: var(--cor-secundaria);
    line-height: 1.2;
}

/* ---- abas do anúncio (Anúncio / Mídias / Mapa) ---- */
.abas-anuncio {
    display: flex;
    gap: 22px;
    border-bottom: 1px solid rgba(28, 28, 28, .08);
    margin-bottom: 20px;
    overflow-x: auto;
    /* Definir só overflow-x força o overflow-y "visible" implícito a
       virar "auto" também (regra da spec CSS Overflow quando os dois
       eixos divergem) - qualquer estouro vertical de 1px (comum com
       texto de tamanhos diferentes na mesma linha, como o "(1)" da aba
       Mapa) já bastava pra aparecer uma barra de rolagem vertical
       perene do lado das abas. Só o eixo horizontal precisa rolar. */
    overflow-y: hidden;
}
.aba-btn {
    font-family: var(--font-titulo);
    font-weight: 600;
    font-size: .875rem;
    color: var(--cor-texto-muted);
    background: none;
    border: 0;
    cursor: pointer;
    padding: 10px 0;
    position: relative;
    white-space: nowrap;
}
.aba-btn.active {
    color: var(--cor-secundaria);
}
.aba-btn.active::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--cor-destaque);
    border-radius: 2px;
}
/* mostrar/esconder o painel de cada aba já é resolvido pelo mecanismo
   genérico existente (.tab-content > .tab-pane / .fade / .show / .active
   em tailwind-input.css, trocado por inicializarAbas() em ui.js) - as
   abas do anúncio só reaproveitam esse sistema, sem CSS próprio pra isso. */

/* ---- grade de fotos da aba Mídias ---- */
/* Mosaico da aba Mídias: cada foto no formato original, sem cortar
   (ao contrário do carrossel de prévia lá em cima, de propósito) -
   columns em vez de grid faz esse efeito Pinterest/masonry sem JS de
   layout nenhum, já que a galeria não guarda largura/altura de cada
   foto no banco (imovel_fotos não tem esses campos, e não precisa
   ganhar - columns não usa isso). */
.midias-grid {
    columns: 2;
    column-gap: 10px;
}
@media (min-width: 640px) {
    .midias-grid {
        columns: 3;
    }
}
.midia-item {
    display: block;
    break-inside: avoid;
    margin-bottom: 10px;
    border-radius: var(--raio-surface);
    overflow: hidden;
    background: var(--cor-fundo);
}
.midia-item img {
    width: 100%;
    height: auto;
    display: block;
}

/* ---- painel único (substitui pilha de .card empilhados com borda em
   cada linha) - uma superfície só por seção, com grid de specs em vez
   de list-group com <li> com borda-topo cada um. */
.painel-surface {
    position: relative;
    background: #fff;
    border-radius: var(--raio-surface);
    box-shadow: var(--sombra-surface);
    padding: 20px;
    margin-bottom: 16px;
}
.painel-surface h3,
.painel-surface h5 {
    font-family: var(--font-titulo);
    font-size: .95rem;
    font-weight: 600;
    margin: 0 0 14px;
}
/* Lista (ex: list-group do Bootstrap) encostada nas bordas de um
   .painel-surface, cancelando os 20px de padding do container só
   nesse elemento - pra virar borda-a-borda em vez de ficar com um
   respiro duplo (padding do painel + padding de cada item da lista). */
.painel-surface-lista {
    margin: 0 -20px -20px;
}

/* Caixa de alerta (renderAlerta() em partials/ui/alerta.php) - raio
   grande + sombra como qualquer .painel-surface, em vez do antigo
   "rounded-padrao border" com texto colorido (lia como alerta antigo
   de Bootstrap, apontado como "amador" e inconsistente com o resto do
   site). A barra de destaque na borda esquerda (tentativa anterior)
   foi removida - um raio de 22px numa faixa de só 4px de largura não
   acompanha a curva do canto do box, então a barra ficava com uma
   ponta/curva solta, destoando do contorno real da caixa. A cor da
   variante (sucesso/aviso/perigo/neutro) já é comunicada pelo próprio
   fundo suave (bg-*-suave) - texto fica na cor padrão do site. */
.alerta-caixa {
    border-radius: var(--raio-surface);
    box-shadow: var(--sombra-surface);
    padding: 16px 20px;
    color: var(--cor-primaria);
}
.alerta-caixa h4,
.alerta-caixa h5 {
    font-family: var(--font-titulo);
}

/* Mapa expansível em tela cheia, estilo Airbnb (aba Mapa do anúncio e
   da busca). O botão fica sobre o próprio mapa; ativo, o wrapper vira
   fixed:inset-0 no tier mais alto de z-index do site - acima até do
   modal de lead (1070/1071) - e cobre sozinho a navegação inferior/
   barra de contato (1015-1030), sem precisar escondê-las via JS. */
.mapa-expandivel {
    position: relative;
}
/* isolation:isolate contém os z-index internos do Leaflet (até 1000
   nos próprios controles) dentro do próprio mapa - mesma solução já
   usada em #mapa-revenda (imobiliária). Sem isso, rolar a página até
   o mapa ficar embaixo do header fixo (.header-custom, z-index:50)
   deixava os controles do Leaflet vazarem por cima do header
   (relatado como "o mapa passa por cima do header", reproduzido em
   produção/anônimo). Method mais robusto que só subir o z-index de
   cada elemento concorrente (header, nav inferior etc) um por um -
   qualquer elemento novo no futuro já fica protegido de graça. */
.mapa-leaflet-alvo {
    isolation: isolate;
}
.btn-expandir-mapa {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1010;
    width: 38px;
    height: 38px;
    border-radius: 999px;
    background: #fff;
    border: 0;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--cor-primaria);
    cursor: pointer;
    font-size: .9rem;
}
.mapa-expandivel.mapa-tela-cheia {
    position: fixed;
    inset: 0;
    z-index: 1075;
    background: #fff;
    margin: 0;
    border-radius: 0;
}
/* !important necessário aqui pra vencer o height/border-radius inline
   (style="...") que o próprio div do mapa já traz no HTML - não tem
   como uma classe vencer estilo inline sem isso, é a única disputa
   real (não é a guerra unlayered-vs-Tailwind de sempre). */
.mapa-expandivel.mapa-tela-cheia .mapa-leaflet-alvo {
    height: 100% !important;
    border-radius: 0 !important;
}
.mapa-expandivel.mapa-tela-cheia .btn-expandir-mapa {
    top: calc(12px + env(safe-area-inset-top, 0px));
}
.specs-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px 20px;
}
.specs-grid .spec {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.specs-grid .spec .spec-label {
    font-size: .69rem;
    color: var(--cor-texto-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}
.specs-grid .spec .spec-valor {
    font-size: .875rem;
    font-weight: 600;
    color: var(--cor-primaria);
}

/* ---- card de imóvel v2 (listagem/home/busca) - foto edge-to-edge com
   tag de tipo, favorito e preço flutuando por cima, em vez de foto
   dentro de padding com preço abaixo do body. Reaproveita a mesma
   estrutura de dados de renderCardImovel(), só troca a composição. */
.card-imovel-v2 {
    position: relative;
    border-radius: var(--raio-surface);
    overflow: hidden;
    box-shadow: var(--sombra-surface);
    background: #fff;
    display: flex;
    flex-direction: column;
    /* Junto do align-items:stretch padrão (grid/flex não sobrescrevem
       isso em nenhum container que usa este card), faz todo card da
       mesma fileira/carrossel ficar com a mesma altura - sem isso o
       card em si só cresceria até o tamanho do próprio conteúdo. */
    height: 100%;
    transition: transform .2s ease, box-shadow .2s ease;
}
.card-imovel-v2:hover {
    transform: translateY(-3px);
    box-shadow: var(--sombra-surface-flutuante);
}
.card-imovel-v2 .civ2-foto {
    position: relative;
    height: 190px;
    flex-shrink: 0;
    overflow: hidden;
    background: var(--cor-fundo);
}
.card-imovel-v2 .civ2-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .35s ease;
}
.card-imovel-v2:hover .civ2-foto img {
    transform: scale(1.06);
}
.card-imovel-v2 .civ2-play-video {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .9rem;
    pointer-events: none;
}
.card-imovel-v2 .civ2-play-video i {
    margin-left: 2px;
}
.card-imovel-v2 .civ2-tags {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    /* Sem "right" - com os dois (left+right) juntos num container
       flex absoluto, o comportamento de "esticar" pra caber entre eles
       é ambíguo entre navegadores (às vezes vira fit-content mesmo
       assim) e, combinado com flex-wrap, chegou a jogar a tag de tipo
       pra uma "segunda linha" abaixo da estrela - exatamente o
       problema que devia ter sumido. max-width sozinho já evita
       esbarrar no coração de favoritar sem essa ambiguidade. */
    max-width: calc(100% - 56px);
}
/* .tag (gerarTagAnuncio, "Patrocinado"/condição) nasce position:absolute
   pra outro contexto - aqui vira mais um item do flex column acima. */
.card-imovel-v2 .civ2-tags .tag {
    position: static;
}
/* Badge de destaque (gerarTagAnuncio) vira só o ícone da estrela aqui -
   com texto ("Patrocinado") a pílula quebrava linha nos cards mais
   estreitos do grid. */
.card-imovel-v2 .civ2-tags .tag-featured {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    font-size: .8rem;
}
.card-imovel-v2 .civ2-tipo-tag {
    background: rgba(28, 28, 28, .7);
    color: #fff;
    font-size: .656rem;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    white-space: nowrap;
}
.card-imovel-v2 .civ2-preco {
    position: absolute;
    bottom: 10px;
    left: 10px;
    font-size: .875rem;
}
.card-imovel-v2 .civ2-body {
    padding: 14px 16px 16px;
    flex: 1;
    display: flex;
    flex-direction: column;
}
.card-imovel-v2 .civ2-body h4 {
    font-family: var(--font-titulo);
    font-size: .906rem;
    font-weight: 600;
    margin: 0 0 4px;
    line-height: 1.3;
}
.card-imovel-v2 .civ2-body .civ2-loc {
    font-size: .75rem;
    color: var(--cor-texto-muted);
    margin: 0 0 10px;
    display: flex;
    align-items: center;
    gap: 4px;
}
.card-imovel-v2 .civ2-body .civ2-specs {
    display: flex;
    gap: 10px;
    font-size: .719rem;
    color: var(--cor-texto-muted);
    /* Empurra pro fim do card (mesma técnica de margin auto em flex
       column) - assim, mesmo quando o título quebra em 2 linhas em
       alguns cards e não em outros, os specs de todos os cards da
       mesma fileira ficam alinhados na mesma altura. */
    margin-top: auto;
    padding-top: 8px;
}
.card-imovel-v2 .civ2-body .civ2-specs span {
    display: flex;
    align-items: center;
    gap: 4px;
}
/* .btn-favorito já existe (ver seção 3) - variante flutuante sobre a
   foto do card v2, mesmo componente/JS, só reposicionado. */
.card-imovel-v2 .btn-favorito {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .92);
    /* .btn-favorito base é ícone branco pensado pra fundo escuro
       (bottom:10px, círculo semi-transparente) - aqui o fundo é claro,
       então o ícone precisa ser escuro pra aparecer. */
    color: var(--cor-primaria);
}
.card-imovel-v2 .btn-favorito.favorito-ativo {
    color: var(--cor-destaque);
}

/* Alternador grade/lista da busca (/anuncios) - só desktop (o botão
   já nasce hidden lg:flex no PHP; no mobile a coluna única já É a
   lista, não precisa de alternativa). */
/* "Exibir"/"Ordenar por" da busca - mesma pill (bg-brand-fundo,
   rounded-padrao) do alternador grade/lista ao lado, em vez da caixa
   com borda + rótulo flutuando em cima de cada select. O <label> de
   renderSelect() continua no DOM (leitor de tela), só fica invisível
   na tela (mesma técnica do .sr-only do Tailwind) - o ícone à
   esquerda já comunica o que cada select faz. display:flex e
   border:0 aqui vencem o "flex flex-col gap-1.5" e a borda que vêm
   fixos do wrapper/select de renderSelect() porque CSS solto já vence
   utilitário Tailwind neste projeto - não precisou tocar no partial
   compartilhado (usado em várias outras páginas). */
.opcoes-exibicao-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 6px;
    color: var(--cor-texto-muted);
    font-size: .75rem;
}
.opcoes-exibicao-campo {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0;
}
.opcoes-exibicao-campo label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.opcoes-exibicao-campo select {
    border: 0;
    background: transparent;
    padding: 8px 4px;
    font-weight: 600;
    font-size: .813rem;
    color: var(--cor-primaria);
    box-shadow: none;
}
.opcoes-exibicao-campo select:focus {
    outline: none;
    box-shadow: none;
}
.opcoes-exibicao-divisor {
    width: 1px;
    height: 20px;
    background: rgba(28, 28, 28, .1);
}
.btn-modo-exibicao {
    width: 34px;
    height: 34px;
    border-radius: var(--raio-borda-padrao);
    border: 0;
    background: transparent;
    color: var(--cor-texto-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.btn-modo-exibicao.active {
    background: #fff;
    color: var(--cor-primaria);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}
/* .modo-lista troca o grid de cards por uma linha por imóvel (foto à
   esquerda, dados à direita) - mesmo HTML/card, só CSS reflui o
   layout. height:auto e display:flex aqui vencem os pares
   height:100%/display:grid vindos de utilitário Tailwind (@layer
   utilities) porque CSS sem @layer já vence utilitário neste projeto,
   sem precisar de !important. Preso em min-width: a preferência é
   lembrada via localStorage (mesmo navegador entre visitas) e sem
   isso um valor "lista" salvo no desktop quebraria o card no mobile
   (linha horizontal apertada numa tela de 375px) quando o botão que
   alterna já nasce escondido lá. */
@media (min-width: 1024px) {
    .grid-resultados.modo-lista {
        display: flex;
        flex-direction: column;
        gap: 16px;
    }
    .grid-resultados.modo-lista .col {
        width: 100%;
    }
    .grid-resultados.modo-lista .card-imovel-v2 {
        display: flex;
        flex-direction: row;
        height: auto;
    }
    .grid-resultados.modo-lista .civ2-foto {
        width: 260px;
        flex: 0 0 260px;
        height: 180px;
    }
    .grid-resultados.modo-lista .civ2-body {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding: 16px 24px;
    }
    .grid-resultados.modo-lista .civ2-body h4 {
        font-size: 1.05rem;
    }
    .grid-resultados.modo-lista .civ2-body .civ2-specs {
        font-size: .8rem;
        gap: 16px;
        /* No modo lista o corpo já centraliza tudo verticalmente
           (justify-content:center acima) - sem isso o margin-top:auto
           base ganharia do justify-content (margin auto sempre absorve
           o espaço livre primeiro) e colaria os specs no rodapé aqui
           também, o que não faz sentido numa linha horizontal. */
        margin-top: 0;
    }
}

/* ---- barra de contato fixa (mobile, só na página do anúncio) - preço
   + WhatsApp grudados acima da navegação inferior. */
.contato-fixo-mobile {
    position: fixed;
    left: 0;
    right: 0;
    /* Precisa bater exato com a altura real do .tabbar-mobile (~52px,
       medida) - 64px deixava uma folga visível entre as duas barras. */
    bottom: calc(52px + env(safe-area-inset-bottom, 0px));
    /* Precisa vencer os controles internos do Leaflet (zoom +/-,
       atribuição), que usam z-index até 1000 - reportado como "o mapa
       segue sobressaindo ao menu". Mesmo raciocínio do drawer/modal
       (z-[1065]/1070 em tailwind-input.css), só que abaixo deles: a
       barra de contato/nav inferior deve perder pra um drawer/modal
       aberto por cima, mas sempre vencer o mapa. */
    z-index: 1015;
    background: #fff;
    box-shadow: 0 -6px 18px rgba(0, 0, 0, .08);
    padding: 12px 16px;
    display: flex;
    align-items: center;
    gap: 12px;
}
/* O bloco já era centralizado na barra, mas o que a vista lê é o valor
   (strong), e ele caía ~11px abaixo do centro visual com o rótulo "Preço"
   ocupando a metade de cima do bloco. As entrelinhas apertadas encolhem o
   bloco (40px -> 27px medido) e a margem inferior sobe ele metade dela -
   um item flex é centralizado contando as margens. Desvio do valor caiu
   de 11px pra ~1px. */
.contato-fixo-mobile .cfm-preco {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-bottom: 10px;
}
.contato-fixo-mobile .cfm-preco strong {
    display: block;
    font-family: var(--font-titulo);
    font-size: .95rem;
    color: var(--cor-secundaria);
    line-height: 1.05;
}
.contato-fixo-mobile .cfm-preco span {
    display: block;
    font-size: .625rem;
    color: var(--cor-texto-muted);
    line-height: 1;
    margin-bottom: 1px;
}
.contato-fixo-mobile .btn-primario-flex {
    flex: 1;
    /* min-width:0 é o que permite o texto ("Chamar no WhatsApp")
       encolher/quebrar em vez de forçar a barra inteira a alargar -
       item flex sem isso tem min-width implícito = largura do
       conteúdo, empurrando os ícones de compartilhar/favoritar (ver
       .cfm-acoes) pra fora da barra em telas estreitas. */
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: var(--cor-destaque);
    color: #fff;
    font-weight: 600;
    font-size: .85rem;
    /* Este botão usa classe própria, sem .btn nem rounded-padrao, então
       escapou do bloco geral que pôs os formulários em formato pílula -
       era o único botão quadrado que sobrava à vista na barra. */
    border-radius: 999px;
    padding: 11px;
    border: 0;
    cursor: pointer;
}
/* Compartilhar/favoritar dentro da barra fixa - mesmo botão redondo
   .btn-icon-flutuante (pensado pra flutuar sobre foto), só que menor
   e com fundo sólido (a barra já é branca, o semi-transparente
   original ficava sem contraste nenhum aqui). .btn-favorito "puro"
   nasce position:absolute (canto de um card) - reseta pra static de
   novo, mesmo motivo da barra flutuante antiga que ele substituiu. */
.contato-fixo-mobile .cfm-acoes {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}
.contato-fixo-mobile .cfm-icone {
    width: 34px;
    height: 34px;
    background: var(--cor-fundo);
    box-shadow: none;
    color: var(--cor-secundaria);
}
.contato-fixo-mobile .cfm-icone.favorito-ativo {
    color: var(--cor-destaque);
}
.contato-fixo-mobile .btn-favorito {
    position: static;
}
/* O menu de compartilhar abre pra CIMA aqui (top-full, o padrão do
   .dropdown-menu-custom, jogaria a lista pra fora da tela por baixo -
   o botão já mora perto do rodapé). */
.contato-fixo-mobile .dropdown-menu-custom {
    top: auto;
    bottom: 100%;
    margin-top: 0;
    margin-bottom: 8px;
    /* left:0 (não right:0, o padrão do .dropdown-menu-custom) - o
       botão de compartilhar mora perto da esquerda da barra aqui
       (preço + 2 ícones + WhatsApp), então um menu de min-w-[200px]
       ancorado pela direita estourava a tela pela esquerda. */
    left: 0;
    right: auto;
}
@media (min-width: 1024px) {
    .contato-fixo-mobile {
        display: none !important;
    }
}
/* A barra de contato fixa substitui o FAB de WhatsApp no mobile (as
   duas coexistindo era exatamente o "puxadinho" apontado nos
   protótipos) - o botão voltar ao topo continua.
   body.tem-contato-fixo em vez de body:has(.contato-fixo-mobile): um
   relato real de usuário (banner de cookies inacessível, botão
   cortado fora da tela num navegador Android real) apontou que
   :has() pode não estar disponível em todo navegador/WebView de
   verdade usado pelos visitantes, mesmo sendo suportado nas
   ferramentas de teste - diferente de :has(), uma classe no <body>
   escrita pelo PHP (ver layout/header.php, setada por anuncio-
   detalhes.php antes do <body> ser montado) funciona em qualquer
   navegador. Trocado em todo lugar do arquivo que dependia de
   :has(.tabbar-mobile)/:has(.contato-fixo-mobile) pra alguma decisão
   de layout crítica no mobile. */
@media (max-width: 1023.98px) {
    body.tem-contato-fixo .fab-button.whatsapp-btn {
        display: none;
    }
}

/* ---- navegação inferior fixa (mobile) - substitui o menu hambúrguer
   como navegação primária; o hambúrguer/drawer continuam existindo
   pra itens secundários (Imobiliárias, Guia de serviços, Banco de
   pedidos, Blog) que não cabem nos 5 ícones. */
.tabbar-mobile {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1020;
    background: var(--cor-secundaria);
    justify-content: space-around;
    padding: 10px 6px calc(10px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -6px 18px rgba(0, 0, 0, .15);
}
.tabbar-mobile .tm-item {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    color: rgba(255, 255, 255, .5);
    text-decoration: none;
}
.tabbar-mobile .tm-item.active {
    color: var(--cor-destaque);
}
/* :not(.tm-icone-wrap) - sem isso, esse seletor também pegava o span
   embrulho do ícone+badge de favoritos (ambos são span filho direto de
   .tm-item) e encolhia o ícone junto (herda font-size), desalinhando
   ele verticalmente dos outros 4 ícones da nav. */
.tabbar-mobile .tm-item span:not(.tm-icone-wrap) {
    font-size: .563rem;
    font-weight: 600;
}
.tabbar-mobile .tm-item svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* Contador de favoritos no ícone da nav inferior - mesmo .badge-favoritos
   do header (favoritos.js já atualiza qualquer elemento com essa classe),
   só precisa do wrapper posicionado porque aqui o ícone é bem menor (18px)
   que o círculo do header. */
.tm-icone-wrap {
    position: relative;
    display: inline-flex;
}
.tabbar-mobile .tm-item .badge-favoritos-nav {
    top: -7px;
    right: -10px;
    font-size: .55rem;
}
@media (min-width: 1024px) {
    .tabbar-mobile {
        display: none !important;
    }
}
/* Sem barra de contato fixa (páginas fora do anúncio), a navegação
   inferior sozinha ainda precisa de espaço reservado no fim da página
   pro conteúdo não ficar escondido atrás dela. Preso em max-width: as
   regras SEM media query tinham especificidade maior que o reset "zera
   no desktop" abaixo de 1024px - o reset nunca vencia, sobrava
   padding-bottom permanente até no desktop (relatado como "espaço em
   branco após o footer"). Valores batem com a altura real medida do
   .tabbar-mobile (~52px) e do .tabbar-mobile + .contato-fixo-mobile
   juntos (~118px). .tabbar-mobile é renderizado sem condição nenhuma
   pelo footer.php (sempre existe no mobile, não precisa checar) - só
   .contato-fixo-mobile é condicional (só no anúncio, só com WhatsApp
   cadastrado), daí a classe body.tem-contato-fixo (ver layout/
   header.php) em vez de :has(), que um navegador/WebView real
   (relatado por usuário) pode não suportar. */
@media (max-width: 1023.98px) {
    body:not(.tem-contato-fixo) {
        padding-bottom: calc(52px + env(safe-area-inset-bottom, 0px));
    }
    body.tem-contato-fixo {
        padding-bottom: calc(118px + env(safe-area-inset-bottom, 0px));
    }
    /* .fab-container (botão voltar ao topo) é fixed bottom-5 (20px) -
       sem isso ele fica embaixo da navegação inferior nova, os dois se
       sobrepondo (relatado como "a barra esbarra com a seta"). Sobe o
       suficiente pra ficar acima da .tabbar-mobile (e mais ainda quando
       a .contato-fixo-mobile também está presente). */
    .fab-container,
    .fab-filtros-wrapper {
        bottom: calc(52px + 12px + env(safe-area-inset-bottom, 0px));
    }
    body.tem-contato-fixo .fab-container,
    body.tem-contato-fixo .fab-filtros-wrapper {
        bottom: calc(118px + 12px + env(safe-area-inset-bottom, 0px));
    }
    /* .fab-filtros-wrapper só tem z-40 do Tailwind (perde pro Leaflet,
       que usa até 1000 nos próprios controles) - CSS sem @layer já vence
       utilitário do Tailwind neste projeto, então nem precisa de
       !important. Mesmo tier de .fab-container. */
    .fab-filtros-wrapper {
        z-index: 1025;
    }
}

/* Aviso de privacidade (era chamado "banner de cookies" no código,
   renomeado - ver layout/footer.php): virou um "balão" flutuante
   desacoplado da borda inferior, em vez de barra full-bleed grudada
   em bottom:0. Rodadas de bug reais que já saíram dessa barra: (1) no
   mobile ela brigava com a navegação inferior por z-index/posição;
   (2) no desktop o z-index:80 original do utilitário Tailwind perdia
   pro .fab-container (botão voltar ao topo, mesmo canto inferior
   direito) - o botão "Aceitar" aparecia visualmente mas o clique ia
   pro FAB por cima; (3) a causa raiz real por trás de boa parte disso
   nem era nosso CSS - o Brave Shields (e bloqueadores com listas de
   "annoyances"/cookie notice) escondia ou bloqueava cliques no
   elemento só por causa do nome "cookie" no id/class, então qualquer
   ajuste de posição/z-index não resolvia de vez enquanto o nome
   continuasse batendo com o filtro. Cartão compacto com margem em
   todos os lados, raio de canto, z-index acima de tudo e nome neutro
   resolve as três famílias de bug de uma vez. */
.aviso-privacidade-custom {
    left: 12px;
    right: 12px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    border-radius: var(--raio-surface);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .3);
    z-index: 1090;
}
@media (min-width: 640px) {
    .aviso-privacidade-custom {
        left: auto;
        max-width: 420px;
        right: calc(16px + env(safe-area-inset-right, 0px));
    }
}
/* Ainda precisa subir acima da navegação inferior/barra de contato
   (.tabbar-mobile é sempre renderizado no mobile por footer.php, não
   precisa condicional) - com UM valor generoso (a soma das duas,
   118px) que cobre as duas situações (só nav, ou nav + barra de
   contato), em vez de medir o caso exato. Sobra um respiro a mais nas
   páginas que só têm a navegação sozinha; troca aceitável por uma
   regra só, sem depender de :has() (ver comentário grande logo acima
   de .fab-button.whatsapp-btn sobre por quê). */
@media (max-width: 1023.98px) {
    .aviso-privacidade-custom {
        bottom: calc(118px + 12px + env(safe-area-inset-bottom, 0px));
    }
}

/* ---- card de post do blog (mesmo espírito do card-imovel-v2: foto
   edge-to-edge, sem moldura própria) ---- */
.card-blog-v2 {
    position: relative;
    border-radius: var(--raio-surface);
    overflow: hidden;
    box-shadow: var(--sombra-surface);
    background: #fff;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.card-blog-v2 .cb2-foto {
    height: 180px;
    background: var(--cor-fundo);
}
.card-blog-v2 .cb2-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.card-blog-v2 .cb2-body {
    padding: 16px;
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* ---- doorways de SEO na home (Frente B Fase 2) - pílulas de link,
   geradas a partir de combinações tipo+cidade com estoque real. */
.doorways-lista {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.doorway-chip {
    display: inline-flex;
    align-items: center;
    background: #fff;
    box-shadow: var(--sombra-surface);
    border-radius: 999px;
    padding: 10px 18px;
    font-size: .85rem;
    font-weight: 500;
    color: var(--cor-primaria);
    text-decoration: none;
    transition: box-shadow .15s ease, color .15s ease;
}
.doorway-chip:hover {
    color: var(--cor-destaque);
    box-shadow: var(--sombra-surface-flutuante);
}

/* =================================================================
   14. Stories dos anúncios em destaque
   ================================================================= */
/* Reaproveita o mecanismo genérico [data-modal] (abrirModal()/
   fecharModal() de ui.js, mesmo modal-lead.php usa) - só que em tela
   cheia preta, no tier de z-index mais alto do site (acima até do
   mapa em tela cheia, 1075) - intencional, é a única coisa que
   deveria conseguir cobrir um mapa em tela cheia aberto. CSS solto
   (fora de @layer) já vence o utilitário Tailwind de
   [data-modal-painel] (flex items-center justify-center p-4,
   pensado pro diálogo centrado) sem precisar de !important - mesma
   convenção usada o resto da sessão. */
.stories-overlay [data-modal-backdrop] {
    z-index: 1080;
    background: #000;
}
.stories-painel {
    position: fixed;
    inset: 0;
    z-index: 1081;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: 0;
    background: #000;
    max-width: none;
}
.stories-progresso {
    display: flex;
    gap: 4px;
    padding: 10px 10px 0;
    padding-top: calc(10px + env(safe-area-inset-top, 0px));
}
.stories-progresso-item {
    flex: 1;
    height: 3px;
    background: rgba(255, 255, 255, .35);
    border-radius: 999px;
    overflow: hidden;
}
.stories-progresso-preenchimento {
    display: block;
    height: 100%;
    width: 0%;
    background: #fff;
}
@keyframes stories-preencher {
    from { width: 0%; }
    to { width: 100%; }
}
.stories-fechar {
    position: absolute;
    top: calc(16px + env(safe-area-inset-top, 0px));
    right: 12px;
    z-index: 2;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .4);
    border: 0;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    cursor: pointer;
}
/* Botão de mudo/som - mesmo círculo do fechar, um pouco à esquerda
   dele. Só aparece em story de vídeo (stories.js alterna a classe
   hidden); .stories-mudo.hidden aqui dentro (em vez de confiar só na
   .hidden solta do Tailwind) porque CSS sem @layer deste arquivo já
   vence QUALQUER utility, então um .stories-mudo{display:flex} sozinho
   ganharia até do .hidden por especificidade de camada, não só de
   seletor. */
.stories-mudo {
    position: absolute;
    top: calc(16px + env(safe-area-inset-top, 0px));
    right: 58px;
    z-index: 2;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .4);
    border: 0;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    cursor: pointer;
}
.stories-mudo.hidden {
    display: none;
}
.stories-midia {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    min-height: 0;
}
.stories-midia .stories-video,
.stories-midia .stories-foto {
    max-width: 100%;
    max-height: 100%;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
.stories-tap-zone {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 35%;
    background: transparent;
    border: 0;
    z-index: 1;
    padding: 0;
}
.stories-tap-zone.prev { left: 0; }
.stories-tap-zone.next { right: 0; }
.stories-rodape {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    padding: 16px;
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, rgba(0, 0, 0, .7), transparent);
    color: #fff;
}
.stories-rodape-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.stories-rodape-info strong {
    font-family: var(--font-titulo);
    font-size: .95rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}
.stories-rodape-info span {
    font-size: .8rem;
    opacity: .85;
}
.stories-rodape-acoes {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-shrink: 0;
}
.stories-curtir {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: none;
    border: 0;
    color: #fff;
    font-size: .75rem;
    cursor: pointer;
}
.stories-curtir i {
    font-size: 1.3rem;
}
.stories-curtir.curtido i {
    color: var(--cor-destaque);
}
.stories-ver-anuncio {
    background: #fff;
    color: var(--cor-primaria);
    font-weight: 600;
    font-size: .8rem;
    padding: 8px 16px;
    border-radius: 999px;
    white-space: nowrap;
    text-decoration: none;
}

/* Ícone "Destaques" na nav inferior - cor de destaque em vez do
   cinza neutro dos outros 4 itens, chama atenção como o botão que
   abre algo especial (mesmo espírito de anel de status do
   WhatsApp/Instagram, só que mais simples). É <button>, não <a> (não
   navega, só abre o overlay via JS). */
.tm-item-destaques {
    background: none;
    border: 0;
    cursor: pointer;
}
/* Precisa do mesmo peso de seletor que .tabbar-mobile .tm-item (a
   regra de cor cinza-padrão dos itens da nav) pra vencer sem
   !important - uma classe só (.tm-item-destaques sozinha) perde pra
   um seletor composto de duas classes, mesmo vindo depois no
   arquivo. */
.tabbar-mobile .tm-item-destaques {
    color: var(--cor-destaque);
}
.tm-item-destaques.carregando {
    opacity: .6;
    pointer-events: none;
}
/* Anel pulsante ao redor do ícone - mesmo pedido do usuário do anel
   de "novo story" do Instagram, com a mesma técnica de "ping" já usada
   no botão de filtro da busca (.fab-filtro-pulso): um círculo que
   nasce colado no ícone e expande enquanto desaparece, em loop. Mora
   no .tm-icone-wrap (span em volta só do ícone, não do rótulo de
   texto embaixo) pra não esticar/puxar o layout do item. */
.tm-item-destaques .tm-icone-wrap {
    position: relative;
    /* Largura/altura fixas e iguais - sem isso a caixa do wrap só
       tinha a largura natural do glifo do ícone (fa-bolt não é
       quadrado), e o ::before com inset uniforme virava uma elipse em
       vez de círculo. */
    width: 18px;
    height: 18px;
    align-items: center;
    justify-content: center;
}
.tm-item-destaques .tm-icone-wrap::before {
    content: '';
    position: absolute;
    inset: -5px;
    border-radius: 50%;
    border: 1.5px solid var(--cor-destaque);
    animation: tm-anel-pulso 1.8s ease-out infinite;
}
@keyframes tm-anel-pulso {
    0% { transform: scale(.8); opacity: 1; }
    100% { transform: scale(1.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .tm-item-destaques .tm-icone-wrap::before {
        animation: none;
    }
}

/* Corpo do post: mesma superfície do resto do site (raio e sombra vindos
   dos tokens da Linguagem Visual 2.0, via .painel-surface) em vez do
   rounded-3/shadow-sm do shim de compatibilidade do Bootstrap. O padding
   de .painel-surface (20px) é apertado pra um texto longo, então aqui ele
   é maior - e o p-md-5 que dava essa folga no desktop nem existia mais
   depois da migração pro Tailwind, virou classe morta. */
.post-content.painel-surface {
    padding: 24px;
}
@media (min-width: 768px) {
    .post-content.painel-surface {
        padding: 40px;
    }
}

/* Card de post do blog ganha o mesmo hover do card de imóvel: sobe um
   pouco, aprofunda a sombra e aproxima a foto. Antes só o card-imovel-v2
   tinha, e a diferença aparecia lado a lado na home. */
.card-blog-v2 {
    transition: transform .2s ease, box-shadow .2s ease;
}
.card-blog-v2:hover {
    transform: translateY(-3px);
    box-shadow: var(--sombra-surface-flutuante);
}
.card-blog-v2 .cb2-foto img {
    transition: transform .35s ease;
}
.card-blog-v2:hover .cb2-foto img {
    transform: scale(1.06);
}

/* =================================================================
   Inputs e botões no formato "pílula"
   -----------------------------------------------------------------
   Mesmo formato da barra de busca da home (.hero-busca, raio 1rem no
   contêiner e 999px no botão), estendido ao resto dos formulários - que
   antes ficavam no --raio-borda-padrao de 8px.

   Fica fora de @layer, então vence os utilitários rounded-padrao do
   Tailwind sem precisar de !important.

   Textarea fica com 1rem em vez de 999px - uma caixa alta virando
   cápsula corta os cantos do texto. Os botões alcançados são só os que
   usam rounded-padrao (.btn e o que sai de partials/ui/botao.php):
   botão redondo de ícone, favorito e navegação de carrossel não usam
   essa classe, então continuam como estão.
   ================================================================= */
.btn,
button.rounded-padrao,
a.rounded-padrao,
.form-control,
.form-select,
input[type="text"],
input[type="search"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="password"],
input[type="date"],
select {
    border-radius: 999px;
}

textarea,
.form-control[rows] {
    border-radius: 1rem;
}

/* Respiro lateral pra o conteúdo não encostar na curva da pílula. O campo
   com prefixo fica de fora (regra própria logo abaixo), e o input/select
   do hero também (regra logo mais abaixo) - excluídos aqui via :not()
   porque um seletor por tipo (input[type=...]) tem mais especificidade
   que uma classe sozinha (.hero-busca-input), então sem isso a exclusão
   de baixo nunca venceria e o hero ganharia um padding extra indevido. */
input[type="text"]:not(.campo-com-prefixo):not(.hero-busca-input),
input[type="search"]:not(.campo-com-prefixo):not(.hero-busca-input),
input[type="email"]:not(.campo-com-prefixo):not(.hero-busca-input),
input[type="tel"]:not(.campo-com-prefixo):not(.hero-busca-input),
input[type="number"]:not(.campo-com-prefixo):not(.hero-busca-input),
input[type="password"]:not(.campo-com-prefixo):not(.hero-busca-input),
select:not(.hero-busca-select) {
    padding-left: 1rem;
    padding-right: 1rem;
}

/* Campo de valor (o "R$" dentro do input, ver partials/ui/input.php). Na
   pílula o pl-9 do Tailwind não dava conta: o prefixo, ancorado em left-3,
   caía dentro da curva, e o valor digitado colava nele. Empurra os dois -
   prefixo e texto - pra fora do arco. Já entra corrigido (achado no
   AcheiCarros logo depois do formato pílula ter sido aprovado lá). */
.campo-prefixo {
    left: 1rem;
}
input.campo-com-prefixo {
    padding-left: 2.6rem;
    padding-right: 1rem;
}

/* Seta do select. A seta nativa é desenhada colada na borda direita e não
   respeita padding-right, então com o raio de 999px ela encostava na curva.
   Troca pela mesma seta desenhada da busca do hero, que dá pra posicionar a
   1rem da borda, alinhada com o respiro do texto do outro lado. */
select:not(.hero-busca-select) {
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236B6B6B' stroke-width='1.6'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 0.85rem;
    padding-right: 2.4rem;
}

/* A busca do hero já tem o formato próprio - não deve ser reprocessada. */
.hero-busca-input,
.hero-busca-select {
    border-radius: 0;
    padding-left: 0;
    padding-right: 0;
}
.hero-busca-select {
    padding-right: 1.35rem;
}
