/*
 * BANNERS — CSS do motor de anuncios (espaco livre animado e banner do
 * anunciante). Mora no plugin, e nao no tema, por dois motivos:
 *
 * 1. O CPT banner e do plugin; trocar de tema nao pode levar junto o visual
 *    dos anuncios ja vendidos.
 * 2. O preview ao vivo no admin usa exatamente estas regras. Se elas
 *    estivessem no style.css do tema, o admin nao as carregaria e o preview
 *    seria uma copia paralela — duas fontes da verdade para o mesmo visual.
 *
 * As variaveis do tema (--font-serif, --font-primary) aparecem sempre com
 * fallback, porque no admin o tema nao esta carregado.
 */

/* ==========================================================================
   ESPAÇO PUBLICITÁRIO — reserva o formato declarado
   Cada posição já declarava seu formato ("790 x 90 px"), mas nada no HTML
   reservava o espaço: o slot do topo anunciava 790x90 e renderizava 1170x81.
   Agora o slot vale antes e depois de o anúncio existir, então a página não
   pula quando o criativo carrega e o anunciante vê o espaço que comprou.
   ========================================================================== */
.ct-ad-slot {
    width: 100%;
    max-width: var(--ct-ad-w, 790px);
    aspect-ratio: var(--ct-ad-ratio, 790 / 90);
    margin: 0 auto;
    display: flex;
    /* Trava de seguranca: nada dentro do anuncio pode passar do formato
       reservado e empurrar o resto da pagina. */
    overflow: hidden;
    /*
     * Container de consulta por tamanho: os textos do banner animado usam
     * "cqw" (abaixo) em vez de "vw" para escalar com a LARGURA DO PROPRIO
     * ANUNCIO, nao da tela do visitante. Sem isto, "Grande" ficava com o
     * mesmo tamanho de fonte tanto no formato padrao (728px) quanto no
     * banner do topo (1200px, bem maior) — porque "vw" nao sabe nada sobre
     * o tamanho do slot, so da janela. Faz um numero so de regras servir
     * todos os 11 formatos, cada um do tamanho certo, em vez de um jogo de
     * CSS exclusivo por formato para manter sincronizado.
     */
    container-type: inline-size;
}
/*
 * Descendente, e nao filho direto: com o rodizio o container passou a ficar
 * dois niveis abaixo (.ct-ad-slot > .ct-ad-palco > .ct-ad-slide >
 * .ct-ad-container). Como filho direto a regra deixou de casar, o container
 * ficou sem altura e o <a> do anuncio parou de receber clique — o banner
 * aparecia certinho e nao clicava.
 */
.ct-ad-slot .ct-ad-container {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: stretch;
    padding: 0;
}
/* ==========================================================================
   ESPAÇO COMERCIAL LIVRE — placeholder com brilho
   Espaço parado parecia buraco de layout ou anúncio que falhou. Um brilho
   lento atravessando a caixa mostra que o lugar está vivo e à venda — sem
   fingir carregamento, que é o que um shimmer rápido de skeleton diria.
   ========================================================================== */
.ct-ad-vazio {
    position: relative;
    overflow: hidden;
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 16px 22px;
    /* border-radius: 10px;
    Fundo escuro de proposito: peca publicitaria de verdade tem presenca
       propria e se destaca da pagina. A caixa clara tracejada lia como
       "buraco no layout", nao como anuncio.
    border: 1px solid rgba(56, 189, 248, .28); */
    background:
        radial-gradient(120% 160% at 0% 0%, #16304f 0%, transparent 55%),
        radial-gradient(120% 160% at 100% 100%, #10233c 0%, transparent 55%),
        linear-gradient(135deg, #0b1220, #101c30);
}

/*
 * Camada de profundidade: dois halos coloridos girando devagar por tras do
 * conteudo. E o que da a sensacao de peca "viva" — sem eles o fundo escuro
 * fica chapado. transform em camada propria, entao nao repinta o texto.
 */
.ct-ad-vazio::before {
    content: "";
    position: absolute;
    top: -60%;
    left: -30%;
    width: 160%;
    height: 220%;
    background:
        radial-gradient(closest-side, rgba(56, 189, 248, .30), transparent 70%) 20% 40% / 55% 65% no-repeat,
        radial-gradient(closest-side, rgba(34, 197, 94, .22), transparent 70%) 80% 60% / 50% 60% no-repeat;
    animation: ct-ad-aurora 16s linear infinite;
    pointer-events: none;
    z-index: 0;
}

@keyframes ct-ad-aurora {
    0%   { transform: rotate(0deg)   translate3d(0, 0, 0); }
    50%  { transform: rotate(180deg) translate3d(3%, 2%, 0); }
    100% { transform: rotate(360deg) translate3d(0, 0, 0); }
}

.ct-ad-vazio--lateral {
    flex-direction: column;
    justify-content: center;
    text-align: center;
    padding: 20px 16px;
}

/* Conteudo acima do brilho: a faixa passa POR TRAS do texto. Por cima, ela
   lavaria as letras de branco a cada volta. */
.ct-ad-vazio > * {
    position: relative;
    z-index: 1;
}

/*
 * A faixa de luz. transform num pseudo-elemento roda em camada propria — o
 * navegador nao repinta o conteudo a cada quadro, o que importa porque uma
 * pagina pode ter meia duzia destes ao mesmo tempo.
 */
.ct-ad-vazio::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 38%;
    height: 100%;
    /* Reflexo de vidro passando sobre a peca. Sobre fundo escuro ele aparece
       de verdade — sobre o cinza claro anterior quase nao se via. */
    background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, .16) 45%, rgba(255, 255, 255, .30) 50%, rgba(255, 255, 255, .16) 55%, transparent 100%);
    transform: translateX(-140%) skewX(-14deg);
    animation: ct-ad-brilho 4.5s ease-in-out infinite;
    pointer-events: none;
    z-index: 2;
}

/* A parada entre 55% e 100% e proposital: varre e descansa, em vez de virar
   uma esteira continua no canto do olho de quem esta lendo a materia. */
@keyframes ct-ad-brilho {
    0%   { transform: translateX(-140%) skewX(-14deg); }
    55%  { transform: translateX(360%) skewX(-14deg); }
    100% { transform: translateX(360%) skewX(-14deg); }
}

/* Palco das cenas: altura fixa porque as cenas ficam empilhadas em absolute.
   Sem altura, o palco colapsaria e a caixa pularia a cada troca. */
.ct-ad-vazio-palco {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 46px;
}

.ct-ad-vazio--lateral .ct-ad-vazio-palco {
    width: 100%;
    height: 118px;
    flex: none;
}

.ct-ad-cena {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    gap: 14px;
    opacity: 0;
    animation: ct-ad-troca-cena 12s ease-in-out infinite;
}

.ct-ad-vazio--lateral .ct-ad-cena {
    flex-direction: column;
    justify-content: center;
    gap: 10px;
}

/* 12s / 3 cenas = 4s cada. O atraso escalonado faz o rodizio sem uma linha
   de JavaScript — anuncio da casa nao merece script rodando na materia. */
.ct-ad-cena--2 { animation-delay: 4s; }
.ct-ad-cena--3 { animation-delay: 8s; }

/* Entra deslizando da esquerda e sai encolhendo: a cena tem direcao, em vez
   de so piscar no lugar. */
@keyframes ct-ad-troca-cena {
    0%   { opacity: 0; transform: translateX(-18px) scale(.97); }
    5%   { opacity: 1; transform: translateX(0) scale(1); }
    28%  { opacity: 1; transform: translateX(0) scale(1); }
    33%  { opacity: 0; transform: translateX(14px) scale(.97); }
    100% { opacity: 0; transform: translateX(14px) scale(.97); }
}

.ct-ad-vazio-icone {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: rgba(56, 189, 248, .14);
    border: 1px solid rgba(56, 189, 248, .35);
    color: #38bdf8;
    font-size: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    /*
     * Sem pulso aqui de proposito. Cada slot tem 3 cenas empilhadas e as 3
     * pulsavam juntas — inclusive as invisiveis —, e box-shadow repinta a
     * cada quadro. Eram 3 repinturas por slot sem nenhum ganho visual: o
     * icone ja entra em movimento junto com a cena. O brilho que precisa
     * puxar o olho e o do botao, e esse ficou.
     */
}

.ct-ad-vazio-titulo {
    margin: 0 0 3px 0;
    font-size: 15.5px;
    font-weight: 800;
    color: #ffffff;
    letter-spacing: -.01em;
}

.ct-ad-vazio-formato {
    font-size: 12px;
    color: #94a3b8;
    font-weight: 600;
}

.ct-ad-vazio-formato span {
    color: #38bdf8;
    font-weight: 800;
}

.ct-ad-vazio-cta {
    background: linear-gradient(135deg, #16a34a, #15803d);
    color: #ffffff;
    font-weight: 800;
    font-size: 12.5px;
    padding: 9px 18px;
    border-radius: 6px;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex-shrink: 0;
    transition: transform .2s ease, box-shadow .2s ease;
    animation: ct-ad-cta-brilho 2.8s ease-in-out infinite;
}

/* O botao respira junto com o icone: e o ponto de acao da peca e precisa
   puxar o olho depois que a cena termina de entrar. */
@keyframes ct-ad-cta-brilho {
    0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, .45), 0 4px 12px rgba(0, 0, 0, .25); }
    50%      { box-shadow: 0 0 0 9px rgba(34, 197, 94, 0), 0 4px 12px rgba(0, 0, 0, .25); }
}

.ct-ad-vazio-cta:hover {
    color: #ffffff;
    transform: translateY(-1px) scale(1.03);
}

