/* ── Hero (Hero.astro) ── */
/* O respiro do topo é o MESMO recuo dos lados (13/08, era --esp-6 fixo):
   usando o próprio --gutter, a moldura do conteúdo fica uniforme nos três
   lados e acompanha sozinha qualquer ajuste futuro do recuo lateral. */
.fas-hero { display: grid; gap: var(--esp-4); padding-top: var(--gutter); }
/* Sem isso o item de grid não encolhe abaixo do min-content dos filhos de
   largura fixa do trilho (22rem cada). */
.fas-hero .palco { min-width: 0; }

/* A partir de 64rem os links vão para a coluna lateral, como no mockup.
   Abaixo disso eles ficam embaixo: em 390px uma coluna lateral de 260px
   deixaria ~120px para o carrossel.

   A igualdade de altura banner = links, terceira versão (10/08): o palco é
   um item de grid comum que estica com a linha, e o carrossel é absoluto
   DENTRO dele — abspos dentro de elemento posicionado é o caso mais velho
   e mais interoperável do CSS. As duas versões anteriores divergiam entre
   motores: a cadeia de height:100% rendia +18px no navegador do dono do
   projeto, e abspos direto na célula de grid depende de suporte a
   grid-área-como-bloco-contenedor, que o WebKit historicamente errou.
   Como o carrossel é absoluto, o palco contribui ZERO de altura — a linha
   1 é ditada só pelos Links Úteis, em qualquer motor.

   O corte é 48rem e não 64rem (11/08): entre 768 e 1024px o hero era uma
   coluna só, e o banner 16:9 de largura cheia chegava a 943×530 — sozinho
   na primeira dobra, com o painel do rádio jogado para y=1166. Auditoria
   mediu essa faixa como a pior do site. Em duas colunas o banner cai para
   ~1,2:1 ao lado dos Links Úteis e o rádio sobe para dentro da dobra. */
@media (min-width: 48rem) {
  .fas-hero { grid-template-columns: minmax(0, 1.9fr) minmax(17rem, 1fr); }
  .fas-hero .palco { position: relative; }
  .fas-hero .palco > .fas-carrossel { position: absolute; inset: 0; }
  .fas-hero > .fas-radio { grid-column: 1 / -1; }
}

/* Sem a coluna de Links Úteis, o palco volta a ser bloco normal (o carrossel absoluto não teria altura). */
@media (min-width: 48rem) {
  .fas-hero--sem-links { grid-template-columns: 1fr; }
  .fas-hero--sem-links .palco > .fas-carrossel { position: static; }
  /* Sem banners, os Links úteis ocupam a largura toda em colunas. */
  .fas-hero--sem-banners { grid-template-columns: 1fr; }
  .fas-hero--sem-banners .fas-links .lista { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); max-height: none; overflow: visible; }
}

/* ── Carrossel (Carrossel.astro) ── */
.fas-carrossel { position: relative; display: grid; gap: var(--esp-3); }
/* O Hero estica este item de grid até a altura da coluna de Links Úteis
   (ver Hero.astro); sem altura própria aqui e no trilho, o `height: 100%`
   em cascata até o card do banner (que vira `position: absolute` no modo
   interno) não teria de onde herdar um número. */
/* gap: 0 no modo interno — a faixa dos pontos tem 44px de altura própria e
   os pontos ficam centrados nela, então ela já traz o respiro. Com o gap de
   12px do carrossel somado aos 16px do hero, sobravam 72px de vão entre o
   banner e os Links Úteis, com os pontos flutuando no meio do nada
   (apontado em 11/08). */
.fas-carrossel--interno { height: 100%; gap: 0; }
/* padding/margin zerados: o truque de 3px para o anel de foco (herdado do
   trilho comum) roubava 6px de altura do banner com box-sizing: border-box
   — era ESTA a diferença de altura contra os Links Úteis que o dono do
   projeto via (10/08). O anel de foco não é cortado aqui: outline desenha
   por cima e o palco não tem overflow. */
/* Mobile (< 48rem): sangria suave até a borda da tela com padding-inline igual ao gutter.
   O 1º card começa alinhado com o cabeçalho na esquerda e o 2º vaza na borda direita. */
.fas-carrossel:not(.fas-carrossel--interno) {
  margin-inline: calc(var(--gutter) * -1);
}
.fas-carrossel:not(.fas-carrossel--interno) .trilho {
  padding-inline: var(--gutter);
  scroll-padding-inline: var(--gutter);
  gap: var(--gutter);
}

.fas-carrossel .trilho {
  display: flex;
  /* Rolagem nativa fluida */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding-block: 3px;
  margin-block: -3px;
}
.fas-carrossel .trilho::-webkit-scrollbar { display: none; }

/* Cards visíveis por tela (Configurações do site › Home): --carrossel-* vem do plugin.
   Largura = (trilho - vãos) / n; fração de n deixa o próximo card espiando. */
.fas-carrossel .trilho { --carrossel-n: var(--carrossel-celular, 1.2); --carrossel-vao: var(--gutter); }
.fas-carrossel .trilho > * { flex: 0 0 calc((100% - (var(--carrossel-n) - 1) * var(--carrossel-vao)) / var(--carrossel-n)); scroll-snap-align: start; }
/* O Hero tem um item por vez em qualquer largura; a régua diz onde estamos. */
.fas-carrossel:has([data-auto]) .trilho > * { flex: 0 0 100%; }

.fas-carrossel .controles { display: none; justify-content: flex-end; gap: var(--esp-2); }
@media (min-width: 48rem) {
  .fas-carrossel:not(.fas-carrossel--interno) {
    margin-inline: 0;
  }
  .fas-carrossel:not(.fas-carrossel--interno) .trilho {
    padding-inline: 3px;
    scroll-padding-inline: 0;
    gap: var(--esp-4);
  }
  .fas-carrossel .controles { display: flex; }
  .fas-carrossel .trilho { --carrossel-n: var(--carrossel-tablet, 2); --carrossel-vao: var(--esp-4); }
}
@media (min-width: 64rem) {
  .fas-carrossel .trilho { --carrossel-n: var(--carrossel-desktop, 3); }
}
.fas-carrossel .seta {
  display: grid;
  place-items: center;
  /* 44px de alvo de toque. */
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--cor-borda);
  border-radius: 50%;
  background: var(--cor-overlay);
  /* Sempre um pouco de desfoque atrás da seta: sobre imagem clara, o fundo
     translúcido sozinho perde contraste — o blur garante leitura mesmo
     assim, dentro ou fora do modo interno. */
  backdrop-filter: blur(6px);
  color: var(--cor-texto);
  cursor: pointer;
  transition: background var(--dur-rapida) var(--ease-padrao);
}
.fas-carrossel .seta:hover:not([disabled]) { background: rgb(126 74 255 / .5); }
.fas-carrossel .seta[disabled] { opacity: .35; cursor: not-allowed; }

.fas-carrossel .regua { display: flex; justify-content: center; gap: var(--esp-2); }

/* Modo interno (só o Hero): as setas saem da fileira acima do trilho e
   viram um par sobreposto à imagem, uma de cada lado, centralizadas na
   vertical pelo align-items: center num overlay de altura cheia — o
   padding-inline aqui (não em .trilho) é o que afasta cada seta da borda.
   A régua desce para dentro do banner, na base, como no mockup. */
.fas-carrossel--interno .controles {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  /* Mobile-first: setas no TERÇO SUPERIOR do banner (onde só tem imagem) —
     centradas na vertical elas caíam em cima da manchete no card 16:9
     estreito (revisão mobile de 10/08). */
  align-items: flex-start;
  justify-content: space-between;
  padding-block: var(--esp-4);
  padding-inline: var(--esp-3);
  /* Some com o espaço entre as setas: sem pointer-events aqui a área
     inteira do banner "roubaria" o clique que deveria ir para o CTA. */
  pointer-events: none;
}
.fas-carrossel--interno .seta { pointer-events: auto; }
/* A régua vive DENTRO do banner em qualquer largura (13/08).
   Ela tinha ido para fora no mobile (11/08) por três motivos medidos, e dois
   deles eram o mesmo motivo: o botão de CTA. Em faixa de largura cheia a
   caixa dela cobria a metade de baixo do botão e comia o clique; ancorada à
   direita, em 360px o alvo do primeiro ponto encostava nele. Desde que o
   banner inteiro virou link (13/08) não existe mais botão para colidir, e a
   faixa externa passou a ser só uma tira de 44px roubando altura da página.
   O terceiro motivo — ponto translúcido some sobre foto clara — continua
   valendo, e é resolvido no contraste do próprio ponto, não na posição.
   O alvo de cada ponto segue 32×24, exceção documentada da Restrição 14: as
   setas de 44×44 são a alternativa equivalente (WCAG 2.5.5).
   `pointer-events: none` na régua e `auto` na marca: a caixa da régua
   atravessa o banner de ponta a ponta e sem isso ela roubaria o clique do
   link em toda a faixa da base. */
.fas-carrossel--interno .regua {
  position: absolute;
  inset: auto 0 var(--esp-3) 0;
  z-index: 2;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.fas-carrossel--interno .marca { pointer-events: auto; }

/* O hero recupera as setas ANTES dos outros carrosséis: em 40rem, não em
   48. O corte é o MESMO do retrato 4:5 (CardBanner.astro) — quando a imagem
   deixa de ser retrato, ela volta a ter largura para as setas por cima sem
   roubar a foto. Um breakpoint só para as duas mudanças, não dois quase
   .fas-carrossel iguais. Estes seletores têm especificidade maior que a regra geral acima,
   então mandam nos dois sentidos. */
.fas-carrossel--interno .controles { display: none; }
@media (min-width: 40rem) {
  .fas-carrossel--interno .controles { display: flex; }
}

/* De 48rem pra cima (mesmo corte do Hero) o banner é alto, porque estica
   até a altura da coluna de Links Úteis — as setas voltam ao centro
   vertical, onde não cobrem nem a foto nem a manchete. */
@media (min-width: 48rem) {
  .fas-carrossel--interno .controles { align-items: center; padding-block: 0; }
}
/* Pontos discretos que viram pílula quando ativos — pedido de 10/08: o
   seletor anterior (traços de 28×5) era grande demais. O alvo de toque
   continua 32×24 (o ::after é só o desenho); segue o único controle
   exempto dos 44px de altura (Restrição 14): as setas de 44×44 ao lado
   são a alternativa equivalente, exceção da WCAG 2.5.5. */
.fas-carrossel .marca {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.fas-carrossel .marca::after {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: var(--raio-pill);
  /* O ponto é um CONTROLE: a WCAG 1.4.11 pede 3:1 contra o que estiver
     atrás. A 35% ele dá 2,4:1 sobre o planalto escuro da tarja e some de
     vez sobre foto clara. A 55% dá 4,3:1 medido, com a mesma leitura
     discreta — quem carrega o destaque é a pílula de acento ao lado, não o
     brilho do ponto apagado. */
  background: rgb(233 221 255 / .55);
  transition: width var(--dur-rapida) var(--ease-padrao), background var(--dur-rapida) var(--ease-padrao);
}
.fas-carrossel .marca[aria-selected='true']::after { width: 16px; background: var(--cor-acento); }

/* scroll-behavior: smooth É movimento. E o avanço automático é o pior tipo
   de movimento para quem pediu para não ter — o script também respeita, mas
   a rolagem instantânea precisa vir do CSS. */
@media (prefers-reduced-motion: reduce) {
  .fas-carrossel .trilho { scroll-behavior: auto; }
}

/* ── Links úteis (LinksUteis.astro) ── */
.fas-links {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  padding: var(--esp-5);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  background: var(--cor-superficie-alta);
}
.fas-links .titulo { color: var(--cor-acento); margin-bottom: var(--esp-1); }
.fas-links .lista { display: flex; flex-direction: column; gap: var(--esp-2); }
/* A partir do 7º link a lista rola, só onde o aside divide altura com o
   banner (>= 48rem, o mesmo corte do grid do Hero). O teto é a altura de
   exatamente 6 atalhos + os 5 vãos entre eles: o 7º aparece cortado ao
   meio, que é o convite visual para rolar. */
@media (min-width: 48rem) {
  .fas-links .lista--rolavel {
    max-height: calc(6 * 3.25rem + 5 * var(--esp-2));
    overflow-y: auto;
    scrollbar-width: thin;
    padding-right: var(--esp-1);
  }
}
.fas-links .atalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
  /* 52px: é o alvo do mockup e já passa dos 44px mínimos. */
  min-height: 3.25rem;
  padding-inline: var(--esp-4);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-1);
  background: rgb(46 28 107 / .55);
  color: var(--cor-texto);
  font-size: var(--texto-mini);
  font-weight: var(--peso-forte);
  transition: background var(--dur-rapida) var(--ease-padrao),
              border-color var(--dur-rapida) var(--ease-padrao);
}
/* Os atalhos encolhem por natureza, mas dentro da lista rolável cada um
   precisa manter a altura cheia, senão o teto espreme todos em vez de
   deixar o excedente para a rolagem. */
