/* Fundacao style+layout do builder visual (V1-B, Onda 1; cascata tablet e
 * componente depoimentos: F1a, Onda 2).
 *
 * Layout via CLASSES CSS UTILITARIAS FINITAS - NUNCA style="grid-column:..."
 * arbitrario montado com valor bruto do form (zero injecao de CSS). O
 * container do canvas de secoes ganha `.lgd-cms-grid` (grid de 12 colunas);
 * cada secao ganha `.lgd-cms-item` + as classes `.lgd-col--{bp}-{span|off}-N`
 * calculadas por `grid_classes()` (app/web/templates/partials/
 * page_sections.html) a partir de `PageSection.layout` (ja sanitizado por
 * app.schemas.page.sanitize_layout).
 *
 * `.lgd-cms-item` SEM nenhuma classe `.lgd-col--*` = full-width
 * (grid-column: 1 / -1), fora de qualquer media query - e o comportamento
 * quando layout={} (nenhum span/offset customizado) e TAMBEM o
 * comportamento padrao no mobile (breakpoint < 768px) quando a secao nao
 * tem override "mobile": full-width empilhado, na ordem do DOM (=
 * PageSection.position), preservando a ordem de leitura (WCAG 1.3.2) mesmo
 * quando o desktop reposiciona visualmente com offset.
 *
 * CASCATA de 3 breakpoints (F1a/R2, decisao do Planejador): o bloco desktop
 * (min-width:768px) e a BASE HERDAVEL - aplica de 768px pra cima inteiro
 * quando nao ha override de tablet. O bloco tablet
 * (min-width:768px and max-width:1023.98px) vem DEPOIS do bloco desktop no
 * arquivo, MESMA especificidade (0,1,0 em ambos - uma classe cada) - por
 * isso so vence em 768-1023px por ORDEM DE FONTE (regra que aparece depois
 * no CSS ganha em empate de especificidade). Acima de 1024px o bloco tablet
 * nao se aplica (fora do max-width) e o desktop volta a valer sozinho. NAO
 * trocar o bloco desktop para `min-width:1024px` puro - isso quebraria essa
 * heranca (tablet deixaria de herdar span/offset do desktop quando a secao
 * so tem override desktop, sem override tablet proprio).
 *
 * 66 regras fixas de grid (12 span + 12 offset, x3 breakpoints - inclui
 * tablet, F1a/R2) - nenhuma delas e gerada a partir de entrada do usuario,
 * todas pre-existem aqui.
 */

.lgd-cms-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  /* Respiro entre secoes (leva TH). Antes era ZERO: blocos empilhados se
     encostavam e dois ladrilhos lado a lado ficavam colados, sem costura
     entre as fotos.
     O grid desconta o gap das colunas sozinho, entao nenhum `span` precisou
     mudar. 30px espelha o `t4s-gx-md-30`/`t4s-gy-md-30` do site publicado;
     no mobile cai para 16px, onde a tela e estreita e um vao grande custa
     mais do que entrega. */
  gap: 30px;
}

@media (max-width: 767.98px) {
  .lgd-cms-grid { gap: 16px; }
}

.lgd-cms-item {
  grid-column: 1 / -1;
}

/* As regras de SPAN escrevem `grid-column-start: auto` + `grid-column-end:
 * span N`, nunca o atalho `grid-column: span N`.
 *
 * Motivo (defeito achado na leva TH): o atalho define o START como "span N"
 * e o END como auto. A regra de OFFSET vem depois na cascata e sobrescreve o
 * START com o numero da coluna - apagando a largura junto. Resultado: toda
 * secao com span E offset ao mesmo tempo renderizava com UMA coluna (um
 * video com span 8 / offset 2 saiu com 120px de 1440). Separadas, o offset
 * troca so o start e a largura sobrevive.
 *
 * O `start: auto` explicito e necessario porque `.lgd-cms-item` (base) traz
 * `grid-column: 1 / -1`: sem zerar, todo item spanado comecaria na coluna 1
 * e eles empilhariam em vez de ficar lado a lado.
 */

/* Desktop (>= 768px): span/offset customizados por PageSection.layout.desktop. */
@media (min-width: 768px) {
  .lgd-col--d-span-1 { grid-column-start: auto; grid-column-end: span 1; }
  .lgd-col--d-span-2 { grid-column-start: auto; grid-column-end: span 2; }
  .lgd-col--d-span-3 { grid-column-start: auto; grid-column-end: span 3; }
  .lgd-col--d-span-4 { grid-column-start: auto; grid-column-end: span 4; }
  .lgd-col--d-span-5 { grid-column-start: auto; grid-column-end: span 5; }
  .lgd-col--d-span-6 { grid-column-start: auto; grid-column-end: span 6; }
  .lgd-col--d-span-7 { grid-column-start: auto; grid-column-end: span 7; }
  .lgd-col--d-span-8 { grid-column-start: auto; grid-column-end: span 8; }
  .lgd-col--d-span-9 { grid-column-start: auto; grid-column-end: span 9; }
  .lgd-col--d-span-10 { grid-column-start: auto; grid-column-end: span 10; }
  .lgd-col--d-span-11 { grid-column-start: auto; grid-column-end: span 11; }
  .lgd-col--d-span-12 { grid-column-start: auto; grid-column-end: span 12; }

  /* SEM regra .lgd-col--d-off-0: grid_classes() (partials/page_sections.html)
     nunca emite essa classe (bugfix V2-B2) - grid-column-start:1 explicito
     em offset 0 quebrava o auto-placement do CSS Grid (2 itens adjacentes
     span-6/offset-0 empilhavam em vez de ficar lado a lado). Offset 0 fica
     SEM classe, deixando o auto-placement natural do grid posicionar os
     itens sequencialmente. Regra removida (nao so inerte) para nao poder
     ser reintroduzida sem querer. */
  .lgd-col--d-off-1 { grid-column-start: 2; }
  .lgd-col--d-off-2 { grid-column-start: 3; }
  .lgd-col--d-off-3 { grid-column-start: 4; }
  .lgd-col--d-off-4 { grid-column-start: 5; }
  .lgd-col--d-off-5 { grid-column-start: 6; }
  .lgd-col--d-off-6 { grid-column-start: 7; }
  .lgd-col--d-off-7 { grid-column-start: 8; }
  .lgd-col--d-off-8 { grid-column-start: 9; }
  .lgd-col--d-off-9 { grid-column-start: 10; }
  .lgd-col--d-off-10 { grid-column-start: 11; }
  .lgd-col--d-off-11 { grid-column-start: 12; }
}

/* Tablet (768px-1023.98px): span/offset customizados por
   PageSection.layout.tablet (F1a/R2) - SOBRESCREVE o bloco desktop acima
   NESTA faixa por ordem de fonte (ver nota da cascata no topo do arquivo).
   Sem override "tablet" nesta secao -> nenhuma destas classes e emitida por
   grid_classes() -> a secao continua herdando o bloco desktop normalmente. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .lgd-col--t-span-1 { grid-column-start: auto; grid-column-end: span 1; }
  .lgd-col--t-span-2 { grid-column-start: auto; grid-column-end: span 2; }
  .lgd-col--t-span-3 { grid-column-start: auto; grid-column-end: span 3; }
  .lgd-col--t-span-4 { grid-column-start: auto; grid-column-end: span 4; }
  .lgd-col--t-span-5 { grid-column-start: auto; grid-column-end: span 5; }
  .lgd-col--t-span-6 { grid-column-start: auto; grid-column-end: span 6; }
  .lgd-col--t-span-7 { grid-column-start: auto; grid-column-end: span 7; }
  .lgd-col--t-span-8 { grid-column-start: auto; grid-column-end: span 8; }
  .lgd-col--t-span-9 { grid-column-start: auto; grid-column-end: span 9; }
  .lgd-col--t-span-10 { grid-column-start: auto; grid-column-end: span 10; }
  .lgd-col--t-span-11 { grid-column-start: auto; grid-column-end: span 11; }
  .lgd-col--t-span-12 { grid-column-start: auto; grid-column-end: span 12; }

  /* SEM regra .lgd-col--t-off-0: mesmo motivo do bloco desktop acima -
     grid_classes() (partials/page_sections.html) nunca emite essa classe. */
  .lgd-col--t-off-1 { grid-column-start: 2; }
  .lgd-col--t-off-2 { grid-column-start: 3; }
  .lgd-col--t-off-3 { grid-column-start: 4; }
  .lgd-col--t-off-4 { grid-column-start: 5; }
  .lgd-col--t-off-5 { grid-column-start: 6; }
  .lgd-col--t-off-6 { grid-column-start: 7; }
  .lgd-col--t-off-7 { grid-column-start: 8; }
  .lgd-col--t-off-8 { grid-column-start: 9; }
  .lgd-col--t-off-9 { grid-column-start: 10; }
  .lgd-col--t-off-10 { grid-column-start: 11; }
  .lgd-col--t-off-11 { grid-column-start: 12; }
}