/* ==========================================================================
   BANNER ANIMADO DO ANUNCIANTE — imagem de fundo + movimento do portal
   O cliente manda uma foto; o movimento (zoom lento, reflexo, entrada do
   texto) e do portal. Resolve o comercio local, que raramente tem peca
   animada pronta.
   ========================================================================== */
.ct-ad-animado {
    position: relative;
    display: block;
    flex: 1;
    min-width: 0;
    /*
     * min-height:0 e obrigatorio: como item flex, o padrao e min-height:auto,
     * e o conteudo empurrava a peca para alem do slot — um 1200x90 renderizava
     * 112px de altura e vazava sobre o conteudo da pagina. O formato vendido
     * manda; o que nao couber e problema de configuracao da peca, nao motivo
     * para o anuncio invadir a materia.
     */
    min-height: 0;
    overflow: hidden;
    border-radius: 0;
    text-decoration: none;
    background: #0b1220;
}

/* Zoom lento e continuo na foto (efeito Ken Burns): e o que transforma uma
   imagem parada em peca com vida, sem exigir nada do anunciante. */
.ct-ad-animado-fundo {
    position: absolute;
    inset: 0;
    /*
     * !important em width/height: o motivo NAO e o modelo animado em si —
     * e um conflito de especificidade com o TEMA. ".ct-header-banner img"
     * (style.css do tema, escrita para o modelo antigo de imagem simples,
     * que so precisa ser responsiva) tambem mira em <img>, com uma classe a
     * mais de especificidade (".ct-header-banner img" > ".ct-ad-animado-
     * fundo"), e vencia essa regra: "height:auto" do tema substituia o
     * "height:100%" daqui, a foto caia para a proporcao natural (larga e
     * baixa virava alta e estreita) e o banner do topo (1200x220, o formato
     * mais largo do site) mostrava so o TOPO da imagem em vez de um recorte
     * centralizado. E exatamente o cenario que este arquivo existe para
     * evitar (ver o comentario no topo do arquivo): CSS de anuncio nao pode
     * depender de nenhuma regra do tema, nem para o lado "responsivo".
     */
    width: 100% !important;
    height: 100% !important;
    /*
     * object-fit/-position sao a versao para <img> de background-size/
     * -position cover/center; ficam inertes quando o elemento e o <span>
     * dos fundos solidos/degrade/padrao, entao a mesma regra atende os
     * dois casos. A classe fica direto no <img> (dentro de um <picture>
     * sem nenhum estilo proprio) — um <picture> parado, sem "display:
     * contents" nem qualquer outra regra, nao atrapalha em nada, porque so
     * ancestrais com position != static contam na hora do navegador achar
     * o containing block do <img>.
     */
    background-size: cover;
    background-position: center;
    object-fit: cover;
    object-position: center;
    transform: scale(1.02);
    animation: ct-ad-kenburns 20s ease-in-out infinite alternate;
}

@keyframes ct-ad-kenburns {
    0%   { transform: scale(1.02) translate3d(0, 0, 0); }
    100% { transform: scale(1.13) translate3d(-1.5%, -1%, 0); }
}

/* --- Tipos de animação do fundo (escolhidos no admin) --- */

/* Panorâmica: percorre a foto na horizontal. Precisa de escala extra, senão
   a borda da imagem entra no quadro no fim do percurso. */
.ct-ad-animado--e-pan .ct-ad-animado-fundo {
    animation-name: ct-ad-pan;
    animation-duration: 24s;
}

@keyframes ct-ad-pan {
    0%   { transform: scale(1.16) translate3d(3%, 0, 0); }
    100% { transform: scale(1.16) translate3d(-3%, 0, 0); }
}

/* Respiração: vai e volta no mesmo eixo, sem deslocar. É a opção segura para
   arte que já tem texto embutido — não corta nada das bordas. */
.ct-ad-animado--e-pulse .ct-ad-animado-fundo {
    animation-name: ct-ad-respira;
    animation-duration: 7s;
}

@keyframes ct-ad-respira {
    0%   { transform: scale(1.01); }
    100% { transform: scale(1.06); }
}

/* Rolagem vertical: pensado para print de página inteira (bem mais alto que
   largo) — em vez de cortar o meio da imagem com object-fit:cover e parar
   por ai, percorre ela de cima a baixo devagar, tipo "tour" pela página.
   object-position anima direto (sem transform/scale) porque e a propriedade
   que decide QUAL FATIA de uma imagem grande demais aparece no quadro —
   funciona pra qualquer proporção de imagem, sem precisar calcular
   porcentagem de translate como as outras animações fazem. */
.ct-ad-animado--e-rolagem .ct-ad-animado-fundo {
    animation-name: ct-ad-rolagem;
    animation-duration: 34s;
}

@keyframes ct-ad-rolagem {
    0%   { object-position: center top; }
    100% { object-position: center bottom; }
}

/*
 * Vitrine: quadro fixo (moldura) exibindo um print de pagina inteira
 * percorrendo sozinho, de cima a baixo. Sempre a direita, ligeiramente
 * inclinado — pensado para banner de fundo solido/design, nao foto (com
 * fundo em foto os dois brigariam pelo mesmo protagonismo).
 */
.ct-ad-vitrine {
    position: absolute;
    /*
     * Rolagem pega a altura toda do anuncio — centralizado (top:50% +
     * translateY(-50%)) em vez de top:0, porque a altura agora VARIA com a
     * inclinacao (ver --ct-vitrine-altura): girar um retangulo faz as
     * pontas dele espetarem pra fora da caixa reta, e o que sobra visivel
     * no meio fica mais baixo do que os 100% originais. Comecando mais
     * alto (135%) e centralizado, a sobra das pontas ao girar deixa
     * visivel algo proximo da altura cheia; sem inclinacao (checkbox
     * desmarcado), a variavel volta pra 100% — ver --vitrine-sem-rotacao
     * mais abaixo. O flyer (peca pronta, altura fixa) ignora essa
     * variavel: .ct-ad-vitrine--flyer declara a propria altura.
     */
    top: 50%;
    right: 38px;
    left: auto;
    width: 24%;
    --ct-vitrine-altura: 135%;
    height: var(--ct-vitrine-altura);
    max-width: 360px;
    /*
     * --ct-vitrine-tx comeca em 0% (direita/esquerda, sem deslocamento
     * horizontal extra) e so vira -50% quando a posicao e "centro" (ver
     * regras --vp-centro abaixo). Fica numa variavel, e nao dentro do
     * transform de cada modo (rolagem/flyer) direto, porque os dois tem
     * transform DIFERENTE entre si (rolagem tem rotate, flyer nao) — assim
     * os dois leem a MESMA variavel e a posicao funciona nos dois sem
     * precisar de uma regra pra cada combinacao de tipo x posicao.
     *
     * --ct-vitrine-rot: a inclinacao do rolagem agora e opcional (campo
     * "Inclinar a Vitrine?" no admin) — 6deg e so o PADRAO; quando
     * desmarcado, o PHP acrescenta a classe --vitrine-sem-rotacao, que
     * zera essa variavel pra 0deg mais abaixo no arquivo.
     */
    --ct-vitrine-tx: 0%;
    --ct-vitrine-rot: 6deg;
    transform: translate(var(--ct-vitrine-tx), -50%) rotate(var(--ct-vitrine-rot));
    border-radius: 0;
    overflow: hidden;
    /* box-shadow: 0 10px 24px rgba(0, 0, 0, .22);
    border: 1px solid rgba(0, 0, 0, .06);
    background-color: #fff;
    
     * background-image, e nao <img>+object-fit: um print de pagina inteira e
     * bem mais ESTREITO que o quadro e comprido pra caramba (ex.: 455x2560).
     * object-fit:cover ajusta pela LARGURA — encaixaria a pagina inteira
     * espremida no quadro, e o texto/foto ficam pequenos demais pra
     * reconhecer. background-size com largura fixa (bem maior que a
     * largura real do quadro) da o zoom que falta: so uma faixa vertical
     * da pagina aparece de cada vez, do tamanho de leitura de verdade.
     */
    background-repeat: no-repeat;
    background-size: 300px;
    /*
     * Sem !important aqui: uma declaracao !important normal SEMPRE vence
     * animacao/keyframe na cascata do CSS, sem excecao — nao e um bug do
     * navegador, e a regra. Era exatamente isso que travava a rolagem antes:
     * a animacao rodava (nenhum erro), mas o valor dela nunca aparecia
     * porque este !important prendia o background-position no lugar o
     * tempo todo.
     */
    background-position: -7px 0;
    animation: ct-ad-vitrine-rolagem 94s ease-in-out infinite alternate;
}

@keyframes ct-ad-vitrine-rolagem {
    0%   { background-position: -7px 0%; }
    100% { background-position: -7px 100%; }
}

@media (max-width: 767px) {
    .ct-ad-vitrine {
        display: none;
    }
}

/*
 * Posicao horizontal da vitrine — vale pros dois tipos (rolagem e flyer),
 * por isso mexe so em left/right/--ct-vitrine-tx, nunca no "transform"
 * inteiro (que cada tipo já declara do seu jeito, com ou sem rotate).
 */
.ct-ad-animado--vp-esquerda .ct-ad-vitrine {
    left: 38px;
    right: auto;
}

.ct-ad-animado--vp-centro .ct-ad-vitrine {
    left: 50%;
    right: auto;
    --ct-vitrine-tx: -50%;
}

