/* blocos.css — a biblioteca de blocos.
 *
 * Cada bloco funciona com qualquer conjunto de tokens. A diferença entre um
 * "linktree" e um "catálogo" está em QUAIS blocos a página combina, não em
 * folhas de estilo diferentes — por isso tudo vive num arquivo só.
 *
 * Está tudo aqui (e não em base/blocos/*.css) porque não existe bundler no
 * projeto: oito arquivos seriam oito requisições pra economizar 3 KB. Se um
 * dia passar de ~40 KB, aí sim vale dividir.
 *
 *   1. hero          — quem é a marca, em uma tela
 *   2. faixa-links   — o linktree enriquecido: foto + subtexto por link
 *   3. catalogo      — produtos com preço
 *   4. destaque      — um produto só, com espaço pra argumentar (e-book, combo)
 *   5. galeria       — grade de fotos + lightbox
 *   6. prova         — depoimentos
 *   7. faq           — perguntas, em <details> nativo
 *   8. rodape        — contato e marca d'água de proposta
 *   9. zap-fixo      — CTA de WhatsApp ancorada no rodapé da viewport
 */

/* ---- 1. hero ---------------------------------------------------------- */

.hero {
  padding-block: clamp(2.5rem, 1.5rem + 5vw, 5rem) var(--e-7);
  text-align: center;
}

.hero__marca {
  width: 116px;
  height: 116px;
  margin-inline: auto;
  margin-bottom: var(--e-5);
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--sombra-g);
}

.hero__nome {
  margin-bottom: var(--e-3);
}

.hero__linha {
  max-width: 46ch;
  margin-inline: auto;
  font-size: var(--t-lg);
  color: var(--texto-suave);
}

.hero__acoes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e-3);
  margin-top: var(--e-6);
}

/* Variante dividida: painel de marca de um lado, foto do outro.
 *
 * Preferida à foto sangrando quando (a) a marca tem logotipo que merece
 * ser lido antes de qualquer outra coisa e (b) as fotos disponíveis são
 * retrato. Foto retrato esticada pra ocupar tela cheia é recorte de 40%
 * do original com ampliação — fica borrada e some o assunto. Aqui a foto
 * entra numa coluna retrato e é exibida abaixo do tamanho nativo. */
.hero--dividido {
  display: grid;
  grid-template-columns: 1fr;
  min-height: auto;
  padding: 0;
  text-align: initial;
}

/* 74svh e não 86: a primeira tela precisa deixar visível que há página
 * abaixo dela. Hero que ocupa quase toda a altura da janela parece um
 * cartaz e engana quem chega — o visitante não rola porque não sabe que
 * há conteúdo. O teto de 620px segura o exagero em monitor alto. */
@media (min-width: 860px) {
  .hero--dividido {
    grid-template-columns: 1.05fr 0.95fr;
    align-items: stretch;
    min-height: min(74svh, 620px);
  }
}

.hero__painel {
  position: relative;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--e-4);
  padding: var(--e-7) var(--margem-lateral);
  background: var(--superficie-2);
  text-align: center;
  overflow: hidden; /* segura o açúcar dentro do painel */
}

.hero__painel > * {
  position: relative;
  z-index: 1;
}

/* No celular o painel de marca já come uma tela; se a foto pedir 58svh,
 * sobra um dedo de bolo acima da dobra. 44svh deixa o bolo aparecer junto
 * com o fim do painel. No desktop a altura vem do grid, não daqui. */
.hero__foto {
  position: relative;
  min-height: 44svh;
  overflow: hidden;
}

/* absoluta: se a imagem participar do fluxo, é a ALTURA NATURAL dela que
 * define a linha do grid — a foto de 1200x1800 numa coluna de 608px pede
 * 912px e o `min-height: 620px` do hero vira letra morta. Fora do fluxo,
 * quem manda na altura é o painel de texto, que é o certo. */
.hero__foto img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 38%;
}