/* Mobile (< 768px): span/offset customizados por PageSection.layout.mobile.
   Sem override aqui, `.lgd-cms-item` (regra base acima, fora de media
   query) ja garante full-width empilhado - estas regras so entram em jogo
   quando `grid_classes()` emite uma classe `.lgd-col--m-*` explicita. */
@media (max-width: 767px) {
  .lgd-col--m-span-1 { grid-column-start: auto; grid-column-end: span 1; }
  .lgd-col--m-span-2 { grid-column-start: auto; grid-column-end: span 2; }
  .lgd-col--m-span-3 { grid-column-start: auto; grid-column-end: span 3; }
  .lgd-col--m-span-4 { grid-column-start: auto; grid-column-end: span 4; }
  .lgd-col--m-span-5 { grid-column-start: auto; grid-column-end: span 5; }
  .lgd-col--m-span-6 { grid-column-start: auto; grid-column-end: span 6; }
  .lgd-col--m-span-7 { grid-column-start: auto; grid-column-end: span 7; }
  .lgd-col--m-span-8 { grid-column-start: auto; grid-column-end: span 8; }
  .lgd-col--m-span-9 { grid-column-start: auto; grid-column-end: span 9; }
  .lgd-col--m-span-10 { grid-column-start: auto; grid-column-end: span 10; }
  .lgd-col--m-span-11 { grid-column-start: auto; grid-column-end: span 11; }
  .lgd-col--m-span-12 { grid-column-start: auto; grid-column-end: span 12; }

  /* SEM regra .lgd-col--m-off-0: mesmo motivo do bloco desktop acima. */
  .lgd-col--m-off-1 { grid-column-start: 2; }
  .lgd-col--m-off-2 { grid-column-start: 3; }
  .lgd-col--m-off-3 { grid-column-start: 4; }
  .lgd-col--m-off-4 { grid-column-start: 5; }
  .lgd-col--m-off-5 { grid-column-start: 6; }
  .lgd-col--m-off-6 { grid-column-start: 7; }
  .lgd-col--m-off-7 { grid-column-start: 8; }
  .lgd-col--m-off-8 { grid-column-start: 9; }
  .lgd-col--m-off-9 { grid-column-start: 10; }
  .lgd-col--m-off-10 { grid-column-start: 11; }
  .lgd-col--m-off-11 { grid-column-start: 12; }
}

/* ------------------------------------------------------ Canvas livre (WX2)
 *
 * Page.layout_mode == canvas: secoes posicionadas ABSOLUTAMENTE num canvas
 * de 1200px de referencia (CANVAS_WIDTH em app/schemas/page.py). Os valores
 * de left/top/width/min-height/z-index no atributo style de .lgd-cms-abs
 * vem SEMPRE de ints validados por sanitize_layout (render_section_canvas
 * em partials/page_sections.html) - nunca texto bruto do form.
 *
 * Responsividade SEM JS publico (3 faixas):
 * 1. Container >= 1200px: canvas 1:1, centralizado.
 * 2. Container < 1200px (ate 768px de viewport): o canvas INTEIRO escala
 *    proporcionalmente - scale = largura do container / 1200, calculado em
 *    CSS puro com container query units + trigonometria:
 *    tan(atan2(100cqw, 1200px)) e a razao ADIMENSIONAL (100cqw/1200px)
 *    exigida por transform:scale(). A altura do outer compensa com o mesmo
 *    fator (transform nao altera o layout flow). Navegador sem suporte a
 *    atan2/cqw (pre-2023) cai no fallback @supports: canvas 1:1 com scroll
 *    horizontal - exatamente o comportamento do proprio Wix classico.
 * 3. Viewport <= 767px (mobile): o canvas e "des-absolutizado" e vira
 *    empilhamento vertical na ordem do DOM (que o servidor emite ordenada
 *    por Y - paridade com o layout mobile auto-gerado do Wix classico).
 *    !important e necessario e correto aqui: e a UNICA forma de uma regra
 *    de stylesheet vencer o style inline de posicao.
 *
 * No EDITOR (.lgd-cms-canvas-outer--edit) a escala e DESLIGADA (canvas
 * sempre 1:1 com scroll horizontal) - a matematica de drag/resize do
 * canvas-editor.js trabalha em px reais do canvas, sem fator de conversao.
 */

.lgd-cms-canvas-outer {
  container-type: inline-size;
  overflow-x: auto;
  overflow-y: hidden;
}

.lgd-cms-canvas {
  position: relative;
  width: 1200px;
  margin: 0 auto;
}

.lgd-cms-abs {
  position: absolute;
  box-sizing: border-box;
}

.lgd-cms-abs--full {
  left: 0 !important;
  width: 1200px !important;
}

.lgd-cms-abs__preview,
.lgd-cms-abs__inner {
  width: 100%;
  min-height: inherit;
  box-sizing: border-box;
}

.lgd-cms-abs .lgd-cms-abs__inner > section {
  margin: 0;
}

.lgd-cms-abs img {
  max-width: 100%;
}

/* Faixa 2: escala proporcional so no PUBLICO (nunca --edit), so quando o
   navegador suporta cqw + atan2 (senao fica o overflow-x:auto do outer). */
@supports (width: 100cqw) and (transform: scale(tan(atan2(1px, 1px)))) {
  @container (max-width: 1199.98px) {
    .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) .lgd-cms-canvas {
      transform: scale(tan(atan2(100cqw, 1200px)));
      transform-origin: top left;
    }
  }
  .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) {
    overflow-x: hidden;
    /* Compensa a altura do flow (transform nao encolhe o layout): altura
       real = altura do canvas (var de int validado) x fator de escala. */
    height: calc(var(--lgd-canvas-h, 240px) * min(1, tan(atan2(100cqw, 1200px))));
  }
}

/* Faixa 3: mobile empilha na ordem do DOM (servidor ja ordena por Y). */
@media (max-width: 767px) {
  .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) {
    height: auto;
    overflow-x: visible;
  }
  .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) .lgd-cms-canvas {
    transform: none;
    width: 100%;
    height: auto !important;
  }
  .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) .lgd-cms-abs {
    position: static !important;
    width: 100% !important;
    min-height: 0 !important;
    margin: 0 0 16px;
  }
  .lgd-cms-canvas-outer:not(.lgd-cms-canvas-outer--edit) .lgd-cms-abs--hide-m {
    display: none !important;
  }
}

/* Emulacao do stack mobile no EDITOR (WY2, device-mode do builder):
   canvas-editor.js aplica esta classe quando o preview esta com largura
   < 768px - o @media real acima responde ao VIEWPORT, nao a moldura do
   preview, entao o editor precisa das mesmas regras acionaveis por classe.
   MANTENHA ESPELHADO com o bloco @media (max-width: 767px) acima (mesmas
   declaracoes, mesmo !important para vencer o style inline de posicao). */