/*
 * Tamanho da vitrine — "medio" e o que ja vem declarado em .ct-ad-vitrine
 * e .ct-ad-vitrine--flyer (nao precisa de regra propria). O :not() abaixo
 * existe porque QUALQUER vitrine em modo flyer tambem carrega a classe
 * ".ct-ad-vitrine" (a classe base) — sem ele, uma regra "pequeno" escrita
 * so pra rolagem entraria em empate de especificidade com a de flyer, e
 * quem ganhasse dependeria da ORDEM no arquivo, nao da regra certa.
 *
 * So largura no rolagem: a altura dele e sempre 100% (ver .ct-ad-vitrine),
 * pequeno/grande so estreitam ou alargam a janela pro print da pagina.
 */
.ct-ad-animado--vs-pequeno .ct-ad-vitrine:not(.ct-ad-vitrine--flyer) { width: 18%; max-width: 260px; }
.ct-ad-animado--vs-grande  .ct-ad-vitrine:not(.ct-ad-vitrine--flyer) { width: 25%; max-width: 460px; }

.ct-ad-animado--vs-pequeno .ct-ad-vitrine--flyer { width: 11%; height: 64px;  max-width: 120px; }
.ct-ad-animado--vs-grande  .ct-ad-vitrine--flyer  { width: 22%; height: 122px; max-width: 230px; }

/* Inclinar a Vitrine (so importa no rolagem — o flyer nunca inclina, ja
   nao le --ct-vitrine-rot nem --ct-vitrine-altura no proprio transform/
   height). Desmarcado no admin = PHP acrescenta esta classe, que zera a
   rotacao E volta a altura pros 100% certinhos (sem inclinacao nao ha
   ponta nenhuma pra sobrar, entao nao precisa da altura extra). */
.ct-ad-animado--vitrine-sem-rotacao .ct-ad-vitrine {
    --ct-vitrine-rot: 0deg;
    --ct-vitrine-altura: 100%;
}

/*
 * Vitrine em modo "flyer": ate 3 imagens do MESMO tamanho se revezando no
 * quadro (em vez de um print unico maior que a moldura rolando por
 * dentro). Cada <img> preenche o quadro (object-fit:cover) e quem faz o
 * rodizio e o rodizio de opacidade/posicao abaixo — mesmo espirito das
 * Cenas Alternadas do texto principal (ver ct-ad-rodizio-2/3), so que
 * aqui a direcao da transicao (sumir e aparecer, ou deslizar por um dos
 * 4 lados) e escolhida pelo anunciante, entao as keyframes leem a
 * distancia de fora via variavel CSS em vez de ter uma keyframe nomeada
 * por direcao — evita repetir 5 (transicoes) x 3 (quantidades) blocos
 * quase identicos, e principalmente evita reabrir a guerra de
 * especificidade do "animation" (shorthand) vs. "animation-delay" que já
 * pegou este arquivo antes: aqui a direcao nunca é a mesma propriedade
 * que o atraso, entao as duas nunca disputam a mesma declaracao.
 */
/*
 * Diferente do rolagem (que pega quase a altura toda do banner e fica
 * levemente inclinado, imitando um print de tela): o flyer e a peca do
 * anunciante, pronta — nao precisa de tanto destaque nem de inclinacao.
 * Fica reto (sem o rotate do rolagem) e menor, sobrando espaco acima e
 * abaixo dentro do banner.
 */
.ct-ad-vitrine--flyer {
    /*
     * height fixa (nao a variavel do rolagem) — o flyer e uma peca pronta,
     * nao precisa de compensacao de inclinacao (nunca gira: --ct-vitrine-rot
     * nao entra neste transform). background:#fff (shorthand, nao so
     * background-color) por garantia: limpa qualquer background-image/
     * position/size que sobrasse do modo rolagem se o anunciante trocar de
     * tipo sem recarregar a pagina.
     */
    height: 90px;
    width: 16%;
    max-width: 170px;
    transform: translate(var(--ct-vitrine-tx), -50%);
    border-radius: 10px;
}

.ct-ad-vitrine-flyer-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /*
     * contain, e nao cover: no modo flyer a imagem e a peca inteira que o
     * anunciante desenhou (quadrada ou retangular, com cantos e sombra
     * proprios) — cover cortaria (mascararia) as bordas pra preencher o
     * quadro fixo do rolagem, que tem OUTRA proporcao. contain mostra a
     * imagem inteira, sem recorte; a "moldura" quem da e o proprio fundo
     * branco do quadro (.ct-ad-vitrine--flyer) por tras.
     */
    object-fit: contain;
    opacity: 0;
    visibility: hidden;
    --ct-vf-x-in: 0%;
    --ct-vf-y-in: 0%;
    --ct-vf-x-out: 0%;
    --ct-vf-y-out: 0%;
    /*
     * rotX gira em torno do eixo HORIZONTAL (efeito "de cima pra baixo" ou
     * vice-versa — como uma pagina virando por cima); rotY gira em torno
     * do eixo VERTICAL (efeito "da esquerda pra direita" ou vice-versa).
     * O perspective() dentro do proprio transform (em vez de "perspective"
     * como propriedade do pai) mante o efeito 3D contido so nesta imagem,
     * sem afetar a moldura por tras.
     */
    --ct-vf-rotx-in: 0deg;
    --ct-vf-rotx-out: 0deg;
    --ct-vf-roty-in: 0deg;
    --ct-vf-roty-out: 0deg;
}

/* Uma imagem so: nada pra revezar, fica parada e visivel. */
.ct-ad-vitrine--flyers-1 .ct-ad-vitrine-flyer-img {
    opacity: 1;
    visibility: visible;
}

.ct-ad-vitrine--flyers-2 .ct-ad-vitrine-flyer-img { animation: ct-ad-vitrine-flyer-2 12s ease-in-out infinite; }
.ct-ad-vitrine--flyers-3 .ct-ad-vitrine-flyer-img { animation: ct-ad-vitrine-flyer-3 18s ease-in-out infinite; }

.ct-ad-vitrine--flyers-2 .ct-ad-vitrine-flyer-img--2,
.ct-ad-vitrine--flyers-3 .ct-ad-vitrine-flyer-img--2 { animation-delay: 6s; }
.ct-ad-vitrine--flyers-3 .ct-ad-vitrine-flyer-img--3 { animation-delay: 12s; }

@keyframes ct-ad-vitrine-flyer-2 {
    0%      { opacity: 0; visibility: visible; transform: perspective(900px) translate(var(--ct-vf-x-in), var(--ct-vf-y-in)) rotateX(var(--ct-vf-rotx-in)) rotateY(var(--ct-vf-roty-in)); }
    3%, 47% { opacity: 1; visibility: visible; transform: perspective(900px) translate(0, 0) rotateX(0deg) rotateY(0deg); }
    50%     { opacity: 0; visibility: hidden;  transform: perspective(900px) translate(var(--ct-vf-x-out), var(--ct-vf-y-out)) rotateX(var(--ct-vf-rotx-out)) rotateY(var(--ct-vf-roty-out)); }
    100%    { opacity: 0; visibility: hidden;  transform: perspective(900px) translate(var(--ct-vf-x-out), var(--ct-vf-y-out)) rotateX(var(--ct-vf-rotx-out)) rotateY(var(--ct-vf-roty-out)); }
}

@keyframes ct-ad-vitrine-flyer-3 {
    0%      { opacity: 0; visibility: visible; transform: perspective(900px) translate(var(--ct-vf-x-in), var(--ct-vf-y-in)) rotateX(var(--ct-vf-rotx-in)) rotateY(var(--ct-vf-roty-in)); }
    2%, 31% { opacity: 1; visibility: visible; transform: perspective(900px) translate(0, 0) rotateX(0deg) rotateY(0deg); }
    33%     { opacity: 0; visibility: hidden;  transform: perspective(900px) translate(var(--ct-vf-x-out), var(--ct-vf-y-out)) rotateX(var(--ct-vf-rotx-out)) rotateY(var(--ct-vf-roty-out)); }
    100%    { opacity: 0; visibility: hidden;  transform: perspective(900px) translate(var(--ct-vf-x-out), var(--ct-vf-y-out)) rotateX(var(--ct-vf-rotx-out)) rotateY(var(--ct-vf-roty-out)); }
}

/* Direcao da transicao escolhida pelo anunciante — so troca as variaveis
   que as keyframes acima leem, a forma da transicao (segura, some) é a
   mesma pra todas. "fade" nao precisa de regra: 0% em tudo já e o padrão
   declarado no ".ct-ad-vitrine-flyer-img" acima. */
.ct-ad-animado--vtr-direita  .ct-ad-vitrine-flyer-img { --ct-vf-x-in: 100%;  --ct-vf-x-out: -100%; }
.ct-ad-animado--vtr-esquerda .ct-ad-vitrine-flyer-img { --ct-vf-x-in: -100%; --ct-vf-x-out: 100%; }
.ct-ad-animado--vtr-cima     .ct-ad-vitrine-flyer-img { --ct-vf-y-in: -100%; --ct-vf-y-out: 100%; }
.ct-ad-animado--vtr-baixo    .ct-ad-vitrine-flyer-img { --ct-vf-y-in: 100%;  --ct-vf-y-out: -100%; }
/* Girar: viradas em 3D, tipo pagina ou cartao, nao giro plano. rotateX =
   eixo horizontal (efeito "de cima pra baixo"/vice-versa); rotateY = eixo
   vertical (efeito "da esquerda pra direita"/vice-versa). */
.ct-ad-animado--vtr-girar-cima     .ct-ad-vitrine-flyer-img { --ct-vf-rotx-in: 100deg;  --ct-vf-rotx-out: -100deg; }
.ct-ad-animado--vtr-girar-baixo    .ct-ad-vitrine-flyer-img { --ct-vf-rotx-in: -100deg; --ct-vf-rotx-out: 100deg; }
.ct-ad-animado--vtr-girar-esquerda .ct-ad-vitrine-flyer-img { --ct-vf-roty-in: -100deg; --ct-vf-roty-out: 100deg; }
.ct-ad-animado--vtr-girar-direita  .ct-ad-vitrine-flyer-img { --ct-vf-roty-in: 100deg;  --ct-vf-roty-out: -100deg; }