.fas-links .lista--rolavel .atalho { flex-shrink: 0; }
.fas-links .lista--rolavel li { flex-shrink: 0; }
.fas-links .atalho:hover { background: rgb(126 74 255 / .28); border-color: var(--cor-borda-ativa); color: var(--cor-texto); }
.fas-links .atalho--destaque {
  border-color: var(--cor-borda-ativa);
  background: linear-gradient(120deg, rgb(121 226 255 / .2), rgb(126 74 255 / .22));
}
.fas-links .texto { min-width: 0; }

/* ── Rádio (PainelRadio.astro) ── */
.fas-radio {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  overflow: hidden;
  padding: var(--esp-3) var(--esp-4);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  background: radial-gradient(120% 160% at 12% 0%, rgb(126 74 255 / .24), rgb(21 9 49 / .88) 60%);
  backdrop-filter: blur(12px);
  box-shadow: 0 4px 20px rgb(0 0 0 / .2);
}

/* ── Linha 1: Principal ─────────────────────────────────────────── */
.fas-radio .agora {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--esp-3);
  width: 100%;
  min-width: 0;
}

.fas-radio .bloco-controle {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  flex-shrink: 0;
}

.fas-radio .tocar {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: var(--alvo-toque);
  height: var(--alvo-toque);
  border: 0;
  border-radius: 50%;
  background: var(--gradiente-acao);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 0 16px rgb(126 74 255 / .45);
  transition: transform var(--dur-rapida) var(--ease-padrao), filter var(--dur-rapida) var(--ease-padrao);
}
.fas-radio .tocar:hover {
  transform: scale(1.06);
  filter: brightness(1.12);
}
.fas-radio .icone-pausa { display: none; }
.fas-radio .tocar[aria-pressed='true'] .icone-pausa { display: block; }
.fas-radio .tocar[aria-pressed='true'] .icone-play { display: none; }

.fas-radio .emissora-texto--desk { display: none; }

.fas-radio .faixa {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

.fas-radio .meta-mobile {
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  margin-bottom: 2px;
}
.fas-radio .meta-mobile .estado {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.fas-radio .sep { color: var(--cor-texto-suave); opacity: .6; flex-shrink: 0; }
.fas-radio .nome-mob {
  color: var(--cor-texto);
  font-size: var(--texto-rotulo);
  font-weight: var(--peso-display);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fas-radio .estado { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.fas-radio .pulso {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cor-alerta);
  flex-shrink: 0;
  animation: pulsar-radio 1.6s var(--ease-padrao) infinite;
}
@keyframes pulsar-radio {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .5; transform: scale(.8); }
}

/* Mini Equalizador animado quando tocando */
.fas-radio .equalizador {
  display: none;
  align-items: flex-end;
  gap: 2px;
  height: 9px;
  width: 9px;
  flex-shrink: 0;
}
.fas-radio .barra {
  width: 2px;
  border-radius: 1px;
  background: var(--cor-alerta);
  animation: barra-pulsa 0.8s ease-in-out infinite alternate;
}
.fas-radio .b1 { height: 40%; animation-delay: 0.1s; }
.fas-radio .b2 { height: 90%; animation-delay: 0.3s; }
.fas-radio .b3 { height: 60%; animation-delay: 0.2s; }
@keyframes barra-pulsa {
  0% { height: 25%; }
  100% { height: 100%; }
}
.fas-radio:has(.tocar[aria-pressed='true']) .equalizador { display: inline-flex; }
.fas-radio:has(.tocar[aria-pressed='true']) .pulso { display: none; }

.fas-radio .vivo { color: var(--cor-alerta); font-size: var(--texto-rotulo); flex-shrink: 0; }
.fas-radio .nome { font-size: var(--texto-mini); font-weight: var(--peso-display); }
.fas-radio .etiqueta { color: var(--cor-texto-suave); opacity: .75; font-size: var(--texto-rotulo); margin-bottom: 2px; }
.fas-radio .etiqueta--desk { display: none; }

/* Faixa Tocando Agora: 1 linha com elipse */
.fas-radio .titulo-faixa {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--texto-mini);
  font-weight: var(--peso-display);
  line-height: 1.25;
  letter-spacing: var(--tracking-titulo);
  color: var(--cor-texto);
  min-width: 0;
}
.fas-radio .artista {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
  margin-top: 1px;
  min-width: 0;
}

.fas-radio .ultima { display: none; }
.fas-radio .ultima[hidden] { display: none; }
.fas-radio .ultima-linha { display: flex; align-items: baseline; gap: var(--esp-2); min-width: 0; font-size: var(--texto-mini); }
.fas-radio .hora { flex-shrink: 0; color: var(--cor-acento); font-weight: var(--peso-forte); font-variant-numeric: tabular-nums; }
.fas-radio .tit--ultima { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--peso-medio); }

/* ── Linha 2: Esteira de Recentes (Fina e discreta) ─────────────── */
.fas-radio .recentes[hidden] { display: none; }
.fas-radio .recentes {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  width: 100%;
  min-width: 0;
  overflow: hidden;
  border-top: 1px solid rgb(126 74 255 / .18);
  padding-top: var(--esp-2);
  margin-top: 2px;
}
/* No mobile a etiqueta é oculta para a esteira usar 100% da largura */
.fas-radio .etiqueta--recentes { display: none; }

.fas-radio .rolagem {
  flex: 1;
  width: 100%;
  min-width: 0;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 .75rem, #000 calc(100% - .75rem), transparent);
}
.fas-radio .fita {
  display: flex;
  width: max-content;
  animation: fita-rola 45s linear infinite;
}
.fas-radio .rolagem:hover .fita,
.fas-radio .rolagem:focus-within .fita { animation-play-state: paused; }
@keyframes fita-rola { to { transform: translateX(-50%); } }

.fas-radio .lista-recentes { display: flex; gap: var(--esp-2); padding-right: var(--esp-2); }
.fas-radio .recente {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px var(--esp-3);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-pill);
  background: var(--cor-superficie-alta);
  font-size: var(--texto-rotulo);
}
.fas-radio .recente[hidden] { display: none; }
.fas-radio .tit { max-width: 13rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--cor-texto); }

@media (prefers-reduced-motion: reduce) {
  .fas-radio .rolagem { overflow-x: auto; scrollbar-width: none; }
}