.lgd-cms-canvas-outer--emul-m {
  height: auto !important;
  overflow-x: visible;
}
.lgd-cms-canvas-outer--emul-m .lgd-cms-canvas {
  transform: none !important;
  width: 100% !important;
  height: auto !important;
}
.lgd-cms-canvas-outer--emul-m .lgd-cms-abs {
  position: static !important;
  width: 100% !important;
  min-height: 0 !important;
  margin: 0 0 16px;
}
.lgd-cms-canvas-outer--emul-m .lgd-cms-abs--hide-m {
  display: none !important;
}

/* Elementos leves do catalogo (WX1): imagem simples e botao. */
.lgd-cms-imagem__img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}

.lgd-cms-botao {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: inherit;
}

.lgd-cms-botao__btn {
  display: inline-block;
  padding: 12px 28px;
  border-radius: 4px;
  text-decoration: none;
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  letter-spacing: .05em;
  transition: opacity .15s ease;
}

.lgd-cms-botao__btn:hover {
  opacity: .85;
}

.lgd-cms-botao__btn--primario {
  background: var(--accent-color, #523336);
  color: #fff;
  border: 1px solid var(--accent-color, #523336);
}

.lgd-cms-botao__btn--secundario {
  background: transparent;
  color: var(--accent-color, #523336);
  border: 1px solid var(--accent-color, #523336);
}

/* Componente depoimentos (F1a/R3, secao `PageSectionType.depoimentos`;
 * modo automatico + correcao de contraste C5 na leva UJ, item (ii) do
 * plano). Markup em depoimentos_section() (app/web/templates/partials/
 * page_sections.html). Estrelas ZERO-JS: 5 <svg> estaticos por item, a
 * classe --filled aplicada campo a campo no Jinja conforme item.nota (1-5,
 * ja validado pelo schema). Usa as custom properties de base.html
 * (--gold-color/--gold-deep/--heading-color/--text-color, definidas no
 * :root de todo template que estende base.html) com fallback hex identico
 * caso a variavel nao esteja disponivel por algum motivo. Sem animacao.
 *
 * C5 (WCAG 2.1 SC 1.4.11): a cor deixou de ser o UNICO lugar que distingue
 * estrela cheia/vazia - par medido `#A59E59` x `#d9d9d9` = 1.95:1 (abaixo
 * do minimo de 3:1). Duas correcoes, aplicadas aos DOIS modos (manual e
 * automatico): (a) `--gold-deep: #7A7333` na estrela cheia (3.44:1 contra a
 * vazia, 4.85:1 contra o fundo branco); (b) a nota vira TEXTO VISIVEL
 * (`.lgd-cms-depo__nota`, "N de 5") ao lado das estrelas - `role="img"`/
 * `aria-label` SAIRAM do `.lgd-cms-depo__rating` (ver macro): com
 * `role="img"` no container, o texto adicionado ali dentro nao seria lido
 * por leitor de tela (torna tudo apresentacional). */
.lgd-cms-depo__title {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #222222);
  text-align: center;
  margin: 0 0 24px;
}

.lgd-cms-depo__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
}

.lgd-cms-depo__item {
  padding: 20px;
}

.lgd-cms-depo__rating {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0 0 10px;
}

.lgd-cms-depo__star {
  width: 16px;
  height: 16px;
  fill: #d9d9d9;
}

.lgd-cms-depo__star--filled {
  fill: var(--gold-deep, #7A7333);
}

.lgd-cms-depo__nota {
  margin-left: 6px;
  font-size: 13px;
  color: var(--text-color, #767676);
}

.lgd-cms-depo__nome {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  font-weight: 600;
  color: var(--heading-color, #222222);
  margin: 0 0 6px;
}

/* Selo "Compra verificada" (SO no ramo automatico da macro - avaliacao real
 * com pedido concluido, review_service.is_eligible): classe propria em vez
 * de herdar o peso 600/cor de titulo de `.lgd-cms-depo__nome`, senao o selo
 * pareceria parte do nome do cliente. */
.lgd-cms-depo__selo {
  font-weight: 400;
  color: var(--gold-deep, #7A7333);
}

.lgd-cms-depo__texto {
  color: var(--text-color, #767676);
  line-height: 1.8;
}

/* Aviso do bloco automatico, SO no editor (0 elegiveis ou menos que o
 * pedido) - precedente `.lgd-cms-vitrine__placeholder` abaixo. Nunca
 * renderizado no publico (ver visibilidade da macro). */
.lgd-cms-depo__aviso {
  color: var(--text-color, #767676);
  text-align: center;
  margin: 0;
  padding: 16px 0 0;
}

/* ------------------------------------------------------------- WZ-B: hover
 * anim / vitrine / video / posts_grid (secoes vitrine/video/posts_grid,
 * markup em app/web/templates/partials/page_sections.html).
 */

/* .lgd-anim-zoom (style.hover_anim="zoom", allowlist curada em
 * app.schemas.page._HOVER_ANIMS): aplicada SO em banner/hero/imagem (ver
 * render_section/canvas_inner) - zoom leve na <img> interna no hover/foco.
 * Restrita a `hover: hover` + `pointer: fine` (dispositivos com mouse de
 * verdade - touch nao tem estado de hover persistente, o zoom ficaria
 * "preso" apos o toque). Overflow escondido no container para o zoom nao
 * vazar do card. */
@media (hover: hover) and (pointer: fine) {
  .lgd-anim-zoom { overflow: hidden; }
  .lgd-anim-zoom img { transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1); }
  .lgd-anim-zoom:hover img,
  .lgd-anim-zoom:focus-within img { transform: scale(1.04); }
}
/* prefers-reduced-motion SEMPRE neutraliza (independente do par acima) -
 * !important necessario para vencer a transition/transform de hover/foco
 * quando o usuario pediu menos movimento. */
@media (prefers-reduced-motion: reduce) {
  .lgd-anim-zoom img {
    transition: none !important;
    transform: none !important;
  }
}

/* .lgd-cms-vitrine (secao `vitrine`, referencia a uma vitrine cadastrada -
 * NAO confundir com a vitrine global "Destaques" da home, que usa markup
 * proprio em home.html). `lgd-destaques` (classe irma no <section>, ver
 * vitrine_section) reaproveita o CSS de card de
 * partials/catalog_grid_styles.html - aqui so o grid/titulo/estado vazio. */
.lgd-cms-vitrine__head { text-align: center; margin: 0 0 24px; }
.lgd-cms-vitrine__title {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #222222);
  margin: 0;
}
.lgd-cms-vitrine__grid {
  display: grid;
  grid-template-columns: repeat(var(--lgd-vitrine-cols, 4), 1fr);
  gap: 24px;
}
@media (max-width: 767px) {
  .lgd-cms-vitrine__grid { grid-template-columns: repeat(2, 1fr); }
}

/* Estado vazio SO no editor (vitrine_section/posts_grid_section nunca
 * emitem esta secao no publico sem produtos/posts - ver macros) - placeholder
 * selecionavel com borda tracejada dourada, min-height ~120px. */
.lgd-cms-vitrine--empty,
.lgd-cms-postsgrid--empty {
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  border: 2px dashed var(--gold-color, #A59E59);
  border-radius: 6px;
}
.lgd-cms-vitrine__placeholder,
.lgd-cms-postsgrid__placeholder {
  color: var(--text-color, #767676);
  text-align: center;
  margin: 0;
}

/* .lgd-cms-video (secao `video`, revisto na TZ1): o player do provedor,
 * incorporado direto - a fachada <details>/<summary> com capa propria foi
 * removida (ver a nota longa em video_section, partials/page_sections.html).
 * Sobrou o essencial: uma caixa 16/9 com o iframe preenchendo. */
.lgd-cms-video__frame {
  position: relative;
  aspect-ratio: 16 / 9;
}
.lgd-cms-video__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* MODO CANVAS: o video preenche a ALTURA definida no editor.
 *
 * Fora do canvas (modo fluxo) o bloco e governado por `aspect-ratio: 16/9`
 * acima - a altura deriva da largura, que e o comportamento certo num
 * layout empilhado. No canvas livre, porem, o admin define largura E altura
 * ao arrastar as alcas, e o aspect-ratio fixo IGNORAVA a altura: o
 * redimensionamento vertical nao surtia efeito nenhum na pagina publicada.
 *
 * A cadeia inteira (envelope -> preview -> inner -> section -> frame) vira
 * flex-column com `flex: 1`, de modo que o iframe estique ate a altura do
 * envelope (`min-height` vindo de `layout.free.h`). `min-height: 0` em cada
 * elo e obrigatorio: sem ele, o tamanho minimo automatico do flex item
 * impede o encolhimento e o bloco nunca fica MENOR que 16/9.
 * `aspect-ratio: auto` desarma a regra base. */
.lgd-cms-abs--video,
.lgd-cms-abs--video .lgd-cms-abs__preview,
.lgd-cms-abs--video .lgd-cms-abs__inner,
.lgd-cms-abs--video .lgd-cms-video {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
.lgd-cms-abs--video .lgd-cms-video__frame {
  flex: 1 1 auto;
  min-height: 0;
  aspect-ratio: auto;
}

/* .lgd-cms-postsgrid / .lgd-cms-postcard (secao `posts_grid`): grade dos N
 * posts publicados mais recentes, um UNICO <a> envolvente por card.
 *
 * O respiro lateral fica na SECAO (nao no grid): o bloco pode ser
 * renderizado full-bleed (modo canvas com free.full, ou como filho direto
 * do container da home), e sem este padding os cards das pontas encostam
 * na borda da janela. `box-sizing: border-box` garante que o padding nao
 * some com a largura util em modo canvas (onde a largura vem do inline
 * style em px). */
.lgd-cms-postsgrid {
  box-sizing: border-box;
  padding: 0 16px;
}
@media (min-width: 768px) {
  .lgd-cms-postsgrid { padding: 0 24px; }
}
.lgd-cms-postsgrid__title {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #222222);
  text-align: center;
  margin: 0 0 24px;
}
.lgd-cms-postsgrid__grid {
  display: grid;
  grid-template-columns: repeat(var(--lgd-blog-cols, 3), 1fr);
  gap: 24px;
}
@media (max-width: 767px) {
  .lgd-cms-postsgrid__grid { grid-template-columns: repeat(2, 1fr); }
}
.lgd-cms-postcard {
  display: block;
  color: inherit;
  text-decoration: none;
  border-radius: 6px;
  overflow: hidden;
}
.lgd-cms-postcard:focus-visible {
  outline: 2px solid var(--gold-color, #A59E59);
  outline-offset: 3px;
}
.lgd-cms-postcard__cover {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.lgd-cms-postcard__body { padding: 14px 2px 0; }
.lgd-cms-postcard__title {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #222222);
  font-size: 100%;
  margin: 0 0 6px;
}
.lgd-cms-postcard:hover .lgd-cms-postcard__title { text-decoration: underline; }
.lgd-cms-postcard__date {
  display: block;
  color: var(--text-color, #767676);
  font-size: 8px; /* .8rem do storefront (1rem=10px) - ver nota do title */
  margin: 0 0 8px;
}
.lgd-cms-postcard__excerpt {
  color: var(--text-color, #767676);
  line-height: 1.6;
  margin: 0 0 8px;
}
.lgd-cms-postcard__meta {
  display: block;
  color: var(--text-color, #767676);
  font-size: 7.8px; /* .78rem do storefront (1rem=10px) - ver nota do title */
}

/* Contrato com a fatia WZ-F (canvas/editor): esconde o botao "Adicionar ao
 * carrinho" do card de produto (partials/product_card.html, via
 * vitrine_section acima) quando renderizado DENTRO do editor - nenhum POST
 * de carrinho deve ser possivel a partir do admin. A classe .lgd-card-actions
 * ainda nao existe enquanto a WZ-F nao termina; a regra e inofensiva ate
 * la (seletor sem alvo no DOM atual). */
.lgd-pgb-block .lgd-card-actions,
[data-pgb-canvas-free] .lgd-card-actions {
  display: none !important;
}

/* ------------------------------------------------------------ hero (TX5)
 *
 * O fundo do overlay (`background: rgba(34,34,34,.55)`) e a geometria do
 * hero vivem DUPLICADOS nos <style> de home.html, catalog.html e
 * page_public.html - cada uma dessas paginas tem sua propria variacao
 * (altura maxima, border-radius, tamanho do titulo) e nenhuma estende as
 * outras. Por isso o "sem veu cinza" NAO e aplicado por classe aqui: uma
 * regra .lgd-cms-hero__overlay--limpo teria a MESMA especificidade (0,1,0)
 * dos blocos inline daquelas paginas e PERDERIA por ordem de fonte (eles
 * vem depois de cms-sections.css no documento). O `background:none` sai
 * como style INLINE direto no elemento pela macro hero_section
 * (partials/page_sections.html), que vence qualquer folha.
 *
 * O que fica AQUI e so o que nao conflita com aquelas copias:
 *
 * 1. text-shadow de apoio no eyebrow/subheading quando o veu some. Seletor
 *    de 2 classes (0,2,0) justamente para vencer as copias por
 *    especificidade, sem !important. O heading ja tinha text-shadow em
 *    home.html/page_public.html; aqui ele e reafirmado para cobrir tambem
 *    catalog.html, onde nao havia. Sem o fundo cinza o contraste sobre foto
 *    clara pode ficar abaixo de 4.5:1 (WCAG AA) - decisao do cliente,
 *    mitigada (nao resolvida) por esta sombra.
 *
 * 2. .lgd-cms-hero__link: o <a> que envolve a imagem quando ha cta_url sem
 *    cta_label (hero clicavel inteiro, mesmo padrao de banner.link_url).
 *    `display:block` evita a folga de linha-base abaixo da <img> inline. */
.lgd-cms-hero__overlay--limpo .lgd-cms-hero__eyebrow,
.lgd-cms-hero__overlay--limpo .lgd-cms-hero__heading,
.lgd-cms-hero__overlay--limpo .lgd-cms-hero__subheading {
  text-shadow: 0 1px 6px rgba(0, 0, 0, .55);
}

.lgd-cms-hero__link {
  display: block;
}

/* ---------------------------------------------------------------- icone (UC)
 *
 * Bloco de destaque com icone + titulo + texto curto, que reproduz o item
 * `t4s-shipping-item` hoje fixo no tema do site publicado.
 *
 * CLASSES PROPRIAS, VALORES DO TEMA: as regras de `t4s-shipping-*` dependem
 * de um ancestral `.t4s-shipping-list` carregando modificadores e variaveis
 * CSS, e ja tivemos regressao por acoplar a esse CSS minificado (o
 * `::before` de `.t4s-product-inner` cobrindo o link do card de produto).
 * Entao aqui as classes sao nossas e o que foi copiado sao as MEDIDAS -
 * icone 24/36/48px, circulo 60/80/95px, respiro de 20px (10px no mobile),
 * titulo 16px/500/#222, texto 13px/#878787 com linha de 24px - para o
 * resultado ficar igual ao que esta no ar.
 *
 * `--lgd-icone-cl` e a unica peca customizavel por bloco (cor do icone, via
 * atributo `style` gerado a partir de hex ja validado). O default reproduz
 * o `--icon-cl: #523336` do site. */
.lgd-cms-icone {
  --lgd-icone-cl: var(--accent-color, #523336);
  display: block;
}
.lgd-cms-icone__inner {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  color: inherit;
  text-decoration: none;
}
.lgd-cms-icone__fig {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--lgd-icone-cl);
}
.lgd-cms-icone__svg { display: block; fill: currentColor; }
/* Icones de TRACO (viewBox 24, desenhados com stroke): precisam do contrario
 * - sem preenchimento e com o contorno na cor. Mesma divisao que o tema faz
 * entre o caminhao (traco) e a medalha (preenchida). */
.lgd-cms-icone__svg--traco {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* ARTE OFICIAL (--arte): os icones extraidos do Manual Legado 2026 sao PNG
 * COLORIDO (vinho + dourado + azul da marca), nao desenho em currentColor.
 * Duas consequencias, ambas tratadas aqui:
 *
 *   1. `object-fit: contain` porque o recorte e quadrado e o desenho nem
 *      sempre ocupa a largura toda - sem isto o navegador esticaria a arte.
 *   2. O circulo NAO pode mais se pintar no hover: aquele efeito existe para
 *      inverter um icone monocromatico para branco, e uma arte colorida
 *      simplesmente sumiria por tras do disco vinho. `:has()` deixa a regra
 *      valer so no card que contem arte - os icones de traco continuam com
 *      a animacao original. */
.lgd-cms-icone__svg--arte {
  object-fit: contain;
}
.lgd-cms-icone--circulo .lgd-cms-icone__fig:has(.lgd-cms-icone__svg--arte)::before {
  content: none;
}
.lgd-cms-icone--circulo:hover .lgd-cms-icone__fig:has(.lgd-cms-icone__svg--arte) {
  color: var(--lgd-icone-cl);
}
.lgd-cms-icone__body { display: block; min-width: 0; }
.lgd-cms-icone__title {
  display: block;
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  font-size: 16px;
  font-weight: 500;
  color: var(--heading-color, #222);
  margin: 0 0 4px;
}
.lgd-cms-icone__text {
  display: block;
  font-size: 13px;
  line-height: 24px;
  color: var(--text-color, #878787);
}

/* Tamanhos (mesmos px do tema). */
.lgd-cms-icone--pequeno .lgd-cms-icone__svg { width: 24px; height: 24px; }
.lgd-cms-icone--medio .lgd-cms-icone__svg { width: 36px; height: 36px; }
.lgd-cms-icone--grande .lgd-cms-icone__svg { width: 48px; height: 48px; }
/* A arte do manual vem com MARGEM INTERNA propria (o desenho ocupa pouco
 * mais da metade do quadrado recortado do circulo). Nas medidas acima - que
 * valem para desenhos sangrando ate a borda do viewBox - ela apareceria com
 * cerca de 60% do peso visual dos vizinhos. Estas medidas igualam o TRACO na
 * tela, nao a caixa.
 * ORDEM IMPORTA: mesma especificidade das tres regras acima (0,2,0), entao
 * precisam vir DEPOIS - foi exatamente assim que a primeira tentativa ficou
 * sem efeito. */
.lgd-cms-icone--pequeno .lgd-cms-icone__svg--arte { width: 40px; height: 40px; }
.lgd-cms-icone--medio .lgd-cms-icone__svg--arte { width: 58px; height: 58px; }
.lgd-cms-icone--grande .lgd-cms-icone__svg--arte { width: 72px; height: 72px; }

/* Variante `topo`: icone acima, tudo centralizado. */
.lgd-cms-icone--topo .lgd-cms-icone__inner {
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
}

/* Variante `circulo`: moldura redonda que se preenche no hover, com o icone
 * invertendo para o claro - efeito `t4s-shipping-icon-circle` do tema. O
 * preenchimento e um ::before que ESCALA (transform), nunca uma transicao de
 * background-color: assim a animacao roda na GPU e nao repinta a caixa. */
.lgd-cms-icone--circulo .lgd-cms-icone__fig {
  position: relative;
  border: 1px solid var(--lgd-icone-cl);
  border-radius: 50%;
  overflow: hidden;
  transition: color .3s;
}
.lgd-cms-icone--circulo .lgd-cms-icone__fig::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background-color: var(--lgd-icone-cl);
  transform: scale(0);
  transition: transform .3s;
}
.lgd-cms-icone--circulo .lgd-cms-icone__svg { position: relative; z-index: 2; }
.lgd-cms-icone--circulo:hover .lgd-cms-icone__fig::before { transform: scale(1); }
.lgd-cms-icone--circulo:hover .lgd-cms-icone__fig { color: #fff; }
.lgd-cms-icone--circulo.lgd-cms-icone--pequeno .lgd-cms-icone__fig { width: 60px; height: 60px; }
.lgd-cms-icone--circulo.lgd-cms-icone--medio .lgd-cms-icone__fig { width: 80px; height: 80px; }
.lgd-cms-icone--circulo.lgd-cms-icone--grande .lgd-cms-icone__fig { width: 95px; height: 95px; }

/* Saltinho do icone no hover do item (o `bounceIn` do tema). Keyframes
 * PROPRIA: o nome `bounceIn` e referenciado pelo CSS do tema mas definido em
 * outro arquivo dele, que pode nao estar carregado - depender daquele nome
 * daria uma animacao silenciosamente inerte. */
@keyframes lgd-icone-bounce {
  0% { transform: scale(1); }
  40% { transform: scale(1.14); }
  70% { transform: scale(.96); }
  100% { transform: scale(1); }
}
.lgd-cms-icone:hover .lgd-cms-icone__svg { animation: lgd-icone-bounce .5s ease; }

@media (max-width: 767px) {
  .lgd-cms-icone--lado .lgd-cms-icone__inner { gap: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .lgd-cms-icone:hover .lgd-cms-icone__svg { animation: none; }
  .lgd-cms-icone--circulo .lgd-cms-icone__fig,
  .lgd-cms-icone--circulo .lgd-cms-icone__fig::before { transition: none; }
}

/* -------------------------------------------------- banner: carrossel + veu
 *
 * Carrossel em CSS PURO (nenhum JS no storefront): as imagens sao empilhadas
 * e trocam por CROSSFADE de opacidade, cada uma com um atraso de um "slot".
 *
 * Por que crossfade e nao uma tira deslizante: o loop fecha sozinho. Uma
 * tira precisaria repetir a primeira imagem no fim para poder voltar ao
 * inicio sem "rebobinar" na frente do visitante - markup duplicado e uma
 * imagem a mais no HTML. Com opacidade, a ultima cruza com a primeira
 * naturalmente.
 *
 * Cada imagem fica visivel ~6s. A duracao TOTAL do ciclo depende de quantas
 * sao, entao ha um keyframes por quantidade (2 a 5) - o mesmo teto do schema
 * (MAX_BANNER_SLIDES_EXTRA em app/schemas/page.py). Os ATRASOS, esses, sao
 * os mesmos para qualquer N: slot fixo de 6s por posicao. */
.lgd-cms-banner--carrossel .lgd-cms-banner__slides { position: relative; display: block; }
/* A primeira imagem fica no FLUXO - e ela que da altura ao bloco (as demais
 * sao absolutas e nao contariam para o tamanho). Por isso as outras tambem
 * precisam de object-fit: se tiverem proporcao diferente, preenchem a mesma
 * caixa em vez de distorcer. */
.lgd-cms-banner--carrossel .lgd-cms-banner__img + .lgd-cms-banner__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.lgd-cms-banner--carrossel .lgd-cms-banner__img {
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
.lgd-cms-banner--carrossel .lgd-cms-banner__img:nth-child(1) { animation-delay: 0s; }
.lgd-cms-banner--carrossel .lgd-cms-banner__img:nth-child(2) { animation-delay: 6s; }
.lgd-cms-banner--carrossel .lgd-cms-banner__img:nth-child(3) { animation-delay: 12s; }
.lgd-cms-banner--carrossel .lgd-cms-banner__img:nth-child(4) { animation-delay: 18s; }
.lgd-cms-banner--carrossel .lgd-cms-banner__img:nth-child(5) { animation-delay: 24s; }

.lgd-cms-banner--slides-2 .lgd-cms-banner__img {
  animation-name: lgd-banner-fade-2; animation-duration: 12s;
}
.lgd-cms-banner--slides-3 .lgd-cms-banner__img {
  animation-name: lgd-banner-fade-3; animation-duration: 18s;
}
.lgd-cms-banner--slides-4 .lgd-cms-banner__img {
  animation-name: lgd-banner-fade-4; animation-duration: 24s;
}
.lgd-cms-banner--slides-5 .lgd-cms-banner__img {
  animation-name: lgd-banner-fade-5; animation-duration: 30s;
}

/* A janela "visivel" de cada imagem e 100/N do ciclo; o resto e a travessia.
 * O trecho final voltando a 1 e o que cruza com a imagem seguinte saindo. */
@keyframes lgd-banner-fade-2 {
  0%, 42% { opacity: 1; } 50%, 92% { opacity: 0; } 100% { opacity: 1; }
}
@keyframes lgd-banner-fade-3 {
  0%, 28% { opacity: 1; } 33.33%, 94.4% { opacity: 0; } 100% { opacity: 1; }
}
@keyframes lgd-banner-fade-4 {
  0%, 21% { opacity: 1; } 25%, 96% { opacity: 0; } 100% { opacity: 1; }
}
@keyframes lgd-banner-fade-5 {
  0%, 16.7% { opacity: 1; } 20%, 96.7% { opacity: 0; } 100% { opacity: 1; }
}

/* Passar o mouse congela a troca - dá tempo de ler/clicar sem a imagem
 * mudar embaixo do cursor. */
.lgd-cms-banner--carrossel:hover .lgd-cms-banner__img { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  /* Quem pediu menos movimento ve so a primeira imagem - parada. Nao basta
   * `animation: none`: sem isso as demais ficariam empilhadas em opacidade
   * 1, todas por cima da primeira. */
  .lgd-cms-banner--carrossel .lgd-cms-banner__img { animation: none !important; }
  .lgd-cms-banner--carrossel .lgd-cms-banner__img + .lgd-cms-banner__img { display: none; }
}

/* VEU (so quando ha titulo ou subtitulo, classe --overlay emitida pela macro).
 *
 * Seletor de DUAS classes de proposito: `.lgd-cms-banner__text` esta
 * duplicado nos <style> de home/catalog/product/page_public com
 * especificidade 0,1,0 - em 0,2,0 estas regras vencem em qualquer ordem de
 * carregamento, sem !important e sem precisar do style inline que o hero
 * exigiu (la o conflito era no MESMO elemento).
 *
 * Efeito colateral ASSUMIDO: nas paginas onde o texto do banner aparecia
 * ABAIXO da imagem (catalogo, PDP, pagina institucional) ele passa a ficar
 * sobre ela, como ja era na home. E o que "overlay sobre a imagem" pede, e
 * unifica um comportamento que estava divergente em quatro arquivos. */
.lgd-cms-banner--overlay { position: relative; }
.lgd-cms-banner--overlay .lgd-cms-banner__text {
  position: absolute;
  inset: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 24px;
  text-align: center;
  /* "Opacidade reduzida": escurece o suficiente para o texto branco passar
   * de 4.5:1 (WCAG AA) sobre foto clara, sem apagar a imagem. */
  background: rgba(34, 34, 34, .42);
}
.lgd-cms-banner--overlay .lgd-cms-banner__heading,
.lgd-cms-banner--overlay .lgd-cms-banner__subheading {
  color: #fff;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .45);
}
/* O veu cobre a imagem inteira e engoliria o clique do link do banner. O
 * texto nao e interativo, entao deixa passar - mesma solucao do hero. A
 * classe SO e emitida no publico: no editor o texto precisa receber clique
 * para a edicao no lugar. */
.lgd-cms-banner__text--inerte { pointer-events: none; }

/* ---------------------------------------------- banner: bolinhas de navegacao
 *
 * Markup (page_sections.html): um <input type="radio"> oculto por slide
 * (filhos diretos da <section>) + uma bolinha (<label for="...">) por
 * slide - os radios dao semantica e navegacao por teclado de graca, e sao
 * o que o banner-carousel.js escuta ('change').
 *
 * A INTERACAO e do banner-carousel.js (progressive enhancement, incluido
 * so por base.html): ele poe a classe --js na secao, o que desliga as
 * animacoes CSS abaixo, e passa a reger o crossfade por transicao de
 * opacidade (classe __img--ativa) + setInterval - clicar numa bolinha
 * troca ja e REINICIA a contagem do automatico. SEM JS nada disso existe:
 * o crossfade 100% CSS acima segue intocado e as bolinhas nem aparecem
 * (display:none), em vez de prometer um clique que nao funcionaria.
 *
 * Por que JS e nao o radio-hack CSS-only da galeria da PDP (product.html):
 * duas versoes anteriores tentaram reiniciar o ciclo trocando o
 * animation-name no :checked (copias "-jump" dos keyframes). So que o
 * hover no banner PAUSA as animacoes (regra do carrossel, acima) e clicar
 * numa bolinha exige o mouse sobre o banner - o reinicio acontecia sempre
 * com a animacao PAUSADA, comportamento mal-especificado que varia por
 * engine: funcionava no Chromium, congelava no navegador do cliente ("a
 * imagem nao passa e nem a passagem automatica funciona"). A galeria da
 * PDP pode seguir CSS-only porque la nao ha animacao envolvida - e so
 * mostrar/esconder. Aqui, qualquer regra `lgd-cms-banner__radio:checked`
 * de volta neste arquivo e regressao. */
.lgd-cms-banner__radio {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
/* Escondidas ate o JS assumir (--js). No editor o JS nao carrega, mas a
 * bolinha e visual do bloco e precisa aparecer - dai as duas variantes de
 * editor na regra de exibicao. */
.lgd-cms-banner__dots { display: none; }
.lgd-cms-banner--js .lgd-cms-banner__dots,
.lgd-pgb-block__preview .lgd-cms-banner__dots,
[data-pgb-canvas-free] .lgd-cms-banner__dots {
  position: absolute;
  left: 0; right: 0; bottom: 14px; z-index: 3;
  display: flex; justify-content: center; align-items: center; gap: 6px;
}
/* Bolinhas pequenas e discretas (pedido do cliente): 6px de circulo visivel
 * + 5px de "almofada" invisivel (so aumenta a area de toque, sem aparecer),
 * fundo base bem translucido. */
.lgd-cms-banner__dot {
  display: block; position: relative;
  width: 6px; height: 6px; padding: 5px; box-sizing: content-box;
  border-radius: 50%; background: rgba(255, 255, 255, .3);
  cursor: pointer;
}
.lgd-cms-banner__dot-fill {
  position: absolute; inset: 5px; border-radius: 50%;
  /* Alfa no proprio fundo: o pico da bolinha ativa fica em .8, mais
     discreto que um branco solido. */
  background: rgba(255, 255, 255, .8);
  opacity: 0;
  transition: opacity .4s ease;
  animation-iteration-count: infinite; animation-timing-function: linear;
}

/* SEM JS (na pratica: o preview do editor, unico lugar onde as bolinhas
 * aparecem sem --js), o preenchimento acompanha a troca automatica
 * reusando os MESMOS @keyframes lgd-banner-fade-N das imagens, com o mesmo
 * atraso por posicao. Com --js, o proprio JS marca a bolinha ativa. */
.lgd-cms-banner--slides-2 .lgd-cms-banner__dot-fill {
  animation-name: lgd-banner-fade-2; animation-duration: 12s;
}
.lgd-cms-banner--slides-3 .lgd-cms-banner__dot-fill {
  animation-name: lgd-banner-fade-3; animation-duration: 18s;
}
.lgd-cms-banner--slides-4 .lgd-cms-banner__dot-fill {
  animation-name: lgd-banner-fade-4; animation-duration: 24s;
}
.lgd-cms-banner--slides-5 .lgd-cms-banner__dot-fill {
  animation-name: lgd-banner-fade-5; animation-duration: 30s;
}
.lgd-cms-banner__dot:nth-child(1) .lgd-cms-banner__dot-fill { animation-delay: 0s; }
.lgd-cms-banner__dot:nth-child(2) .lgd-cms-banner__dot-fill { animation-delay: 6s; }
.lgd-cms-banner__dot:nth-child(3) .lgd-cms-banner__dot-fill { animation-delay: 12s; }
.lgd-cms-banner__dot:nth-child(4) .lgd-cms-banner__dot-fill { animation-delay: 18s; }
.lgd-cms-banner__dot:nth-child(5) .lgd-cms-banner__dot-fill { animation-delay: 24s; }

/* Passar o mouse congela o preenchimento (mesma pausa das imagens, acima),
 * pra nao "correr" embaixo do cursor - so importa no preview do editor. */
.lgd-cms-banner--carrossel:hover .lgd-cms-banner__dot-fill { animation-play-state: paused; }

/* Com o JS no comando: animacao CSS fora do caminho (imagens E bolinhas) e
 * crossfade por transicao - quem tem a classe --ativa (posta pelo JS) fica
 * com opacity 1. A 1a imagem continua no fluxo dando altura ao bloco
 * (regra do carrossel acima); so muda quem controla a opacidade. Mesma
 * especificidade (0,2,0) das regras --slides-N de animacao: vence por vir
 * DEPOIS no arquivo. */
.lgd-cms-banner--js .lgd-cms-banner__img {
  animation: none;
  opacity: 0;
  transition: opacity 1s ease;
}
.lgd-cms-banner--js .lgd-cms-banner__img--ativa { opacity: 1; }
.lgd-cms-banner--js .lgd-cms-banner__dot-fill { animation: none; }
.lgd-cms-banner--js .lgd-cms-banner__dot--ativa .lgd-cms-banner__dot-fill { opacity: 1; }

/* Sem animacao, sem carrossel de verdade (so a 1a imagem, ver regra acima)
 * - as bolinhas ficariam prometendo uma navegacao que nao existe. O JS
 * tambem nem se inicializa (matchMedia no banner-carousel.js); o
 * !important cobre a regra --js acima caso a preferencia mude com a pagina
 * ja aberta. */
@media (prefers-reduced-motion: reduce) {
  .lgd-cms-banner__dots { display: none !important; }
}

/* No EDITOR (fluxo ou canvas), a bolinha fica so VISUAL - clicar nela
 * atrapalharia a selecao/arrasto do bloco (canvas-editor.js trata qualquer
 * mousedown que nao seja num contenteditable focado como inicio de
 * arrasto). O radio continua existindo no DOM (o `for` do label nao fica
 * orfao), so inerte ao ponteiro. */
.lgd-pgb-block__preview .lgd-cms-banner__dots,
[data-pgb-canvas-free] .lgd-cms-banner__dots { pointer-events: none; }

/* =================================================================== UE4
 * APARENCIA CANONICA DAS SECOES - valores COPIADOS do <style> de home.html
 * (a pagina de referencia do editor visual), que so os tinha inline.
 *
 * Motivo: o canvas do editor carrega apenas ESTA folha - banner/hero/
 * richtext/imagem+texto/colunas ficavam SEM nenhuma regra visual la (o hero
 * nem tinha o overlay posicionado sobre a imagem) e o editor "estilo Wix"
 * divergia gritantemente do resultado publicado. Com a base aqui, editor e
 * home leem exatamente as mesmas regras.
 *
 * As DEMAIS paginas publicas (page_public/catalog/product) MANTEM suas
 * copias inline proprias, que vem depois desta folha no documento e vencem
 * o empate de especificidade (0,1,0) por ordem de fonte - o visual delas
 * nao muda onde elas redeclarem a propriedade. Propriedade que so exista
 * aqui passa a valer la tambem (unificacao ja assumida na UD).
 * home.html teve a copia REMOVIDA (valores identicos aos daqui). */

.lgd-cms-banner { margin: 0 0 40px; position: relative; }
.lgd-cms-banner__img { width: 100%; height: auto; display: block; }
.lgd-cms-banner__text { text-align: center; margin-top: 12px; }
.lgd-cms-banner__heading {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  margin: 0 0 6px;
}
.lgd-cms-banner__subheading { margin: 0; }
/* Tipografia que a home dava ao texto do banner (sempre sobre a imagem la):
 * escopada no veu (--overlay, que e exatamente "tem texto") para valer em
 * TODAS as paginas onde o texto fica sobre a imagem - 0,2,0 vence as copias
 * inline como as demais regras do veu acima. */
.lgd-cms-banner--overlay .lgd-cms-banner__heading { font-size: 20px; }
.lgd-cms-banner--overlay .lgd-cms-banner__subheading { font-size: 36px; font-weight: 600; }

.lgd-cms-richtext {
  max-width: 70ch;
  margin: 0 auto 40px;
  line-height: 1.8;
  color: var(--text-color, #767676);
}
.lgd-cms-richtext h2,
.lgd-cms-richtext h3 {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #222);
}
/* UF: escala de titulo DENTRO do texto. Sem isto, h2 herda o `29px` global
   do tema (base.html) e fica MAIOR que o titulo da propria pagina
   (`.lgd-cms-title`, 26px no desktop) - hierarquia invertida, visivel assim
   que uma pagina de texto longo (as institucionais) ganhou subtitulos.
   Margens copiadas do template legal antigo. */
.lgd-cms-richtext h2 { font-size: 20px; margin: 32px 0 12px; }
.lgd-cms-richtext h3 { font-size: 17px; margin: 24px 0 10px; }
.lgd-cms-richtext a { color: var(--accent-color, #523336); }
/* Citacao/destaque: o "aviso jurídico" das paginas institucionais e um
   <blockquote> (o sanitizador nao aceita `class`), entao ele precisa se
   distinguir do corpo sozinho - a caixa creme com faixa dourada e a mesma
   que o template legal usava numa div com classe propria.
   `font-style`/`font-size` normalizados porque o tema estiliza TODO
   blockquote como citacao (italico, 14px fixo), o que nao serve para um
   aviso. A FONTE (serifada, Libre Baskerville) fica: o tema a impoe com
   `!important` e o resultado dentro da caixa creme ficou bom - nao vale
   comprar uma briga de `!important` por isso. */
.lgd-cms-richtext blockquote {
  margin: 24px 0;
  padding: 16px 20px;
  border-left: 3px solid var(--gold-color, #A59E59);
  border-radius: 8px;
  background: #FBF1DC;
  font-style: normal;
  font-size: inherit;
}
.lgd-cms-richtext blockquote p:last-child { margin-bottom: 0; }
/* O tema desenha aspas decorativas de 50px em `blockquote:before`
   (6e040003-base.css) posicionadas de forma ABSOLUTA - dentro da caixa elas
   caem EM CIMA da primeira palavra ("A66o:" no lugar de "Aviso:", visto ao
   vivo). Seletor de classe + elemento (0,1,2) vence o `blockquote:before`
   do tema (0,0,2) em qualquer ordem de carregamento. */
.lgd-cms-richtext blockquote::before,
.lgd-cms-richtext blockquote::after { content: none; }
.lgd-cms-richtext ul,
.lgd-cms-richtext ol { padding-left: 20px; margin: 0 0 16px; }

.lgd-cms-imgtext {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 28px;
  margin: 0 auto 40px;
  max-width: 1200px;
  padding: 0 16px;
}
.lgd-cms-imgtext--right { flex-direction: row-reverse; }
.lgd-cms-imgtext__img,
.lgd-cms-imgtext__body { flex: 1 1 320px; min-width: 280px; }
.lgd-cms-imgtext__img img { width: 100%; height: auto; border-radius: 8px; display: block; }
.lgd-cms-imgtext__heading {
  font-family: var(--font-heading-family, "Tenor Sans", serif);
  color: var(--heading-color, #523336);
  margin: 0 0 10px;
}
.lgd-cms-imgtext__text { color: var(--text-color, #878787); line-height: 1.8; }

.lgd-cms-hero { position: relative; margin-bottom: 40px; }
.lgd-cms-hero__img {
  width: 100%;
  height: auto;
  max-height: 640px;
  object-fit: cover;
  display: block;
}
.lgd-cms-hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  padding: 15px;
  /* Cor solida (nao gradiente): contraste >= 4.5:1 p/ texto branco sobre
     qualquer foto (WCAG AA) - historico em home.html/WZ-B. */
  background: rgba(34, 34, 34, .55);
}
.lgd-cms-hero__eyebrow {
  color: #fff;
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: 13px;
  font-weight: 600;
  margin: 0;
}
.lgd-cms-hero__heading {
  color: #fff;
  font-size: 28px;
  margin: 0 0 6px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .35);
}
@media (min-width: 768px) {
  .lgd-cms-hero__heading { font-size: 42px; }
}
.lgd-cms-hero__subheading { color: #fff; margin: 0 0 6px; }

.lgd-cms-colunas {
  display: grid;
  grid-template-columns: repeat(var(--lgd-cms-colunas-count, 2), 1fr);
  gap: 28px;
  max-width: 1200px;
  margin: 0 auto 40px;
  padding: 0 16px;
}
@media (max-width: 767px) {
  .lgd-cms-colunas { grid-template-columns: 1fr; }
}

/* =================================================================== UE4
 * CONTEXTO DO STOREFRONT DENTRO DO EDITOR (.lgd-cms-edit-ctx - classe
 * aplicada SO pelo builder, em admin/page_builder.html; nenhuma pagina
 * publica a emite).
 *
 * O canvas do editor vive no admin, que nao carrega base.html - sem isto o
 * conteudo herdava a tipografia do PAINEL (fonte, corpo 16px, cores) em vez
 * da do site (Muli 14px/1.7, títulos Tenor Sans). Reproduz o essencial do
 * <style> de base.html:
 *   - tokens de marca (custom properties herdam para toda a subarvore);
 *   - corpo e titulos com os MESMOS px do publico;
 *   - `:where()` nos seletores de elemento de proposito: zera a
 *     especificidade, igualando os h1-h6/a de base.html (0,0,1) - sem isso
 *     `.lgd-cms-edit-ctx h2` (0,1,1) venceria regras de componente (0,1,0)
 *     que no publico vencem, invertendo a cascata so no editor. */
.lgd-cms-edit-ctx {
  /* Espelha os mesmos stacks do :root de base.html (Castellar nos titulos,
     NT Seawave no corpo, familias antigas como fallback) - se estes dois
     ficarem para tras, o editor mente sobre o resultado publico, que e
     exatamente o que este bloco existe para evitar. */
  --font-body-family: "NT Seawave Alternative", "Muli", sans-serif;
  --font-heading-family: "Castellar", "Tenor Sans", serif;
  --text-color: var(--text-color, #000);
  --heading-color: var(--heading-color, #000);
  --accent-color: #523336;
  --accent-color-darken: #3A2426;
  --accent-color-hover: var(--accent-color-darken);
  --secondary-color: var(--heading-color, #000);
  --link-color: #523336;
  --link-color-hover: #3A2426;
  --border-color: #ddd;
  --button-background: #523336;
  --button-color: #fff;
  --button-background-hover: #3A2426;
  --button-color-hover: #fff;
  --gold-color: #A59E59;
  --gold-deep: #7A7333;
  --brand-blue-color: #CFE1E6;
  --ink-color: #2A211B;
  font-family: var(--font-body-family);
  font-size: 14px;
  letter-spacing: 0;
  color: var(--text-color);
  line-height: 1.7;
  font-weight: 400;
}
:where(.lgd-cms-edit-ctx) h1,
:where(.lgd-cms-edit-ctx) h2,
:where(.lgd-cms-edit-ctx) h3,
:where(.lgd-cms-edit-ctx) h4,
:where(.lgd-cms-edit-ctx) h5,
:where(.lgd-cms-edit-ctx) h6 {
  color: var(--heading-color);
  font-family: var(--font-heading-family);
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: 0;
}
:where(.lgd-cms-edit-ctx) h1 { font-size: 37px; }
:where(.lgd-cms-edit-ctx) h2 { font-size: 29px; }
:where(.lgd-cms-edit-ctx) h3 { font-size: 23px; }
:where(.lgd-cms-edit-ctx) h4 { font-size: 18px; }
:where(.lgd-cms-edit-ctx) h5 { font-size: 17px; }
:where(.lgd-cms-edit-ctx) h6 { font-size: 15.5px; }
:where(.lgd-cms-edit-ctx) a { color: var(--link-color); }
:where(.lgd-cms-edit-ctx) a:hover { color: var(--link-color-hover); }
/* MEDIDO no storefront em execucao (getComputedStyle de um <p> da home):
   margin 0 0 20px - resultado liquido da cascata do tema (base.css da
   20px, o reset de theme.css nao o derruba). */
:where(.lgd-cms-edit-ctx) p { margin: 0 0 20px; }

/* --- Banner com link: zoom na imagem ao passar o mouse (leva TH) ---------
 *
 * Replica o efeito `t4s-eff-img-zoom` do site publicado, usado nos dois
 * blocos "FAÇA SEU EVENTO" e "VINHOS PREMIADOS". Vale SO para banner com
 * `link_url`: sem link nao ha para onde ir, e um zoom em bloco nao clicavel
 * so promete interacao que nao existe.
 *
 * O `overflow: hidden` mora no <section> (nao no <a>): e ele que recorta a
 * imagem crescida. E o `transform` fica na IMAGEM, nunca no container - no
 * container ele criaria um contexto de empilhamento novo e o texto
 * sobreposto (position:absolute) escalaria junto.
 */
.lgd-cms-banner:has(.lgd-cms-banner__link) { overflow: hidden; }
.lgd-cms-banner:has(.lgd-cms-banner__link) .lgd-cms-banner__img {
  transition: transform .55s cubic-bezier(.2, .6, .3, 1);
  will-change: transform;
}
.lgd-cms-banner:has(.lgd-cms-banner__link):hover .lgd-cms-banner__img,
.lgd-cms-banner:has(.lgd-cms-banner__link):focus-within .lgd-cms-banner__img {
  transform: scale(1.07);
}
/* Escurece de leve no hover para o texto sobreposto nao perder contraste
   quando a imagem cresce e traz areas claras para baixo do texto. */
.lgd-cms-banner--overlay:has(.lgd-cms-banner__link) .lgd-cms-banner__text::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .18);
  opacity: 0;
  transition: opacity .55s ease;
  pointer-events: none;
}
.lgd-cms-banner--overlay:has(.lgd-cms-banner__link):hover .lgd-cms-banner__text::before {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .lgd-cms-banner:has(.lgd-cms-banner__link) .lgd-cms-banner__img,
  .lgd-cms-banner--overlay:has(.lgd-cms-banner__link) .lgd-cms-banner__text::before {
    transition: none;
  }
  .lgd-cms-banner:has(.lgd-cms-banner__link):hover .lgd-cms-banner__img { transform: none; }
}

/* Proporcao dos banners-ladrilho lado a lado (leva TH).
 *
 * O site publicado recorta essas imagens em 2:1 no desktop
 * (`--aspect-ratioapt: 2`) e ~1:1 no mobile (`--aspect-ratioaptmb: 1.001`).
 * Sem isto a foto entra na proporcao NATIVA - as duas sao quadradas
 * (1824x1822), e cada ladrilho virava um bloco de 719px de altura em vez de
 * uma faixa de ~360px, empurrando o resto da home para baixo.
 *
 * O seletor amarra a proporcao a SECAO ESTAR EM MEIA LARGURA (a classe de
 * span vem do grid, calculada por grid_classes a partir de
 * PageSection.layout) - nao a "ser banner". Um banner de largura cheia
 * continua na proporcao da imagem, que e o certo para um banner de topo.
 */
@media (min-width: 768px) {
  .lgd-cms-item[class*="-span-6"] .lgd-cms-banner__img,
  .lgd-cms-item[class*="-span-5"] .lgd-cms-banner__img,
  .lgd-cms-item[class*="-span-4"] .lgd-cms-banner__img {
    aspect-ratio: 2 / 1;
    object-fit: cover;
    width: 100%;
    height: auto;
  }
}