@media (prefers-reduced-motion: reduce) {
    .ct-ad-vitrine-flyer-img {
        animation: none !important;
    }
    .ct-ad-vitrine-flyer-img--1 {
        opacity: 1;
        visibility: visible;
    }
}

.ct-ad-animado--e-fixo .ct-ad-animado-fundo {
    animation: none;
    transform: none;
}

/*
 * Tinta de cor sobre a foto: cor e opacidade vem inline (style="") direto
 * do PHP, porque sao valores livres (qualquer hex, 0-100%) — nao uma lista
 * fechada que vira classe, como o resto das opcoes de fundo. Fica ENTRE a
 * foto e o veu escuro (que continua por cima, cuidando so da legibilidade
 * do texto) — os dois efeitos empilham sem brigar.
 */
.ct-ad-animado-tint {
    position: absolute;
    inset: 0;
}

/* Veu escuro: texto do portal sobre foto de terceiro precisa de contraste
   garantido — sem isso a legibilidade depende da foto que subirem. */
.ct-ad-animado-veu {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(6, 12, 22, .92) 0%, rgba(6, 12, 22, .72) 42%, rgba(6, 12, 22, .15) 78%, rgba(6, 12, 22, 0) 100%);
}

.ct-ad-animado--lateral .ct-ad-animado-veu {
    background: linear-gradient(0deg, rgba(6, 12, 22, .95) 0%, rgba(6, 12, 22, .70) 45%, rgba(6, 12, 22, .10) 100%);
}

/* Reflexo periodico, o mesmo vocabulario do espaco livre. */
.ct-ad-animado::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 38%;
    height: 100%;
    background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, .18) 50%, transparent 100%);
    transform: translateX(-140%) skewX(-14deg);
    animation: ct-ad-brilho 5.5s ease-in-out infinite;
    pointer-events: none;
    z-index: 3;
}

.ct-ad-animado-txt {
    position: absolute;
    left: 22px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    max-width: 62%;
    display: flex;
    flex-direction: column;
    gap: 4px;
    /*
     * Sem animacao no bloco: quem anima agora sao os filhos (chapeu, titulo,
     * subtitulo), pelas classes --x-. O bloco usa transform para se
     * posicionar, e uma animacao aqui sobrescrevia esse transform — no modo
     * centro, o texto terminava a animacao fora do lugar.
     */
}

.ct-ad-animado--lateral .ct-ad-animado-txt {
    top: auto;
    bottom: 62px;
    transform: none;
    left: 18px;
    right: 18px;
    max-width: none;
}

@keyframes ct-ad-anim-entra {
    0%   { opacity: 0; transform: translateY(-50%) translateX(-16px); }
    100% { opacity: 1; transform: translateY(-50%) translateX(0); }
}

.ct-ad-animado--lateral .ct-ad-animado-txt {
    animation-name: ct-ad-anim-entra-lateral;
}

@keyframes ct-ad-anim-entra-lateral {
    0%   { opacity: 0; transform: translateY(14px); }
    100% { opacity: 1; transform: translateY(0); }
}

.ct-ad-animado-titulo {
    font-family: var(--font-serif, "Source Serif 4", Georgia, serif);
    font-size: 21px;
    font-weight: 700;
    line-height: 1.15;
    color: #ffffff;
    letter-spacing: -.01em;
}

/* --- Tipos de fonte do título (escolhidos no admin) ---
   As 4 primeiras usam as familias que o portal ja carrega: itálico e caixa
   alta são tratamentos, não fontes novas — nenhum custo extra na página.
   Condensada e arredondada, no fim, são as únicas 2 que trazem fonte
   própria (banners.css enfileira Bebas Neue + Fredoka à parte, ver
   cidadetrevo_banner_fontes_extra_url em banner-render.php). */
.ct-ad-animado--f-sans .ct-ad-animado-titulo {
    font-family: var(--font-primary, "Google Sans", system-ui, sans-serif);
    font-weight: 800;
    letter-spacing: -.02em;
}

.ct-ad-animado--f-caps .ct-ad-animado-titulo {
    font-family: var(--font-primary, "Google Sans", system-ui, sans-serif);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    font-size: 18px;
    line-height: 1.2;
}

.ct-ad-animado--f-italico .ct-ad-animado-titulo {
    font-family: var(--font-serif, "Source Serif 4", Georgia, serif);
    font-style: italic;
    font-weight: 600;
    letter-spacing: 0;
}

/* Condensada: uma família alta e estreita (peso único, "display") — o
   mesmo espírito de cartaz de evento das opções de "impacto" da Globo.
   Caixa alta é o uso natural dela, então força o transform como o caps já
   faz, em vez de deixar por conta de quem digita o título. */
.ct-ad-animado--f-condensada .ct-ad-animado-titulo {
    font-family: "Bebas Neue", "Oswald", var(--font-primary, "Google Sans"), system-ui, sans-serif;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: .03em;
    line-height: 1.05;
}

/* Arredondada: cantos suaves, peso médio-alto — o tom "amigável" (ex.:
   chamadas de entretenimento/lazer), ao lado das opções mais editoriais. */
.ct-ad-animado--f-arredondada .ct-ad-animado-titulo {
    font-family: "Fredoka", var(--font-primary, "Google Sans"), system-ui, sans-serif;
    font-weight: 600;
    letter-spacing: -.01em;
}

/*
 * --- Tamanho do título (escala relativa ao PRÓPRIO anúncio, não à tela) ---
 * "cqw" (ver .ct-ad-slot) veio no lugar de "vw": em "vw", 4vw numa tela de
 * desktop comum (1300-1800px) já passa de 28px sozinho, então "Grande"
 * batia no teto quase sempre — o mesmo tamanho saía tanto num formato de
 * 728px quanto no banner do topo de 1200px, que é bem maior. Com "cqw" o
 * MESMO conjunto de regras dá um título proporcionalmente maior no formato
 * grande e menor no pequeno (300px), sem precisar de uma folha de estilo
 * por formato.
 */
.ct-ad-animado--t-pequeno .ct-ad-animado-titulo { font-size: clamp(14px, 2.2cqw, 24px); }
.ct-ad-animado--t-medio   .ct-ad-animado-titulo { font-size: clamp(16px, 2.6cqw, 30px); }
.ct-ad-animado--t-grande  .ct-ad-animado-titulo { font-size: clamp(20px, 3.6cqw, 40px); }

.ct-ad-animado--f-caps.ct-ad-animado--t-pequeno .ct-ad-animado-titulo { font-size: clamp(12px, 1.8cqw, 20px); }
.ct-ad-animado--f-caps.ct-ad-animado--t-medio   .ct-ad-animado-titulo { font-size: clamp(14px, 2.2cqw, 25px); }
.ct-ad-animado--f-caps.ct-ad-animado--t-grande  .ct-ad-animado-titulo { font-size: clamp(16px, 2.8cqw, 34px); }

/* Bebas Neue é mais estreita por caractere que o Google Sans: cabe mais
   texto no mesmo espaço, então a escala pode subir um pouco sem estourar —
   o mesmo raciocínio de tamanho dedicado que o caps já tem, acima. */
.ct-ad-animado--f-condensada.ct-ad-animado--t-pequeno .ct-ad-animado-titulo { font-size: clamp(15px, 2.4cqw, 22px); }
.ct-ad-animado--f-condensada.ct-ad-animado--t-medio   .ct-ad-animado-titulo { font-size: clamp(18px, 3.0cqw, 28px); }
.ct-ad-animado--f-condensada.ct-ad-animado--t-grande  .ct-ad-animado-titulo { font-size: clamp(22px, 3.8cqw, 36px); }

/* --- Posição do texto ---
   O véu acompanha o lado do texto: escurecer a esquerda com o texto à
   direita deixaria a legibilidade por conta da sorte da foto. */
/*
 * Centro e o unico modo em que texto, botao e destaque disputam a MESMA
 * coluna. Em absoluto eles se sobrepunham — num 728x90 (90px de altura) o
 * bloco de texto centralizado e o botao no rodape ocupavam o mesmo espaco.
 * Aqui a peca vira uma coluna flex e os tres voltam ao fluxo normal, que e o
 * que garante que um empurre o outro em vez de deitar por cima.
 */
.ct-ad-animado--p-centro {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 16px;
}

.ct-ad-animado--p-centro .ct-ad-animado-txt,
.ct-ad-animado--p-centro .ct-ad-animado-cta,
.ct-ad-animado--p-centro .ct-ad-animado-destaque {
    position: static;
    transform: none;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
}

.ct-ad-animado--p-centro .ct-ad-animado-txt {
    max-width: 100%;
    text-align: center;
    align-items: center;
}

.ct-ad-animado--p-centro .ct-ad-animado-veu {
    background: linear-gradient(90deg, rgba(6, 12, 22, .55) 0%, rgba(6, 12, 22, .82) 50%, rgba(6, 12, 22, .55) 100%);
}

.ct-ad-animado--p-direita .ct-ad-animado-txt {
    left: auto;
    right: 22px;
    text-align: right;
    align-items: flex-end;
    animation-name: ct-ad-anim-entra-dir;
}

@keyframes ct-ad-anim-entra-dir {
    0%   { opacity: 0; transform: translateY(-50%) translateX(16px); }
    100% { opacity: 1; transform: translateY(-50%) translateX(0); }
}