/* No celular, sem altura fixa o contêiner assume a proporção da própria
 * foto — não há recorte, `object-position` não faz nada, e o visitante vê
 * meia tela do arranjo de flores antes de chegar ao bolo. Com altura
 * cravada a foto vira faixa e o enquadramento desce para o bolo, que é o
 * que ela vende. */
@media (max-width: 859px) {
  .hero__foto {
    height: 36svh;
    min-height: 0;
  }
  .hero__foto img {
    object-position: center 62%;
  }
}

/* No hero dividido, o logotipo é o título — não um selo acima dele. */
.hero__frase {
  max-width: 26ch;
  font-family: var(--fonte-display);
  font-size: var(--t-xl);
  line-height: 1.28;
  color: var(--texto);
}

.hero__linha {
  max-width: 44ch;
  margin-inline: auto;
  color: var(--texto-suave);
  font-size: var(--t-sm);
}

/* ---- açúcar de confeiteiro ----
 * Camada de partículas do vitrine.js. Fica atrás do texto e não recebe
 * clique. Se o JS não rodar ou o usuário pedir menos movimento, o canvas
 * simplesmente não é criado e nada muda de layout. */
.acucar {
  position: absolute;
  inset: 0;
  z-index: 1; /* acima da foto */
  pointer-events: none;
}

/* ---- glacê escorrendo ----
 * Divisor entre seções. A borda reta vira um pingo de cobertura, na cor
 * da seção de cima. Cresce quando entra na tela. */
.pingo {
  position: relative;
  height: 36px;
  margin-top: -1px;
  margin-bottom: calc(var(--e-8) * -0.5);
  color: var(--superficie-2);
  pointer-events: none;
}

.pingo--claro {
  color: var(--superficie);
}

/* Cobertura escorrendo por cima da seção, e não pingando dela: a faixa
 * fica no topo e os pingos descem para dentro do conteúdo. */
.pingo--cobertura {
  height: 64px;
  margin-top: 0;
  margin-bottom: calc(var(--e-6) * -1);
  color: var(--chocolate, var(--acento-forte));
  z-index: 1;
}

.pingo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  transform-origin: top center;
  /* creme sobre branco tem quase zero contraste — sem a sombra o pingo
     não existe na tela. Com ela, lê como relevo de cobertura. */
  filter: drop-shadow(0 2px 2px rgb(60 50 30 / 0.1));
  /* Azulejo de 320px com sete pingos de larguras e profundidades
     diferentes, repetido na horizontal. Largo e irregular de propósito:
     com azulejo curto e pingos iguais a repetição fica evidente e lê como
     serrilha decorativa, não como cobertura.
     A ponta de cada pingo é um semicírculo de verdade (comando A): com
     curva cúbica cujos dois controles convergem no vértice sai bico, que
     é o oposto de calda. A banda ocupa 21% da altura do azulejo — é por
     isso que a animação parte de scaleY(.21): a faixa já nasce inteira e
     só os pingos escorrem. */
  --gota: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 76' preserveAspectRatio='none'%3E%3Cpath d='M320,0 L320,16 L309,16 C309,25.144 307.68,28.5984 307.68,36.32 A9.68,9.68 0 0 1 288.32,36.32 C288.32,28.5984 287,25.144 287,16 L266,16 C266,35.656 264.32,43.0816 264.32,59.68 A12.32,12.32 0 0 1 239.68,59.68 C239.68,43.0816 238,35.656 238,16 L212,16 C212,22.336 210.92,24.7296 210.92,30.08 A7.92,7.92 0 0 1 195.08,30.08 C195.08,24.7296 194,22.336 194,16 L171,16 C171,31.552 169.44,37.4272 169.44,50.56 A11.44,11.44 0 0 1 146.56,50.56 C146.56,37.4272 145,31.552 145,16 L122,16 C122,26.89 120.8,31.004 120.8,40.2 A8.8,8.8 0 0 1 103.2,40.2 C103.2,31.004 102,26.89 102,16 L80,16 C80,37.456 78.32,45.5616 78.32,63.68 A12.32,12.32 0 0 1 53.68,63.68 C53.68,45.5616 52,37.456 52,16 L34,16 C34,23.74 32.8,26.664 32.8,33.2 A8.8,8.8 0 0 1 15.2,33.2 C15.2,26.664 14,23.74 14,16 L0,16 L0,0 Z' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask: var(--gota) repeat-x top center / 320px 100%;
  mask: var(--gota) repeat-x top center / 320px 100%;
}

