/* ============================================================
   ECHOO NATURE FEST — folha de estilos

   O site é CLARO, com um gradiente de dia a atravessar a página.
   A excepção é o topo, que é escuro de propósito: é o único sítio
   onde o amarelo #FDCD66 do logótipo se lê, e onde o halo do blob
   não se transforma numa mancha suja.

   O amarelo vem do ficheiro da designer, não de interpretação —
   `echoo fotos/logotipo/echoo-nature-fest-2026.svg`.
   ============================================================ */

:root {
  color-scheme: light;

  /* ══════════════════════════════════════════════════════════════
     A PALETA DE 2024/25 — as três cores da identidade, tiradas dos
     próprios ficheiros da marca em site/img (logo-info-manga.png e
     logo-info-turquesa.png). Não são interpretação: são as cores que
     lá estão.
     ══════════════════════════════════════════════════════════════ */
  /* O AMARELO. Durante algum tempo o site usou #FFCC00, tirado do site de
     2025, mais saturado do que o do logótipo. Deixou de fazer sentido quando
     chegou o SVG da designer: o ficheiro da marca é #FDCD66, e ter dois
     amarelos a 1,02:1 um do outro lê-se como um erro, não como uma escolha.
     Ganha o ficheiro — é ele que vai para cartazes e redes.

     E o rosa tem um trabalho definido no site de 2025: escreve a tradução
     inglesa. O português vem em amarelo, o inglês a seguir em rosa —
     «Experiências Gastronómicas / Gastronomic Experiences». */
  --manga:   #FDCD66;   /* o amarelo do ficheiro do logótipo */
  --rosa:    #FFCC99;   /* o rosa claro de 2025 — a cor da tradução */

  /* O ROSA FORTE. É o topo do fundo do site de 2025, que é literalmente
     `linear-gradient(180deg, #C23D68 0%, #D8A24B 100%)` — framboesa em
     cima, ouro em baixo.

     Não se copia a rampa inteira porque ela não segura texto nenhum: o
     amarelo deles sobre o ouro dá 1,51:1, e não existe cor que passe nas
     duas pontas (o creme cai a 2,25 no ouro, a tinta a 2,51 na framboesa).
     Traz-se a framboesa para onde ela funciona: blocos com texto claro por
     cima — na barra dá 4,96:1. */
  --rosa-forte: #C23D68;
  --menta:   #A0D0B0;   /* o verde-água da segunda versão do logótipo */
  --malva:   #887880;   /* o neutro, o que escreve «FEST '24» */

  /* --- papel e tinta --- */
  --papel:    #FFFDF6;
  --cartao:   #FFFFFF;
  --cartao-2: #FDF6E6;
  --rule:     #E6DCC6;

  /* A tinta é o malva escurecido: fica na família da marca em vez de
     ser um cinzento emprestado. Medida sobre a rampa toda, no pior
     ponto (o manga puro): 8,11 / 5,29 / 4,91. */
  --tinta:   #3A3036;
  --tinta-2: #574B53;
  --tinta-3: #5E4F58;

  /* o gradiente do botão: as duas cores da marca, ponta a ponta */
  --grad-quente: linear-gradient(120deg, #FDCD66 0%, #FFD24D 54%, #FFCC99 100%);

  /* ══════════════════════════════════════════════════════════════
     O GRADIENTE — um dia claro no Chão das Feiteiras. Sobe do creme da
     manhã ao manga a pino (onde vive a open call), desce pela menta da
     laurissilva e volta ao creme.

     REGRA que manda em tudo o resto: nenhuma cor da marca serve para
     TEXTO sobre claro. O manga sobre creme dá 1,35:1 e a menta 1,45:1
     — ilegíveis. Servem para BLOCOS inteiros, com tinta escura por
     cima, e aí dão 8:1 ou mais. É por isso que neste site a cor
     aparece em painéis e a letra é sempre escura.
     ══════════════════════════════════════════════════════════════ */
  --grad-pagina: linear-gradient(180deg,
      #FFF6F0  0%,
      #FFE8D8  8%,
      #FFCC99  17%,   /* o rosa de 2025, a primeira luz */
      #FFD49A  26%,
      #FFDC7A  35%,
      #FDCD66  44%,   /* o amarelo de 2025, a pino */
      #FFD84D  53%,
      #F2DE9C  62%,
      #DCE4BE  71%,
      #C6DFCE  80%,   /* a menta da laurissilva */
      #DCEBE0  88%,
      #F2F7F0  94%,
      #FFFDF6  100%);

  /* --- tipos --- */
  --f-disp: "Gabarito", "Trebuchet MS", system-ui, sans-serif;
  --f-body: "Karla", system-ui, -apple-system, sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;

  /* --- ritmo --- */
  --measure: 64ch;
  --wide: 1180px;
  /* A ESCALA DE ESPACOS. Estes numeros comandam o ar todo do site — os
     intervalos entre blocos, entre paragrafos, dentro dos cartoes.

     Estiveram uma vez em 36/58/88/128 e o site lia-se como se estivesse
     sempre com zoom: a 80% no browser ficava bem, a 100% ficava grande.
     Desceram em duas voltas ate aqui. Se algum dia voltar a parecer
     esticado, e aqui que se mexe — e mexe-se nos numeros todos ao mesmo
     tempo, porque mexer num so desequilibra o ritmo da pagina.

     O CORPO DE TEXTO NAO ACOMPANHA. Esta nos 16px e ai fica: abaixo disso
     deixa de se ler bem, e um site publico nao pode pedir isso a ninguem.
     A sensacao de "menos zoom" vem dos titulos e do ar, nao do corpo. */
  --s1: 8px;  --s2: 11px; --s3: 16px;
  --s4: 27px; --s5: 43px; --s6: 65px; --s7: 90px;

  /* ══════════════════════════════════════════════════════════════
     CAMADA 2 — FUNÇÕES. Os componentes só falam com estes nomes.
     ══════════════════════════════════════════════════════════════ */

  /* O logótipo NÃO pode ser manga sobre claro: dá 1,00:1 no manga da
     rampa, desaparece. Vai a tinta, como o «FEST '24» do original. */
  --c-marca:           var(--tinta);   /* por omissao (rodape, fundo claro) */
  --c-num-contagem:    var(--tinta);
  --c-cta-no-claro:    var(--manga);

  --c-titulo:          var(--tinta);
  --c-titulo-hero:     var(--tinta);
  --c-eyebrow:         var(--tinta-2);
  --c-eyebrow-hero:    var(--tinta);

  --c-link:            var(--tinta-3);
  --c-link-hover:      #96500F;

  --c-num-estat:       var(--tinta);
  --c-meta:            var(--tinta-2);

  --c-icone-cartao:    #5E8E72;
  --c-icone-nav:       var(--papel);   /* o botao do menu vive na barra rosa */
  --c-icone-aviso:     #5E8E72;

  --c-borda-activa:    var(--malva);
  --c-foco:            #96500F;
  --c-contorno-botao:  var(--tinta-2);
  /* verde-escuro e nao rosa: o rosa e agora o fundo desta seccao, e
     um marcador rosa sobre fundo rosa nao se ve. */
  --c-marcador:        var(--rosa-forte);

  --c-levada-canal:    #6E5F68;
  --c-levada-pedras:   #A08A96;
  --c-destaque-cartao: var(--rosa-forte);
  --c-linha-detalhe:   var(--malva);

  --curva: cubic-bezier(0.22, 0.61, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--grad-pagina) var(--papel);
  background-repeat: no-repeat;
  color: var(--tinta);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }

/* O `hidden` TEM DE GANHAR SEMPRE.

   O browser esconde `[hidden]` com `display: none`, mas basta uma classe
   nossa com `display` para lhe passar à frente — e passa, porque uma classe
   pesa mais do que a regra do browser. Foi o que aconteceu ao campo de
   ficheiros do formulário: o JavaScript punha `hidden = true`, o
   `.campo { display: flex }` ganhava, e o campo continuava à vista — sem
   `name` e desactivado, a engolir em silêncio o que lá puséssemos.

   Com isto, `hidden` volta a querer dizer escondido, em toda a parte.      */
[hidden] { display: none !important; }

a { color: var(--c-link); text-underline-offset: 3px; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--c-foco);
  outline-offset: 3px;
  border-radius: 3px;
}

.wrap  { width: 100%; max-width: var(--wide); margin: 0 auto; padding: 0 24px; }
.prose { max-width: var(--measure); }

/* saltar para o conteúdo — teclado e leitores de ecrã */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--manga); color: var(--tinta); font-weight: 700;
  padding: 12px 20px; border-radius: 0 0 6px 0;
}
.skip:focus { left: 0; }

/* ---------- tipografia ---------- */

h1, h2, h3, .display {
  font-family: var(--f-disp);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.02;
  text-wrap: balance;
  margin: 0;
  color: var(--tinta);
}
h1 { font-size: clamp(2rem, 5.2vw, 3.33rem); }
h2 { font-size: clamp(1.55rem, 3.6vw, 2.15rem); }
h3 { font-size: clamp(1.05rem, 2vw, 1.17rem); letter-spacing: -0.02em; }

.eyebrow {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--c-eyebrow);
  margin: 0;
}

.lede { font-size: 1.05rem; color: var(--tinta-2); margin: var(--s3) 0 0; }
p { margin: var(--s2) 0 0; }
p.first { margin-top: var(--s3); }

/* ---------- botões ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 9px; min-height: 48px; padding: 0 24px;
  border-radius: 999px; border: 1.5px solid transparent;
  font-family: var(--f-body); font-weight: 700; font-size: 0.97rem;
  text-decoration: none; cursor: pointer;
  transition: transform 200ms var(--curva), background-color 200ms var(--curva),
              background-position 420ms var(--curva),
              border-color 200ms var(--curva), color 200ms var(--curva);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* o botão principal carrega o gradiente da marca em miniatura */
.btn-1 { background: var(--grad-quente); color: var(--tinta); background-size: 160% 100%; background-position: 0% 50%; }
.btn-1:hover { background-position: 100% 50%; }

.btn-2 { border-color: color-mix(in srgb, var(--c-contorno-botao) 58%, transparent); color: var(--c-contorno-botao); background: transparent; }
.btn-2:hover { background: color-mix(in srgb, var(--c-contorno-botao) 14%, transparent); border-color: var(--c-contorno-botao); }

.btn[aria-disabled="true"] {
  background: var(--cartao-2); color: var(--tinta-3);
  border-color: var(--rule); cursor: not-allowed; pointer-events: none;
}

/* ---------- logótipo ---------- */

/* Até aqui o logótipo era uma imitação composta em Gabarito, com dois blobs
   feitos de border-radius. Passou a ser o SVG da designer.

   O ficheiro tem uma cor só, e por isso não pode ser recolorido por CSS —
   há uma versão por cor em site/img/logo/, geradas por tools/logo.py. Qual
   entra depende do fundo, e isso não é gosto, é medida:

     amarelo #FDCD66 sobre a barra rosa #C23D68 ... 3,39:1   passa
     amarelo #FDCD66 sobre o creme #FFFDF6 ........ 1,46:1   desaparece
     tinta   #3A3036 sobre o creme ................. 8,52:1   passa          */