.ct-ad-animado--p-direita .ct-ad-animado-veu {
    background: linear-gradient(270deg, rgba(6, 12, 22, .92) 0%, rgba(6, 12, 22, .72) 42%, rgba(6, 12, 22, .15) 78%, rgba(6, 12, 22, 0) 100%);
}

/* Com o texto à direita, o botão troca de lado para não colidir. */
.ct-ad-animado--p-direita .ct-ad-animado-cta {
    right: auto;
    left: 22px;
}

/* Centralizado nao tem lado livre para o botao: ele desce para o rodape da
   peca, centralizado. Esconder seria desobedecer quem marcou "exibir botao". */
.ct-ad-animado--p-centro .ct-ad-animado-cta {
    top: auto;
    bottom: 10px;
    right: auto;
    left: 50%;
    transform: translateX(-50%);
}

/* Com o botao no rodape, o texto sobe para nao encostar nele. */
.ct-ad-animado--p-centro .ct-ad-animado-txt {
    top: 42%;
}

/* --- Intensidade do escurecimento --- */
.ct-ad-animado--v-forte  .ct-ad-animado-veu { opacity: 1; }
.ct-ad-animado--v-medio  .ct-ad-animado-veu { opacity: .82; }
.ct-ad-animado--v-leve   .ct-ad-animado-veu { opacity: .55; }
.ct-ad-animado--v-nenhum .ct-ad-animado-veu { display: none; }

/*
 * Sem escurecer a foto inteira, o texto ganha uma placa propria atras de si.
 * Testado: so com text-shadow, titulo sobre foto contrastada (pior caso: arte
 * que ja tem letreiro proprio) fica ilegivel. A placa preserva a imagem em
 * volta e garante a leitura no unico lugar onde ela e obrigatoria.
 *
 * So faz sentido com fundo em FOTO: com fundo solido/design (bg-imagem
 * ausente) a cor de fundo ja e previsivel e escolhida por quem cadastrou o
 * banner, entao a placa so atrapalhava — sobrava uma caixa escura solta
 * sobre um fundo claro, sem nenhuma foto por tras pra justificar.
 */
.ct-ad-animado--bg-imagem.ct-ad-animado--v-nenhum .ct-ad-animado-txt {
    padding: 9px 14px;
    border-radius: 8px;
    /* .55 ainda deixava titulo colorido brigar com foto contrastada no teste;
       .72 segura a leitura e continua mostrando a arte em volta. */
    background: rgba(6, 12, 22, .72);
}

.ct-ad-animado--bg-imagem.ct-ad-animado--v-nenhum .ct-ad-animado-titulo,
.ct-ad-animado--bg-imagem.ct-ad-animado--v-nenhum .ct-ad-animado-sub {
    text-shadow: 0 2px 10px rgba(0, 0, 0, .85), 0 1px 3px rgba(0, 0, 0, .9);
}

/* --- Cor e efeito do título --- */
.ct-ad-animado--c-amarelo .ct-ad-animado-titulo {
    color: #fde047;
}