/* 2,6s, não 0,9s. Cobertura é viscosa: começa a ceder devagar, ganha peso
 * no meio do caminho e para sem quicar. O bezier faz essa curva — nada de
 * overshoot elástico, que faria a calda "pular" de volta pra cima. */
.js .pingo::before {
  transform: scaleY(0.21);
  transition: transform 2600ms cubic-bezier(0.7, 0.02, 0.35, 1);
}

.js .pingo--cobertura::before {
  transition-duration: 3200ms; /* mais fundo, escorre mais devagar */
}

.js .pingo.visivel::before {
  transform: scaleY(1);
}

@media (prefers-reduced-motion: reduce) {
  .js .pingo::before,
  .js .pingo.visivel::before {
    transform: none;
    transition: none;
  }
}

/* ---- 2. faixa-links --------------------------------------------------- */

/* Duas colunas a partir de 720px. Em coluna única, quatro links de 100px
 * empilhados empurram todo o resto meia tela pra baixo — e a faixa de
 * links existe justamente pra encurtar caminho, não pra alongar. */
.links {
  display: grid;
  gap: var(--e-3);
}

@media (min-width: 720px) {
  .links {
    grid-template-columns: 1fr 1fr;
  }
}

/* O link deixa de ser uma linha de texto e passa a mostrar o produto.
 * É a diferença visível entre esta página e um agregador de bio. */
.link {
  display: grid;
  grid-template-columns: 84px 1fr auto;
  align-items: center;
  gap: var(--e-4);
  padding: var(--e-3);
  background: var(--superficie-2);
  border: 1px solid var(--borda);
  border-radius: var(--raio-g);
  color: inherit;
  text-decoration: none;
  transition: transform var(--transicao), box-shadow var(--transicao),
    border-color var(--transicao);
}

.link:hover {
  transform: translateY(-2px);
  border-color: var(--acento);
  box-shadow: var(--sombra-g);
}

.link__foto {
  width: 84px;
  height: 84px;
  border-radius: calc(var(--raio-g) - 4px);
  object-fit: cover;
  /* o assunto de foto de produto costuma estar acima do centro
     geométrico — no quadrado, centralizar corta a parte que interessa */
  object-position: center 35%;
  background: var(--superficie-3);
}

.link__titulo {
  font-weight: var(--peso-forte);
  line-height: 1.3;
}

/* block: se ficar inline, o .link__selo que vem depois entra na mesma
 * linha e sobe por cima do texto */
.link__sub {
  display: block;
  font-size: var(--t-sm);
  color: var(--texto-suave);
  line-height: 1.4;
}

.link__seta {
  padding-inline-end: var(--e-3);
  color: var(--texto-suave);
  transition: transform var(--transicao), color var(--transicao);
}

.link:hover .link__seta {
  transform: translateX(3px);
  color: var(--acento);
}

/* selo opcional: "novo", "esgotado", "só encomenda" */
.link__selo {
  display: inline-block;
  margin-top: var(--e-1);
  padding: 2px 8px;
  border-radius: var(--raio-pilula);
  background: var(--acento);
  color: var(--sobre-acento);
  font-size: var(--t-xs);
  font-weight: var(--peso-forte);
}

/* ---- 3. catalogo ------------------------------------------------------ */

/* auto-FIT, não auto-fill: com dois cartões numa largura que comportaria
 * quatro, o auto-fill cria as quatro faixas e deixa os cartões espremidos
 * em 320px — a tabela de preços dentro deles quebra "R$ 70" em duas
 * linhas. O auto-fit descarta as faixas vazias e os dois ocupam a
 * largura toda. */
.catalogo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: var(--e-5);
}