.mark {
  display: inline-flex; align-items: center;
  text-decoration: none; line-height: 0;
}
.mark img { height: 30px; width: auto; display: block; }

/* na barra rosa cabe menos e o amarelo é ele próprio; o logótipo nunca
   encolhe para dar espaço às ligações (com a barra cheia ficava esmagado) */
.nav .mark { flex-shrink: 0; }
.nav .mark img { height: 26px; }

/* ---------- navegação ---------- */

.nav {
  position: sticky; top: 0; z-index: 40;
  /* A barra e o rosa forte de 2025 — o mesmo #C23D68 do topo do fundo
     deles. E a unica zona escura da pagina, por isso tudo o que vive nela
     e claro. Quase opaca de proposito: translucida por cima da fotografia
     do topo ficava suja em vez de rosa. */
  background: rgba(194, 61, 104, 0.95);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color 300ms var(--curva), background-color 300ms var(--curva);
}
.nav.colado { border-bottom-color: #8E2A4B; background: rgba(194, 61, 104, 0.99); }

.nav .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); min-height: 68px;
}
.nav-links { display: flex; align-items: center; gap: var(--s4); }
.nav-links a {
  font-family: var(--f-mono); font-size: 11.5px;
  letter-spacing: 0.11em; text-transform: uppercase;
  /* creme, nao tinta: a barra e a unica zona escura do site */
  color: var(--papel); text-decoration: none;
  padding: 6px 0; position: relative;
  transition: color 200ms var(--curva);
}
.nav-links a:hover { color: var(--manga); }
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
  height: 1px; background: var(--manga);
  transition: right 260ms var(--curva);
}
.nav-links a:hover::after { right: 0; }

/* Tem de ser `.nav-links a.lang` e não só `.lang`: a regra `.nav-links a`
   acima é mais específica e, com `.lang` sozinho, comia-lhe o padding
   lateral — a pastilha encolhia para 18 px e o texto ficava colado à
   borda. */
.nav-links a.lang {
  font-family: var(--f-mono); font-size: 11.5px; letter-spacing: 0.11em;
  color: var(--papel); text-decoration: none;
  border: 1px solid color-mix(in srgb, var(--papel) 62%, transparent);
  border-radius: 999px; padding: 7px 13px;
  min-height: 34px; display: inline-flex; align-items: center;
  transition: background-color 200ms var(--curva);
}
.nav-links a.lang:hover { background: color-mix(in srgb, var(--papel) 22%, transparent); }

/* As duas pílulas da barra partem desta regra: «Bilhete», cheia de manga
   como o botão principal do topo, para o bilhete se ver de qualquer página;
   e «Inscrições» (`.nav-cta-2`, mais abaixo), contornada. */
.nav-links a.nav-cta {
  background: var(--manga); color: var(--tinta); font-weight: 500;
  border-radius: 999px; padding: 7px 14px; min-height: 34px;
  /* borda transparente da mesma largura que a da pílula «Inscrições»
     (mais abaixo): sem ela as duas ficavam com alturas diferentes, lado a lado */
  border: 1.5px solid transparent;
  display: inline-flex; align-items: center;
  transition: background-color 200ms var(--curva);
}
.nav-links a.nav-cta:hover { color: var(--tinta); background: #FFD84D; }
.nav-links a.nav-cta::after { display: none; }

/* menu de telemóvel */
.menu-btn {
  display: none; background: transparent; border: 0; cursor: pointer;
  width: 46px; height: 46px; padding: 0; color: var(--c-icone-nav);
  align-items: center; justify-content: center;
}
.menu-btn svg { width: 25px; height: 25px; }

/* ---------- topo / hero ---------- */

/* O TOPO OCUPA O ECRA TODO, MENOS UMA MARGEM.

   Duas coisas puxam em sentidos contrarios. O video e 16:9 e entra em
   `object-fit: cover`: se o topo for baixo e largo, o que sobra do
   fotograma e cortado em cima e em baixo. Quanto mais alto o topo, menos
   se corta. Mas o conteudo esta encostado ao fundo (`align-items: flex-end`),
   por isso um topo mais alto empurra a contagem decrescente para baixo — e
   se ela passar a dobra, deixa de se ver.

   A conta que concilia as duas: a contagem acaba em
   `69 (barra) + altura do topo - 16 (respiro de baixo)`. Para caber no ecra,
   a altura do topo tem de ser no maximo `altura da janela - 53`. Os 80px
   deixam essa folga e ainda sobra margem.

   `svh` e a altura do ecra sem contar com as barras do browser do telemovel,
   que aparecem e desaparecem com o scroll; sem isso o topo dava saltos.     */
.hero {
  position: relative;
  min-height: calc(100vh - 80px);
  display: flex; align-items: flex-end; overflow: hidden;
}
@supports (height: 100svh) {
  .hero { min-height: calc(100svh - 80px); }
}
.hero-foto { position: absolute; inset: 0; overflow: hidden; }
.hero-foto img {
  /* UMA SÓ FOTOGRAFIA, em todos os ecrãs.
     Houve aqui duas — uma panorâmica para computador e uma vertical para
     telemóvel — mas ver uma imagem no telemóvel e outra no computador,
     conforme o vídeo tocasse ou não, dava a sensação de dois sites. Agora
     é a mesma, e o `cover` trata do enquadramento: no telemóvel mostra o
     tipi de alto a baixo, no computador uma faixa larga do interior.
     Os 62% puxam o corte para baixo do centro, onde estão as pessoas. */
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%;
  /* a escala dá folga para a fotografia se deslocar sem mostrar as bordas */
  transform: scale(1.16); transform-origin: 50% 40%;
  will-change: transform;
}

/* O VÍDEO DO TOPO ESTÁ POR CIMA DA FOTOGRAFIA, MAS EM REPOUSO NÃO SE VÊ.

   É a mesma regra da cortina de folhagem: o estado de repouso é o que se
   lê. A fotografia continua no HTML e continua à vista; só quando o
   JavaScript confirma que o vídeo está mesmo a tocar é que a classe
   `.video-ligado` o faz aparecer por cima. Sem JS, sem ficheiro, em ecrã
   estreito ou com o vídeo recusado pelo browser, fica a fotografia — e
   ninguém dá por nada.

   O enquadramento e a escala são os mesmos da fotografia, para a paralaxe
   do topo tratar os dois da mesma maneira e a troca não dar um salto.     */
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%;
  transform: scale(1.16); transform-origin: 50% 40%;
  will-change: transform;
  opacity: 0; transition: opacity 700ms ease;
  pointer-events: none;
}
.hero-foto.video-ligado .hero-video { opacity: 1; }

/* O VÉU DO TOPO É ESCURO, e o resto da página é claro. É de propósito.

   O logótipo é amarelo #FDCD66 e não há como o mudar: recolorido de escuro,
   os seis anéis translúcidos do halo do blob transformam-se numa mancha
   suja. E o amarelo sobre o véu creme antigo media 1,03 a 1,95:1 — sumia.

   Sobre este véu escuro dá 3,6:1, o halo brilha como foi desenhado, e a
   fotografia mantém a profundidade em vez de ficar lavada. Só o topo é
   escuro; da open call para baixo o site volta ao claro.                  */
/* Os valores deste gradiente nao sao decorativos: sao o que mantem o texto
   legivel por cima da fotografia. Medidos com a foto `feira-montanha`, que e
   soalheira, o paragrafo do topo fica com 5,5:1 de contraste (o minimo exigido
   e 4,5:1). Com o 54% a 0.60, como estava, descia a 4,52:1 — mesmo em cima do
   limite. Se um dia trocar a fotografia do topo por outra clara, ou alongar o
   paragrafo, meca outra vez antes de aliviar o veu. */
.hero-veu {
  position: absolute; inset: 0;
  background:
    linear-gradient(to top,
      rgba(42,34,38,0.95) 2%,
      rgba(42,34,38,0.86) 30%,
      rgba(42,34,38,0.68) 54%,
      rgba(42,34,38,0.22) 78%,
      rgba(42,34,38,0.06) 100%);
}
/* z-index acima das serras (z:2): sem isto as cumeadas passavam por cima
   da contagem decrescente, que e conteudo e nao pano de fundo. */
.hero .wrap { position: relative; z-index: 3; padding-top: var(--s6); padding-bottom: var(--s5); will-change: transform, opacity; }

/* Com o véu escuro, todo o texto do topo tem de virar claro. Antes era
   escuro sobre creme; se ficasse assim, desaparecia. */
.hero .eyebrow {
  display: inline-block; color: var(--manga);
  background: rgba(28, 22, 25, 0.55);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  padding: 7px 13px; border-radius: 3px;
}

/* O <h1> passou a ser o lockup completo — a marca, o ano e as datas, como
   a designer os desenhou. Continua a ser o <h1> da página: o texto vive no
   alt da imagem, por isso nem os leitores de ecrã nem o Google o perdem. */
.hero h1 { margin-top: var(--s3); line-height: 0; }
.hero h1 img { width: min(390px, 68vw); height: auto; }

/* o botao de contorno do topo vive agora sobre escuro */
.hero .btn-2 { border-color: rgba(253,205,102,0.55); color: var(--manga); }
.hero .btn-2:hover { background: rgba(253,205,102,0.14); border-color: var(--manga); }

.hero .sub { max-width: 46ch; font-size: 1.05rem; color: #EFE6DC; margin-top: var(--s3); }
.hero .accoes { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }

/* PARAR O VÍDEO. Uma coisa que se mexe sozinha durante mais de cinco
   segundos tem de poder ser parada (WCAG 2.2.2). Fica pequeno e no canto
   — não é conteúdo, é um controlo — mas é um <button> a sério: chega-se
   lá pelo teclado e tem nome para os leitores de ecrã.

   Nasce com `hidden` no HTML e só o JavaScript o mostra, depois de o
   vídeo arrancar. Sem vídeo não há botão a controlar coisa nenhuma.

   z-index 4 porque a .wrap do topo está a 3 e as serras a 2.            */
.video-btn {
  position: absolute; right: 20px; bottom: 20px; z-index: 4;
  width: 38px; height: 38px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(253,205,102,0.45); border-radius: 50%;
  background: rgba(28, 22, 25, 0.55);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  color: var(--manga); cursor: pointer;
  transition: background 180ms ease, border-color 180ms ease;
}
.video-btn[hidden] { display: none; }
.video-btn svg { width: 17px; height: 17px; fill: currentColor; }
.video-btn:hover { background: rgba(28, 22, 25, 0.78); border-color: var(--manga); }
/* sobre o véu escuro o foco global perde-se: aqui o anel é manga */
.video-btn:focus-visible { outline: 2px solid var(--manga); outline-offset: 3px; }

/* contagem decrescente */
.contagem {
  display: flex; gap: var(--s4); flex-wrap: wrap;
  margin-top: var(--s5); padding-top: var(--s3);
  border-top: 1px solid rgba(253,205,102,0.34);
}
.contagem div { display: flex; flex-direction: column; gap: 2px; }
.contagem .n {
  font-family: var(--f-disp); font-weight: 800; font-size: clamp(1.4rem, 2.9vw, 1.8rem);
  color: var(--manga); line-height: 1; font-variant-numeric: tabular-nums;
}
.contagem .r {
  font-family: var(--f-mono); font-size: 10px;
  letter-spacing: 0.15em; text-transform: uppercase; color: #D9CFC5;
}

/* ---------- secções ---------- */

main { position: relative; }
section { position: relative; }
.bloco { padding: var(--s7) 0; }
.bloco-cerrado { padding: var(--s6) 0; }

.cabeca { max-width: 58ch; }
.cabeca h2 { margin-top: var(--s2); }

/* ---------- open call ---------- */

/* O bloco da open call é o único claro da página inteira. É de propósito:
   é a razão de a página existir esta semana, e o contraste com o escuro à
   volta faz com que não se possa passar por ele sem o ver. */
/* A open call já não é um painel claro: destaca-se por uma faixa e pelo
   cartão do prazo, não por mudar o fundo. O fundo é o gradiente da página. */
.opencall { background: transparent; border-top: 1px solid var(--rule);
            border-bottom: 1px solid var(--rule); }
.opencall .wrap { display: grid; grid-template-columns: 1.25fr 1fr; gap: var(--s6); align-items: start; }
/* #653009 é o tom mais claro que ainda passa 4,5:1 sobre TODAS as paragens
   do gradiente, incluindo o coral no canto. O #7A3D10 só passava por sorte,
   por a etiqueta calhar na ponta clara. */


.prazo {
  background: var(--cartao); border: 1px solid var(--rule);
  border-left: 4px solid var(--c-destaque-cartao); border-radius: 6px; padding: var(--s3) var(--s4);
}
.prazo .rot {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3);
}
.prazo .data {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.35rem;
  color: var(--tinta); margin-top: 5px; letter-spacing: -0.02em;
}
.prazo .restam { font-size: 0.94rem; color: var(--c-meta); margin-top: var(--s1); }
/* a data dos resultados fica separada do prazo por um risco: são duas
   informações diferentes, e coladas liam-se como uma só */