/* Desktop Soundbar: 3 colunas fluidas na mesma linha */
@media (min-width: 48rem) {
  .fas-radio {
    padding: var(--esp-3) var(--esp-5);
    gap: var(--esp-2);
  }
  .fas-radio .agora {
    grid-template-columns: auto minmax(0, 1.8fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--esp-5);
  }
  .fas-radio .emissora-texto--desk { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
  .fas-radio .meta-mobile { display: none; }
  .fas-radio .etiqueta--desk { display: block; }
  .fas-radio .etiqueta--recentes { display: block; flex-shrink: 0; margin-bottom: 0; }
  .fas-radio .titulo-faixa { font-size: var(--texto-corpo); }
  .fas-radio .artista { font-size: var(--texto-mini); }
  .fas-radio .ultima { display: block; }
  .fas-radio .faixa, .fas-radio .ultima {
    border-left: 1px solid rgb(126 74 255 / .2);
    padding-left: var(--esp-5);
  }
}

.fas-radio .apenas-leitor { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ── Grade (Grade.astro) ── */
.fas-grade { display: grid; gap: var(--esp-4); }

/* Mobile: a faixa estreita (guias, Lab) usa gap: var(--gutter),
   igualando o vão central ao recuo lateral da tela. */
.fas-grade--estreita { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }

/* Daqui pra cima auto-fit decide sozinho quantas colunas caber. */
@media (min-width: 32rem) {
  .fas-grade--estreita { gap: var(--esp-4); }
  .fas-grade--estreita { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
  .fas-grade--media { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
  .fas-grade--larga { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
}

/* ── Card banner (CardBanner.astro) ── */
/* O fio de 1px que TODOS os outros cards do site têm e este não tinha
   (11/08): Links Úteis, rádio, notícias, edições — todos delimitados, o
   banner não. Sem ele, o lado onde o conteúdo é escuro dissolve contra a
   nebulosa clara e a borda do card vira uma linha imaginária. Com
   box-sizing: border-box (reset.css) a borda não muda a largura do card. */
/* QUEM DEFINE A CAIXA É O CARD, não o filho (13/08). A proporção e o freio
   de altura moravam no placeholder, e um filho que decide o próprio tamanho
   é a receita de sobrar vão entre ele e a borda do pai — em duas frentes:
   o arredondamento próprio dele (que não alcançava a curva do card) e o
   risco de o `max-height` reduzir a largura para manter a proporção. Com a
   caixa aqui e o filho preenchendo por inteiro, nenhuma das duas existe. */
.fas-banner {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  max-height: 62svh;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  overflow: hidden;
  color: var(--cor-texto);
  transition: border-color var(--dur-rapida) var(--ease-padrao);
}
/* Sendo o card inteiro um link, ele precisa de estado visível: a borda
   acende. Nada de translateY aqui — o card vive dentro de um trilho que
   rola, e mover o item na rolagem é o tipo de movimento que enjoa. */
.fas-banner:hover { border-color: var(--cor-borda-ativa); color: var(--cor-texto); }

/* O placeholder (e a foto real) PREENCHE o card, ponta a ponta, sem
   proporção nem arredondamento próprios. Quem arredonda o conjunto é o
   `overflow: hidden` do card. */
.fas-banner [data-foto-pendente],
.fas-banner .foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
}
/* Só a foto: cobre o card recortando o excesso — a proporção da caixa é
   do card (4:5 no celular, 16:9 do tablet pra cima), nunca do arquivo. */
.fas-banner .foto {
  object-fit: cover;
}

/* A proporção do CARD.
   Mobile: RETRATO 4:5 (11/08). Em 16:9 o banner tinha 200px de altura num
   celular de 390 — a manchete de duas linhas comia a imagem toda e não
   sobrava respiro para a foto que vai entrar ali. O freio em `svh` (62 e não
   52: com 52 ele vencia sempre e o 4:5 nunca acontecia) evita que um
   aparelho largo renderize 600px de banner e empurre a página para fora da
   primeira dobra.
   Do tablet pra cima volta o panorâmico: 4:5 em 640px+ viraria um pôster de
   800px de altura. */
@media (min-width: 40rem) {
  .fas-banner { aspect-ratio: 16 / 9; max-height: none; }
}

/* A tarja, e o detalhe que decide se ela funciona: as paradas do gradiente
   .fas-banner são em REM A PARTIR DO TOPO da tarja, .fas-banner não em porcentagem. Em porcentagem,
   uma manchete de 3 linhas empurra o topo do gradiente e o planalto escuro
   nasce mais alto do que o texto — o contraste muda conforme o tamanho do
   título. Em rem, o planalto começa onde o conteúdo começa, e manchete de 2
   ou de 3 linhas lê igual.
   Medido sobre foto BRANCA (pior caso, já que a foto real pode ser um palco
   estourado de luz): manchete passou de 3,67:1 — que reprova a WCAG — para
   17,7:1. Hoje o placeholder é escuro e isso não aparece; quando a foto
   entrar, aparece. */
.fas-banner .tarja {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-2);
  /* O recuo de baixo agora reserva a faixa dos pontos, que vive dentro do
     banner em qualquer largura: 24px de alvo + 12px do inset = 36px. */
  padding: 3.5rem var(--esp-5) var(--esp-10);
  background: linear-gradient(
    to bottom,
    rgb(10 3 26 / 0) 0,
    rgb(10 3 26 / .5) 1.75rem,
    rgb(10 3 26 / .93) 3.5rem,
    rgb(10 3 26 / .93) 100%
  );
}
.fas-banner .categoria { padding: var(--esp-1) var(--esp-3); border: 1px solid currentColor; border-radius: var(--raio-pill); }
.fas-banner .categoria--acento { color: var(--cor-acento); }
.fas-banner .categoria--realce { color: var(--cor-realce); }
.fas-banner .categoria--alerta { color: var(--cor-alerta); }
/* A manchete é o texto mais importante da página: com o retrato 4:5 ela tem
   espaço para respirar, então usa a escala de h2 (era h3) e quebra
   equilibrada em vez de deixar uma palavra órfã na última linha. */
.fas-banner .manchete {
  max-width: 28rem;
  font-size: var(--texto-titulo-2);
  color: #fff;
  text-wrap: balance;
}

.fas-banner .apenas-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Abaixo de 48rem a proporção do Placeholder é que dá a altura do banner.
   De 48rem pra cima o Hero estica o carrossel até a altura da coluna de
   Links Úteis (Hero.astro); aqui só precisamos parar de impor proporção e
   deixar a foto preencher esse espaço.
   Este `min-width` tem que ser o MESMO do Hero: se o hero abrir em duas
   colunas antes daqui, o banner esticaria e a foto ficaria com a proporção
   antiga dentro dele. */
@media (min-width: 48rem) {
  /* Aqui a altura deixa de ser do card: o Hero estica o carrossel até a
     altura da coluna de Links Úteis, e o banner tem que obedecer — daí
     `aspect-ratio: auto` e sem freio. O placeholder já preenche por dentro. */
  .fas-banner { aspect-ratio: auto; max-height: none; }
  /* Daqui pra cima os pontos indicadores voltam para DENTRO do banner,
     centrados na base (Carrossel.astro). Sem esta reserva eles se sobrepõem
     à última linha da tarja. */
  .fas-banner .tarja { padding-bottom: var(--esp-12); }
}

/* ── Card notícia (CardNoticia.astro) ── */
.fas-noticia {
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  height: 100%;
  padding: var(--esp-3);
  overflow: hidden;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  transition: border-color var(--dur-rapida) var(--ease-padrao);
}
.fas-noticia:hover { border-color: var(--cor-borda-ativa); color: var(--cor-texto); }
.fas-noticia .foto { display: block; margin: calc(var(--esp-3) * -1) calc(var(--esp-3) * -1) 0; }
.fas-noticia .foto img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  /* `height: auto` é obrigatório: sem ele o atributo `height` do <img> vence
     o aspect-ratio e a capa sai fora de 16:9 (o bug de 27/08 no CardSet). */
  height: auto;
  object-fit: cover;
  background: rgb(18 7 38);
}
/* A foto encosta nas bordas; quem arredonda os cantos é o overflow do card. */
.fas-noticia .foto [data-foto-pendente] { border-radius: 0; }
.fas-noticia .corpo { display: flex; flex-direction: column; gap: var(--esp-2); padding-inline: var(--esp-2); padding-bottom: var(--esp-2); }
.fas-noticia .meta { display: flex; align-items: baseline; justify-content: space-between; gap: var(--esp-3); }
.fas-noticia .categoria { color: var(--cor-acento); }
.fas-noticia .data { color: var(--cor-texto-suave); font-size: var(--texto-rotulo); }
.fas-noticia .titulo { font-size: var(--texto-pequeno); font-weight: var(--peso-forte); letter-spacing: normal; text-wrap: pretty; }
.fas-noticia .saida { margin-top: auto; color: var(--cor-link); font-size: var(--texto-rotulo); font-weight: var(--peso-forte); }

/* ── Card link/guia/ferramenta (CardLink.astro) ── */
.fas-cartao {
  display: flex;
  flex-direction: column;
  gap: var(--esp-1); /* título→descrição colados, como no card de set */
  /* 44px de alvo mínimo é o piso; o padding já entrega mais que isso. */
  min-height: 5.5rem;
  padding: var(--recuo-painel);
  overflow: hidden;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  transition: border-color var(--dur-rapida) var(--ease-padrao),
              transform var(--dur-rapida) var(--ease-padrao);
}
a.fas-cartao:hover { border-color: var(--cor-borda-ativa); color: var(--cor-texto); transform: translateY(-2px); }
/* Em breve: esmaecido, com o cadeado no rótulo. */
/* A opacidade fica nas PARTES e não no card.
 *
 * Com `opacity: .62` no contêiner, o selo "em breve" era atenuado junto e
 * caía para 4,38:1 contra o fundo, abaixo dos 4,5:1 da WCAG 1.4.3 (pego pelo
 * axe em `/`). Opacidade de pai não se desfaz no filho, e nenhuma cor
 * pré-opacidade alcança o contraste necessário depois da mistura: a soma
 * daria um azul acima de 255.
 *
 * Atenuar foto, título e descrição preserva o mesmo "indisponível" de
 * relance, e deixa legível justamente o selo que EXPLICA por que o card está
 * apagado. */
.fas-cartao--morto .foto img,
.fas-cartao--morto .titulo,
.fas-cartao--morto .descricao {
  opacity: .62;
}

/* position: relative é a âncora da pill "Em breve" (absoluta, canto superior direito da foto). */
.fas-cartao .foto { position: relative; display: block; margin: calc(var(--recuo-painel) * -1) calc(var(--recuo-painel) * -1) var(--esp-2); }
/* Mesma caixa 16:9 do Placeholder: com e sem ilustração, o card mede igual —
   é o que mantém a grade alinhada enquanto as imagens vão chegando. */
.fas-cartao .foto img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  /* `height: auto` obrigatório: sem ele o atributo height do <img> vence o aspect-ratio (imagem padrão 1200×675 saía alta). */
  height: auto;
  object-fit: cover;
}
/* A foto encosta nas bordas do card; quem arredonda é o overflow dele. */
.fas-cartao .foto [data-foto-pendente] { border-radius: 0; }

.fas-cartao .titulo { font-size: var(--texto-pequeno); font-weight: var(--peso-forte); letter-spacing: normal; }
.fas-cartao .descricao { margin-top: 0; color: var(--cor-texto-suave); font-size: var(--texto-mini); line-height: var(--altura-corpo); } /* sem a margem herdada de parágrafo */
/* Pill "Em breve" sobre a foto, no MESMO padrão do selo da capa da edição: canto superior
   esquerdo, recuo var(--esp-5), borda na cor do texto e vidro fosco quase sólido (é o fundo que
   sustenta o contraste sobre qualquer foto). Fica fora da opacidade, que só atenua a imagem. */
.fas-cartao .aviso {
  position: absolute;
  inset: var(--esp-5) auto auto var(--esp-5);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  padding: var(--esp-1) var(--esp-3);
  border: 1px solid currentColor;
  border-radius: var(--raio-pill);
  background: rgb(10 3 26 / .82);
  color: var(--cor-realce);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* translateY no hover é movimento: quem pediu menos movimento não recebe. */
@media (prefers-reduced-motion: reduce) {
  a.fas-cartao:hover { transform: none; }
}

/* Guias e Lab em carrossel: cards do MESMO tamanho da grade estreita que as seções tinham
   (2 colunas no celular, 3 → 4 → 5 conforme a largura, mínimo ~13rem), só que em
   trilho. A fração no celular deixa o terceiro card espiando, como nas notícias. */
.fas-secao--guias .fas-carrossel .trilho, .fas-secao--lab .fas-carrossel .trilho { --carrossel-n: 2.15; }
@media (min-width: 48rem) { .fas-secao--guias .fas-carrossel .trilho, .fas-secao--lab .fas-carrossel .trilho { --carrossel-n: 3; } }
@media (min-width: 64rem) { .fas-secao--guias .fas-carrossel .trilho, .fas-secao--lab .fas-carrossel .trilho { --carrossel-n: 4; } }
@media (min-width: 74rem) { .fas-secao--guias .fas-carrossel .trilho, .fas-secao--lab .fas-carrossel .trilho { --carrossel-n: 5; } }

/* ── Card set (CardSet.astro) ── */
/* position: relative é ESTRUTURAL, não decorativo: o .apenas-leitor abaixo
   é absoluto e, sem um contexto aqui, se ancorava no <main> — escapando do
   trilho do carrossel e esticando o documento em ~750px no mobile (caçado
   na revisão mobile de 10/08). */
.fas-set { position: relative; display: flex; flex-direction: column; gap: var(--esp-3); height: 100%; padding: var(--esp-3); overflow: hidden; border: 1px solid var(--cor-borda); border-radius: var(--raio-2); background: var(--cor-superficie); color: var(--cor-texto); transition: border-color var(--dur-rapida) var(--ease-padrao); }
.fas-set:hover { border-color: var(--cor-borda-ativa); color: var(--cor-texto); }
/* Capa sangrada: colada nas bordas do card, sem moldura — padrão de 10/08.
   Quem arredonda os cantos é o overflow do card. */
.fas-set .capa { position: relative; margin: calc(var(--esp-3) * -1) calc(var(--esp-3) * -1) 0; }
/* A caixa é 16:9 e a capa cobre recortando o excesso, como nos cards de
   evento e banner.

   `height: auto` é OBRIGATÓRIO e não decorativo: o <img> carrega
   .fas-set `height="360"` como ATRIBUTO (que reserva espaço e evita salto de layout),
   e sem anular a altura no CSS o atributo ganha do `aspect-ratio` — a caixa
   virava 350x360, quase quadrada, com tarjas da miniatura à mostra (apontado
   pelo dono em 27/08). Mesma linha, com o mesmo motivo, existe no
   CardEvento. */
.fas-set .foto { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; object-fit: cover; background: rgb(18 7 38); }
.fas-set .play { position: absolute; inset: 50% auto auto 50%; translate: -50% -50%; display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 50%; background: var(--cor-overlay); color: #fff; }
/* Duas linhas, os mesmos tamanhos e o mesmo gap do rodapé do card de
   .fas-set evento: é isso que faz os dois cards terem a MESMA altura no carrossel,
   sem piso artificial nenhum. O e2e compara as duas alturas, então mexer na
   tipografia de um dos cards sem revisar o outro quebra o teste, não o
   layout em produção. */
.fas-set .corpo { display: flex; flex-direction: column; gap: var(--esp-1); padding: 0 var(--esp-2) var(--esp-2); }
/* Mesmos tamanhos do card de evento: título em --texto-mini e subtítulo em
   --texto-rotulo com a cor suave.

   O título é cortado em UMA linha com reticências (decisão do dono em
   27/08): título de vídeo do YouTube é comprido por natureza, e deixá-lo
   quebrar faria cada card do carrossel ter uma altura diferente. `min-width:
   0` no flex é o que permite o corte acontecer — sem ele o item não encolhe
   abaixo do próprio conteúdo e o ellipsis nunca aparece. */
.fas-set .titulo {
  min-width: 0;
  font-size: var(--texto-pequeno);
  font-weight: var(--peso-forte);
  letter-spacing: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fas-set .categoria {
  min-width: 0;
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fas-set .apenas-leitor { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ── Card evento (CardEvento.astro) ── */
/* position: relative é ESTRUTURAL: sem ele o .apenas-leitor absoluto se
   ancora no <main> e escapa do trilho do carrossel. */
.fas-evento {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  height: 100%;
  padding: var(--esp-3);
  overflow: hidden;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  background: var(--cor-superficie);
  color: var(--cor-texto);
  text-decoration: none;
  transition: border-color var(--dur-rapida) var(--ease-padrao);
}
.fas-evento:hover {
  border-color: var(--cor-borda-ativa);
  color: var(--cor-texto);
}

/* Capa da foto 16:9 colada nas bordas superiores do card */
.fas-evento .midia {
  position: relative;
  margin: calc(var(--esp-3) * -1) calc(var(--esp-3) * -1) 0;
}
.fas-evento .midia [data-foto-pendente],
.fas-evento .foto {
  border-radius: 0;
}
/* A caixa é 16:9 e a foto cobre recortando o excesso: a proporção é do
   CARD, nunca do arquivo — é o que permite subir a imagem que se tem sem
   precisar cortá-la antes. Mesma regra do CardBanner. */
.fas-evento .foto {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  object-fit: cover;
}

/* Contêiner de caixinhas sobrepostas no canto inferior esquerdo da foto */
.fas-evento .quandos {
  position: absolute;
  inset: auto auto var(--esp-2) var(--esp-2);
  z-index: 2;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;
}

/* Caixinha de data com dimensões e proporções padronizadas */
.fas-evento .caixa-data {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 3.125rem;
  min-width: 3.125rem;
  max-width: 3.125rem;
  padding: 5px 2px;
  border: 1px solid var(--cor-borda-ativa);
  border-radius: var(--raio-1);
  background: rgb(10 3 26 / .88);
  backdrop-filter: blur(8px);
  text-align: center;
  box-shadow: 0 4px 14px rgb(0 0 0 / .6);
  transition: border-color var(--dur-rapida) var(--ease-padrao);
}
.fas-evento:hover .caixa-data {
  border-color: var(--cor-acento);
}

/* Dia — mesma tipografia, tamanho e peso em todas as caixinhas */
.fas-evento .dia {
  font-size: 1rem;
  font-weight: var(--peso-display);
  line-height: 1.05;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* Mês — acento temático em ciano */
.fas-evento .mes {
  color: var(--cor-acento);
  font-size: 0.625rem;
  font-weight: var(--peso-display);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 1px;
}

/* Linha fina divisória para datas em meses diferentes */
.fas-evento .linha {
  width: 70%;
  border: 0;
  border-top: 1px solid rgb(214 168 255 / .3);
  margin: 2px 0;
}

/* Ano — texto suave */
.fas-evento .ano {
  color: var(--cor-texto-suave);
  font-size: 0.5625rem;
  font-weight: var(--peso-normal);
  line-height: 1;
  margin-top: 1px;
}

.fas-evento .quem {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
  padding: 0 var(--esp-1) var(--esp-1);
}
.fas-evento .titulo {
  font-size: var(--texto-pequeno);
  font-weight: var(--peso-forte);
  letter-spacing: normal;
  text-wrap: pretty;
}
.fas-evento .local {
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
}
.fas-evento .apenas-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (min-width: 48rem) {
  .fas-evento .quandos {
    inset: auto auto var(--esp-3) var(--esp-3);
    gap: 8px;
  }
  .fas-evento .caixa-data {
    width: 3.5rem;
    min-width: 3.5rem;
    max-width: 3.5rem;
    padding: 6px 3px;
  }
  .fas-evento .dia {
    font-size: 1.125rem;
  }
  .fas-evento .mes {
    font-size: 0.6875rem;
  }
  .fas-evento .ano {
    font-size: 0.625rem;
  }
  .fas-evento .quem {
    padding: 0 var(--esp-2) var(--esp-2);
  }
}

/* ── Selo (Selo.astro) ── */
.fas-selo {
  display: inline-flex;
  align-items: center;
  padding: var(--esp-1) var(--esp-3);
  border: 1px solid currentColor;
  border-radius: var(--raio-pill);
}
/* Seis tons para dez selos. Os três estados de janela aberta compartilham o
   ciano de ação do site, e os três de espera o cinza de "ainda não há nada
   para fazer": quem lê de relance precisa distinguir família, não entrada. */
.fas-selo--espera { color: var(--cor-texto-suave); }
.fas-selo--aberto { color: var(--cor-acento); }
.fas-selo--parcial { color: var(--cor-realce); }
.fas-selo--esgotado { color: var(--cor-alerta); }
.fas-selo--vivo { color: var(--cor-vivo); }
.fas-selo--fim { color: var(--cor-texto-suave); opacity: .7; }

/* ── Card edição (CardEdicao.astro) ── */
.fas-edicao {
  display: grid;
  /* minmax(0, 1fr), e não a coluna `auto` implícita: com `auto` a coluna nasce do min-content dos filhos, e em
     telas de 320 o trilho de fotos e o painel de datas pediam ~300px num card de 288. O grid obedecia a eles,
     não ao card; o overflow: hidden cortava a sobra pela direita e todo o miolo perdia o recuo daquele lado, o
     que parecia "card descentralizado" (21/09, revisão em 320). Com o piso zero a coluna é a largura do card
     e quem tem de caber, cabe. */
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-2);
  overflow: hidden;
  background: linear-gradient(150deg, rgb(30 15 69 / .94), rgb(21 9 49 / .94));
  box-shadow: var(--sombra-card);
}
.fas-edicao--destaque { border-color: var(--cor-borda-ativa); }

.fas-edicao .corpo { display: flex; flex-direction: column; gap: var(--esp-4); padding: var(--esp-5); }

/* ── A capa e o selo ────────────────────────────────────────────── */
.fas-edicao .capa { position: relative; min-width: 0; }
/* Capa e nome como link para a página do festival: mesmo visual, só o cursor muda. */
.fas-edicao .capa-link { display: block; color: inherit; text-decoration: none; }
.fas-edicao .nome a { color: inherit; text-decoration: none; }
.fas-edicao .nome a:hover { color: var(--cor-acento); }

/* A foto cobre o espaço da capa recortando o excesso: a proporção é do CARD,
   nunca do arquivo — é o que permite subir a imagem que se tem sem cortá-la
   antes. Aqui o 16:9 é o mesmo piso que o `Placeholder` aplica no mobile; da
   media query de 48rem em diante quem manda é a altura do contêiner, e a
   regra de lá zera este `aspect-ratio` do mesmo jeito que zera o do
   placeholder. */
.fas-edicao .capa-foto {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  object-fit: cover;
  border-radius: 0;
}
/* Rodízio de fotos da edição: trilho com scroll-snap, o mesmo mecanismo do carrossel
   da home (assets/js/carrossel.js), então herda de graça a pausa no mouse e no foco e
   o respeito a prefers-reduced-motion. Só existe com duas fotos ou mais; com uma, a
   capa continua sendo a <img> solta de sempre. */
.fas-edicao .capa-trilho {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}
.fas-edicao .capa-trilho::-webkit-scrollbar { display: none; }
.fas-edicao .capa-item { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; }
@media (prefers-reduced-motion: reduce) {
  .fas-edicao .capa-trilho { scroll-behavior: auto; }
}

/* Véu no topo da capa: hoje o placeholder é escuro e ele mal aparece; com a
   foto real (um palco estourado de luz, provavelmente) é o que garante que o
   selo continue legível. Fica ABAIXO do selo — ele não tem z-index, o selo
   tem. */
.fas-edicao .capa::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 4.5rem;
  background: linear-gradient(to bottom, rgb(10 3 26 / .6), rgb(10 3 26 / 0));
  pointer-events: none;
}
.fas-edicao .capa .fas-selo {
  position: absolute;
  inset: var(--esp-5) auto auto var(--esp-5);
  z-index: 1;
  /* Vidro fosco: o fundo quase sólido é o que sustenta o contraste da cor do
     selo sobre qualquer foto; o blur é o acabamento. */
  background: rgb(10 3 26 / .82);
  backdrop-filter: blur(10px);
}

.fas-edicao .nome { font-size: var(--texto-titulo-3); }
.fas-edicao .quando { margin-top: var(--esp-1); color: var(--cor-texto-suave); font-size: var(--texto-mini); }
/* A linha de endereço: pin, país, lugar. O flex-wrap deixa o lugar cair para
   a linha de baixo em card estreito sem largar o pin do país. */
.fas-edicao .local {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--esp-2);
  margin-top: var(--esp-2);
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
}
.fas-edicao .pin { align-self: center; flex-shrink: 0; color: var(--cor-acento); opacity: .8; }
.fas-edicao .pais { color: var(--cor-acento); }
.fas-edicao .lugar { opacity: .85; }

.fas-edicao .chamada { display: flex; align-items: center; gap: var(--esp-2); color: var(--cor-texto-suave); }
.fas-edicao .pulso { width: 7px; height: 7px; border-radius: 50%; background: var(--cor-texto-suave); animation: pulsar 1.8s var(--ease-padrao) infinite; }
.fas-edicao .pulso--rolando { background: var(--cor-vivo); }
.fas-edicao .pulso--antes { background: var(--cor-acento); }
.fas-edicao .pulso--intervalo-semana, .fas-edicao .pulso--intervalo-dia { background: var(--cor-realce); }
@keyframes pulsar { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.75); } }

/* ── O módulo de estado ─────────────────────────────────────────────
   Uma caixa, não um texto solto (13/08). Antes a contagem flutuava no meio
   do corpo, com "COMEÇA EM" colado nos números, e o card SEM contagem
   ("Aguardando anúncio oficial") não tinha estrutura nenhuma no lugar —
   dois cards lado a lado não pareciam a mesma peça. Agora todo estado mora
   na mesma moldura: com contagem ou com frase, o bloco existe e ocupa o
   mesmo lugar na leitura.
   Nível 2 do padrão de superfícies: elemento sobre caixa. */
.fas-edicao .estado {
  display: grid;
  gap: var(--esp-3);
  /* O recuo nasce enxuto e cresce com a tela: a moldura soma 34px ao mínimo
     do card, e numa tela de 320 isso bastava para o conjunto estourar por
     6px. Mesmo corte do Countdown, que também aperta ali. */
  padding: var(--esp-3);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-1);
  background: var(--cor-superficie-alta);
}
@media (min-width: 22rem) {
  .fas-edicao .estado { padding: var(--esp-4); }
}

/* Sem contagem, a frase É o conteúdo do bloco: ganha corpo de título para
   ter a mesma presença que os números teriam. */
.fas-edicao .frase { font-size: var(--texto-titulo-3); font-weight: var(--peso-forte); line-height: var(--altura-apertada); text-wrap: balance; }
/* A secundária acompanha a contagem: nota de rodapé do bloco, nunca título. */
.fas-edicao .frase--secundaria { color: var(--cor-texto-suave); font-size: var(--texto-mini); font-weight: var(--peso-normal); }

/* Links de ação da edição: links textuais discretos, lado a lado, com ícone de link externo */
.fas-edicao .acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-2) var(--esp-4);
  border-top: 1px solid var(--cor-borda);
  padding-top: var(--esp-3);
}
.fas-edicao .acao {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: var(--esp-1) 0;
  color: var(--cor-texto-suave);
  font-family: inherit;
  font-size: var(--texto-rotulo);
  font-weight: var(--peso-medio);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-rapida) var(--ease-padrao);
}
.fas-edicao .acao:hover {
  color: var(--cor-texto);
}
.fas-edicao .acao span {
  text-decoration: underline;
  text-decoration-color: rgb(214 168 255 / .25);
  text-underline-offset: 3px;
  transition: text-decoration-color var(--dur-rapida) var(--ease-padrao);
}
.fas-edicao .acao:hover span {
  text-decoration-color: var(--cor-borda-ativa);
}
.fas-edicao .icone-ext {
  flex-shrink: 0;
  opacity: .7;
  transition: opacity var(--dur-rapida) var(--ease-padrao), transform var(--dur-rapida) var(--ease-padrao);
}
.fas-edicao .acao:hover .icone-ext {
  opacity: 1;
  transform: translate(1px, -1px);
  color: var(--cor-acento);
}