.produto {
  display: flex;
  flex-direction: column;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio-g);
  overflow: hidden;
  transition: transform var(--transicao), box-shadow var(--transicao);
}

.produto:hover {
  transform: translateY(-3px);
  box-shadow: var(--sombra-g);
}

.produto__foto {
  aspect-ratio: 4 / 3;
  width: 100%;
  object-fit: cover;
  background: var(--superficie-3);
}

.produto__corpo {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  flex: 1;
  padding: var(--e-4);
}

.produto__nome {
  font-family: var(--fonte-display);
  font-size: var(--t-lg);
  line-height: 1.25;
}

.produto__desc {
  font-size: var(--t-sm);
  color: var(--texto-suave);
  flex: 1;
}

.produto__preco {
  font-weight: var(--peso-forte);
  font-size: var(--t-lg);
}

.produto__preco small {
  font-weight: 400;
  font-size: var(--t-xs);
  color: var(--texto-suave);
}

/* ---- 4. destaque ------------------------------------------------------ */

.destaque {
  display: grid;
  gap: var(--e-6);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 760px) {
  .destaque {
    grid-template-columns: 1fr 1fr;
  }
  .destaque--invertido .destaque__midia {
    order: 2;
  }
}

.destaque__midia {
  border-radius: var(--raio-g);
  overflow: hidden;
  box-shadow: var(--sombra-g);
}

/* Duas regras que trabalham juntas:
 *  - aspect-ratio dá a proporção;
 *  - max-height impede que a proporção mande na altura da seção. Numa
 *    coluna de 500px, um 3/4 pede 665px de altura — e aí o leitor rola
 *    meia tela de foto que já viu pra alcançar o texto ao lado.
 * O object-fit recorta o excedente pelo centro. */
.destaque__midia img {
  width: 100%;
  aspect-ratio: 3 / 4;
  max-height: var(--foto-alta);
  object-fit: cover;
}

/* Para foto horizontal. Sem isto o 3/4 padrão recorta uma paisagem até o
 * miolo e o assunto some — foi o que aconteceu com a tábua de bombons. */
.destaque__midia--larga img {
  aspect-ratio: 4 / 3;
}

/* Retrato de baixa resolução (foto de origem pequena, sem substituto):
 * coluna estreita, exibido abaixo do tamanho nativo. Ampliar borra. */
.destaque--retrato {
  gap: var(--e-6);
}

@media (min-width: 760px) {
  .destaque--retrato {
    grid-template-columns: minmax(0, 300px) 1fr;
    align-items: center;
  }
}

.destaque--retrato .destaque__midia img {
  aspect-ratio: 3 / 4;
  max-height: none;
}

.destaque__lista {
  display: grid;
  gap: var(--e-2);
  padding: 0;
  margin: var(--e-4) 0;
  list-style: none;
}

.destaque__lista li {
  display: grid;
  grid-template-columns: 1.2em 1fr;
  gap: var(--e-2);
  color: var(--texto-suave);
}

.destaque__lista li::before {
  content: "—";
  color: var(--acento);
}

/* Lista longa em duas colunas. Para menus de sabor, que são muitos itens
 * curtos: em coluna única viram um metro de rolagem. */
@media (min-width: 620px) {
  .destaque__lista--duas {
    display: block;
    columns: 2;
    column-gap: var(--e-6);
  }
  .destaque__lista--duas li {
    break-inside: avoid;
    margin-bottom: var(--e-2);
  }
}

/* ---- 4b. banner -------------------------------------------------------
 * Foto larga que corta a leitura sem custar meia tela de rolagem. Serve
 * onde a foto é ambiente (mesa posta, vitrine) e não objeto único. */
.banner {
  border-radius: var(--raio-g);
  overflow: hidden;
  box-shadow: var(--sombra);
}

.banner img {
  width: 100%;
  aspect-ratio: 21 / 9;
  max-height: 380px;
  object-fit: cover;
  object-position: center 55%;
}

/* ---- 5. galeria ------------------------------------------------------- */