.prazo .resultados {
  font-size: 0.94rem; color: var(--c-meta);
  margin-top: var(--s2); padding-top: var(--s2);
  border-top: 1px solid var(--rule);
}
.prazo .btn { margin-top: var(--s3); width: 100%; }

/* ---------- os vencedores da open call ----------
   Com `openCall.estado: "vencedores"` (js/dados.js) o JS esconde o cartão do
   prazo e o convite e mostra este bloco. A grelha de duas colunas passa a
   uma — senão ficava uma coluna vazia onde estava o cartão. */
.opencall.estado-vencedores .wrap { grid-template-columns: 1fr; }
.opencall.estado-vencedores .intro { max-width: var(--measure); }
.vencedores-t { margin-top: var(--s5); font-size: clamp(1.3rem, 2.6vw, 1.6rem); }
.vencedores .lede { max-width: 58ch; }
/* Cada artista é uma fila: fotografia pequena à esquerda (um retrato, não um
   cartaz — a primeira versão tinha-as a meia página), nome e texto ao lado. */
.vencedores-lista { display: grid; grid-template-columns: 1fr; gap: var(--s5); margin-top: var(--s4); max-width: 62rem; }
.vencedor { display: grid; grid-template-columns: 200px 1fr; gap: var(--s4); align-items: start; }
.vencedor .tira { aspect-ratio: 1 / 1; }
.vencedor h4 {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.25rem;
  letter-spacing: -0.02em; color: var(--tinta); margin: 0 0 var(--s2);
}
.vencedor p { color: var(--tinta-2); margin: 0; max-width: 62ch; }
@media (max-width: 700px) {
  .vencedor { grid-template-columns: 120px 1fr; gap: var(--s3); }
  .vencedor figcaption { font-size: 9.5px; }
}
@media (max-width: 480px) {
  .vencedor { grid-template-columns: 1fr; }
  .vencedor figure { max-width: 160px; }
}

ul.marcas { list-style: none; padding: 0; margin: var(--s3) 0 0; display: flex; flex-direction: column; gap: var(--s2); }
ul.marcas li { padding-left: 26px; position: relative; color: var(--tinta-2); }
ul.marcas li::before {
  content: ""; position: absolute; left: 0; top: 0.62em;
  width: 9px; height: 9px; border-radius: 50%; background: var(--c-marcador);
}
ul.marcas b { color: var(--tinta); }

/* programa: h1/h2/h3 têm margin:0 (ver acima), por isso os horários dos dois
   dias (molde .tiras-info da página das atividades) e os dois botões levam
   aqui o seu respiro, por baixo do título e da linha */
#programa .tiras-info { margin-top: var(--s4); }
#programa .accoes { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }

/* O cartaz do programa: mais pequeno do que a largura toda de propósito —
   era "demasiado na cara" a ocupar o `.wrap` inteiro. Vive dentro do mesmo
   `.duas` que a secção "O festival" usa (texto de um lado, imagem do outro),
   o que já o limita a metade da largura. A inclinação e a sombra são o que
   fazem a diferença entre "uma imagem" e "um postal pousado na página" — o
   `<figure>` à volta é que entra com o `.rev` (o mesmo fade/deslize do resto
   do site); o `.cartaz` fica com a SUA própria transformação (a inclinação),
   sem os dois a competirem pela mesma propriedade `transform`. */
.cartaz {
  display: block; border-radius: 14px; overflow: hidden;
  transform: rotate(-2.4deg);
  box-shadow: 0 20px 40px -16px rgba(58, 34, 30, 0.38), 0 4px 12px rgba(58, 34, 30, 0.16);
  transition: transform 380ms var(--curva), box-shadow 380ms var(--curva);
}
.cartaz img { display: block; width: 100%; height: auto; }
.cartaz:hover {
  transform: rotate(-0.4deg) scale(1.025);
  box-shadow: 0 26px 52px -14px rgba(58, 34, 30, 0.42), 0 6px 16px rgba(58, 34, 30, 0.18);
}

/* ---------- sobre + galeria ---------- */

.duas { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5); align-items: center; }

.tiras { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); margin-top: var(--s5); }
.tira { position: relative; border-radius: 8px; overflow: hidden; aspect-ratio: 3 / 4; background: var(--cartao); }
.tira img { width: 100%; height: 100%; object-fit: cover; transition: transform 700ms var(--curva); }
.tira:hover img { transform: scale(1.045); }

figure { margin: 0; }
figcaption {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--tinta-3); margin-top: var(--s2);
}

/* números */
.numeros { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s4); margin-top: var(--s5); }
.numeros div { border-top: 1px solid color-mix(in srgb, var(--c-linha-detalhe) 45%, transparent); padding-top: var(--s3); }
.numeros .n {
  font-family: var(--f-disp); font-weight: 800; font-size: clamp(1.65rem, 3.6vw, 2.15rem);
  color: var(--c-num-estat); line-height: 1; letter-spacing: -0.03em;
}
.numeros .r { color: var(--tinta-2); font-size: 0.95rem; margin-top: var(--s1); }
/* os números e a galeria de «O que é» vivem numa secção própria (#galeria),
   a seguir ao bloco das casas de banho: o padding da secção já dá o respiro */
.galeria .numeros { margin-top: 0; }

/* ---------- local ---------- */

.local { background: transparent; }
.local .wrap { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: center; }

.avisos { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s4); }
.aviso {
  display: grid; grid-template-columns: 22px 1fr; gap: var(--s2);
  background: var(--cartao); border: 1px solid var(--rule);
  border-radius: 6px; padding: var(--s3);
  font-size: 0.95rem; color: var(--tinta-2);
}
.aviso svg { width: 20px; height: 20px; color: var(--c-icone-aviso); margin-top: 2px; }
.aviso b { color: var(--tinta); }

/* o bloco das casas de banho secas, a seguir a «O que é»: a grelha .duas, as
   .tira e os .numeros já existem; só o respiro entre o texto, as fotografias,
   os números e os h3 */
.residuos .duas { margin-top: var(--s4); }
.residuos .numeros + .prose { margin-top: var(--s4); }
.residuos h3 { margin-top: var(--s4); }

/* ---------- cartões de ligação ---------- */



.ligacoes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); margin-top: var(--s5); }

.cartao {
  display: flex; flex-direction: column; gap: var(--s2);
  background: var(--cartao); border: 1px solid var(--rule);
  border-radius: 10px; padding: var(--s4);
  color: inherit; text-decoration: none;
  transition: border-color 240ms var(--curva), transform 240ms var(--curva),
              background-color 240ms var(--curva);
}
.cartao:hover { border-color: var(--c-borda-activa); transform: translateY(-3px); background: var(--cartao-2); }

.cartao-topo { display: flex; align-items: center; gap: var(--s2); }
.cartao svg { width: 30px; height: 30px; color: var(--c-icone-cartao); flex: none; }
.cartao .rede {
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3);
}
.cartao h3 { font-family: var(--f-disp); font-weight: 800; font-size: 1.12rem; letter-spacing: -0.02em; }
.cartao p { color: var(--tinta-2); margin: 0; font-size: 0.97rem; max-width: 34ch; }

.cartao .meta {
  margin-top: auto; padding-top: var(--s2);
  font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--c-meta);
  display: flex; align-items: center; gap: 8px;
}
.cartao .seta { transition: transform 240ms var(--curva); }
.cartao:hover .seta { transform: translateX(4px); }

/* ---------- o convite ao bilhete (era a newsletter; a classe ficou) ---------- */

.subscrever { background: transparent; }
.forma { display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s4); max-width: 520px; }
.forma label {
  flex: 1 1 240px; display: flex; flex-direction: column; gap: 7px;
  font-family: var(--f-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--tinta-3);
}
.forma input {
  background: var(--cartao); border: 1px solid var(--rule); border-radius: 6px;
  color: var(--tinta); font-family: var(--f-body); font-size: 1rem;
  padding: 13px 15px; min-height: 48px; width: 100%;
}
.forma input::placeholder { color: var(--tinta-3); }
.forma input:focus { border-color: var(--c-foco); }
.forma .btn { align-self: flex-end; }
.forma-nota { font-size: 0.88rem; color: var(--tinta-3); margin-top: var(--s2); }

/* ---------- rodapé ---------- */

footer.pe { background: transparent; border-top: 1px solid var(--rule); padding: var(--s6) 0 var(--s5); }
.pe-grelha { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--s5); }
.pe h4 {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3); margin: 0 0 var(--s2); font-weight: 500;
}
.pe ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 2px; }
.pe a {
  color: var(--tinta-2); text-decoration: none;
  transition: color 200ms var(--curva);
  /* WCAG 2.2 AA (Target Size, Minimum): 24 px é o mínimo para um alvo de
     ponteiro. Só a altura da linha dava 19 px. */
  display: inline-flex; align-items: center; min-height: 28px;
}
.pe a:hover { color: var(--c-link-hover); }
.pe .creditos {
  margin-top: var(--s6); padding-top: var(--s3); border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap;
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--tinta-3);
}

/* Quem fez o site — linha própria, à parte dos créditos institucionais
   acima, mas com o mesmo estilo pequeno. O logótipo é a variante "light"
   (texto em tinta escura, não o creme pálido da versão para fundo escuro):
   sobre o rodapé claro do site a versão pálida dava 1,2:1 de contraste,
   ilegível — esta dá 16,8:1. */