.ct-ad-animado--c-custom .ct-ad-animado-titulo {
    color: var(--ct-ad-cor, #ffffff);
}

/*
 * Degradê no texto: o preenchimento vira a imagem do gradiente recortada na
 * forma das letras. Se o navegador nao suportar background-clip:text, a cor
 * declarada antes continua valendo — por isso ela vem primeiro.
 */
.ct-ad-animado--c-degrade .ct-ad-animado-titulo,
.ct-ad-animado--c-degrade-frio .ct-ad-animado-titulo {
    color: #ffffff;
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.ct-ad-animado--c-degrade .ct-ad-animado-titulo {
    background-image: linear-gradient(92deg, #fde047 0%, #fbbf24 45%, #fff1a8 100%);
}

.ct-ad-animado--c-degrade-frio .ct-ad-animado-titulo {
    background-image: linear-gradient(92deg, #67e8f9 0%, #38bdf8 45%, #e0f2fe 100%);
}

.ct-ad-animado-sub {
    /* cqw: ver o comentario em .ct-ad-slot. */
    font-size: clamp(11px, 1.8cqw, 20px);
    font-weight: 600;
    color: #cbd5e1;
    line-height: 1.35;
}

.ct-ad-animado-cta {
    position: absolute;
    right: 22px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: linear-gradient(135deg, #16a34a, #15803d);
    color: #ffffff;
    font-size: 12.5px;
    font-weight: 800;
    padding: 9px 18px;
    border-radius: 6px;
    white-space: nowrap;
    animation: ct-ad-cta-brilho 2.8s ease-in-out infinite;
}

.ct-ad-animado--lateral .ct-ad-animado-cta {
    top: auto;
    bottom: 16px;
    left: 18px;
    right: auto;
    transform: none;
}

.ct-ad-animado-cta i {
    transition: transform .25s ease;
}

.ct-ad-animado:hover .ct-ad-animado-cta i {
    transform: translateX(4px);
}

@media (max-width: 600px) {
    .ct-ad-animado-titulo { font-size: 17px; }
    .ct-ad-animado-sub    { display: none; }
    .ct-ad-animado-txt    { max-width: 58%; left: 14px; }
    .ct-ad-animado-cta    { right: 12px; padding: 7px 12px; font-size: 11.5px; }
}

@media (prefers-reduced-motion: reduce) {
    .ct-ad-animado-fundo,
    .ct-ad-animado-txt,
    .ct-ad-animado-cta,
    .ct-ad-animado-selo {
        animation: none;
    }
    .ct-ad-animado::after {
        display: none;
    }
}

/* Marcador de rodizio das cenas. */
.ct-ad-cena-dots {
    position: absolute;
    right: 12px;
    bottom: 9px;
    display: flex;
    gap: 5px;
    z-index: 1;
}

.ct-ad-cena-dots span {
    width: 5px;
    height: 5px;
    border-radius: 4px;
    background: rgba(148, 163, 184, .45);
    animation: ct-ad-dot 12s ease-in-out infinite;
}

.ct-ad-cena-dots span:nth-child(2) { animation-delay: 4s; }
.ct-ad-cena-dots span:nth-child(3) { animation-delay: 8s; }

@keyframes ct-ad-dot {
    0%, 33%, 100% { width: 5px;  background: rgba(148, 163, 184, .45); }
    5%, 28%       { width: 16px; background: #38bdf8; }
}

.ct-ad-vazio--lateral .ct-ad-cena-dots {
    left: 0;
    right: 0;
    justify-content: center;
}

/*
 * Quem pediu menos movimento no sistema nao recebe nenhum: espaco publicitario
 * nao vale desconforto de leitura. A caixa continua legivel e vendavel parada.
 */
@media (prefers-reduced-motion: reduce) {
    .ct-ad-vazio::after,
    .ct-ad-vazio::before {
        display: none;
    }
    .ct-ad-vazio-icone,
    .ct-ad-vazio-cta {
        animation: none;
    }
    /* Sem rodizio nao ha o que marcar. */
    .ct-ad-cena-dots {
        display: none;
    }
    /*
     * Sem o rodizio, as cenas 2 e 3 ficariam em opacity:0 para sempre e o
     * espaco apareceria vazio. Trava na cena 1, que e a que carrega a
     * informacao essencial, e esconde as outras de vez.
     */
    .ct-ad-cena {
        animation: none;
    }
    .ct-ad-cena--1 {
        opacity: 1;
        transform: none;
    }
    .ct-ad-cena--2,
    .ct-ad-cena--3 {
        display: none;
    }
}
.ct-ad-link {
    display: block;
    width: 100%;
    line-height: 0;
}
.ct-ad-img {
    /* !important: mesmo motivo do .ct-ad-animado-fundo (ver acima) — o
       modelo "imagem simples" tem o mesmo risco de colidir com
       ".ct-header-banner img" do tema quando usado nessa posicao. */
    width: 100% !important;
    height: 100% !important;
    object-fit: contain;
    border-radius: 8px;
}
@media (max-width: 767px) {
    /* O criativo de celular tem formato próprio (320x50 no topo, por
       exemplo); reservar a proporção de desktop sobraria espaço. */
    .ct-ad-slot {
        aspect-ratio: var(--ct-ad-ratio-mob, var(--ct-ad-ratio, 790 / 90));
    }
}

/* --- Alinhamento do texto, independente da posicao do bloco ---
   Dá para ancorar o bloco a direita e ainda centralizar o texto dentro dele.
   Sem "auto" aqui: ausente a classe, vale o alinhamento herdado da posicao. */
.ct-ad-animado--a-esquerda .ct-ad-animado-txt {
    text-align: left;
    align-items: flex-start;
}

.ct-ad-animado--a-centro .ct-ad-animado-txt {
    text-align: center;
    align-items: center;
}

.ct-ad-animado--a-direita .ct-ad-animado-txt {
    text-align: right;
    align-items: flex-end;
}

/* ==========================================================================
   RODÍZIO — vários anunciantes na mesma posição
   Antes só o de menor ordem aparecia e os demais ficavam cadastrados sem
   nunca ir ao ar. Agora eles se revezam no mesmo espaço.
   ========================================================================== */
.ct-ad-palco {
    position: relative;
    flex: 1;
    min-width: 0;
    display: flex;
}

.ct-ad-palco > .ct-ad-slide {
    flex: 1;
    min-width: 0;
    display: flex;
}

/* Com rodízio, os anúncios ficam empilhados: todos ocupam o mesmo lugar. */
.ct-ad-rotador > .ct-ad-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    /* visibility (e não só opacity) porque um slide invisível por cima
       roubaria o clique do que está aparecendo — e o clique aqui é o que
       o anunciante paga. */
    visibility: hidden;
}

.ct-ad-rotador > .ct-ad-slide:nth-child(1) { animation-delay: 0s; }
.ct-ad-rotador > .ct-ad-slide:nth-child(2) { animation-delay: 6s; }
.ct-ad-rotador > .ct-ad-slide:nth-child(3) { animation-delay: 12s; }
.ct-ad-rotador > .ct-ad-slide:nth-child(4) { animation-delay: 18s; }
.ct-ad-rotador > .ct-ad-slide:nth-child(5) { animation-delay: 24s; }

/* 6s de exposição por anunciante; a duração total é 6s × quantidade. */
.ct-ad-rot-2 > .ct-ad-slide { animation: ct-ad-rodizio-2 12s ease-in-out infinite; }
.ct-ad-rot-3 > .ct-ad-slide { animation: ct-ad-rodizio-3 18s ease-in-out infinite; }
.ct-ad-rot-4 > .ct-ad-slide { animation: ct-ad-rodizio-4 24s ease-in-out infinite; }
.ct-ad-rot-5 > .ct-ad-slide { animation: ct-ad-rodizio-5 30s ease-in-out infinite; }

@keyframes ct-ad-rodizio-2 {
    0%      { opacity: 0; visibility: visible; }
    3%, 47% { opacity: 1; visibility: visible; }
    50%     { opacity: 0; visibility: hidden; }
    100%    { opacity: 0; visibility: hidden; }
}

@keyframes ct-ad-rodizio-3 {
    0%      { opacity: 0; visibility: visible; }
    2%, 31% { opacity: 1; visibility: visible; }
    33%     { opacity: 0; visibility: hidden; }
    100%    { opacity: 0; visibility: hidden; }
}

@keyframes ct-ad-rodizio-4 {
    0%      { opacity: 0; visibility: visible; }
    2%, 23% { opacity: 1; visibility: visible; }
    25%     { opacity: 0; visibility: hidden; }
    100%    { opacity: 0; visibility: hidden; }
}

@keyframes ct-ad-rodizio-5 {
    0%      { opacity: 0; visibility: visible; }
    1%, 18% { opacity: 1; visibility: visible; }
    20%     { opacity: 0; visibility: hidden; }
    100%    { opacity: 0; visibility: hidden; }
}

/*
 * Sem rodízio para quem pediu menos movimento: fica o primeiro da fila,
 * parado. Um anúncio trocando sozinho é exatamente o tipo de movimento
 * que essa preferência existe para evitar.
 */
@media (prefers-reduced-motion: reduce) {
    .ct-ad-rotador > .ct-ad-slide {
        animation: none;
    }
    .ct-ad-rotador > .ct-ad-slide:nth-child(1) {
        opacity: 1;
        visibility: visible;
    }
    .ct-ad-rotador > .ct-ad-slide:not(:nth-child(1)) {
        display: none;
    }
}

/*
 * Cenas alternadas dentro do MESMO anuncio (chapeu+titulo+subtitulo com ate
 * 3 versoes). Reaproveita os keyframes ct-ad-rodizio-2/3 de cima — a forma
 * da transicao (aparece, segura, some) e identica ao rodizio entre
 * anunciantes diferentes; muda so o que alterna: aqui e o texto de UM
 * anuncio so, nao o slide inteiro.
 */
.ct-ad-animado-cena-txt {
    opacity: 0;
    visibility: hidden;
}

.ct-ad-animado--cenas-2 .ct-ad-animado-cena-txt { animation: ct-ad-rodizio-2 12s ease-in-out infinite; }
.ct-ad-animado--cenas-3 .ct-ad-animado-cena-txt { animation: ct-ad-rodizio-3 18s ease-in-out infinite; }

/*
 * Especificidade tem que IGUALAR a regra do "animation" acima (2 classes),
 * senao ela perde por peso mesmo vindo depois no arquivo — foi exatamente
 * o que aconteceu na primeira versao: o atraso da Cena 2 nunca aplicava
 * porque ".ct-ad-animado-cena-txt--2" sozinho (1 classe) pesa menos que
 * ".ct-ad-animado--cenas-2 .ct-ad-animado-cena-txt" (2 classes).
 */
.ct-ad-animado--cenas-2 .ct-ad-animado-cena-txt--2,
.ct-ad-animado--cenas-3 .ct-ad-animado-cena-txt--2 { animation-delay: 6s; }
.ct-ad-animado--cenas-3 .ct-ad-animado-cena-txt--3 { animation-delay: 12s; }

@media (prefers-reduced-motion: reduce) {
    .ct-ad-animado-cena-txt {
        animation: none;
    }
    .ct-ad-animado-cena-txt--1 {
        opacity: 1;
        visibility: visible;
    }
}

/* --- Chapéu (linha pequena acima do título) --- */
.ct-ad-animado-chapeu {
    font-family: var(--font-primary, "Google Sans", system-ui, sans-serif);
    /* cqw: ver o comentario em .ct-ad-slot. Antes era um numero fixo (10.5px)
       igual em qualquer formato — no banner do topo (1200px) ficava
       minusculo perto do resto da peca. */
    font-size: clamp(10px, 1.3cqw, 15px);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: #38bdf8;
}

/* --- Destaque no lado oposto (substitui o botão) ---
   Ocupa o mesmo lugar do botão e herda a cor do título, para preço e desconto
   lerem como parte da peça, e não como um segundo botão. */
.ct-ad-animado-destaque {
    position: absolute;
    right: 22px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.05;
    text-align: center;
}

.ct-ad-animado--p-direita .ct-ad-animado-destaque {
    right: auto;
    left: 22px;
}

.ct-ad-animado--p-centro .ct-ad-animado-destaque {
    top: auto;
    bottom: 8px;
    right: auto;
    left: 50%;
    transform: translateX(-50%);
}

.ct-ad-animado--lateral .ct-ad-animado-destaque {
    top: auto;
    bottom: 16px;
    left: 18px;
    right: auto;
    transform: none;
    align-items: flex-start;
    text-align: left;
}

.ct-ad-animado-destaque-num {
    font-family: var(--font-primary, "Google Sans", system-ui, sans-serif);
    /* cqw: ver o comentario em .ct-ad-slot. */
    font-size: clamp(20px, 3.6cqw, 40px);
    font-weight: 900;
    letter-spacing: -.03em;
    color: #ffffff;
}

.ct-ad-animado-destaque-sub {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #cbd5e1;
    margin-top: 3px;
}

/* O destaque acompanha a cor escolhida para o título. */
.ct-ad-animado--c-amarelo .ct-ad-animado-destaque-num { color: #fde047; }
.ct-ad-animado--c-custom  .ct-ad-animado-destaque-num { color: var(--ct-ad-cor, #ffffff); }

/* ==========================================================================
   ANIMAÇÃO DE ENTRADA/SAÍDA DO TEXTO
   Anima os FILHOS (chapéu, título, subtítulo), e não o bloco: o bloco usa
   transform para se posicionar (translateY(-50%), translate(-50%,-50%) no
   centro) e uma animação por cima disso brigaria com a centralização —
   o texto saltava de lugar ao terminar de animar.
   ========================================================================== */
.ct-ad-animado-txt > * {
    animation-fill-mode: both;
}

/* Escalonado: chapéu, título e subtítulo entram em sequência, não em bloco. */
.ct-ad-animado-txt > *:nth-child(1) { animation-delay: 0s; }
.ct-ad-animado-txt > *:nth-child(2) { animation-delay: .12s; }
.ct-ad-animado-txt > *:nth-child(3) { animation-delay: .24s; }

.ct-ad-animado--x-deslizar .ct-ad-animado-txt > * {
    animation-name: ct-ad-txt-deslizar;
    animation-duration: .6s;
    animation-timing-function: cubic-bezier(.2, .7, .3, 1);
}

.ct-ad-animado--x-subir .ct-ad-animado-txt > * {
    animation-name: ct-ad-txt-subir;
    animation-duration: .6s;
    animation-timing-function: cubic-bezier(.2, .7, .3, 1);
}

.ct-ad-animado--x-zoom .ct-ad-animado-txt > * {
    animation-name: ct-ad-txt-zoom;
    animation-duration: .55s;
    animation-timing-function: cubic-bezier(.2, .7, .3, 1);
}

/* Ciclo: entra, segura, sai e repete. */
.ct-ad-animado--x-ciclo .ct-ad-animado-txt > * {
    animation-name: ct-ad-txt-ciclo;
    animation-duration: 7s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.ct-ad-animado--x-nenhuma .ct-ad-animado-txt > * {
    animation: none;
}

@keyframes ct-ad-txt-deslizar {
    from { opacity: 0; transform: translateX(-18px); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes ct-ad-txt-subir {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes ct-ad-txt-zoom {
    from { opacity: 0; transform: scale(.86); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes ct-ad-txt-ciclo {
    0%          { opacity: 0; transform: translateY(14px); }
    8%, 62%     { opacity: 1; transform: translateY(0); }
    72%, 100%   { opacity: 0; transform: translateY(-14px); }
}

@media (prefers-reduced-motion: reduce) {
    .ct-ad-animado-txt > * {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}

/* ==========================================================================
   FUNDO SEM FOTO — designs prontos
   Para o anunciante que só tem o logo em PNG e nenhuma foto de fundo.
   ========================================================================== */
.ct-ad-animado--bg-escuro  .ct-ad-animado-fundo { background: radial-gradient(120% 180% at 15% 0%, #334155 0%, transparent 60%), linear-gradient(120deg, #0f172a, #1e293b); }
.ct-ad-animado--bg-azul    .ct-ad-animado-fundo { background: radial-gradient(120% 180% at 15% 0%, #0ea5e9 0%, transparent 60%), linear-gradient(120deg, #082f49, #0c4a6e); }
.ct-ad-animado--bg-verde   .ct-ad-animado-fundo { background: radial-gradient(120% 180% at 15% 0%, #22c55e 0%, transparent 60%), linear-gradient(120deg, #052e16, #14532d); }
.ct-ad-animado--bg-laranja .ct-ad-animado-fundo { background: radial-gradient(120% 180% at 15% 0%, #f97316 0%, transparent 60%), linear-gradient(120deg, #431407, #7c2d12); }
.ct-ad-animado--bg-roxo    .ct-ad-animado-fundo { background: radial-gradient(120% 180% at 15% 0%, #a855f7 0%, transparent 60%), linear-gradient(120deg, #2e1065, #4c1d95); }
.ct-ad-animado--bg-solido  .ct-ad-animado-fundo { background: var(--ct-ad-fundo, #0f172a); }
.ct-ad-animado--bg-pontilhado .ct-ad-animado-fundo { background-color: #0f172a; background-image: radial-gradient(rgba(255, 255, 255, .22) 1.6px, transparent 1.6px); background-size: 16px 16px; }
.ct-ad-animado--bg-diagonal   .ct-ad-animado-fundo { background-color: #0f172a; background-image: repeating-linear-gradient(135deg, rgba(255, 255, 255, .09) 0 10px, transparent 10px 22px); }

/*
 * Design pronto já nasce escuro e uniforme: o véu por cima só apagaria o
 * desenho sem ganhar legibilidade nenhuma. Ele existe para domar FOTO.
 */
.ct-ad-animado:not(.ct-ad-animado--bg-imagem) .ct-ad-animado-veu {
    display: none;
}

/* O zoom/panorâmica são efeitos de foto; num gradiente eles não têm o que
   revelar e só deslocariam o desenho. */
.ct-ad-animado:not(.ct-ad-animado--bg-imagem) .ct-ad-animado-fundo {
    animation: none;
    transform: none;
}

/* ==========================================================================
   PNGs SOBREPOSTOS — logo, produto recortado
   Cada um tem posição, tamanho e efeito próprios.
   ========================================================================== */
.ct-ad-png {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1;
    display: block;
    pointer-events: none;
    line-height: 0;
}

.ct-ad-png img {
    display: block;
    /*
     * !important pelo mesmo motivo do .ct-ad-animado-fundo, mais acima: uma
     * regra do TEMA (".ct-header-banner img", escrita para o modelo antigo
     * de imagem simples) tambem mira em <img> com especificidade igual, e
     * dependendo da ordem de carregamento podia vencer o "height:100%"
     * daqui. O sintoma era a logo em PNG encolher para a propria proporcao
     * (ficando mais baixa que a caixa reservada) e SUBIR — ela nao ficava
     * fora do centro, so nao preenchia a caixa que estava, essa sim,
     * centrada; a sobra ficava toda embaixo, nunca dividida pros dois lados.
     */
    width: 100% !important;
    height: 100% !important;
    object-fit: contain;
}

/* Altura relativa à peça: o mesmo "médio" serve a um 728x90 e a um 300x600. */
.ct-ad-png--t-pequeno { height: 46%; width: 22%; }
.ct-ad-png--t-medio   { height: 68%; width: 30%; }
.ct-ad-png--t-grande  { height: 88%; width: 38%; }

/*
 * Realce: contorno de luz ou de sombra seguindo o RECORTE da imagem —
 * drop-shadow usa o canal alfa do PNG (ao contrario de box-shadow, que
 * desenharia um retangulo em volta). E o que salva um logo ou produto
 * recortado que cairia invisivel num fundo escuro (contorno de luz) ou por
 * cima de letras da propria peca (contorno de sombra), sem precisar
 * redesenhar a arte do anunciante.
 */
.ct-ad-png--r-sombra img {
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .55)) drop-shadow(0 0 10px rgba(0, 0, 0, .35));
}

.ct-ad-png--r-brilho img {
    filter: drop-shadow(0 0 8px rgba(255, 255, 255, .85)) drop-shadow(0 0 16px rgba(255, 255, 255, .5));
}

.ct-ad-png--p-esquerda { left: 12px; }
.ct-ad-png--p-direita  { right: 12px; }
.ct-ad-png--p-centro   { left: 50%; transform: translate(-50%, -50%); }

.ct-ad-png--e-flutuar  { animation: ct-ad-png-flutuar 4s ease-in-out infinite alternate; }
.ct-ad-png--e-deslizar { animation: ct-ad-png-deslizar .8s cubic-bezier(.2,.7,.3,1) both; }
.ct-ad-png--e-zoom     { animation: ct-ad-png-zoom .7s cubic-bezier(.2,.7,.3,1) both; }
.ct-ad-png--e-inclinar { animation: ct-ad-png-inclinar .9s cubic-bezier(.2,.7,.3,1) both; }
.ct-ad-png--e-ciclo    { animation: ct-ad-png-ciclo 7s ease-in-out infinite; }

/*
 * Cada posição precisa das suas keyframes: o transform da animação
 * substitui o do posicionamento, então quem está centralizado tem de
 * carregar o translate(-50%) dentro de cada quadro, senão salta para o lado
 * assim que a animação começa.
 */
@keyframes ct-ad-png-flutuar {
    from { transform: translateY(-50%); }
    to   { transform: translateY(calc(-50% - 7px)); }
}
@keyframes ct-ad-png-deslizar {
    from { opacity: 0; transform: translateY(-50%) translateX(26px); }
    to   { opacity: 1; transform: translateY(-50%) translateX(0); }
}
@keyframes ct-ad-png-zoom {
    from { opacity: 0; transform: translateY(-50%) scale(.7); }
    to   { opacity: 1; transform: translateY(-50%) scale(1); }
}
/* Cartão inclinando em 3D até assentar de frente — o efeito das peças
   "flutuantes" de app/produto em banners profissionais (ex.: Globo.com). */
@keyframes ct-ad-png-inclinar {
    from { opacity: 0; transform: translateY(-50%) perspective(700px) rotateY(-22deg) rotateX(5deg) scale(.9); }
    to   { opacity: 1; transform: translateY(-50%) perspective(700px) rotateY(0deg) rotateX(0deg) scale(1); }
}
@keyframes ct-ad-png-ciclo {
    0%        { opacity: 0; transform: translateY(-50%) scale(.8); }
    10%, 60%  { opacity: 1; transform: translateY(-50%) scale(1); }
    72%, 100% { opacity: 0; transform: translateY(-50%) scale(.8); }
}

.ct-ad-png--p-centro.ct-ad-png--e-flutuar  { animation-name: ct-ad-png-flutuar-c; }
.ct-ad-png--p-centro.ct-ad-png--e-deslizar { animation-name: ct-ad-png-deslizar-c; }
.ct-ad-png--p-centro.ct-ad-png--e-zoom     { animation-name: ct-ad-png-zoom-c; }
.ct-ad-png--p-centro.ct-ad-png--e-inclinar { animation-name: ct-ad-png-inclinar-c; }
.ct-ad-png--p-centro.ct-ad-png--e-ciclo    { animation-name: ct-ad-png-ciclo-c; }

@keyframes ct-ad-png-flutuar-c {
    from { transform: translate(-50%, -50%); }
    to   { transform: translate(-50%, calc(-50% - 7px)); }
}
@keyframes ct-ad-png-deslizar-c {
    from { opacity: 0; transform: translate(-50%, -50%) translateX(26px); }
    to   { opacity: 1; transform: translate(-50%, -50%); }
}
@keyframes ct-ad-png-zoom-c {
    from { opacity: 0; transform: translate(-50%, -50%) scale(.7); }
    to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes ct-ad-png-inclinar-c {
    from { opacity: 0; transform: translate(-50%, -50%) perspective(700px) rotateY(-22deg) rotateX(5deg) scale(.9); }
    to   { opacity: 1; transform: translate(-50%, -50%) perspective(700px) rotateY(0deg) rotateX(0deg) scale(1); }
}
@keyframes ct-ad-png-ciclo-c {
    0%        { opacity: 0; transform: translate(-50%, -50%) scale(.8); }
    10%, 60%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    72%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(.8); }
}

/*
 * Texto centralizado: a peça vira coluna e o texto ganha respiro nas laterais
 * para não correr por baixo de um PNG lateral. O PNG lateral CONTINUA
 * ancorado no seu lado — a posição foi escolhida no admin e ignorá-la seria
 * desobedecer a escolha.
 */
.ct-ad-animado--p-centro {
    padding-left: 42px;
    padding-right: 42px;
}

/*
 * Centro em formato horizontal e o caso apertado: num 728x90 a coluna
 * (chapeu + titulo + subtitulo + botao) somava mais que os 90px e o botao
 * saia da peca. Aqui tudo encolhe para caber — em formato vertical isso nao
 * e preciso, entao a regra exclui o lateral.
 */
.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) {
    gap: 2px;
    padding-top: 6px;
    padding-bottom: 6px;
}

.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) .ct-ad-animado-txt {
    gap: 1px;
}

.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) .ct-ad-animado-chapeu {
    font-size: 9px;
    letter-spacing: .08em;
}

.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) .ct-ad-animado-titulo {
    /* cqw: ver o comentario em .ct-ad-slot. */
    font-size: clamp(14px, 2.2cqw, 24px);
    line-height: 1.1;
}

.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) .ct-ad-animado-sub {
    font-size: 11.5px;
    line-height: 1.2;
}

.ct-ad-animado--p-centro:not(.ct-ad-animado--lateral) .ct-ad-animado-cta {
    padding: 5px 13px;
    font-size: 11px;
}

/* Só o PNG que também é "centro" entra no fluxo da coluna: em absoluto ele
   deitaria exatamente sobre o texto, que ocupa o mesmo meio da peça. */
.ct-ad-animado--p-centro .ct-ad-png--p-centro {
    position: static;
    transform: none;
    animation: none;
    height: auto;
    width: auto;
    max-height: 40%;
    order: -1;
}

@media (prefers-reduced-motion: reduce) {
    .ct-ad-png {
        animation: none !important;
        opacity: 1 !important;
    }
}

/* ==========================================================================
   NOVAS OPÇÕES DE PERSONALIZAÇÃO DO BANNER ANIMADO
   Construídas em cima do mesmo sistema de classes ".ct-ad-animado--eixo-
   valor" acima — todas por transform/opacity, todas respeitam
   prefers-reduced-motion, todas validadas por lista fechada no PHP.
   ========================================================================== */

/* --- Efeito de fundo "Deriva" — panorâmica diagonal, mais dinâmica que o
   zoom simples e sem o corte lateral do "pan" (que anda só na horizontal) --- */
.ct-ad-animado--e-deriva .ct-ad-animado-fundo {
    animation-name: ct-ad-deriva;
    animation-duration: 22s;
}

@keyframes ct-ad-deriva {
    0%   { transform: scale(1.14) translate3d(-2.5%, 2%, 0); }
    100% { transform: scale(1.14) translate3d(2.5%, -2%, 0); }
}

/* --- Selo de canto (badge) — independente do chapéu: fica fixo sobre a
   peça, com pulso próprio, sem depender do bloco de texto principal. --- */
.ct-ad-animado-selo {
    position: absolute;
    top: 10px;
    z-index: 4;
    background: #dc2626;
    color: #ffffff;
    font-size: 10.5px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    padding: 4px 10px;
    border-radius: 999px;
    box-shadow: 0 2px 8px rgba(220, 38, 38, .5);
    animation: ct-ad-selo-pulso 1.8s ease-in-out infinite;
}

.ct-ad-animado-selo:empty {
    display: none;
}

.ct-ad-animado-selo--esquerda { left: 10px; }
.ct-ad-animado-selo--direita  { right: 10px; }

@keyframes ct-ad-selo-pulso {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.07); }
}

/* --- Cor personalizada do botão (CTA) — por padrão o botão usa o verde do
   site; com uma cor própria marcada no admin, ela substitui o degradê. --- */
.ct-ad-animado--cta-custom .ct-ad-animado-cta {
    background: var(--ct-ad-cta-cor, #16a34a);
}

/* --- Contagem regressiva de validade (calculada em banner-frontend.js a
   partir da data de expiração já cadastrada no anúncio). --- */
.ct-ad-animado-countdown {
    position: absolute;
    left: 22px;
    bottom: 10px;
    z-index: 2;
    font-size: 10.5px;
    font-weight: 700;
    color: #fbbf24;
    background: rgba(6, 12, 22, .55);
    padding: 3px 9px;
    border-radius: 5px;
    letter-spacing: .02em;
}

.ct-ad-animado-countdown:empty {
    display: none;
}

.ct-ad-animado--lateral .ct-ad-animado-countdown {
    left: 18px;
    right: auto;
    bottom: auto;
    top: 14px;
}

.ct-ad-animado--p-direita .ct-ad-animado-countdown {
    left: auto;
    right: 22px;
}

.ct-ad-animado--p-centro .ct-ad-animado-countdown {
    position: static;
    margin-top: 2px;
}

/* ==========================================================================
   POP-UP MODAL INTERSTICIAL
   Antes vivia como <style> impresso inline em wp_footer, com o mesmo custo
   de "reinventar a roda" do JS que virou assets/js/banner-popup.js: nunca
   cacheava e nao seguia o padrao de asset de verdade do resto do plugin.
   ========================================================================== */
.ct-popup-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.78);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    z-index: 999999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

.ct-popup-backdrop.is-visible {
    opacity: 1;
    visibility: visible;
}

.ct-popup-modal-card {
    position: relative;
    max-width: 600px;
    width: 100%;
    background: #ffffff;
    border-radius: 12px;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    transform: scale(0.92) translateY(20px);
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.ct-popup-backdrop.is-visible .ct-popup-modal-card {
    transform: scale(1) translateY(0);
}

.ct-popup-close-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background: rgba(15, 23, 42, 0.85);
    color: #ffffff;
    border: none;
    border-radius: 20px;
    padding: 6px 14px;
    font-size: 12px;
    font-weight: 800;
    cursor: pointer;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    transition: background 0.2s, transform 0.15s;
}

.ct-popup-close-btn:hover {
    background: #dc2626;
    transform: scale(1.05);
}

.ct-popup-link {
    display: block;
    line-height: 0;
    max-height: 520px;
    overflow: hidden;
}

.ct-popup-img {
    width: 100%;
    height: auto;
    max-height: 500px;
    object-fit: cover;
    display: block;
}

/* Modelo animado dentro do pop-up: preenche o card por completo (o próprio
   .ct-ad-animado vira absolute dentro deste wrapper com proporção fixa). */
.ct-popup-animado-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: 600 / 500;
    max-height: 500px;
}

.ct-popup-animado-wrap .ct-ad-animado {
    position: absolute;
    inset: 0;
    border-radius: 0;
}

.ct-popup-footer-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    background: #0f172a;
    color: #ffffff;
}

.ct-popup-tag {
    font-size: 10.5px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #94a3b8;
}

.ct-popup-action-btn {
    background: #0284c7;
    color: #ffffff;
    text-decoration: none;
    font-weight: 700;
    font-size: 12px;
    padding: 6px 14px;
    border-radius: 4px;
    transition: background 0.15s;
}

.ct-popup-action-btn:hover {
    background: #0369a1;
    color: #ffffff;
}

@media (max-width: 600px) {
    .ct-popup-modal-card { max-width: 95vw; }
}

/* ==========================================================================
   ADMIN — METABOX DO BANNER
   Era um <style> impresso pela própria função PHP do formulário a cada
   carregamento da tela de edição, em vez de um arquivo carregado (e
   cacheado) pelo navegador uma vez só. Só é enfileirado na tela de edição
   de banner (ver cidadetrevo_banner_enfileira_admin em inc/banner-meta.php),
   então não pesa nada nas páginas do site.
   ========================================================================== */
.ct-banner-editor-grid {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 24px;
}

.ct-banner-card {
    background: var(--ct-surface, #fff);
    border: 1px solid var(--ct-border, #e2e8f0);
    border-radius: 4px;
    padding: 20px;
    box-shadow: 0 1px 1px rgba(0, 0, 0, .03);
    margin-bottom: 20px;
}

.ct-banner-card h3 {
    margin: 0 0 12px 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--ct-ink, #0f172a);
    display: flex;
    align-items: center;
    gap: 8px;
}

.ct-banner-field {
    margin-bottom: 16px;
}

.ct-banner-field label {
    display: block;
    font-weight: 700;
    font-size: 13px;
    color: var(--ct-ink, #1e293b);
    margin-bottom: 6px;
}

.ct-banner-field .ct-desc {
    font-size: 12px;
    color: var(--ct-ink-soft, #64748b);
    margin-bottom: 6px;
    line-height: 1.4;
}

.ct-banner-field select,
.ct-banner-field input[type="text"],
.ct-banner-field input[type="url"],
.ct-banner-field input[type="number"],
.ct-banner-field input[type="date"] {
    width: 100%;
    padding: 8px 12px;
    border-radius: 4px;
    border: 1px solid var(--ct-border, #cbd5e1);
    font-size: 13.5px;
}

.ct-banner-upload-box {
    background: var(--ct-surface-sunken, #f8fafc);
    border: 1px dashed var(--ct-border, #cbd5e1);
    border-radius: 4px;
    padding: 14px;
    text-align: center;
}

.ct-banner-preview-img {
    max-width: 100%;
    max-height: 140px;
    border-radius: 4px;
    margin-top: 10px;
    object-fit: contain;
    background: var(--ct-surface, #ffffff);
    border: 1px solid var(--ct-border, #e2e8f0);
    padding: 4px;
}

/*
 * Variante "linha": botao de um lado, miniatura da imagem do outro — sem
 * mostrar o link da imagem (o campo por baixo e hidden, so o JS do media
 * uploader mexe nele). Classe a parte, e nao alterar .ct-banner-upload-box
 * direto, porque aquela ainda serve o mapa da home mais abaixo, que empilha
 * texto + preview grande com rolagem, nao uma miniatura ao lado do botao.
 */
.ct-banner-upload-linha {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--ct-surface-sunken, #f8fafc);
    border: 1px dashed var(--ct-border, #cbd5e1);
    border-radius: 4px;
    padding: 14px;
}

.ct-banner-upload-linha .ct-banner-preview-img {
    max-width: 120px;
    max-height: 80px;
    margin-top: 0;
    flex-shrink: 0;
}

.ct-site-map-mockup {
    background: #0f172a;
    border-radius: 8px;
    padding: 16px;
    color: #ffffff;
    font-family: monospace;
    font-size: 11px;
}

.ct-mock-box {
    border-radius: 4px;
    padding: 8px;
    text-align: center;
    margin-bottom: 8px;
    font-weight: bold;
    transition: all 0.2s;
    border: 1px dashed rgba(255, 255, 255, 0.2);
}

.ct-mock-box.active {
    border: 2px solid #38bdf8;
    background: rgba(56, 189, 248, 0.25) !important;
    color: #ffffff !important;
    box-shadow: 0 0 10px rgba(56, 189, 248, 0.4);
    transform: scale(1.02);
}