/* 240px dá 4 colunas na largura padrão. Escolhido pela aritmética das
 * linhas órfãs: com 5 colunas, coleções de 6 e 12 fotos sobram 1 e 2 no
 * fim, e uma linha quase vazia estraga a grade. Use --terco quando a
 * coleção for múltipla de 3. */
.galeria {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 45%), 1fr));
  gap: var(--e-3);
}

/* min(300px, 46%) e não min(300px, 100%): no celular o 100% colapsa a
 * grade para uma coluna só e seis fotos viram dois mil pixels de rolagem.
 * Com 46% são sempre pelo menos duas colunas. */
.galeria--terco {
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 46%), 1fr));
}

.galeria button {
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--raio);
  overflow: hidden;
}

.galeria img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: var(--superficie-3);
  transition: transform var(--transicao);
}

.galeria button:hover img {
  transform: scale(1.04);
}

/* lightbox: <dialog> nativo, sem biblioteca */
.lupa {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: min(92vw, 1000px);
  max-height: 92vh;
}

.lupa::backdrop {
  background: rgb(0 0 0 / 0.82);
}

.lupa img {
  width: 100%;
  height: auto;
  max-height: 92vh;
  object-fit: contain;
  border-radius: var(--raio);
}

.lupa__fechar {
  position: absolute;
  top: var(--e-3);
  right: var(--e-3);
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.55);
  color: #fff;
  font-size: 1.3rem;
  cursor: pointer;
}

/* ---- 6. prova --------------------------------------------------------- */

.provas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: var(--e-5);
}

.prova {
  padding: var(--e-5);
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio-g);
}

.prova blockquote {
  margin: 0 0 var(--e-4);
  font-family: var(--fonte-display);
  font-size: var(--t-lg);
  line-height: 1.45;
}

.prova figcaption {
  font-size: var(--t-sm);
  color: var(--texto-suave);
}

/* ---- 7. faq ----------------------------------------------------------- */

.faq {
  display: grid;
  gap: var(--e-2);
}

.faq details {
  border: 1px solid var(--borda);
  border-radius: var(--raio);
  background: var(--superficie);
}

.faq summary {
  padding: var(--e-4);
  font-weight: var(--peso-forte);
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--e-3);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "+";
  color: var(--acento);
  font-size: 1.25em;
  line-height: 1;
}

.faq details[open] summary::after {
  content: "–";
}

.faq details > *:not(summary) {
  padding: 0 var(--e-4) var(--e-4);
  color: var(--texto-suave);
}

/* ---- 8. rodape -------------------------------------------------------- */

.rodape {
  padding-block: var(--e-7);
  background: var(--superficie-2);
  border-top: 1px solid var(--borda);
  text-align: center;
  font-size: var(--t-sm);
  color: var(--texto-suave);
}

.rodape__redes {
  display: flex;
  justify-content: center;
  gap: var(--e-4);
  margin-block: var(--e-4);
}

/* Marca d'água de proposta. Sai na entrega ao cliente — está isolada
 * justamente pra ser um `git rm` de uma linha no HTML. */
.marca-dagua {
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: 1px solid var(--borda);
  font-size: var(--t-xs);
  opacity: 0.75;
}

/* ---- 9. zap-fixo ------------------------------------------------------
 * CTA ancorada no rodapé da janela. Opcional, e a escolha padrão é NÃO
 * usar: numa página com CTA em cada seção ela é a oitava porta para o
 * mesmo lugar, e cobre conteúdo em toda a rolagem. Vale quando a página é
 * curta, ou quando o corpo é leitura longa sem ponto natural de ação.
 * O espaço extra no rodapé só existe se ela existir — daí o :has(). */

body:has(.zap-fixo) .rodape {
  padding-bottom: calc(var(--e-7) + 72px);
}

.zap-fixo {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 40;
  padding: var(--e-3) var(--margem-lateral);
  padding-bottom: calc(var(--e-3) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--superficie) 88%, transparent);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--borda);
  display: flex;
  justify-content: center;
}

.zap-fixo .botao {
  width: min(100%, var(--largura-estreita));
}