.pe-fabrica {
  display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap;
  gap: 8px; margin-top: var(--s4);
}
.pe-fabrica img { display: block; width: auto; height: 30px; }
.pe-fabrica span {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--tinta-3);
}
.pe-fabrica a {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: 0.03em;
  color: var(--tinta-2); text-decoration: none;
  display: inline-flex; align-items: center; min-height: 28px;
  transition: color 200ms var(--curva);
}
.pe-fabrica a:hover { color: var(--c-link-hover); }
/* o logótipo da Telleria Solutions é uma ligação para o site deles */
.pe-fabrica a.pe-fabrica-logo { min-height: 0; transition: opacity 200ms var(--curva); }
.pe-fabrica a.pe-fabrica-logo:hover { opacity: 0.75; }

/* ---------- apoios institucionais ----------
   Os logotipos vieram todos de uma faixa unica desenhada pelo estudio, onde ja
   estavam opticamente equilibrados entre si. Cortei-os em ficheiros separados
   (para poderem reorganizar-se no telemovel, que numa imagem so era impossivel)
   e mantive as proporcoes originais: cada altura abaixo e a altura no ficheiro
   original a multiplicar por 0,55. Nao acerte uma sem acertar as outras pelo
   mesmo factor, senao desfaz o equilibrio que o designer fez.

   O brasao da Regiao Autonoma e a Secretaria Regional sao UM so ficheiro, com a
   risca vertical no meio: e uma assinatura oficial e nao se separa.

   Ficam a preto sobre o creme, como foram fornecidos. Logotipos institucionais
   nao se recolorem nem se poem sobre fotografias. */
.apoios {
  margin-top: var(--s6); padding-top: var(--s4);
  border-top: 1px solid var(--rule);
  display: flex; flex-wrap: wrap; gap: var(--s5) var(--s7); align-items: flex-start;
}
.apoios-fila { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.apoios img { display: block; width: auto; }
.ap-creative { height: 29px; }
.ap-naval    { height: 61px; }
.ap-governo  { height: 52px; }
.ap-mps      { height: 33px; }

@media (max-width: 700px) {
  .apoios { gap: var(--s4) var(--s5); }
  .apoios-fila { gap: var(--s4); }
  .ap-creative { height: 24px; }
  .ap-naval    { height: 50px; }
  .ap-governo  { height: 43px; }
  .ap-mps      { height: 27px; }
  .pe-fabrica img { height: 24px; }
}

/* ---------- a levada ---------- */

/* A LEVADA
   Corre na margem esquerda ao longo de toda a página. Nunca desaparece:
   nos ecrãs largos é o canal a serpentear na goteira; nos estreitos
   encolhe para um fio junto à borda, mas continua a encher-se com o
   scroll. Antes sumia-se abaixo de 1380 px, o que apagava a ideia em
   quase todos os portáteis. */
.levada {
  position: absolute; top: 0; left: 0; height: 100%;
  width: 14px;                 /* ecrãs estreitos: só um fio na borda */
  pointer-events: none; z-index: 3;
}
.levada svg { width: 100%; height: 100%; display: block; }
.levada path { fill: none; stroke-linecap: round; }

/* O canal passou de musgo #80803A para sálvia: contra o fundo em gradiente
   o musgo caía a 2,08:1, abaixo do mínimo de 3:1 para elementos gráficos.
   A sálvia mantém-se acima de 4,8:1 em toda a descida. */
.levada .canal  { stroke: var(--c-levada-canal); stroke-width: 2; opacity: 0.75; }
.levada .pedras { stroke: var(--c-levada-pedras); stroke-width: 2; stroke-dasharray: 2 15; opacity: 0.85; }
.levada .agua   { stroke: url(#grad-levada); stroke-width: 4; opacity: 1; }

/* a partir daqui há goteira suficiente para o canal serpentear a sério
   sem tocar no texto: (1260 - 1180) / 2 = 40 px de folga de cada lado */
@media (min-width: 1260px) {
  .levada { width: 78px; }
  .levada .canal  { stroke-width: 3; }
  .levada .pedras { stroke-width: 3; stroke-dasharray: 2 16; }
  .levada .agua   { stroke-width: 3.5; }
}

/* Acima dos 1500 px a goteira tem 160 px de cada lado e o canal pode
   ocupar 110 sem se aproximar do texto, que so comeca aos 184 px. E a
   largura que faz a curva ler-se como um meandro e nao como um fio. */
@media (min-width: 1500px) {
  .levada { width: 110px; }
  .levada .agua { stroke-width: 4; }
}

/* ---------- as serras do topo ---------- */

/* Três cumeadas empilhadas por cima do véu, a descer a velocidades
   diferentes com o scroll. A mais longe quase não se mexe, a mais perto
   acompanha a fotografia — é a diferença entre elas que dá profundidade,
   não o desenho de cada uma.

   Ficam por cima do véu e por baixo do texto: sob o véu o gradiente do
   fundo comia-as, e por cima do texto tapavam o título. */
.serras {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: min(40vh, 320px);
  pointer-events: none; z-index: 2; overflow: hidden;
}
.serra {
  position: absolute; bottom: 0; left: -5%; width: 110%;
  display: block; will-change: transform;
}
/* alturas diferentes: a de trás assoma por cima das outras duas */
.serra.longe { height: 74%; }
.serra.meio  { height: 88%; }
.serra.perto { height: 100%; }

.serra.longe path { fill: #A9C9B5; opacity: 0.85; }
.serra.meio  path { fill: #6E9C82; opacity: 0.9; }
.serra.perto path { fill: #3E6B52; }

/* ---------- a cortina de folhagem ---------- */

/* Duas metades da mesma fotografia — a ZPS01579, recortada por
   tools/recortar-folhagem.py — sobrepostas por cima da open call. Afastam-se
   à medida que o bloco sobe no ecrã e deixam ver o que está por trás. É a
   ideia da to-top.ch sem as bibliotecas dela: o movimento sai do mesmo ciclo
   de requestAnimationFrame que já desloca o topo.

   REGRA: o estado em repouso é ABERTO, não fechado. Se o JavaScript não
   correr, as duas metades ficam de lado e a open call lê-se na mesma. Ao
   contrário — repouso fechado — um script que falhasse tapava a razão de
   ser da página. */
.mata {
  position: absolute; top: 0; left: 0; right: 0;
  height: min(88vh, 720px);
  overflow: hidden;           /* é isto que impede as metades de alargar a página */
  pointer-events: none;
  z-index: 5;
}
.mata div {
  position: absolute; top: 0; bottom: 0;
  background-size: cover;
  background-repeat: no-repeat;
  /* O painel acaba num rectangulo, e um rectangulo de folhagem a meio da
     pagina le-se como um autocolante. A mascara desfaz-lhe o fundo, que
     numa serra com nevoeiro e a coisa mais natural do mundo. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 96%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 96%);
  will-change: transform;
}

/* Cada metade e um desenho seu, gerado por tools/desenhar-folhagem.py.
   Sobrepoem-se 16% ao meio: como sao desenhos diferentes, a sobreposicao
   adensa em vez de duplicar — que era o defeito da versao fotografica, onde
   as mesmas arvores apareciam duas vezes. */
.mata .esq { left: 0;  width: 58%; background-position: 100% 100%; transform: translate3d(-100%, 0, 0); }
.mata .dir { right: 0; width: 58%; background-position: 0% 100%;   transform: translate3d(100%, 0, 0); }

/* Um SVG por lado, e mais nada: nitido em qualquer ecra, sem escadaria de
   tamanhos e sem image-set. Comprimido pesa menos de 20 KB cada. */
.mata .esq { background-image: url("../img/folhagem-esq.svg"); }
.mata .dir { background-image: url("../img/folhagem-dir.svg"); }

/* ---------- revelação ao scroll ---------- */

/* O estado escondido só existe quando o JavaScript está a correr (a classe
   `js` é posta no <html> logo no cabeçalho). Se o script falhar ou estiver
   desligado, o conteúdo aparece na mesma — o movimento é acabamento, nunca
   a condição para se poder ler a página. */
.js .rev { opacity: 0; transform: translateY(46px); }
.rev.visto {
  opacity: 1; transform: none;
  transition: opacity 820ms var(--curva), transform 820ms var(--curva);
}

/* as fotografias entram com um ligeiro afastamento — dá profundidade
   sem competir com a paralaxe do topo */
.rev .tira img { transform: scale(1.09); transition: transform 1100ms var(--curva); }
.rev.visto .tira img { transform: scale(1); }
.rev.visto .tira:hover img { transform: scale(1.045); }

/* ---------- responsivo ---------- */

@media (max-width: 900px) {
  .opencall .wrap, .local .wrap, .duas { grid-template-columns: 1fr; gap: var(--s4); }
  .pe-grelha { grid-template-columns: 1fr 1fr; gap: var(--s4); }
  /* a levada já não se esconde: encolhe para um fio na borda (ver acima) */
}

/* O menu de telemóvel entra aos 860 px, não aos 700 como o resto do
   telemóvel: com quatro ligações, três pílulas («Atividades», «Autocarros» e
   «Bilhete») e a língua, a barra precisa de ~850 px para caber numa linha
   com o logótipo inteiro — abaixo disso esmagava-o. */
@media (max-width: 860px) {
  .menu-btn { display: inline-flex; }
  .nav-links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start; gap: 0;
    background: #C23D68; border-bottom: 1px solid #8E2A4B;
    padding: var(--s2) 24px var(--s3);
  }
  .nav-links.aberto { display: flex; }
  .nav-links a { padding: 14px 0; width: 100%; font-size: 13px; }
  .nav-links a::after { display: none; }
  /* no menu de telemóvel a pastilha volta a ser inline, não uma barra */
  .nav-links a.lang { width: auto; }
  .nav-links a.nav-cta { width: 100%; justify-content: center; padding: 12px 16px; margin: var(--s2) 0 var(--s1); }
}

@media (max-width: 700px) {
  body { font-size: 16px; }
  :root { --s6: 50px; --s7: 65px; }
  .tiras { grid-template-columns: 1fr 1fr; }
  .numeros { grid-template-columns: 1fr; gap: var(--s3); }
  .ligacoes { grid-template-columns: 1fr; }
  /* a inclinação encolhe: a imagem já ocupa quase o ecrã todo, e uma
     inclinação grande punha-a a sair pela margem */
  .cartaz { transform: rotate(-1.1deg); }
  .cartaz:hover { transform: rotate(-1.1deg); }
  /* a altura do topo vem da regra unica la de cima (calc(100svh - 80px)):
     havia aqui um `88vh` que a substituia, e duas contas para a mesma
     coisa acabam sempre por se desencontrar */
  .hero .accoes .btn { width: 100%; }
  .contagem { gap: var(--s3); }
}

@media (max-width: 420px) {
  .pe-grelha { grid-template-columns: 1fr; }
}

/* ---------- o topo tem de caber no ecrã ----------

   Os dois botões e a contagem decrescente são a razão de ser do topo: dizem
   que há bilhete, que há open call, e quantos dias faltam. Se caírem por
   baixo da dobra, quem chega não os vê — e a maior parte das pessoas não faz
   scroll para procurar o que não sabe que existe.

   O problema não é a largura, é a ALTURA. Um portátil de 1366x768 dá umas
   650px de janela depois das barras do Chrome, e os espaços do topo estavam
   fixos: os mesmos 65px de respiro quer houvesse 900px de altura quer
   houvesse 580px. A contagem ficava 40 a 110px abaixo da dobra.

   O que se aperta aqui é o AR e o tamanho do logótipo — nunca o texto, que
   já está no mínimo. Medido: a 650px de janela a contagem acaba com folga,
   e a 580px também.                                                        */

@media (max-height: 800px) {
  .hero .wrap { padding-top: var(--s4); padding-bottom: var(--s3); }
  .hero h1 { margin-top: var(--s2); }
  .hero h1 img { width: min(360px, 66vw); }
  .hero .sub { margin-top: var(--s2); }
  .hero .accoes { margin-top: var(--s3); }
  .contagem { margin-top: var(--s3); padding-top: var(--s2); }
}

@media (max-height: 640px) {
  .hero h1 img { width: min(300px, 58vw); }
  .hero .sub { font-size: 1rem; margin-top: var(--s1); }
  .contagem { margin-top: var(--s2); }
}

/* ---------- movimento reduzido ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js .rev, .rev { opacity: 1; transform: none; }
  .rev .tira img, .rev.visto .tira:hover img { transform: none; }
  .levada path { stroke-dashoffset: 0 !important; }
  .mata { display: none; }
  .serra { transform: none !important; }
  .hero-foto img, .hero-video { transform: scale(1.16) !important; }
  /* com movimento reduzido o vídeo nem chega a carregar (ver videoTopo()
     em js/echoo.js), por isso o botão não tem nada para controlar */
  .video-btn { display: none !important; }
  .hero .wrap { transform: none !important; opacity: 1 !important; }
}

/* ---------- impressão ---------- */

@media print {
  .nav, .levada, .hero-foto, .video-btn, .subscrever { display: none; }
  body { background: #fff; color: #000; }

  /* o bilhete: só o cartão, com moldura, e o QR a ~40 mm — é SVG, imprime nítido */
  body.com-bilhete .pe, body.com-bilhete .cabeca-pagina, body.com-bilhete .aviso-teste,
  body.com-bilhete .bilhete-accoes, body.com-bilhete .skip, .sugestoes, .popup-ativ { display: none; }
  .bilhete-cartao .faixa-ativ { display: none; } /* com dois selectores: a regra base (.faixa-ativ, flex/grid) vem depois na folha */
  body.com-bilhete .bilhete-cartao { border: 2px solid #000; border-radius: 0; box-shadow: none; break-inside: avoid; }
  body.com-bilhete .bilhete-qr { width: 42mm; border: 0; padding: 0; }
}

/* ══════════════════════════════════════════════════════════════
   FORMULÁRIO DE CANDIDATURA  (candidatura.html / en/apply.html)
   ══════════════════════════════════════════════════════════════ */

.visualmente-escondido {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* a armadilha de spam: fora do ecrã, mas nunca display:none — há robôs
   que ignoram campos escondidos por display */
.armadilha { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.pe-sobre { color: var(--tinta-2); max-width: 34ch; margin-top: var(--s2); }

/* ---------- cabeçalho de página interior ---------- */

.cabeca-pagina { padding: calc(var(--s6) + 40px) 0 var(--s5); }
.cabeca-pagina h1 { margin-top: var(--s2); max-width: 14ch; }
.cabeca-pagina .lede { max-width: 56ch; }
/* a página das atividades: cabeçalho mais baixo, para a grelha entrar no primeiro ecrã */
.cabeca-pagina.compacta { padding: calc(var(--s5) + 40px) 0 var(--s4); }
.cabeca-pagina.compacta h1 { margin-top: 6px; }
.cabeca-pagina.compacta .lede { margin-top: var(--s2); max-width: 64ch; }

.tiras-info {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5);
  margin-top: var(--s5); padding-top: var(--s3);
  border-top: 1px solid var(--rule);
}
.tiras-info > div { display: flex; flex-direction: column; gap: 4px; }
.tiras-info .rot {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3);
}
.tiras-info .val { font-family: var(--f-disp); font-weight: 700; font-size: 1.05rem; color: var(--tinta); }
.tiras-info .restam { font-size: 0.9rem; color: var(--rosa-forte); }

.lig-doc { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; }
.lig-doc svg { width: 17px; height: 17px; flex: none; }

.rot-lista { font-weight: 700; color: var(--tinta); margin-top: var(--s3); }

.wrap-estreito { max-width: 760px; }

/* ---------- horário completo (programa.html / en/schedule.html) ----------
   Os dois dias lado a lado (grelha de duas colunas — ver o `.horario` a
   seguir), cada um com a linha do tempo: um fio vertical em --rule, com uma
   bolinha --rosa-forte por item. Cada item já tem a hora real
   (`.horario-item .hora`, por cima do nome). */
.horario {
  max-width: 1100px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6);
}
.horario-dia { min-width: 0; }
/* a regra base fica DEPOIS do bloco partilhado de 900px (`.duas` e companhia,
   mais acima no ficheiro) — por ordem de cascata, um `@media` mais cedo no
   ficheiro perde para uma regra sem media query mais tarde. Por isso este
   colapso para uma coluna vive aqui, a seguir à própria regra base, e não
   naquele bloco partilhado. */
@media (max-width: 900px) {
  .horario { grid-template-columns: 1fr; gap: var(--s7); }
}

.cabeca-dia {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--s3);
  margin-bottom: var(--s4); padding-bottom: var(--s2);
  border-bottom: 2px solid var(--c-linha-detalhe);
}
.cabeca-dia h2 { margin: 0; }
.cabeca-dia .janela {
  font-family: var(--f-mono); font-size: 12px; letter-spacing: 0.06em;
  color: var(--tinta-2); background: var(--cartao-2);
  border: 1px solid var(--rule); border-radius: 999px; padding: 5px 12px;
}

.horario-lista { list-style: none; margin: 0; padding: 0; position: relative; }
.horario-lista::before {
  content: ""; position: absolute; left: 5px; top: 4px; bottom: 12px;
  width: 2px; background: var(--rule);
}
.horario-item {
  position: relative; padding: 0 0 var(--s3) 28px;
  font-family: var(--f-disp); font-weight: 600; font-size: 1.05rem;
}
.horario-item::before {
  content: ""; position: absolute; left: 0; top: 6px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--papel); border: 2px solid var(--rosa-forte);
}
.horario-item .nome { color: var(--tinta); }
.horario-item .hora {
  display: block; font-family: var(--f-mono); font-weight: 400; font-size: 12px;
  letter-spacing: 0.04em; color: var(--tinta-3); margin-bottom: 2px;
}
/* a linha de pormenor por baixo do nome: o local, quem está no food court,
   o tema das Talks — em corpo de texto, mais pequena e mais clara */
.horario-item .detalhe {
  display: block; font-family: var(--f-body); font-weight: 400; font-size: 0.9rem;
  line-height: 1.45; color: var(--tinta-2); margin-top: 3px; max-width: 46ch;
}

.nota-horario {
  color: var(--tinta-2); font-size: 0.92rem; max-width: 62ch;
  margin-top: var(--s6); padding-top: var(--s4); border-top: 1px solid var(--rule);
}
.nota-horario + .btn { margin-top: var(--s4); }

/* ---------- o formulário ---------- */

#form-candidatura, #form-bilhete { margin-top: var(--s3); }

#form-candidatura fieldset, #form-bilhete fieldset {
  border: 0; padding: 0; margin: 0 0 var(--s5);
  border-top: 1px solid var(--rule); padding-top: var(--s4);
}
#form-candidatura fieldset:first-of-type, #form-bilhete fieldset:first-of-type { border-top: 0; padding-top: 0; }

#form-candidatura legend, #form-bilhete legend {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.35rem;
  letter-spacing: -0.02em; color: var(--tinta);
  display: flex; align-items: center; gap: 12px; padding: 0; margin-bottom: var(--s3);
}
.n-passo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--manga); color: var(--tinta);
  font-family: var(--f-mono); font-size: 13px; font-weight: 500;
}