.fas-edicao .acao--vivo {
  color: var(--cor-alerta);
}
.fas-edicao .acao--vivo:hover {
  color: #fff;
}
.fas-edicao .acao--vivo span {
  text-decoration-color: rgb(255 64 208 / .4);
}
/* "Ver tudo sobre": nossa página do festival. Sempre o último da linha, em ciano,
   empurrado para a ponta direita para não se misturar com os links oficiais. */

/* "Ver detalhes": primeiro da fileira e em ciano de ação, sem ícone (é link interno; a seta externa é dos oficiais). */
.fas-edicao .acao--festival { color: var(--cor-acento); font-weight: var(--peso-forte); }
.fas-edicao .acao--festival span { text-decoration-color: rgb(121 226 255 / .35); }
.fas-edicao .acao--festival:hover { color: #fff; }
.fas-edicao .acao--festival:hover span { text-decoration-color: var(--cor-acento); }

/* ── A faixa de expansão ─────────────────────────────────────────
   Última linha do card, de ponta a ponta. Não pende nem sobra: o
   `overflow: hidden` do card recorta os cantos, então o contorno
   arredondado continua contínuo. É a gaveta do card — clique em qualquer
   ponto da largura abre as datas. */
.fas-edicao .faixa {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  width: 100%;
  /* 44px de área de toque, como todo controle do site. */
  min-height: 2.75rem;
  padding: var(--esp-2) var(--esp-4);
  border: 0;
  border-top: 1px solid var(--cor-borda);
  background: rgb(21 9 49 / .8);
  color: var(--cor-texto-suave);
  font-family: inherit;
  /* Etiqueta, não botão: em texto-mini a faixa competia com o nome da
     edição (apontado em 11/08). Caixa alta miúda com tracking é o mesmo
     idioma de COMEÇA EM e LINKS ÚTEIS — presente sem gritar. */
  font-size: var(--texto-rotulo);
  font-weight: var(--peso-forte);
  letter-spacing: var(--tracking-rotulo);
  text-transform: uppercase;
  text-align: center;
  cursor: pointer;
  transition: background var(--dur-rapida) var(--ease-padrao),
              color var(--dur-rapida) var(--ease-padrao);
}
.fas-edicao .faixa:hover { background: rgb(126 74 255 / .15); color: var(--cor-texto); }
.fas-edicao .faixa svg {
  flex-shrink: 0;
  color: var(--cor-acento);
  transition: rotate var(--dur-media) var(--ease-padrao);
}
.fas-edicao .faixa[aria-expanded='true'] svg { rotate: 180deg; }

@media (prefers-reduced-motion: reduce) {
  .fas-edicao .faixa svg { transition: none; }
}

/* A foto lado a lado, terceira correção de 10/08 — agora com PADRÃO entre
   os cards, exigência do dono do projeto: a coluna da foto tem a MESMA
   largura em todos (52%), tenha o card contagem ou não. A versão anterior
   derivava a largura da altura do card, e o card sem contagem (mais baixo)
   ganhava foto mais estreita que o vizinho.

   Com a largura fixa, o 16:9 da capa vira o PISO de altura do card: quem
   tem menos conteúdo (Bélgica 2027, sem datas) cresce até ele e o corpo
   centra na vertical; quem tem contagem já chega nessa altura. Se um corpo
   um dia passar do piso, a capa estica um pouco além de 16:9 — invisível
   no placeholder, e com foto real é o corte que object-fit: cover faria.

   O ponto de virada é 72rem: MEDIDO em 820px e 1024px, "16:9 + texto
   .fas-edicao legível" não tem solução lado a lado. Abaixo disso a foto fica em cima,
   largura cheia, 16:9 exato. */
/* Do tablet pra cima a foto vai para o lado. Antes isso só acontecia a
   partir de 72rem, e entre 48 e 72rem o card virava uma coluna com a capa
   16:9 de largura cheia — 400px de placeholder vazio em 768px (revisão
   responsiva de 11/08). A coluna da foto nasce estreita (40%) e engorda
   para 52% quando há largura de sobra. */
@media (min-width: 48rem) {
  .fas-edicao { grid-template-columns: 40% minmax(0, 1fr); }
  /* 16:9 é PISO: quando o corpo é mais alto, o grid estica a capa e o
     placeholder acompanha (height 100% + aspect-ratio auto). O align-self
     explícito é obrigatório: para item de grid com aspect-ratio, o alinhamento
     padrão (`normal`) vale como `start`, não como `stretch`: bastou o corpo
     ficar 32px mais alto que a foto para aparecer um vão entre ela e a
     faixa (21/09). */
  .fas-edicao .capa { aspect-ratio: 16 / 9; align-self: stretch; }
  .fas-edicao .capa [data-foto-pendente],
  .fas-edicao .capa-foto { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
  /* height: 100% da foto precisa de pai com altura: sem estas duas linhas a cadeia
     quebra no trilho e a capa volta a 16:9 no meio da coluna lado a lado. */
  .fas-edicao .capa-trilho, .fas-edicao .capa-item, .fas-edicao .capa-item > .capa-link { height: 100%; }
  .fas-edicao .corpo { justify-content: center; }
  .fas-edicao .acao { font-size: var(--texto-mini); }
  /* O painel de datas (slot) e a faixa ocupam a linha inteira — sem isto o
     grid os colocaria na coluna da foto, espremidos. */
  .fas-edicao > .fas-painel { grid-column: 1 / -1; }
  .fas-edicao .faixa { grid-column: 1 / -1; }
}

@media (min-width: 72rem) {
  .fas-edicao { grid-template-columns: 52% minmax(0, 1fr); }
}

/* ── Contagem (Countdown.astro) ── */
.fas-contagem {
  display: flex;
  align-items: flex-end;
  gap: var(--esp-2);
  /* Sem max-width (Restrição Global 4): a largura é a do container do
     card, que já é o limite real. */
}
/* O piso de cada bloco nasce em 2.75rem e só sobe onde há largura (13/08).
   Com 3.25rem fixos a fileira pedia 260px de mínimo — quatro blocos, três
   divisores e seis vãos — contra os 248px que sobram dentro do card numa
   tela de 320. O card estourava 12px, o `overflow: hidden` dele cortava, e
   quem perdia o recuo direito era TUDO que mora ali dentro, inclusive as
   linhas do painel de datas. O valor não sofre: em 320px ele renderiza a
   ~29px (9vw) e dois dígitos cabem folgados em 44. */
.fas-contagem .bloco { flex: 1 1 auto; display: grid; justify-items: center; min-width: 2.75rem; }
/* Abaixo de 22rem (352px) o vão entre blocos cai para 4px: com o card em 288 sobram ~220px para a fileira, e
   com o vão de 8 ela ainda passava 2px em 320 e 15px em 305 (320 com barra de rolagem clássica). */
@media (max-width: 21.99rem) {
  .fas-contagem { gap: var(--esp-1); }
  .fas-contagem .divisor { margin-inline: 2px; }
}
@media (min-width: 22rem) {
  .fas-contagem .bloco { min-width: 3.25rem; }
}
.fas-contagem .valor {
  font-size: clamp(1.75rem, 9vw, 3.25rem);
  font-weight: var(--peso-display);
  line-height: 1;
  /* tabular-nums é o que impede o card de tremer a cada segundo: sem isso,
     a largura do "1" e do "8" difere e a linha inteira se reposiciona. */
  font-variant-numeric: tabular-nums;
}
.fas-contagem .bloco--vivo .valor { color: var(--cor-acento); }
.fas-contagem .unidade { margin-top: var(--esp-2); color: var(--cor-texto-suave); }
.fas-contagem .divisor { width: 1px; height: 2rem; margin-bottom: 1.1rem; background: var(--cor-borda); }

.fas-contagem.contagem--chegou { font-size: var(--texto-titulo-3); font-weight: var(--peso-forte); color: var(--cor-acento); }

/* ── Painel de datas (PillsDeData.astro) ── */
/* Vidro fosco: um painel aberto por vez, pode pagar o blur do header. */
/* Recuo lateral ENXUTO no mobile (13/08), não ausente: os 20px de cada lado
   tiravam 40px da largura útil das linhas justo onde ela é escassa — a data
   .fas-painel quebrava em duas dentro do card enquanto no cronograma, .fas-painel na mesma tela,
   cabia inteira. Zerar resolvia a largura e estragava o resto: as linhas
   encostavam na borda do card. Com 12px sobra respiro, e a largura que
   falta vem do outro lado — a própria linha fica mais compacta em contêiner
   estreito (LinhaDeData). Da largura de tablet em diante o recuo cheio
   volta, que é onde ele é folga e não aperto. */
.fas-painel {
  border-top: 1px solid var(--cor-borda);
  background: rgb(18 7 38 / .6);
  backdrop-filter: blur(10px);
  padding-block: var(--esp-4);
  padding-inline: var(--esp-3);
}
@media (min-width: 40rem) {
  .fas-painel { padding-inline: var(--esp-5); }
}
/* [hidden] com display:grid no mesmo elemento: sem isso o grid ganha e o
   painel fica visível apesar do atributo. */
.fas-painel[hidden] { display: none; }

/* Quem perdeu o recuo do painel foram só as LINHAS, que precisam da largura.
   O cabeçalho é texto solto e continua recuado — colado na borda ele leria
   como se fosse de outro bloco. */
.fas-painel .cabecalho-painel { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--esp-3); margin-bottom: var(--esp-4); padding-inline: var(--esp-2); }
@media (min-width: 40rem) {
  .fas-painel .cabecalho-painel { padding-inline: 0; }
}
.fas-painel .rotulo { color: var(--cor-texto-suave); }
.fas-painel .fuso { color: var(--cor-texto-suave); font-size: var(--texto-rotulo); opacity: .75; }
.fas-painel .sem-datas { display: grid; justify-items: center; gap: var(--esp-2); padding: var(--esp-6) var(--esp-4); text-align: center; }
.fas-painel .sem-datas__titulo { font-size: var(--texto-mini); color: var(--cor-texto-suave); text-wrap: pretty; }
.fas-painel .sem-datas__texto { font-size: var(--texto-rotulo); color: var(--cor-texto-suave); text-wrap: pretty; }

/* ── Trilha do tempo (TrilhaDoTempo.astro) ── */
/* A trilha é o CONTÊINER de consulta das linhas de data (13/08). Sem isto,
   LinhaDeData decidia o layout pela largura da TELA — e a mesma linha vive
   em dois lugares de largura bem diferente: solta na largura do conteúdo
   (Cronograma) e espremida dentro do card de edição (PillsDeData). Em
   768px de tela o painel do card tem 628px, e as quatro colunas, que a tela
   dizia caber, davam 114px ao nome do marco. Medindo o contêiner, cada uma
   escolhe o layout pelo espaço que realmente tem.
   Em navegador sem suporte a container queries a consulta nunca casa e as
   linhas ficam no formato empilhado — completo e legível, só menos denso. */
.fas-trilha {
  position: relative;
  display: grid;
  gap: var(--esp-3);
  container-type: inline-size;
  container-name: trilha;
}

/* O fio passa pelo centro dos marcadores (24px de diâmetro, a 0.75rem da
   .fas-trilha esquerda de cada linha; ver LinhaDeData). As pontas somem em transparent,
   então ele pode passar alguns px dos círculos sem aparecer — é o que torna
   a conta imune à altura variável da última linha. */
.fas-trilha::before {
  content: '';
  position: absolute;
  /* O marcador agora é centrado na linha (~4.5rem de altura): o fio começa
     e termina no centro da primeira/última. */
  top: 2.25rem;
  bottom: 2.25rem;
  left: calc(0.75rem - 1px);
  width: 2px;
  background: linear-gradient(
    180deg,
    transparent,
    color-mix(in srgb, var(--fas-ciano) 55%, transparent) 6%,
    color-mix(in srgb, var(--fas-violeta-aurora) 60%, transparent) 45%,
    color-mix(in srgb, var(--fas-rosa-horizonte) 55%, transparent) 94%,
    transparent
  );
}

/* A gota de luz. Anima `top` de propósito: transform exigiria conhecer a
   altura da trilha, e um elemento de 3×36px reposicionado é custo nulo. */
.fas-trilha::after {
  content: '';
  position: absolute;
  top: 2.25rem;
  left: calc(0.75rem - 1.5px);
  width: 3px;
  height: 2.25rem;
  border-radius: var(--raio-pill);
  background: linear-gradient(180deg, transparent, rgb(121 226 255 / .9), transparent);
  filter: drop-shadow(0 0 4px rgb(121 226 255 / .8));
  animation: trilha-pulso 7s ease-in-out infinite;
}
@keyframes trilha-pulso {
  0%   { top: 2.25rem; opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { top: calc(100% - 4.5rem); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fas-trilha::after { display: none; }
}

/* ── Linha de data (LinhaDeData.astro) ── */
.fas-linha { display: flex; gap: var(--esp-3); }
/* display: flex vence o atributo hidden — sem isto, a linha "escondida"
   pelo servidor ficaria visível (mesma armadilha do chip da rádio). */
.fas-linha[hidden] { display: none; }

.fas-linha .marcador {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  /* Centrado na altura da linha (era margin-top fixo — descentrava). */
  align-self: center;
  border: 1.5px solid var(--cor-borda);
  border-radius: 50%;
  /* Fundo sólido + z-index: o fio da TrilhaDoTempo passa por TRÁS do
     círculo, não por dentro dele. */
  position: relative;
  z-index: 1;
  background: var(--fas-fundo);
  color: var(--cor-texto-suave);
}
.fas-linha .ponto { width: 6px; height: 6px; border-radius: 50%; background: var(--fas-violeta-aurora); }
.fas-linha--ativa .marcador { border-color: var(--cor-vivo); color: var(--cor-vivo); }
.fas-linha--proxima .marcador { border-color: var(--cor-acento); color: var(--cor-acento); }
/* Esmaece por COR, não por opacity: opacity no círculo o deixava
   translúcido e o fio/feixe da trilha aparecia através dele. */
.fas-linha--encerrada .marcador,
.fas-linha--esgotada .marcador,
.fas-linha--esgotada-parcialmente .marcador {
  border-color: rgb(126 74 255 / .25);
  color: rgb(201 184 240 / .45);
}

/* MOBILE — DOIS andares, sem nenhuma célula vazia (13/08):
     quando (data + os dois fusos)  ·  situação
     o quê (edição + marco)         ·  ações
   A versão de três andares deixava a base com os botões sozinhos e uma
   faixa morta à esquerda deles. Em dois andares cada linha do grid tem
   conteúdo dos dois lados, e o card ficou 40px mais baixo. */
.fas-linha .conteudo-linha {
  flex: 1;
  min-width: 0;
  display: grid;
  /* A coluna da direita é TRAVADA na largura dos botões, não `auto`. Com
     `auto` ela se media pelo texto da situação — e como cada linha é um
     grid independente, a linha com "Ativa · encerra em 218 dias" abria uma
     coluna de 136px, sobravam 140px à esquerda e "09:00 BRT · 14:00 CEST"
     (138px) quebrava em duas, enquanto a linha vizinha com "em 39 dias"
     ficava inteira. Travada, a esquerda tem sempre a mesma largura, os
     horários cabem numa linha e as colunas de todos os cards alinham entre
     si. A situação, mais curta, quebra em duas linhas compactas — que é o
     que se quer dela num card estreito. */
  grid-template-columns: minmax(0, 1fr) 6rem;
  grid-template-areas:
    'tempo    situacao'
    'conteudo botoes';
  align-items: center;
  gap: var(--esp-3);
  /* Recuo interno enxuto por padrão: dentro do painel de um card a linha
     tem ~100px a menos que no cronograma, e cada pixel de padding sai da
     data. Com 12px em vez de 16 a data cabe numa linha nos dois lugares. */
  padding: var(--esp-3);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-1);
  /* Nível 1 do padrão: a linha toca a nebulosa direto (cronograma) —
     superfície quase-sólida, não a translúcida de elemento-sobre-caixa. */
  background: var(--cor-superficie);
}
.fas-linha--ativa .conteudo-linha { border-color: rgb(124 242 176 / .4); }
.fas-linha--proxima .conteudo-linha { border-color: var(--cor-borda-ativa); }
.fas-linha--encerrada .conteudo-linha,
.fas-linha--esgotada .conteudo-linha,
.fas-linha--esgotada-parcialmente .conteudo-linha { opacity: .62; }

/* Data encerrada não tem botão NENHUM (nem link, nem calendário). No mobile
   não faz sentido reservar a coluna deles: o marco ficava apertado à
   esquerda com 96px de vazio ao lado, e num painel estreito isso é metade
   da linha. Sem botões, a segunda coluna encolhe até o texto da situação e
   o marco toma a largura inteira.
   O layout de quatro colunas mais abaixo tem de repetir este seletor para
   desfazer a regra — tentar resolver por especificidade com `:where` deu
   híbrido: as colunas vinham de lá e as áreas daqui, e a linha inchava para
   178px. */
.fas-linha--encerrada .conteudo-linha,
.fas-linha--esgotada .conteudo-linha,
.fas-linha--esgotada-parcialmente .conteudo-linha {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    'tempo    situacao'
    'conteudo conteudo';
}

.fas-linha .horarios { grid-area: tempo; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.fas-linha .quando { font-size: var(--texto-mini); font-weight: var(--peso-forte); font-variant-numeric: tabular-nums; }
/* Os dois fusos numa linha só: "10:00 BRT · 15:00 CEST".
   O corpo é o MENOR por padrão e cresce quando há espaço — em contêiner
   apertado (o painel dentro de um card de evento, numa tela de 360) a linha
   em 13px não cabia e quebrava em "10:00 BRT ·" / "15:00 CEST", com o
   separador órfão no fim. Em 10px ela cabe inteira. */
.fas-linha .fusos {
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
  font-weight: var(--peso-medio);
  font-variant-numeric: tabular-nums;
  opacity: .95;
}
/* 20rem de contêiner é medido: o painel numa tela de 360 dá 302px de trilha
   e não cabe; o cronograma na mesma tela dá 328 e cabe. Daqui pra cima esta
   linha sobe para o corpo da data — ela é informação de primeira ordem, não
   nota de rodapé: quem está no Brasil precisa do horário daqui. */
@container trilha (min-width: 20rem) {
  .fas-linha .fusos { font-size: var(--texto-mini); }
}
.fas-linha .rotulo-data { grid-area: conteudo; min-width: 0; margin: 0; line-height: 1.25; text-wrap: pretty; }
.fas-linha .edicao-da-data { display: block; color: var(--cor-texto-suave); font-size: var(--texto-rotulo); font-weight: var(--peso-normal); }
.fas-linha .marco { display: block; color: var(--cor-texto); font-size: var(--texto-mini); font-weight: var(--peso-forte); }
/* Peso forte só no mobile: ali a situação é a única informação da direita e
   precisa se sustentar sozinha. No desktop ela é uma coluna entre outras e
   volta ao peso normal, senão briga com o marco.
   Quem define a largura aqui é a coluna travada do grid; o texto longo
   quebra em duas linhas compactas em vez de esticar a coluna. */
.fas-linha .situacao {
  grid-area: situacao;
  align-self: start;
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
  font-weight: var(--peso-forte);
  line-height: 1.2;
  text-align: right;
}
.fas-linha--ativa .situacao { color: var(--cor-vivo); }
.fas-linha--proxima .situacao { color: var(--cor-acento); }

.fas-linha .botoes { grid-area: botoes; align-self: center; display: flex; justify-content: flex-end; gap: var(--esp-2); margin: 0; }
.fas-linha .botao-linha {
  display: grid;
  place-items: center;
  /* 44px: no mockup estes botões tinham 36px. */
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-1);
  background: transparent;
  color: var(--cor-texto-suave);
  cursor: pointer;
  transition: background var(--dur-rapida) var(--ease-padrao), color var(--dur-rapida) var(--ease-padrao);
}
.fas-linha .botao-linha:hover { background: rgb(126 74 255 / .25); color: var(--cor-texto); }
.fas-linha .botao-linha--cal { border-color: rgb(121 226 255 / .35); color: var(--cor-acento); }
.fas-linha .botao-linha--cal[aria-expanded='true'] { background: rgb(121 226 255 / .15); }

/* Menu "Adicionar ao calendário", ancorado no botão. */
.fas-linha .botoes { position: relative; }
.fas-cal-menu {
  position: absolute; top: calc(100% + var(--esp-2)); right: 0; z-index: 20;
  display: grid; gap: 2px; width: min(17rem, 78vw); padding: var(--esp-2);
  border: 1px solid var(--cor-borda-ativa); border-radius: var(--raio-1);
  background: rgb(21 9 49 / .98); box-shadow: var(--sombra-card);
}
.fas-cal-menu__item { display: grid; grid-template-columns: 1fr auto; align-items: baseline; column-gap: var(--esp-2); padding: var(--esp-2) var(--esp-3); border-radius: calc(var(--raio-1) - 4px); color: var(--cor-texto); font-size: var(--texto-mini); font-weight: var(--peso-medio); text-decoration: none; }
.fas-cal-menu__item:hover, .fas-cal-menu__item:focus-visible { background: rgb(126 74 255 / .25); color: #fff; outline: none; }
.fas-cal-menu__item--destaque { grid-template-columns: 1fr; color: var(--cor-acento); font-weight: var(--peso-forte); border-bottom: 1px solid var(--cor-borda); border-radius: calc(var(--raio-1) - 4px) calc(var(--raio-1) - 4px) 0 0; padding-bottom: var(--esp-3); margin-bottom: var(--esp-1); }
.fas-cal-menu__dica { color: var(--cor-texto-suave); font-size: var(--texto-rotulo); font-weight: var(--peso-normal); }
/* O último link não fecha com linha: quem separa de "Outras opções" é a borda do próprio botão (evita linha dupla). */
.fas-cal-menu > a:last-of-type { border-bottom: 0; margin-bottom: 0; }
.fas-cal-menu__mais { margin-top: var(--esp-1); padding: var(--esp-2) var(--esp-3); border: 0; border-top: 1px solid var(--cor-borda); background: none; color: var(--cor-texto-suave); font-family: inherit; font-size: var(--texto-rotulo); text-align: left; cursor: pointer; }
.fas-cal-menu__mais:hover, .fas-cal-menu__mais:focus-visible { color: var(--cor-texto); outline: none; }

/* Onde há largura de sobra, o recuo interno volta ao cheio. O corte é de
   contêiner: uma trilha de 24rem é o ponto em que os 4px a mais de cada
   lado deixam de custar uma quebra na data. */
@container trilha (min-width: 24rem) {
  .fas-linha .conteudo-linha { padding: var(--esp-3) var(--esp-4); }
}

/* LARGO — quatro colunas de largura DECLARADA, não `auto` (13/08). Com
   `auto auto` no fim, cada linha media as próprias colunas: uma data sem
   link oficial tem um botão a menos, a coluna encolhia e a situação
   escorregava para a direita — nenhuma linha alinhava com a de cima.
   Agora as quatro colunas são as mesmas em todas as linhas:
     horários  ·  marco (1fr, absorve a sobra)  ·  situação  ·  ações
   A coluna de ações tem largura travada mesmo quando só há um botão — ou
   nenhum, no caso das datas encerradas. 6rem e não 5.75rem porque é o que
   dois botões de 44px com o vão de 8px realmente medem; 5.75rem estouraria
   a coluna em 4px.
   O corte é DE CONTÊINER, não de tela, e é 44rem porque é onde as quatro
   colunas fecham a conta com este teto: 13rem + 8.5rem + 6rem e os vãos
   consomem 488px, e é preciso sobrar ~145px para o nome do marco. Num
   contêiner de 659px (uma tela de 700) o marco caía para 101px e as alturas
   voltavam a desencontrar — 83, 99 e 70px na mesma lista. Abaixo daqui o
   empilhamento de dois andares serve melhor.
   O teto da primeira coluna é medido, não chutado: a data mais longa do
   .fas-linha acervo ("10 de novembro de 2026") pede 160px e a linha dos dois fusos,
   agora em corpo maior, pede 138px. Com esse teto a data nunca quebra em
   duas linhas e TODAS as linhas saem com a mesma altura. */
@container trilha (min-width: 44rem) {
  /* As encerradas voltam para as quatro colunas: aqui a coluna de ações
     reservada é justamente o que mantém todas as linhas alinhadas, mesmo
     vazia. */
  .fas-linha .conteudo-linha,
  .fas-linha--encerrada .conteudo-linha,
  .fas-linha--esgotada .conteudo-linha,
  .fas-linha--esgotada-parcialmente .conteudo-linha {
    grid-template-columns: minmax(11rem, 13rem) 1fr minmax(8.5rem, auto) 6rem;
    grid-template-areas: 'tempo conteudo situacao botoes';
    align-items: center;
    gap: var(--esp-4);
  }
  .fas-linha .horarios { gap: 2px; }
  /* Aqui a situação volta a ser uma coluna do grid: o teto e o alinhamento
     ao topo são recursos do empilhamento mobile e sairiam do lugar numa
     linha única. */
  .fas-linha .situacao { align-self: auto; font-weight: var(--peso-normal); }
  /* A altura do botão vira o piso da linha mesmo quando não há botão
     nenhum: sem isso, as datas encerradas ficavam 7px mais baixas que as
     demais e a lista perdia o ritmo. No mobile o piso não entra — ali uma
     faixa vazia de 44px seria só espaço morto. */
  .fas-linha .botoes { width: 6rem; min-height: 2.75rem; }
}

/* ── Cronograma (Cronograma.astro) ── */
.fas-cronograma { display: grid; gap: var(--esp-3); }
/* Centrada sob o título da seção (13/08): é legenda do bloco inteiro, não
   da primeira linha. À esquerda ela parecia pertencer à data de cima. */
.fas-cronograma .fuso {
  color: var(--cor-texto-suave);
  font-size: var(--texto-rotulo);
  opacity: .75;
  text-align: center;
  margin-bottom: var(--esp-4);
}
/* O botão de expandir datas:
   No mobile (< 48rem): centralizado para fechar o bloco com equilíbrio.
   No tablet/desk (>= 48rem): à direita, alinhado ao padrão dos links de seção. */
.fas-cronograma .mais {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  min-height: 2.75rem;
  padding: var(--esp-2) var(--esp-3);
  border: 0;
  border-radius: var(--raio-pill);
  background: none;
  color: var(--tom-secao, var(--cor-acento));
  font-family: inherit;
  font-size: var(--texto-mini);
  font-weight: var(--peso-forte);
  cursor: pointer;
  transition: color var(--dur-rapida) var(--ease-padrao),
              filter var(--dur-rapida) var(--ease-padrao),
              transform var(--dur-rapida) var(--ease-padrao);
}
.fas-cronograma .mais:hover {
  filter: brightness(1.2);
  color: var(--cor-texto);
}
.fas-cronograma .mais:active {
  transform: scale(0.97);
}
.fas-cronograma .mais svg {
  flex-shrink: 0;
  transition: transform var(--dur-rapida) var(--ease-padrao);
}
.fas-cronograma .mais:hover svg {
  transform: translateX(4px);
}
.fas-cronograma .mais[hidden] { display: none; }

@media (min-width: 48rem) {
  .fas-cronograma .mais {
    justify-self: end;
    padding-inline: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fas-cronograma .mais,
  .fas-cronograma .mais svg {
    transition: none;
    transform: none;
  }
  .fas-cronograma .mais:hover svg {
    transform: none;
  }
}

/* ── Mural dos fãs (MuralDeFas.astro) ── */
.fas-ceu .mural {
  display: grid;
  gap: var(--esp-6);
  justify-items: center;
  width: 100%;
}

.fas-ceu {
  position: relative;
  width: 100%;
  min-height: clamp(19rem, 46vw, 25rem);
  overflow: hidden;
  border: 1px solid rgb(214 168 255 / .32);
  border-radius: var(--raio-2);
  box-shadow: var(--sombra-card);
  background: rgb(10 3 26);
}

/* O palco de mídia: atmosfera noturna com poeira estelar suave.
   Qualquer <img>/<video> colocado no palco cobrirá o fundo, preservando
   o contraste das borboletas. */
.fas-ceu .palco {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(1.5px 1.5px at 12% 24%, rgb(233 221 255 / .6), transparent),
    radial-gradient(1px 1px at 28% 62%, rgb(233 221 255 / .45), transparent),
    radial-gradient(1.5px 1.5px at 43% 14%, rgb(121 226 255 / .5), transparent),
    radial-gradient(1px 1px at 58% 48%, rgb(233 221 255 / .4), transparent),
    radial-gradient(1.5px 1.5px at 71% 27%, rgb(233 221 255 / .55), transparent),
    radial-gradient(1px 1px at 84% 66%, rgb(121 226 255 / .45), transparent),
    radial-gradient(1px 1px at 92% 18%, rgb(233 221 255 / .5), transparent),
    radial-gradient(1.5px 1.5px at 66% 82%, rgb(233 221 255 / .4), transparent),
    radial-gradient(85% 65% at 50% 100%, rgb(255 64 208 / .18), transparent 70%),
    radial-gradient(110% 130% at 50% 0%, rgb(126 74 255 / .3), rgb(10 3 26 / .95) 75%),
    rgb(10 3 26);
}
.fas-ceu .palco img,
.fas-ceu .palco video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* As borboletas voam ACIMA do palco de mídia. */
.fas-ceu .fa { z-index: 1; }

/* O JS escreve só o transform do <li>; o visual mora nos filhos. */
.fas-ceu .fa {
  position: absolute;
  display: grid;
  justify-items: center;
  gap: 6px;
  will-change: transform;
  cursor: default;
}

/* O balão de fala da borboleta: microchip delicado e ultra-compacto no mobile */
.fas-ceu .balao {
  position: relative;
  padding: 1.5px 6px;
  border: 1px solid rgb(214 168 255 / .3);
  border-radius: var(--raio-pill);
  background: rgb(10 3 26 / .86);
  backdrop-filter: blur(8px);
  color: var(--cor-texto);
  font-size: 0.625rem; /* 10px no mobile */
  font-weight: var(--peso-forte);
  letter-spacing: .02em;
  white-space: nowrap;
  transition:
    border-color var(--dur-rapida) var(--ease-padrao),
    box-shadow var(--dur-rapida) var(--ease-padrao),
    color var(--dur-rapida) var(--ease-padrao);
}
.fas-ceu .balao::after {
  content: '';
  position: absolute;
  bottom: -2.5px;
  left: 50%;
  width: 5px;
  height: 5px;
  background: rgb(10 3 26 / .86);
  border-right: 1px solid rgb(214 168 255 / .3);
  border-bottom: 1px solid rgb(214 168 255 / .3);
  transform: translateX(-50%) rotate(45deg);
  transition: border-color var(--dur-rapida) var(--ease-padrao);
}
.fas-ceu .fa:hover .balao {
  border-color: var(--cor-acento);
  box-shadow: 0 0 16px rgb(121 226 255 / .45);
  color: var(--fas-ciano);
}
.fas-ceu .fa:hover .balao::after {
  border-color: var(--cor-acento);
}
.fas-ceu .fa:hover .asa {
  transform: scale(1.15);
}

/* O bater de asas — 28px no celular, 36px no tablet/desk */
/* Asa em 2D, e é de propósito.
   A do fundo (.pagina-cabecalho .pouso) continua 3D: lá são duas borboletas, grandes e quase paradas,
   e o 3D vale a pena. Aqui são até 14, pequenas (28px) e atravessando a tela. `perspective` +
   `preserve-3d` + `rotateY` obrigam o navegador a re-rasterizar a camada a cada giro da asa, e com a
   camada também se deslocando ele não reaproveita nada: o tranco caía exatamente no bater da asa
   (relato do Jordy em 23/09). O `scaleX` faz a mesma leitura visual nesse tamanho, por uma fração do
   custo, e o `rotate` de poucos graus devolve a sensação de profundidade que o 3D dava. */
.fas-ceu .asa {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  flex-shrink: 0;
  transition: transform var(--dur-media) var(--ease-padrao);
}
.fas-ceu .camera {
  display: block;
  width: 100%;
  height: 100%;
}
.fas-ceu .asa .borboleta { display: block; width: 100%; height: 100%; filter: none; }
.fas-ceu .asa .borboleta svg { width: 100%; height: 100%; }
.fas-ceu .asa .asa--esq { animation: mural-asa-esq var(--bate, 2s) ease-in-out infinite var(--defasagem, 0s); }
.fas-ceu .asa .asa--dir { animation: mural-asa-dir var(--bate, 2s) ease-in-out infinite var(--defasagem, 0s); }

@keyframes mural-asa-esq {
  0%, 100% { transform: rotate(2deg)  scaleX(0.96); }
  32%      { transform: rotate(12deg) scaleX(0.64); }
}
@keyframes mural-asa-dir {
  0%, 100% { transform: rotate(-2deg)  scaleX(0.96); }
  32%      { transform: rotate(-12deg) scaleX(0.64); }
}

/* Travessia: cada borboleta entra por um lado, cruza o céu e sai pelo outro, numa altura própria.
   Desenho de 23/09, proposto pelo Jordy. O voo anterior era simulado em JavaScript (vagando, desviando
   umas das outras) e engasgava no celular: o tranco caía sempre no bater da asa, porque a camada
   estava se deslocando E se redesenhando ao mesmo tempo, e o navegador não conseguia reaproveitar o
   desenho pronto. Aqui a travessia é uma animação CSS de duas linhas, que o compositor resolve
   sozinho, e a asa deixou de ser 3D (ver mais abaixo).
   O atraso negativo faz o céu já nascer povoado, em vez de esperar a primeira travessia. Quem sai pelo
   outro lado volta com OUTRO @: home.js troca o nome a cada volta (evento animationiteration), uma
   escrita de texto por travessia, nada por quadro. */
.fas-ceu .fa {
  left: 0;
  animation: mural-travessia var(--dur, 30s) linear var(--atraso, 0s) infinite;
}
@keyframes mural-travessia {
  from { transform: translateX(-100%); }
  to   { transform: translateX(var(--ceu, 100vw)); }
}
.fas-ceu .fa--1 { top: 12%; --dur: 26s; --atraso: -16.1s; --bate: 1.9s; --defasagem: -0.4s; }
.fas-ceu .fa--2 { top: 46%; --dur: 34s; --atraso: -8.0s; --bate: 2.3s; --defasagem: -1.1s; }
.fas-ceu .fa--3 { top: 74%; --dur: 29s; --atraso: -24.8s; --bate: 2.05s; --defasagem: -0.7s; }
.fas-ceu .fa--4 { top: 28%; --dur: 38s; --atraso: -17.9s; --bate: 2.5s; --defasagem: -1.6s; }
.fas-ceu .fa--5 { top: 60%; --dur: 31s; --atraso: -2.8s; --bate: 2.15s; --defasagem: -0.2s; }
.fas-ceu .fa--6 { top: 8%; --dur: 27s; --atraso: -19.1s; --bate: 1.95s; --defasagem: -1.3s; }
.fas-ceu .fa--7 { top: 36%; --dur: 36s; --atraso: -11.7s; --bate: 2.4s; --defasagem: -0.9s; }
.fas-ceu .fa--8 { top: 78%; --dur: 30s; --atraso: -28.3s; --bate: 2.2s; --defasagem: -1.8s; }
.fas-ceu .fa--9 { top: 20%; --dur: 33s; --atraso: -18.5s; --bate: 2.1s; --defasagem: -0.5s; }
.fas-ceu .fa--10 { top: 52%; --dur: 28s; --atraso: -5.0s; --bate: 2.35s; --defasagem: -1.4s; }
.fas-ceu .fa--11 { top: 66%; --dur: 35s; --atraso: -27.9s; --bate: 1.85s; --defasagem: -0.8s; }
.fas-ceu .fa--12 { top: 16%; --dur: 25s; --atraso: -10.4s; --bate: 2.45s; --defasagem: -1.2s; }
.fas-ceu .fa--13 { top: 40%; --dur: 37s; --atraso: -1.3s; --bate: 2.25s; --defasagem: -0.3s; }
.fas-ceu .fa--14 { top: 70%; --dur: 32s; --atraso: -20.9s; --bate: 2.0s; --defasagem: -1.5s; }

/* Escalonamento progressivo de borboletas por largura de tela:
   - < 360px: 3 borboletas
   - >= 360px (22.5rem): 4 borboletas
   - >= 540px (33.75rem): 6 borboletas
   - >= 768px (48rem): 10 borboletas
   - >= 1024px (64rem): 14 borboletas

   Os degraus do celular caíram pela metade em 23/09 (eram 6 e 8). Motivo: cada borboleta é uma camada
   de composição própria (`will-change: transform`) com um subárvore 3D dentro (`perspective` +
   `preserve-3d`) e duas asas animando sem parar, mais um balão com texto. Isso é caro de rasterizar em
   GPU de celular, e o custo cresce com a quantidade. As do fundo (.pagina-cabecalho .pouso) têm a mesma
   estrutura e nunca engasgaram: são 2.
   Antes disto, o voo já tinha saído do thread principal para o compositor (home.js) e o carrossel
   parou de forçar layout (carrossel.js); as duas coisas foram medidas e ajudaram, mas não bastaram no
   aparelho do Jordy. Se ainda travar com 4, a causa não é quantidade e o caminho é outro.
   O desktop não mudou: lá sobra GPU e o céu cheio é o efeito desejado. */
.fas-ceu .fa--4, .fas-ceu .fa--5, .fas-ceu .fa--6, .fas-ceu .fa--7, .fas-ceu .fa--8, .fas-ceu .fa--9, .fas-ceu .fa--10, .fas-ceu .fa--11, .fas-ceu .fa--12, .fas-ceu .fa--13, .fas-ceu .fa--14 { display: none; }
@media (min-width: 22.5rem) {
  .fas-ceu .fa--4 { display: grid; }
}
@media (min-width: 33.75rem) {
  .fas-ceu .fa--5, .fas-ceu .fa--6 { display: grid; }
}
@media (min-width: 48rem) {
  .fas-ceu .fa--7, .fas-ceu .fa--8, .fas-ceu .fa--9, .fas-ceu .fa--10 { display: grid; }
}
@media (min-width: 48rem) {
  .fas-ceu .balao {
    padding: 2px 8px;
    font-size: 0.6875rem; /* 11px no desk */
  }
  .fas-ceu .balao::after {
    width: 6px;
    height: 6px;
    bottom: -3.5px;
  }
  .fas-ceu .asa {
    width: 2.25rem;
    height: 2.25rem;
  }
}
@media (min-width: 64rem) {
  .fas-ceu .fa--11, .fas-ceu .fa--12, .fas-ceu .fa--13, .fas-ceu .fa--14 { display: grid; }
}

@media (prefers-reduced-motion: reduce) {
  .fas-ceu .asa .asa--esq,
  .fas-ceu .asa .asa--dir { animation: none; }
  .fas-ceu .fa:hover .asa { transform: none; }

  /* Sem a travessia, toda borboleta ficaria empilhada em left: 0, uma por cima da outra. Quem pediu
     menos movimento merece o mesmo céu, só parado: aqui elas ganham posição horizontal própria.
     As porcentagens são de `left`, e o translateX negativo tira a borboleta da borda sem transbordar. */
  .fas-ceu .fa { animation: none; transform: translateX(-10%); }
  .fas-ceu .fa--1 { left: 6%; }   .fas-ceu .fa--2 { left: 52%; }  .fas-ceu .fa--3 { left: 22%; }
  .fas-ceu .fa--4 { left: 64%; }  .fas-ceu .fa--5 { left: 12%; }  .fas-ceu .fa--6 { left: 44%; }
  .fas-ceu .fa--7 { left: 30%; }  .fas-ceu .fa--8 { left: 58%; }  .fas-ceu .fa--9 { left: 8%; }
  .fas-ceu .fa--10 { left: 40%; } .fas-ceu .fa--11 { left: 68%; } .fas-ceu .fa--12 { left: 18%; }
  .fas-ceu .fa--13 { left: 48%; } .fas-ceu .fa--14 { left: 26%; }
}

/* ── Mural: rodapé (contagem + botão que substitui o ver-todos) e painel "Quero voar" ── */
.fas-secao--mural .fas-mural-rodape { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--esp-2) var(--esp-4); margin-top: var(--esp-bloco-interno); }
.fas-secao--mural .fas-mural-rodape .ver-todos { margin: 0; border: 0; background: none; font-family: inherit; cursor: pointer; }
.fas-secao--mural .fas-mural-rodape .ver-todos[aria-expanded="true"] svg { transform: rotate(90deg); }
.fas-secao--mural .contagem { margin: 0; color: var(--cor-texto-suave); font-size: var(--texto-mini); }
@media (min-width: 48rem) {
  .fas-secao--mural .fas-mural-rodape { justify-content: space-between; }
  .fas-secao--mural .fas-mural-rodape .ver-todos { margin-left: auto; }
}

/* O painel "Quero voar" é um <dialog>, e tem três estados de vida:
   1. Sem JavaScript: nasce com `open` no HTML e é um bloco na página — é assim que os passos aparecem
      sem script (não há formulário: o cadastro é um direct no Instagram, ver o template).
   2. Com JavaScript, fechado: o JS marca --pronto e chama close(). O `display: none` do próprio
      <dialog> tira o painel do fluxo, e a home para de ser esticada por ele.
   3. Com JavaScript, aberto: --modal, sobreposto, com fundo escurecido. No celular é uma folha que sobe
      do rodapé (cantos redondos só em cima, ao alcance do polegar, respeitando a safe-area do iPhone); a
      partir de 48rem vira um cartão estreito centrado. Uma coluna nas duas larguras: os passos empilham.
   A regra de html.js abaixo cobre o intervalo entre o HTML chegar e o JS rodar: sem ela o painel
   apareceria aberto por um instante e a página daria um pulo — justamente o que o modal resolve.
   O :not() com as duas classes evita empate de especificidade: assim que o JS assume, ela não casa
   mais, e nenhuma das regras depende da ordem em que foi escrita. */
html.js .fas-mural-voar[open]:not(.fas-mural-voar--pronto, .fas-mural-voar--modal) { display: none; }
.fas-mural-voar {
  position: static; width: auto; max-width: none; max-height: none; margin: var(--esp-4) 0 0;
  padding: var(--esp-6); border: 1px solid var(--cor-borda); border-radius: var(--raio-2);
  background: var(--cor-superficie); color: inherit;
}
.fas-mural-voar[open] { display: grid; gap: var(--esp-5); }
.fas-mural-voar--modal {
  position: fixed; inset: auto 0 0; margin: 0 auto; width: 100%;
  max-height: calc(100dvh - var(--esp-8));
  padding: var(--esp-4) var(--esp-5) calc(var(--esp-6) + env(safe-area-inset-bottom, 0px));
  border-bottom: 0; border-radius: var(--raio-2) var(--raio-2) 0 0;
  /* Opaco, e não a --cor-superficie (.9) que vale no fluxo: sobreposto ao corpo da home, o texto de
     trás atravessava o quadro como fantasma. Mesmo problema e mesma saída do menu lateral, na
     revisão mobile de 10/08 — lá está o comentário longo. */
  background: rgb(26 11 61);
  overflow-y: auto; overscroll-behavior: contain;
  box-shadow: 0 -24px 64px rgb(0 0 0 / .5);
}
/* Puxador da folha: só um sinal visual de que é uma folha (o X fecha); some no cartão do desktop. */
.fas-mural-voar--modal::before { content: ''; width: 2.5rem; height: 4px; margin: 0 auto calc(var(--esp-3) * -1); border-radius: var(--raio-pill); background: var(--cor-borda); }
.fas-mural-voar::backdrop { background: rgb(7 2 18 / .6); backdrop-filter: blur(4px); }
.fas-mural-voar--modal[open] { animation: mural-sobe var(--dur-media) var(--ease-padrao); }
@keyframes mural-sobe { from { opacity: 0; translate: 0 var(--esp-8); } to { opacity: 1; translate: 0 0; } }
@keyframes mural-entra { from { opacity: 0; translate: 0 var(--esp-2); } to { opacity: 1; translate: 0 0; } }
@media (min-width: 48rem) {
  .fas-mural-voar--modal {
    inset: 0; margin: auto; width: min(26rem, calc(100% - var(--esp-6)));
    padding: var(--esp-6); border-bottom: 1px solid var(--cor-borda); border-radius: var(--raio-2);
    box-shadow: 0 24px 64px rgb(0 0 0 / .5);
  }
  .fas-mural-voar--modal::before { display: none; }
  .fas-mural-voar--modal[open] { animation: mural-entra var(--dur-rapida) var(--ease-padrao); }
}
@media (prefers-reduced-motion: reduce) { .fas-mural-voar--modal[open] { animation: none; } }
/* O cabeçalho só existe no modal: na página o botão logo acima já diz o mesmo, e não há o que fechar. */
.fas-mural-voar__cabeca { display: none; }
/* Cabeçalho centrado: a borboleta pousada do divisor do rodapé (shell.css, mesma batida de 3,5s) acima do título,
   e o X no canto superior direito, na linha da borboleta — o título, logo abaixo, nunca passa por baixo dele. */
.fas-mural-voar--modal .fas-mural-voar__cabeca { position: relative; display: grid; justify-items: center; gap: var(--esp-2); text-align: center; }
.fas-mural-voar__cabeca-titulo { margin: 0; font-size: var(--texto-titulo-3); letter-spacing: var(--tracking-titulo); line-height: 1.2; text-wrap: balance; }
.fas-mural-voar__pouso { display: block; width: 2.5rem; height: 2.5rem; perspective: 420px; filter: drop-shadow(0 0 6px rgb(150 96 255 / .35)); animation: pouso-corpo 3.5s ease-in-out infinite; }
.fas-mural-voar__pouso .camera { display: block; width: 100%; height: 100%; transform-style: preserve-3d; transform: rotateX(-24deg); }
.fas-mural-voar__pouso .borboleta { display: block; width: 100%; height: 100%; filter: none; }
.fas-mural-voar__pouso .borboleta svg { width: 100%; height: 100%; }
.fas-mural-voar__pouso .asa--esq { animation: pouso-asa-esq 3.5s ease-in-out infinite; }
.fas-mural-voar__pouso .asa--dir { animation: pouso-asa-dir 3.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .fas-mural-voar__pouso, .fas-mural-voar__pouso .asa--esq, .fas-mural-voar__pouso .asa--dir { animation: none; }
}
.fas-mural-voar__fechar {
  position: absolute; top: calc(var(--esp-2) * -1); right: calc(var(--esp-2) * -1);
  display: inline-grid; place-items: center; width: var(--alvo-toque); height: var(--alvo-toque);
  border: 0; border-radius: 50%; background: none; color: var(--cor-texto-suave); cursor: pointer;
}
.fas-mural-voar__fechar:hover { color: var(--cor-acento); }
.fas-mural-voar__fechar:focus-visible { outline: 2px solid var(--cor-borda-ativa); outline-offset: 2px; }
/* Passos em linha do tempo vertical: o número num círculo com o gradiente da ação, e uma linha fina que
   nasce sob ele e vai até o número do passo seguinte (atravessa o gap da lista). O último não a desenha.
   Hierarquia: o título do painel (titulo-3) manda; os passos usam corpo em negrito, com o número ao lado. */
.fas-mural-voar__passos { display: grid; gap: var(--esp-6); margin: 0; padding: 0; list-style: none; }
.fas-mural-voar__passo { position: relative; display: grid; grid-template-columns: 1.75rem minmax(0, 1fr); column-gap: var(--esp-3); align-items: start; }
.fas-mural-voar__passo:not(:last-child)::before {
  content: ''; position: absolute; left: calc(0.875rem - 1px); top: 1.75rem; bottom: calc(var(--esp-6) * -1); width: 2px;
  background: linear-gradient(to bottom, var(--fas-violeta-aurora), var(--cor-borda));
}
.fas-mural-voar__num {
  display: inline-grid; place-items: center; width: 1.75rem; height: 1.75rem; border-radius: 50%;
  background: var(--gradiente-acao); color: var(--fas-lavanda); font-size: var(--texto-mini); font-weight: var(--peso-forte);
  box-shadow: 0 0 0 3px rgb(126 74 255 / .18);
}
.fas-mural-voar__corpo { display: grid; gap: var(--esp-3); min-width: 0; }
.fas-mural-voar__titulo { display: flex; align-items: center; min-height: 1.75rem; margin: 0; font-size: var(--texto-corpo); font-weight: var(--peso-forte); letter-spacing: var(--tracking-titulo); }
.fas-mural-voar__corpo > p { margin: 0; color: var(--cor-texto-suave); font-size: var(--texto-mini); text-wrap: pretty; }
/* Ações de largura total e altura de alvo de toque: no celular a folha é operada com o polegar. Os passos 1 e 2 são
   convite (--leve: contorno); só o direct, que é o que cadastra, leva o gradiente do .botao. */
.fas-mural-voar__acao { display: inline-flex; align-items: center; justify-content: center; gap: var(--esp-2); width: 100%; min-height: var(--alvo-toque); font-size: var(--texto-controle); }
.fas-mural-voar__acao svg { flex: none; }
.fas-mural-voar__acao--leve {
  padding: var(--esp-2) var(--esp-5); border: 1px solid var(--cor-borda); border-radius: var(--raio-pill); background: rgb(126 74 255 / .1);
  color: var(--cor-texto); font-family: inherit; font-weight: var(--peso-forte); line-height: inherit; text-decoration: none; cursor: pointer;
  transition: background var(--dur-rapida) var(--ease-padrao), border-color var(--dur-rapida) var(--ease-padrao);
}
.fas-mural-voar__acao--leve:hover { border-color: var(--cor-borda-ativa); background: rgb(126 74 255 / .22); color: var(--cor-texto); }
.fas-mural-voar__acao--leve:focus-visible { outline: 2px solid var(--cor-borda-ativa); outline-offset: 2px; }
/* Passo 3: a palavra MURAL numa caixa da largura das ações (borda tracejada, como um cupom), que copia ao toque — o
   ícone vira check e "Copiado!" aparece abaixo por 2 s; depois o botão do direct e a nota do tempo até aparecer. */
.fas-mural-voar__palavra-linha { display: grid; justify-items: center; gap: var(--esp-2); margin: 0; }
.fas-mural-voar__palavra {
  display: flex; align-items: center; justify-content: center; gap: var(--esp-3); width: 100%; min-height: 3.25rem; padding: var(--esp-2) var(--esp-4);
  border: 1px dashed var(--cor-borda-ativa); border-radius: var(--raio-1); background: rgb(7 2 18 / .45);
  font: inherit; font-size: var(--texto-titulo-2); font-weight: var(--peso-display); letter-spacing: var(--tracking-rotulo); line-height: 1; cursor: pointer;
  transition: border-color var(--dur-rapida) var(--ease-padrao), box-shadow var(--dur-rapida) var(--ease-padrao);
}
.fas-mural-voar__palavra > span:first-child { color: var(--fas-lavanda); }
.fas-mural-voar__palavra-icone { display: inline-grid; color: var(--cor-texto-suave); }
.fas-mural-voar__palavra-icone svg { grid-area: 1 / 1; }
.fas-mural-voar__palavra-icone svg:last-child { display: none; }
.fas-mural-voar__palavra--copiada { border-style: solid; border-color: var(--cor-acento); }
.fas-mural-voar__palavra--copiada .fas-mural-voar__palavra-icone { color: var(--cor-acento); }
.fas-mural-voar__palavra--copiada .fas-mural-voar__palavra-icone svg:first-child { display: none; }
.fas-mural-voar__palavra--copiada .fas-mural-voar__palavra-icone svg:last-child { display: block; }
.fas-mural-voar__palavra:hover, .fas-mural-voar__palavra:focus-visible { border-color: var(--cor-acento); box-shadow: 0 0 0 3px rgb(121 226 255 / .2); outline: none; }
.fas-mural-voar__copiado { color: var(--cor-acento); font-size: var(--texto-mini); font-weight: var(--peso-forte); }
.fas-mural-voar__copiado:empty { display: none; }
.fas-mural-voar__corpo > .fas-mural-voar__nota { text-align: center; font-size: var(--texto-legenda); }


/* Ajustes locais */
.fas-noticia .data { white-space: nowrap; flex-shrink: 0; }
.fas-noticia .categoria { min-width: 0; }