.campo { display: flex; flex-direction: column; margin-bottom: var(--s3); }
.dois-campos { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }

.campo label {
  font-weight: 600; font-size: 0.97rem; color: var(--tinta); margin-bottom: 6px;
}
.obrig { color: var(--rosa-forte); }

.campo .ajuda {
  font-size: 0.89rem; color: var(--tinta-3); margin: 0 0 8px; max-width: 62ch; line-height: 1.5;
}

.campo input[type="text"], .campo input[type="email"], .campo input[type="tel"],
.campo input[type="url"], .campo textarea {
  font-family: var(--f-body); font-size: 1rem; color: var(--tinta);
  background: var(--cartao); border: 1.5px solid var(--rule); border-radius: 8px;
  padding: 13px 15px; min-height: 50px; width: 100%;
  transition: border-color 180ms var(--curva), box-shadow 180ms var(--curva);
}
.campo textarea { min-height: auto; line-height: 1.6; resize: vertical; }
.campo input::placeholder, .campo textarea::placeholder { color: #A79C93; }

.campo input:focus, .campo textarea:focus {
  outline: none; border-color: var(--tinta);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--manga) 55%, transparent);
}
.campo input:focus-visible, .campo textarea:focus-visible { outline: none; }


/* estado de erro: a moldura muda E aparece texto — nunca só a cor */
.campo input[aria-invalid="true"], .campo textarea[aria-invalid="true"] {
  border-color: var(--rosa-forte);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rosa-forte) 18%, transparent);
}

/* o <select> (n.º de pessoas no bilhete) veste-se como os inputs */
.campo select {
  font-family: var(--f-body); font-size: 1rem; color: var(--tinta);
  background: var(--cartao); border: 1.5px solid var(--rule); border-radius: 8px;
  padding: 13px 15px; min-height: 50px; width: 100%;
  transition: border-color 180ms var(--curva), box-shadow 180ms var(--curva);
}
.campo select:focus {
  outline: none; border-color: var(--tinta);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--manga) 55%, transparent);
}
.campo select[aria-invalid="true"] {
  border-color: var(--rosa-forte);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rosa-forte) 18%, transparent);
}
/* a legenda do bilhete leva uma linha de ajuda por baixo */
fieldset > .ajuda { font-size: 0.92rem; color: var(--tinta-2); margin: calc(-1 * var(--s2)) 0 var(--s3); max-width: 62ch; line-height: 1.5; }

/* um grupo de opções (os dias do bilhete): um fieldset pequeno dentro do
   grande, por isso desfaz-se aqui o risco e a legenda de secção */
#form-bilhete .campo-opcoes { border-top: 0; padding-top: 0; margin: 0 0 var(--s3); }
#form-bilhete .campo-opcoes legend {
  display: block; font-family: var(--f-body); font-weight: 600; font-size: 0.97rem;
  letter-spacing: 0; color: var(--tinta); margin-bottom: 8px; padding: 0;
}
.campo-opcoes .opcao { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.campo-opcoes input[type="radio"], .campo-opcoes input[type="checkbox"] { width: 22px; height: 22px; margin: 0; accent-color: var(--rosa-forte); cursor: pointer; flex: none; }
.campo-opcoes label { margin: 0; font-weight: 400; font-size: 0.97rem; cursor: pointer; }

.erro { margin: 6px 0 0; font-size: 0.88rem; color: #A32347; font-weight: 600; min-height: 0; }
.erro:empty { display: none; }

.conta {
  margin: 5px 0 0; font-family: var(--f-mono); font-size: 10.5px;
  letter-spacing: 0.06em; color: var(--tinta-3); text-align: right;
}
.conta.perto { color: #A32347; }

/* caixas de confirmação */
.campo-caixa {
  display: grid; grid-template-columns: 24px 1fr; gap: 12px;
  align-items: start; margin-bottom: var(--s2);
}
.campo-caixa input[type="checkbox"] {
  width: 24px; height: 24px; margin: 1px 0 0; accent-color: var(--rosa-forte); cursor: pointer;
}
.campo-caixa label { margin: 0; font-weight: 400; font-size: 0.95rem; line-height: 1.5; }
.campo-caixa .erro { grid-column: 2; }

/* ---------- rodapé do formulário ---------- */

.rodape-form {
  border-top: 1px solid var(--rule); padding-top: var(--s4); margin-top: var(--s4);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2);
}
.rodape-form .btn { min-width: 240px; }
.erro-geral { margin: 0; color: #A32347; font-weight: 600; font-size: 0.95rem; }
.erro-geral:empty { display: none; }

/* ---------- estados finais ---------- */

.sucesso, .aviso-fechado {
  background: var(--cartao); border: 1.5px solid var(--rule);
  border-left: 5px solid var(--menta); border-radius: 10px;
  padding: var(--s4); margin-top: var(--s3);
}
.aviso-fechado { border-left-color: var(--malva); }
.sucesso h2, .aviso-fechado h2 { font-size: 1.6rem; }
.sucesso p, .aviso-fechado p { color: var(--tinta-2); max-width: 56ch; }
.sucesso .btn { margin-top: var(--s3); }

/* ---------- o bilhete ----------
   O cartão que aparece depois de pedir o bilhete (bilhete.html), e o de
   verificação, que é o mesmo cartão com outro conteúdo. Dados à esquerda,
   QR à direita; empilham no telemóvel. */

.aviso-teste {
  background: #FFF3D6; border: 1px solid #E3B84E; color: var(--tinta);
  border-radius: 8px; padding: 10px 14px; font-weight: 600; margin: 0 0 var(--s3);
}

.bilhete-cartao {
  display: grid; grid-template-columns: 1fr auto; gap: var(--s5); align-items: start;
  background: var(--cartao); border: 1.5px solid var(--rule); border-left: 5px solid var(--manga);
  border-radius: 12px; padding: var(--s5); margin-top: var(--s3);
  scroll-margin-top: 90px; /* o scrollIntoView deixava o topo do cartão debaixo da barra */
}
.bilhete-cartao:focus { outline: none; }
.bilhete-cartao .eyebrow { margin: 0; }
.bilhete-cartao h2 { margin-top: var(--s2); font-size: 1.8rem; }
.bilhete-num {
  font-family: var(--f-mono); font-size: 2.4rem; letter-spacing: 0.06em; line-height: 1.1;
  color: var(--tinta); margin: var(--s3) 0 var(--s3); font-variant-numeric: tabular-nums;
}
.bilhete-lista { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2) var(--s4); margin: 0; }
.bilhete-lista > div { display: flex; flex-direction: column; }
.bilhete-lista dt {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3);
}
.bilhete-lista dd { margin: 2px 0 0; font-family: var(--f-disp); font-weight: 700; font-size: 1.05rem; color: var(--tinta); }
.bilhete-aviso { margin: var(--s3) 0 0; color: var(--tinta-2); font-size: 0.95rem; }
.bilhete-accoes { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s4); }
.bilhete-cartao .forma-nota { margin-top: var(--s2); }

/* a faixa no cartão, a seguir aos botões: miniaturas das atividades, texto e a seta para a
   secção #sugestoes. Só com um bilhete no ecrã (js/echoo.js, mostrarFaixa);
   é uma âncora normal — o deslize é o scroll-behavior da página. */
.faixa-ativ {
  display: flex; align-items: center; gap: var(--s2); margin-top: var(--s3);
  padding: var(--s2) var(--s3); background: var(--cartao-2); border: 1.5px solid var(--rule);
  border-radius: 10px; color: var(--tinta); text-decoration: none;
  transition: border-color 200ms var(--curva);
}
.faixa-ativ:hover, .faixa-ativ:focus-visible { border-color: var(--manga); color: var(--tinta); }
.faixa-ativ:focus-visible { border-radius: 10px; } /* a regra geral do foco põe 3px */
.faixa-ativ-fotos { display: flex; flex-shrink: 0; }
.faixa-ativ-fotos picture {
  display: block; width: 40px; height: 40px; border-radius: 50%; overflow: hidden;
  border: 2px solid var(--cartao); background: var(--cartao);
}
.faixa-ativ-fotos picture + picture { margin-left: -10px; }
.faixa-ativ-fotos img { display: block; width: 100%; height: 100%; object-fit: cover; }
.faixa-ativ-fotos picture.foto-baixo img { object-position: 50% 80%; }
.faixa-ativ-texto { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.faixa-ativ-texto strong { font-family: var(--f-disp); font-weight: 700; font-size: 1rem; line-height: 1.25; color: var(--tinta); }
.faixa-ativ-texto span { font-size: 0.88rem; line-height: 1.35; color: var(--tinta-2); }
.faixa-ativ-seta {
  flex-shrink: 0; margin-left: auto; width: 36px; height: 36px; border-radius: 50%;
  background: var(--manga); color: var(--tinta);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 240ms var(--curva);
}
.faixa-ativ:hover .faixa-ativ-seta { transform: translateY(3px); }
/* a seta acena três vezes e pára — menos de 5 s, como pede a WCAG 2.2.2 (classe .acena,
   posta pelo JavaScript quando a faixa fica mesmo à vista); com prefers-reduced-motion
   o reset lá em baixo anula-a */
.faixa-ativ.acena .faixa-ativ-seta svg { animation: faixa-seta 1.6s ease-in-out 3; }
@keyframes faixa-seta { 50% { transform: translateY(4px); } }

/* fundo branco e margem à volta: um QR lê-se pelo contraste com o que o rodeia */
.bilhete-qr { width: 176px; padding: 8px; background: #fff; border: 1px solid var(--rule); border-radius: 8px; }
.bilhete-qr svg { display: block; width: 100%; height: auto; }
.bilhete-qr:empty { display: none; }

.verificacao.valido { border-left-color: var(--menta); }
.verificacao.invalido { border-left-color: var(--rosa-forte); }

/* ---------- responsivo ---------- */

@media (max-width: 640px) {
  .dois-campos { grid-template-columns: 1fr; gap: 0; }
  .cabeca-pagina { padding-top: calc(var(--s5) + 30px); }
  .rodape-form .btn { width: 100%; }
  .tiras-info { gap: var(--s3); }
  .bilhete-cartao { grid-template-columns: 1fr; padding: var(--s4); }
  .bilhete-lista { grid-template-columns: 1fr; }
  .bilhete-num { font-size: 1.9rem; }
  .bilhete-qr { width: 160px; }
  .bilhete-accoes .btn { width: 100%; }
  /* a faixa em grelha: miniaturas, título e seta numa linha, o detalhe na linha toda */
  .faixa-ativ { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: var(--s2); row-gap: 4px; padding: var(--s2); }
  .faixa-ativ-texto { display: contents; }
  .faixa-ativ-fotos { grid-area: 1 / 1; }
  .faixa-ativ-texto strong { grid-area: 1 / 2; font-size: 0.95rem; }
  .faixa-ativ-texto span { grid-area: 2 / 1 / 3 / 4; font-size: 0.84rem; }
  .faixa-ativ-seta { grid-area: 1 / 3; margin-left: 0; width: 32px; height: 32px; }
  .faixa-ativ-fotos picture { width: 36px; height: 36px; }
  .faixa-ativ-fotos picture + picture { margin-left: -12px; }
  .faixa-ativ-fotos picture:nth-child(n+3) { display: none; } /* duas miniaturas: o título precisa do espaço */
}

/* caixa de recurso: aparece só se não houver serviço de envio ligado,
   com a candidatura já escrita para a pessoa copiar para um e-mail */
.resumo-fallback {
  width: 100%; margin-top: var(--s3);
  font-family: var(--f-mono); font-size: 12.5px; line-height: 1.7;
  color: var(--tinta); background: var(--cartao-2);
  border: 1.5px dashed var(--malva); border-radius: 8px; padding: 14px 16px;
  resize: vertical;
}

/* ══════════════════════════════════════════════════════════════
   LIGAÇÕES PARA O INSTAGRAM  (links.html)
   A página da bio: fundo rosa forte como a barra, o logótipo amarelo e
   três botões grandes, a toda a largura. Sem menu nem rodapé.
   ══════════════════════════════════════════════════════════════ */

body.linktree { background: var(--rosa-forte); color: var(--papel); }
.ligacoes-ig {
  min-height: 100svh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  width: min(100% - 40px, 420px); margin: 0 auto; padding: var(--s6) 0;
}
.ligacoes-ig .marca-ig img { width: min(260px, 64vw); height: auto; display: block; }
.ligacoes-ig .eyebrow { color: var(--papel); margin-top: var(--s3); }
.ligacoes-ig .lista { display: grid; gap: var(--s2); width: 100%; margin-top: var(--s5); }
.ligacoes-ig .btn { width: 100%; min-height: 58px; font-size: 1.05rem; }
.ligacoes-ig .btn-2 { border-color: rgba(253, 205, 102, 0.6); color: var(--manga); }
.ligacoes-ig .btn-2:hover { background: rgba(253, 205, 102, 0.14); border-color: var(--manga); }
.ligacoes-ig .btn svg { width: 22px; height: 22px; flex: none; }
/* o verde do Spotify, para o ícone se reconhecer à primeira */
.ligacoes-ig .spotify svg { color: #1DB954; }
.ligacoes-ig .rodape-ig {
  margin-top: var(--s5); font-family: var(--f-mono); font-size: 11.5px;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: color-mix(in srgb, var(--papel) 80%, transparent);
}
.ligacoes-ig .rodape-ig a {
  color: var(--papel); text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--papel) 45%, transparent);
}
.ligacoes-ig .rodape-ig a:hover { color: var(--manga); border-bottom-color: var(--manga); }

/* ══════════════════════════════════════════════════════════════
   ATIVIDADES E WORKSHOPS  (atividades.html, en/activities.html)
   Grelha de cartões compactos: miniatura, hora, nome, preço, lugares,
   «Ver mais» e «Inscrever». A descrição abre com o «Ver mais»; a classe
   .compacta entra por JavaScript, por isso sem ele (ou se o echoo.js
   falhar) a descrição está sempre à vista e o botão não aparece.
   Em baixo, um único formulário para todas.
   ══════════════════════════════════════════════════════════════ */

/* A secção usa o .wrap largo (como o cabeçalho da página) para a grelha
   ter 3 colunas; o resto — avisos, cartão da inscrição, formulário —
   fica a 760 px, como antes. */
.wrap-atividades > :not(.atividades-lista) { max-width: 760px; }
.wrap-atividades noscript { display: block; }

.atividades-lista {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s3);
}
.atividades-dia {
  grid-column: 1 / -1;
  font-family: var(--f-mono); font-size: 11.5px; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--tinta-3); margin: var(--s3) 0 0; padding-bottom: 8px; border-bottom: 1px solid var(--rule);
}
.atividades-dia:first-child { margin-top: 0; }

.atividade {
  display: grid; grid-template-columns: 96px minmax(0, 1fr);
  column-gap: var(--s3); row-gap: var(--s2); align-content: start;
  background: var(--cartao); border: 1.5px solid var(--rule); border-left: 5px solid var(--manga);
  border-radius: 12px; padding: var(--s3); margin: 0;
  scroll-margin-top: 90px;
}
.atividade-foto {
  grid-column: 1; grid-row: 1 / span 3;
  width: 96px; aspect-ratio: 1; border-radius: 8px; overflow: hidden; background: var(--cartao-2);
}
.atividade-foto img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* fotos ao alto em que o assunto está em baixo (a vela contra o céu) */
.atividade-foto.foto-baixo img { object-position: 50% 80%; }

.atividade-cabeca { grid-column: 2; display: flex; flex-direction: column; gap: 2px; }
.atividade-cabeca .hora {
  font-family: var(--f-mono); font-size: 11.5px; letter-spacing: 0.08em; color: var(--tinta-3); white-space: nowrap;
}
.atividade-cabeca h4 { margin: 0; font-size: 1rem; line-height: 1.25; letter-spacing: -0.01em; }

.atividade-meta { grid-column: 2; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--s2); }
.atividade-meta .preco { font-family: var(--f-disp); font-weight: 800; font-size: 1.05rem; color: var(--tinta); }
.atividade-meta .lugares { font-size: 0.82rem; color: var(--tinta-3); }
.atividade-meta .lugares.poucos { color: #A32347; font-weight: 600; }

.atividade-accoes { grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.atividade-accoes .btn-inscrever { margin-left: auto; min-height: 38px; padding: 0 18px; font-size: 0.9rem; }
.atividade-mais {
  display: none; /* só quando o JavaScript ligar a .compacta */
  appearance: none; background: none; border: 0; margin: 0; padding: 0 2px; min-height: 38px;
  align-items: center; cursor: pointer;
  font: inherit; font-size: 0.88rem; font-weight: 600; color: var(--tinta-2);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--rule);
}
.atividade-mais:hover, .atividade-mais:focus-visible { color: var(--tinta); text-decoration-color: var(--manga); }
.atividades-lista.compacta .atividade-mais { display: inline-flex; }

/* a descrição: sempre à vista; com a lista .compacta só no cartão .aberta */
.atividade-desc {
  grid-column: 1 / -1; margin: 0; padding-top: var(--s2); border-top: 1px solid var(--rule);
  color: var(--tinta-2); font-size: 0.93rem; line-height: 1.5;
}
.atividades-lista.compacta .atividade:not(.aberta) .atividade-desc { display: none; }

/* as que não pedem inscrição: filete verde e, no lugar do botão, a etiqueta */
.atividade.livre { border-left-color: var(--menta); }
.atividade-livre-nota {
  margin-left: auto; display: inline-flex; align-items: center; padding: 8px 14px;
  border-radius: 999px; background: var(--cartao-2); border: 1.5px solid var(--menta);
  font-size: 0.85rem; font-weight: 600; line-height: 1.3; color: var(--tinta-2);
}

/* esgotada */
.atividade.esgotada { border-left-color: var(--rule); }
.atividade.esgotada h4, .atividade.esgotada .atividade-desc { color: var(--tinta-3); }
.atividade.esgotada .atividade-foto img { filter: grayscale(1); opacity: 0.6; }
.atividade.esgotada .btn-inscrever { pointer-events: none; opacity: 0.45; }

@media (max-width: 1100px) {
  .atividades-lista { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .atividade { grid-template-columns: 80px minmax(0, 1fr); column-gap: var(--s2); }
  .atividade-foto { width: 80px; }
}

/* o formulário, por baixo da lista: veste-se como o do bilhete */
#form-inscricao { margin-top: var(--s6); padding-top: var(--s5); border-top: 2px solid var(--rule); scroll-margin-top: 90px; }
#form-inscricao fieldset {
  border: 0; padding: 0; margin: 0 0 var(--s5);
  border-top: 1px solid var(--rule); padding-top: var(--s4);
}
#form-inscricao fieldset:first-of-type { border-top: 0; padding-top: 0; }
#form-inscricao legend {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.35rem;
  letter-spacing: -0.02em; color: var(--tinta);
  display: flex; align-items: center; gap: 12px; padding: 0; margin-bottom: var(--s3);
}
.form-inscricao-t { font-size: 2rem; margin: 0 0 var(--s4); }
#form-inscricao .campo .ajuda[data-ativ="resumo"] { margin: 8px 0 0; color: var(--tinta); font-weight: 600; }
#form-inscricao .campo .ajuda[data-ativ="resumo"]:empty { display: none; }
/* o campo do NIF entra alinhado com a caixa que o abre */
#form-inscricao [data-ativ="nif-campo"] { margin-left: 36px; max-width: 280px; }

@media (max-width: 640px) {
  .atividades-lista { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
  .atividade { grid-template-columns: 72px minmax(0, 1fr); padding: var(--s2) var(--s3) var(--s3) var(--s2); }
  .atividade-foto { width: 72px; }
  .form-inscricao-t { font-size: 1.6rem; }
  #form-inscricao [data-ativ="nif-campo"] { margin-left: 0; max-width: none; }
}

/* as opções (com/sem pequeno-almoço) no formulário das atividades: o
   mesmo pequeno fieldset dos dias do bilhete */
#form-inscricao .campo-opcoes { border-top: 0; padding-top: 0; margin: 0 0 var(--s3); }
#form-inscricao .campo-opcoes legend {
  display: block; font-family: var(--f-body); font-weight: 600; font-size: 0.97rem;
  letter-spacing: 0; color: var(--tinta); margin-bottom: 8px; padding: 0;
}

/* o bloco das atividades sem inscrição, por baixo da grelha */
.sem-inscricao { margin-top: var(--s5); }
.sem-inscricao ul { list-style: none; margin: var(--s3) 0 0; padding: 0; }
.sem-inscricao li { margin: 0 0 var(--s2); color: var(--tinta-2); font-size: 0.95rem; line-height: 1.5; max-width: 72ch; }
.sem-inscricao li .hora { font-family: var(--f-mono); font-size: 11.5px; letter-spacing: 0.08em; color: var(--tinta-3); margin-right: 6px; white-space: nowrap; }
.sem-inscricao li strong { color: var(--tinta); }

/* ---------- as pílulas contornadas da barra: «Atividades» e «Autocarros» ----------
   Ao lado do «Bilhete» (cheio), em todas as páginas. */
.nav-links a.nav-cta-2 { background: transparent; color: var(--manga); border: 1.5px solid color-mix(in srgb, var(--manga) 70%, transparent); }
.nav-links a.nav-cta-2:hover { background: color-mix(in srgb, var(--manga) 16%, transparent); border-color: var(--manga); color: var(--manga); }
/* Entre o menu de telemóvel (≤860 px) e ~1060 px a barra vai cheia (quatro ligações,
   três pílulas e a língua): aperta-se o espaçamento em vez de esconder
   ligações, e cada texto fica numa linha só. */
@media (min-width: 861px) and (max-width: 1060px) {
  .nav-links { gap: 15px; }
  .nav-links a, .nav-links a.lang { font-size: 11px; letter-spacing: 0.08em; white-space: nowrap; }
  .nav-links a.nav-cta { padding: 7px 11px; }
  .nav-links a.lang { padding: 7px 10px; }
}

/* ---------- inscrições na página inicial: quatro cartões com fotografia ---------- */
.inscricoes-inicio .cartoes-ativ { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s3); margin: var(--s4) 0; }
.cartao-ativ {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--cartao); border: 1.5px solid var(--rule); border-radius: 12px; overflow: hidden;
  text-decoration: none; color: var(--tinta);
  transition: transform 180ms var(--curva), box-shadow 180ms var(--curva), border-color 180ms var(--curva);
}
.cartao-ativ:hover { transform: translateY(-3px); box-shadow: 0 10px 28px rgba(58, 48, 54, 0.14); border-color: var(--manga); }
.cartao-ativ picture { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--cartao-2); }
.cartao-ativ img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cartao-ativ.foto-baixo img { object-position: 50% 80%; }
.cartao-ativ-nome { font-family: var(--f-disp); font-weight: 700; font-size: 1.05rem; line-height: 1.25; letter-spacing: -0.01em; padding: 12px 14px 0; }
.cartao-ativ-meta { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.08em; color: var(--tinta-3); padding: 6px 14px 0; }
.cartao-ativ-preco { font-family: var(--f-disp); font-weight: 800; font-size: 1.05rem; padding: 8px 14px 14px; margin-top: auto; }
.inscricoes-inicio .cta { margin: 0; }
/* as sugestões na página do bilhete: os mesmos cartões, quantos houver nos dias da pessoa */
/* auto-fill (não auto-fit): as colunas vazias ficam, e um cartão sozinho (um bilhete só de sábado) tem o tamanho de um cartão, não a largura toda */
.sugestoes .cartoes-ativ { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--s3); margin: var(--s4) 0; }
.sugestoes .cta { margin: 0; }
/* mais perto do cartão (o #formulario já tem o fundo), e sem ficar debaixo da barra ao vir da faixa */
.sugestoes { padding-top: var(--s4); scroll-margin-top: 90px; }
.cartao-ativ-restam { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.06em; color: var(--rosa-forte); padding: 6px 14px 0; }
.cartao-ativ.poucos .cartao-ativ-restam { font-weight: 700; }

/* o pop-up das atividades, ao pedir o bilhete (um <dialog>: o fundo escurece,
   Esc fecha). A caixa de dentro tem o espaço; o próprio dialog não, para um
   clique fora da caixa (no fundo) se distinguir de um clique dentro. */
.popup-ativ {
  width: min(920px, calc(100% - 32px)); max-width: none; max-height: 90vh; overflow: auto;
  padding: 0; border: 0; border-radius: 16px; background: var(--cartao); color: var(--tinta);
  box-shadow: 0 24px 60px rgba(58, 48, 54, 0.35);
}
.popup-ativ::backdrop { background: rgba(27, 20, 22, 0.62); }
.popup-ativ-caixa { position: relative; padding: var(--s5) var(--s4) var(--s4); }
.popup-ativ-x {
  position: absolute; top: 8px; right: 8px; width: 44px; height: 44px; border: 0; border-radius: 999px;
  background: transparent; color: var(--tinta-2); font-size: 1.9rem; line-height: 1; cursor: pointer;
}
.popup-ativ-x:hover { background: var(--cartao-2); color: var(--tinta); }
.popup-ativ-confirma {
  display: inline-block; margin: 0 0 var(--s3); padding: 6px 12px; border-radius: 999px;
  background: var(--cartao-2); font-weight: 700; font-size: 0.92rem; color: var(--tinta);
}
.popup-ativ h2 { margin-top: var(--s2); }
.popup-ativ-nota { margin: var(--s2) 0 0; font-size: 0.92rem; font-weight: 600; color: var(--tinta-2); }
.popup-ativ .cartoes-ativ { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--s3); margin: var(--s4) 0; }
.popup-ativ-accoes { display: flex; flex-wrap: wrap; gap: var(--s2); }
@media (max-width: 560px) {
  .popup-ativ-caixa { padding: var(--s5) var(--s3) var(--s3); }
  .popup-ativ .cartoes-ativ { grid-template-columns: 1fr 1fr; gap: var(--s2); }
  .popup-ativ .cartao-ativ-nome { font-size: 0.9rem; padding: 10px 10px 0; }
  .popup-ativ .cartao-ativ-meta, .popup-ativ .cartao-ativ-restam { padding-left: 10px; padding-right: 10px; }
  .popup-ativ .cartao-ativ-preco { font-size: 0.95rem; padding: 6px 10px 10px; }
  .popup-ativ-accoes .btn { width: 100%; }
}
/* seis cartões: 3 colunas (duas filas) no desktop, 2 no telemóvel grande, 1 no pequeno */
@media (max-width: 700px) { .inscricoes-inicio .cartoes-ativ { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .inscricoes-inicio .cartoes-ativ { grid-template-columns: 1fr; } }

/* ══════════════════════════════════════════════════════════════
   AUTOCARRO  (autocarro.html, en/bus.html)
   O horário está no HTML, dentro do formulário: um bloco por dia, e em
   cada um as subidas e as descidas. Cada viagem é uma linha .viagem em
   grelha — a hora, o preço com os lugares que restam, e o <select> dos
   lugares. Por baixo, quem viaja, o resumo com o total e o botão.
   ══════════════════════════════════════════════════════════════ */

/* o que só faz sentido com JavaScript (os campos e o botão da reserva) */
html:not(.js) .so-js { display: none; }

.tiras-info .sub { font-size: 0.85rem; line-height: 1.4; color: var(--tinta-2); max-width: 30ch; }
.opcional { font-weight: 400; color: var(--tinta-3); }

#form-autocarro { margin-top: var(--s3); }
#form-autocarro fieldset {
  border: 0; padding: 0; margin: 0 0 var(--s5);
  border-top: 1px solid var(--rule); padding-top: var(--s4); min-width: 0;
}
#form-autocarro fieldset:first-of-type { border-top: 0; padding-top: 0; }
#form-autocarro legend {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.35rem;
  letter-spacing: -0.02em; color: var(--tinta);
  display: flex; align-items: center; gap: 12px; padding: 0; margin-bottom: var(--s3);
}
#form-autocarro [data-bus="nif-campo"] { max-width: 280px; }

.bus-dia { margin: 0 0 var(--s4); }
.bus-dia > h3 {
  font-family: var(--f-mono); font-weight: 400; font-size: 11.5px; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--tinta-3); margin: 0; padding-bottom: 8px; border-bottom: 1px solid var(--rule);
}
.bus-sentido { margin-top: var(--s3); }
.bus-sentido h4 {
  font-family: var(--f-disp); font-weight: 700; font-size: 1rem; line-height: 1.3;
  letter-spacing: -0.01em; color: var(--tinta); margin: 0 0 var(--s1);
}

.viagem {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto;
  column-gap: var(--s3); row-gap: 4px; align-items: center;
  background: var(--cartao); border: 1.5px solid var(--rule); border-left: 5px solid var(--manga);
  border-radius: 10px; padding: var(--s2) var(--s3); margin: 0 0 var(--s1);
  scroll-margin-top: 90px;
}
.viagem.gratis { border-left-color: var(--menta); }
.viagem.escolhida { background: var(--cartao-2); border-color: var(--malva); border-left-color: var(--manga); }
.viagem.gratis.escolhida { border-left-color: var(--menta); }
.viagem-hora {
  font-family: var(--f-disp); font-weight: 800; font-size: 1.3rem; line-height: 1.1;
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--tinta);
}
.viagem-meta { display: flex; flex-direction: column; min-width: 0; }
.viagem-preco { font-family: var(--f-disp); font-weight: 700; font-size: 1rem; line-height: 1.3; color: var(--tinta); }
.viagem-restam { font-size: 0.82rem; line-height: 1.35; color: var(--tinta-3); }
.viagem-restam:empty { display: none; }
.viagem-restam.poucos { color: #A32347; font-weight: 600; }
.viagem-lugares { display: flex; align-items: center; gap: 8px; }
.viagem-lugares label { font-size: 0.82rem; font-weight: 600; color: var(--tinta-2); }
.viagem select {
  font-family: var(--f-body); font-size: 1rem; color: var(--tinta);
  background: var(--cartao); border: 1.5px solid var(--rule); border-radius: 8px;
  padding: 8px 10px; min-height: 44px; width: 76px;
  transition: border-color 180ms var(--curva), box-shadow 180ms var(--curva);
}
.viagem select:focus {
  outline: none; border-color: var(--tinta);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--manga) 55%, transparent);
}
.viagem select[aria-invalid="true"] {
  border-color: var(--rosa-forte);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rosa-forte) 18%, transparent);
}
.viagem select:disabled { background: var(--cartao-2); color: var(--tinta-3); cursor: not-allowed; }
.viagem-nota { grid-column: 1 / -1; margin: 0; font-size: 0.85rem; line-height: 1.45; color: var(--tinta-2); }
.viagem .erro { grid-column: 1 / -1; margin: 0; }

/* esgotada, ou com a venda fechada */
.viagem.esgotada, .viagem.fechada { border-left-color: var(--rule); }
.viagem.esgotada .viagem-hora, .viagem.fechada .viagem-hora,
.viagem.esgotada .viagem-preco, .viagem.fechada .viagem-preco { color: var(--tinta-3); }

/* o resumo: as viagens escolhidas, uma por linha, e o total */
.bus-resumo {
  width: 100%; background: var(--cartao-2); border: 1.5px solid var(--rule);
  border-radius: 10px; padding: var(--s3);
}
.bus-resumo:empty { display: none; }
.bus-resumo p { margin: 0; color: var(--tinta-2); font-size: 0.95rem; }
.bus-resumo ul { list-style: none; margin: 0; padding: 0; }
.bus-resumo li {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3);
  padding: 5px 0; border-bottom: 1px solid var(--rule); font-size: 0.95rem; line-height: 1.4; color: var(--tinta);
}
.bus-resumo li span:last-child { white-space: nowrap; font-variant-numeric: tabular-nums; }
.bus-resumo .bus-total {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3);
  margin-top: var(--s2); font-family: var(--f-disp); font-weight: 800; font-size: 1.2rem; color: var(--tinta);
}
.bus-regras { margin: 0; padding-left: 1.2em; font-size: 0.9rem; line-height: 1.5; color: var(--tinta-2); }
.bus-regras li { margin: 0 0 2px; }
.bus-lembrete {
  margin: var(--s4) 0 0; padding: var(--s2) var(--s3); background: var(--cartao); border: 1.5px solid var(--rule);
  border-left: 5px solid var(--menta); border-radius: 10px; color: var(--tinta-2); font-size: 0.95rem;
}

/* o cartão da reserva feita: uma coluna, com um bilhete por viagem (dados e QR) */
.bilhete-cartao.bus-cartao { grid-template-columns: minmax(0, 1fr); }
.bus-bilhetes { display: grid; gap: var(--s2); margin-top: var(--s4); }
.bus-bilhetes:empty { display: none; }
.bus-bilhete {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s3); align-items: center;
  border: 1.5px solid var(--rule); border-radius: 10px; padding: var(--s3); margin: 0;
  break-inside: avoid;
}
.bus-bilhete .bilhete-num { font-size: 1.35rem; margin: 0 0 6px; }
.bus-bilhete h3 { font-size: 1.15rem; line-height: 1.2; }
.bus-bilhete p { margin: 4px 0 0; color: var(--tinta-2); font-size: 0.93rem; line-height: 1.4; }
.bus-bilhete p.bilhete-num { color: var(--tinta); }
.bus-bilhete .bilhete-qr { width: 132px; }

/* a linha do autocarro no cartão da Plantação de árvores (atividades.html) */
.atividade-bus {
  grid-column: 1 / -1; margin: 0; padding-top: var(--s2); border-top: 1px solid var(--rule);
  color: var(--tinta-2); font-size: 0.88rem; line-height: 1.45;
}

/* a faixa do autocarro no cartão do bilhete: a mesma faixa das atividades, sem miniaturas;
   a seta aponta para a direita (vai para outra página), e é para lá que se mexe */
.faixa-bus:hover .faixa-ativ-seta { transform: translateX(3px); }
@media (max-width: 640px) {
  .faixa-bus { grid-template-columns: minmax(0, 1fr) auto; }
  .faixa-bus .faixa-ativ-texto strong { grid-area: 1 / 1; }
  .faixa-bus .faixa-ativ-texto span { grid-area: 2 / 1 / 3 / 3; }
  .faixa-bus .faixa-ativ-seta { grid-area: 1 / 2; }
}

/* o bloco do autocarro no pop-up do bilhete: o horário compacto, só as horas */
.popup-bus {
  margin: var(--s4) 0; padding: var(--s3); background: var(--cartao-2);
  border: 1.5px solid var(--rule); border-radius: 12px;
}
.popup-bus.destaque { margin-top: 0; background: var(--cartao); border-color: var(--manga); border-left-width: 5px; }
.popup-ativ .popup-bus h3 { margin: 0; font-size: 1.2rem; }
.popup-bus-preco { margin: 4px 0 0; font-weight: 600; font-size: 0.95rem; color: var(--tinta-2); }
.popup-bus-horario { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2) var(--s4); margin: var(--s3) 0; }
.popup-bus-horario > div { min-width: 0; }
.popup-bus-horario dt {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--tinta-3);
}
.popup-bus-horario dd { margin: 3px 0 0; font-size: 0.93rem; line-height: 1.45; color: var(--tinta); font-variant-numeric: tabular-nums; }
.popup-bus-horario dd b { font-weight: 700; }
.popup-bus-nota { margin: 0 0 var(--s3); font-size: 0.85rem; color: var(--tinta-2); }

@media (max-width: 640px) {
  .viagem { grid-template-columns: 54px minmax(0, 1fr) auto; column-gap: var(--s2); padding: var(--s2); }
  .viagem-hora { font-size: 1.15rem; }
  /* o rótulo «Lugares» sobe para cima do <select>, para o preço ter a largura */
  .viagem-lugares { flex-direction: column; align-items: flex-start; gap: 2px; }
  .viagem-lugares label { font-size: 0.75rem; }
  #form-autocarro [data-bus="nif-campo"] { max-width: none; }
  .bus-bilhete { grid-template-columns: minmax(0, 1fr); }
  .bus-bilhete .bilhete-qr { width: 148px; }
}
@media (max-width: 560px) {
  .popup-bus-horario { grid-template-columns: 1fr; }
  .popup-bus .btn { width: 100%; }
}

/* impressão: o cartão da reserva com um bilhete por viagem e o seu QR; o
   formulário (o horário, os campos) não se imprime */
@media print {
  body.com-bilhete #form-autocarro, body.com-bilhete .bus-lembrete { display: none; }
  .bus-bilhete { border: 1px solid #000; border-radius: 0; }
  body.com-bilhete .bus-bilhete .bilhete-qr { width: 36mm; border: 0; padding: 0; }
}
