/* ══════════════════════════════════════════════════════════
   Missas em Curitiba
   ══════════════════════════════════════════════════════════ */

:root{
  /* Base neutra: preto, branco e o mínimo de cinza possível.
     Cor entra só onde ela informa alguma coisa. */
  --preto:17 17 17;

  /* as únicas cores do site, todas com significado fixo:
     azul = informação · amarelo = atenção · vermelho = apagar */
  --info:#1257a8;      --info-soft:#eef4fd;    --info-linha:#c9dcf6;
  --amarelo:#8a5800;   --amarelo-soft:#fff7e2; --amarelo-linha:#f2dba6;
  --vermelho:#c22c2c;  --vermelho-escuro:#99201f;

  --bone:#ffffff;
  --bone-2:#f6f6f6;
  --cinza:#f2f2f2;                /* caixinhas de horário */
  --paper:#ffffff;
  --ink:#111111;
  --ink-2:rgb(var(--preto) / .8);
  --ink-3:rgb(var(--preto) / .58);
  --line:rgb(var(--preto) / .07);
  --line-2:rgb(var(--preto) / .13);

  --accent:rgb(var(--preto));     /* interface: chips ativos, seleção */
  --accent-soft:rgb(var(--preto) / .06);
  --pin:rgb(var(--preto));        /* pins das paróquias no mapa */
  --blue-rgb:10 132 255;          /* exceção: o azul de "você está aqui" */
  --blue:rgb(var(--blue-rgb));
  /* o mapa é a única superfície com cor própria: azul claro */
  /* em componentes para o degradê das laterais poder usar a mesma cor com transparência */
  --mapa-fundo-rgb:245 251 255;
  --mapa-fundo:rgb(var(--mapa-fundo-rgb));
  --land:#cfe6fa;
  --land-hi:#b2d7f6;

  --r-sm:8px; --r-md:12px; --r-lg:18px;
  --warn-h:26.6px;            /* altura dos avisos — 20% menor que os 33,3px originais */
  --shadow:0 1px 2px rgb(var(--preto) / .05), 0 8px 24px -12px rgb(var(--preto) / .22);
  /* Sem contorno, é a sombra que separa o branco do fundo. Duas camadas: uma rente,
     que marca a borda, e outra larga e fraca, que dá a distância. A versão "alta" é
     para o toque do mouse — o objeto sobe um pouco em vez de ganhar um traço. */
  --relevo:0 1px 2px rgb(var(--preto) / .07), 0 5px 16px -6px rgb(var(--preto) / .2);
  --relevo-alto:0 2px 5px rgb(var(--preto) / .09), 0 12px 26px -8px rgb(var(--preto) / .28);
  /* contorno dos botões que continuam com traço em vez de sombra: mais presente que
     --line-2 (13%), que sumia em tela clara, mas longe do hover — se o repouso já
     estivesse quase preto, escurecer no hover não diria mais nada */
  --linha-botao:rgb(var(--preto) / .3);
  --sans:'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --display:'Bricolage Grotesque', 'Public Sans', sans-serif;
  --top-h:64px;
}

*{box-sizing:border-box}
/* height:100% travava o alcance do position:sticky — com a página rolando no body,
   o cabeçalho descolava depois de ~800 px. min-height resolve e não muda o desktop. */
html,body{min-height:100%}
body{
  margin:0; background:var(--bone); color:var(--ink);
  font-family:var(--sans); font-size:16px; font-weight:300; line-height:1.5;
  -webkit-font-smoothing:antialiased;
  /* mata o zoom por toque duplo, que disparava sem querer ao tocar em cards e chips.
     A pinça continua funcionando: quem precisa aumentar a letra não perde nada. */
  touch-action:manipulation;
}
button,input,textarea,select{font:inherit; color:inherit}
h1,h2,h3,p{margin:0}
strong,b{font-weight:500}   /* o padrão do navegador é 700 */
.so-estreito{display:none}  /* textos curtos, usados só no celular */
svg{display:block}

.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--ink); color:var(--bone); padding:10px 16px; border-radius:0 0 var(--r-sm) 0;
}
.skip:focus{left:0}

/* ─────────────── topo ─────────────── */
.top{
  height:var(--top-h); position:sticky; top:0; z-index:40;
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:0 20px; background:rgb(255 255 255 / .92); backdrop-filter:blur(12px);
  /* mesma linguagem do painel de resultados: sem risco, com sombra — a barra passa a
     parecer apoiada por cima da página, e não colada nela por uma linha */
  box-shadow:0 1px 2px rgb(var(--preto) / .04), 0 5px 16px -6px rgb(var(--preto) / .12);
}
.brand{display:flex; align-items:center; gap:12px; min-width:0}
.brand-mark{width:26px; height:26px; color:var(--accent); flex:none}
.brand-txt{min-width:0}
.brand h1{
  font-family:var(--display); font-size:21px; font-weight:500;
  letter-spacing:-.025em; line-height:1.1; white-space:nowrap;
  font-variation-settings:'opsz' 24;
}
.brand p{font-size:13px; color:var(--ink-3); letter-spacing:.02em; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis}
.top-actions{display:flex; gap:8px; flex:none}

.btn{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  border:1px solid var(--linha-botao); background:var(--paper); color:var(--ink-2);
  padding:8px 13px; border-radius:99px; font-size:13.5px; font-weight:400;
  transition:.15s border-color,.15s color,.15s background;
}
.btn svg{width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round}
.btn:hover{border-color:var(--ink-3); color:var(--ink)}
.btn.is-on{background:var(--accent); border-color:var(--accent); color:#fff}
/* confirmação rápida: o botão fica preto por 1 s depois de copiar */
.btn.is-ok{background:var(--accent); border-color:var(--accent); color:#fff}

/* balão flutuante de confirmação — some sozinho */
/* só a opacidade transiciona: animar o transform brigava com a centralização
   e deixava o balão fora do lugar */
.toast{
  position:fixed; top:calc(var(--top-h) + 14px); left:50%; z-index:60;
  transform:translateX(-50%); opacity:0; pointer-events:none;
  background:var(--ink); color:#fff; border-radius:18px; padding:11px 18px;
  font-size:14px; font-weight:500; line-height:1.4; text-align:center;
  /* max-content mantém as mensagens curtas em uma linha; as longas quebram na tela */
  width:max-content; max-width:min(420px, calc(100vw - 32px));
  box-shadow:var(--shadow); transition:opacity .18s ease;
}
.toast.on{opacity:1}
/* ancorado sob o botão clicado: sem a centralização horizontal */
.toast.ancorado{left:auto; transform:none}

/* ─────────────── shell ─────────────── */
.shell{display:grid; grid-template-columns:38% 62%; height:calc(100dvh - var(--top-h))}
@media (min-width:1500px){ .shell{grid-template-columns:34% 66%} }

/* Três tamanhos de mapa, só no computador — no celular quem manda é a aba de abrir e
   fechar, embaixo do mapa. Por isso a consulta: se alguém amplia o mapa e depois estreita
   a janela, as regras simplesmente deixam de valer, sem deixar o telefone com metade da
   tela em mapa. Dentro dela, estes seletores ganham do bloco de 1500px por especificidade. */
@media (min-width:901px){
  body.mapa-grande .shell{grid-template-columns:66% 34%}
  body.mapa-oculto .shell{grid-template-columns:1fr}
  body.mapa-oculto .map-pane{display:none}
}

/* ─────────────── mapa ─────────────── */
/* fundo opaco: translúcido deixava o conteúdo da lista aparecer por baixo ao rolar */
/* sem risco divisório: quem separa o mapa da lista é a sombra do painel, que sugere
   uma folha apoiada em cima em vez de duas metades coladas */
.map-pane{position:relative; background:var(--mapa-fundo)}

/* aba de abrir/fechar o mapa — só no celular */
.mapa-aba{display:none}
.map-wrap{position:absolute; inset:0; overflow:hidden}
/* arrastar o mapa não pode virar seleção de texto dos nomes de bairro */
#map{
  width:100%; height:100%; touch-action:none; cursor:grab;
  user-select:none; -webkit-user-select:none; -webkit-tap-highlight-color:transparent;
}
#map.is-drag{cursor:grabbing}

.bairro{
  fill:var(--land); stroke:var(--mapa-fundo); stroke-width:1;
  vector-effect:non-scaling-stroke; transition:fill .12s;
}
.bairro.hot{fill:var(--land-hi)}
/* sem cursor próprio: o bairro deixa passar o "grab"/"grabbing" do mapa, que é o
   que a mão está fazendo ali — arrastando, não clicando */
.blabel{
  font-size:10.5px; font-weight:500; letter-spacing:.05em; text-transform:uppercase;
  fill:var(--ink-3); text-anchor:middle; pointer-events:none; opacity:0;
  transition:opacity .2s; paint-order:stroke;
  stroke:var(--mapa-fundo); stroke-width:3px; stroke-linejoin:round;
}
#labels.show .blabel{opacity:.85}

.pin{cursor:pointer}
.pin .halo{fill:var(--accent); opacity:0; transition:opacity .15s}
.pin .body{fill:var(--pin); stroke:var(--mapa-fundo); stroke-width:2}
.pin .igreja{fill:#fff; stroke:none; pointer-events:none}
.pin .pin-nome{
  font-size:11px; font-weight:500; fill:var(--ink); opacity:0; pointer-events:none;
  transition:opacity .15s; paint-order:stroke; stroke:var(--mapa-fundo);
  stroke-width:3.5px; stroke-linejoin:round;
}
.pin:hover .halo,.pin.is-sel .halo,.pin.is-hot .halo{opacity:.24}
.pin:hover .pin-nome,.pin.is-sel .pin-nome,.pin.is-hot .pin-nome{opacity:1}
.pin.is-sel .body,.pin.is-hot .body{fill:var(--info)}
.pin.is-dim{opacity:.22}

/* rolagem no celular: pins das paróquias que estão à vista na lista */
.pin .body{transition:fill .15s, r .15s}
.pin.is-visivel .body{fill:var(--info); r:11.5}
.pin.is-visivel .halo{opacity:.14}
.pin.is-hot .body{r:12.5}
.pin.is-hot .halo{opacity:.3}
.me-dot{fill:var(--blue); stroke:#fff; stroke-width:2.5}
.me-ring{fill:var(--blue); opacity:.18}

.map-ctrl{position:absolute; right:14px; top:14px; display:flex; flex-direction:column; gap:6px}
.btn-sq{
  width:34px; height:34px; display:grid; place-items:center; cursor:pointer;
  background:var(--paper); border:0; border-radius:var(--r-sm);
  /* font-size manda no "+" e no "−", que são texto; os outros dois são desenho */
  color:var(--ink-2); font-size:21px; box-shadow:var(--relevo); transition:.15s;
}
.btn-sq:hover{color:var(--ink); box-shadow:var(--relevo-alto)}
.btn-sq svg{width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round}

/* alterna entre a seta de abrir e a de fechar, conforme o mapa está ampliado */
#zlargo .ic-fechar{display:none}
#zlargo[aria-pressed="true"] .ic-abrir{display:none}
#zlargo[aria-pressed="true"] .ic-fechar{display:block}

/* "Me achar no mapa": no canto oposto ao zoom e com a mesma aparência dos botões
   do mapa — antes era um texto azul na legenda e ninguém entendia que dava para clicar */
/* pílula, como as ações dos cards — o quadrado fica só para os botões de zoom,
   que são ícone puro e vivem empilhados */
.btn-mapa{
  position:absolute; left:14px; top:14px; z-index:5;
  display:inline-flex; align-items:center; gap:7px; height:34px; padding:0 14px;
  cursor:pointer; background:var(--paper); border:0;
  border-radius:99px; color:var(--ink-2); font-size:13px; font-weight:500;
  box-shadow:var(--relevo); transition:.15s; max-width:calc(100% - 28px);
}
.btn-mapa:hover{color:var(--ink); box-shadow:var(--relevo-alto)}
.btn-mapa span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.btn-mapa svg{width:15px; height:15px; flex:none; fill:none; stroke:currentColor;
  stroke-width:1.8; stroke-linecap:round}

/* "Só desta área": mesma casca dos botões do mapa, no canto de baixo para não
   disputar espaço com o "Me achar no mapa" nem com o zoom */
.mapa-check{
  position:absolute; left:14px; bottom:14px; z-index:5;
  display:inline-flex; align-items:center; gap:8px; height:34px; padding:0 14px;
  cursor:pointer; background:var(--paper); border:0;
  border-radius:99px; color:var(--ink-2); font-size:13px; font-weight:500;
  box-shadow:var(--relevo); transition:.15s; white-space:nowrap;
}
.mapa-check:hover{color:var(--ink); box-shadow:var(--relevo-alto)}
.mapa-check input{accent-color:var(--accent); width:15px; height:15px; margin:0; cursor:pointer}

.tip{
  position:absolute; z-index:20; max-width:250px; pointer-events:none;
  background:var(--ink); color:var(--bone); padding:9px 12px; border-radius:var(--r-sm);
  font-size:13.5px; line-height:1.4; box-shadow:var(--shadow);
}
.tip b{display:block; font-weight:500; font-size:13px; margin-bottom:2px}
.tip em{font-style:normal; color:rgb(255 255 255 / .62)}

/* ─────────────── filtros ─────────────── */
.list-pane{display:flex; flex-direction:column; min-height:0; background:var(--bone)}
/* No computador o painel inteiro — filtros e resultados — flutua sobre o mapa.
   position+z-index são necessários: o .map-pane é `relative` e, sem isso, pintaria por
   cima e engoliria justamente a sombra que dá o descolamento. */
@media (min-width:901px){
  /* mesma receita de duas camadas das outras sombras, deitada para a esquerda, só que
     bem mais fraca: uma superfície do tamanho da tela inteira acumula muito mais área
     escura que um card, e na opacidade dos cards virava uma faixa cinzenta no meio da
     página. É a mesma sombra da barra de cima. */
  .list-pane{
    position:relative; z-index:1;
    box-shadow:-1px 0 2px rgb(var(--preto) / .04), -5px 0 16px -6px rgb(var(--preto) / .12);
  }
}
/* Duas camadas com papéis distintos. `.filters` é a FAIXA: fundo branco de ponta a
   ponta, que gruda no topo e esconde os cards passando por baixo. `.filtros-caixa` é
   o DESENHO: o retângulo cinza que diz "isto aqui é um grupo". Separadas porque, com
   uma só, ou a caixa era colada nas bordas (e deixava de ser caixa) ou os cards
   apareciam correndo pelas beiradas dela. */
.filters{padding:14px 20px 0; background:var(--paper); flex:none}
.filtros-caixa{
  display:flex; flex-direction:column; gap:14px;
  padding:14px 16px; border-radius:var(--r-md);
  /* bem mais claro que o dos chips (8%) — eles precisam aparecer por cima dela */
  background:rgb(var(--preto) / .03);
}
/* tudo em linha: cada filtro ocupa uma faixa fina, não um bloco */
.f-line{display:flex; align-items:center; gap:12px; min-height:32px}
.f-line-wrap{flex-wrap:wrap; gap:12px}
.f-label{
  flex:none; width:58px; font-size:11.5px; font-weight:500; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-3);
}
/* mesma linguagem dos selos de bairro e distância: pílula estreita, sem sublinhado */
.linkish{
  flex:none; cursor:pointer; border:0; text-decoration:none;
  background:var(--accent-soft); color:var(--ink-2);
  padding:4px 10px; border-radius:99px;
  font-size:12px; font-weight:400;
  transition:.14s;
}
.linkish:hover{background:var(--cinza); color:var(--ink)}
/* margin-left:auto empurra o "Limpar" para a ponta direita da faixa de filtros */
.linkish-limpar{margin-left:auto; color:var(--vermelho); background:rgb(194 44 44 / .07)}   /* vermelho = apagar */
.linkish-limpar:hover{background:rgb(194 44 44 / .13); color:var(--vermelho-escuro)}

/* buscar por nome é uma das três formas de achar a paróquia, não uma nota de rodapé:
   ganha contorno, tinta cheia e a mesma altura dos chips de período ao lado */
.busca-toggle{
  flex:none; display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  /* mesmo cinza dos botões dos cards: são o mesmo tipo de ação */
  border:1px solid var(--linha-botao); background:var(--paper); color:var(--ink-2);
  min-height:38px; padding:0 14px; border-radius:99px;
  font-size:13.5px; font-weight:500; transition:.14s;
}
.busca-toggle svg{width:15px; height:15px; flex:none; fill:none; stroke:currentColor;
  stroke-width:1.9; stroke-linecap:round}
.busca-toggle:hover{border-color:var(--ink); background:var(--cinza)}
/* No computador ele vive dentro da caixa cinza dos filtros, e ali o branco já basta
   para se destacar — o contorno virava um traço a mais numa faixa que já tem chip
   demais. No celular ele fica: lá não há caixa, seria branco sobre branco.
   Precisa vir DEPOIS da regra base: as duas têm o mesmo peso, e ganha a última. */
/* Sem contorno: ele vive dentro da caixa cinza dos filtros nas duas telas, e ali o
   branco já basta para se destacar — o traço virava mais uma linha numa faixa que já
   tem chip demais. Precisa vir DEPOIS da regra base: as duas têm o mesmo peso, e
   quando isso acontece ganha a última. */
.busca-toggle{border-color:transparent}
.busca-toggle:hover{border-color:var(--ink-3)}

/* Quem pede a localização é o "Me achar no mapa", em cima do mapa, nas duas telas —
   dois botões para a mesma coisa, um deles longe do mapa, só dividiam a atenção.
   O botão continua no HTML, escondido: o código escreve nele os estados
   ("Localizando…", o motivo de uma falha) e quebraria se ele não existisse. */
#btn-geo{display:none}
.busca-toggle[aria-expanded="true"]{display:none}

.search{display:flex; align-items:center; gap:12px}
.search[hidden]{display:none}
.search-campo{position:relative; flex:1; min-width:0}
#busca-fechar{flex:none; white-space:nowrap}
.search-campo > svg{position:absolute; left:11px; top:50%; transform:translateY(-50%);
  width:15px; height:15px; fill:none; stroke:var(--ink-3); stroke-width:1.8; stroke-linecap:round}
#busca-fechar{flex:none; white-space:nowrap}
/* branco e na mesma altura do "Fechar busca" ao lado: os dois formam um par, e dentro
   da caixa cinza dos filtros o campo precisa ser a superfície clara onde se escreve.
   Altura fixa em vez de padding vertical porque `box-sizing:border-box` vale para tudo
   aqui — assim ela bate com a da pílula sem depender da fonte. */
.search input{
  width:100%; height:40px; padding:0 34px; border-radius:99px;
  border:0; background:var(--paper); outline:none; font-size:14px;
}
.search input::-webkit-search-cancel-button{display:none}
.search input:focus{box-shadow:inset 0 0 0 2px var(--accent)}
.busca-x{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  width:22px; height:22px; display:grid; place-items:center; cursor:pointer;
  border:0; background:none; color:var(--ink-3); font-size:18px; line-height:1; border-radius:99px;
}
.busca-x:hover{color:var(--ink); background:var(--bone-2)}
.busca-x[hidden]{display:none}

.chips{display:flex; flex-wrap:wrap; gap:5px; min-width:0}
#dias{flex:1; flex-wrap:nowrap}
#dias button{flex:1; min-width:0; padding-inline:4px; text-align:center}
/* colunas iguais: todos os períodos ficam com a largura do maior ("Qualquer") */
/* --dia-w é medido em tempo de execução: a largura dos chips de dia depende da
   linha inteira, então não dá para reproduzi-la só com CSS */
/* minmax: a coluna acompanha o chip de dia quando há espaço, mas nunca fica menor
   que a própria palavra. Sem isso, com o mapa ampliado a lista estreita e "Qualquer"
   aparecia cortado no meio. */
#periodos{
  display:grid; grid-template-columns:repeat(4, minmax(max-content, var(--dia-w, max-content)));
  width:max-content; max-width:100%;
}
#periodos button{padding-inline:6px; text-align:center}
/* dias e períodos com a mesma altura e alvo de toque confortável (público mais velho) */
.chips button{
  /* mais escuro que o --cinza geral: estes chips agora ficam sobre a caixa cinza dos
     filtros, e no tom antigo os desmarcados quase sumiam contra ela */
  cursor:pointer; border:0; background:rgb(var(--preto) / .08); color:var(--ink-2);
  min-height:38px; padding:0 13px; border-radius:99px;
  font-size:14px; font-weight:400; transition:.13s;
}
.chips button:hover{background:rgb(var(--preto) / .14); color:var(--ink)}
.chips button.is-on{background:var(--accent); border-color:var(--accent); color:#fff; font-weight:500}
.chips button.is-today:not(.is-on){font-weight:500; color:var(--ink)}
.chips-sm button{padding:0 14px}


/* ─────────────── lista ─────────────── */
.scroll{flex:1; min-height:0; overflow-y:auto; scroll-behavior:smooth; overscroll-behavior:contain}

/* aviso fixo acima dos resultados — amarelo: é um alerta, não uma informação neutra */
.aviso{
  display:flex; align-items:center; gap:9px; margin:14px 20px 0;
  background:var(--amarelo-soft); border-radius:99px; padding:3px 8px 3px 16px;
  min-height:var(--warn-h);
  font-size:12px; line-height:1.45; color:var(--amarelo);   /* todo o texto no mesmo amarelo do "Atenção" */
}
.aviso-x{
  flex:none; margin-left:auto; width:26px; height:26px; display:grid; place-items:center;
  cursor:pointer; border:0; background:none; color:var(--amarelo);
  font-size:19px; line-height:1; border-radius:99px; opacity:.65; transition:.14s;
}
.aviso-x:hover{opacity:1; background:rgb(138 88 0 / .1)}
.aviso[hidden]{display:none}
/* saída sozinha depois de um minuto. A altura entra na transição junto com a opacidade,
   senão a lista daria um salto no instante em que ele some. O max-height de partida é
   medido no JS: em CSS não dá para animar a partir de uma altura automática. */
.aviso{transition:opacity .4s, max-height .4s, margin .4s, padding .4s}
.aviso.saiu{
  opacity:0; pointer-events:none; overflow:hidden;
  max-height:0 !important; min-height:0; margin-top:0; padding-top:0; padding-bottom:0;
}

/* cabe em uma linha no desktop; no celular quebra normalmente, sem cortar texto */
@media (min-width:1460px){ .aviso{white-space:nowrap} }

/* ── o aviso como balão sobre o mapa ──────────────────────────────
   Ele deixa de ocupar uma faixa da lista e passa a flutuar, some sozinho e só aparece
   na primeira visita. No computador fica no canto de baixo à direita do mapa, longe do
   "Me achar no mapa" (em cima, à esquerda), do zoom (em cima, à direita) e do "Só desta
   área" (embaixo, à esquerda). O JS move o elemento para dentro do .map-pane. */
.aviso.flutua{
  position:absolute; right:14px; bottom:14px; left:auto; z-index:6;
  /* estreito de propósito: encostado à direita, deixa livre o canto de baixo à
     esquerda, onde mora o "Só desta área" */
  margin:0; max-width:min(330px, calc(100% - 28px)); white-space:normal;
  padding:7px 8px 9px 12px; border-radius:14px;
  box-shadow:var(--relevo); overflow:hidden;
}
/* barra de tempo: encolhe da largura toda até zero enquanto o balão está na tela,
   para o sumiço não pegar ninguém de surpresa no meio da leitura */
.aviso.flutua::after{
  content:''; position:absolute; left:0; bottom:0; width:100%; height:3px;
  background:var(--amarelo); opacity:.45; transform-origin:left center;
  animation:aviso-tempo var(--aviso-ms, 10s) linear forwards;
}
@keyframes aviso-tempo{ from{transform:scaleX(1)} to{transform:scaleX(0)} }
.aviso svg{flex:none; width:15px; height:15px; fill:none;
  stroke:var(--amarelo); stroke-width:1.9; stroke-linecap:round}
.aviso strong{font-weight:500}   /* a cor já vem do .aviso */
/* Faixa branca inteira, não um degradê. O degradê deixava os cards aparecerem
   esmaecidos por baixo do resumo e do "Ordenar por", como se o texto estivesse
   impresso em cima deles. Agora eles passam POR BAIXO de uma superfície opaca, e a
   sombra — que só entra depois do primeiro pixel de rolagem — é o que conta que há
   conteúdo escondido ali atrás. Parada no topo, sem rolagem, ela não tem sombra:
   não há nada por baixo para justificar relevo. */
/* folga igual em cima e embaixo, e curta: a pílula já tem 38 px de altura própria,
   então o que sobrava aqui era só ar em volta dela */
.list-head{padding:6px 20px; position:sticky; top:0; z-index:2;
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  background:var(--bone); box-shadow:none; transition:box-shadow .18s}
body.lista-rolada .list-head{box-shadow:0 6px 18px -8px rgb(var(--preto) / .28)}
/* texto normal, não caixa alta: é uma frase para ler ("21 paróquias · 25 missas ·
   segunda-feira"), e não um rótulo de seção — em maiúsculas com espaçamento, os
   números, que são o que interessa, ficavam mais difíceis de bater o olho */
.list-head h2{font-size:14px; font-weight:400; letter-spacing:0;
  text-transform:none; color:var(--ink-2)}

.ordenar{display:inline-flex; align-items:center; gap:7px; flex:none}
.ordenar > span{font-size:13.5px; font-weight:400; letter-spacing:0;
  text-transform:none; color:var(--ink-3)}
/* dropdown prÃ³prio: o <select> nativo abre um menu do sistema, pequeno e longe do controle */
.sel{position:relative}
/* preto como os dias marcados: a ordem muda o topo da lista, é decisão de peso
   e não podia parecer menos clicável que os filtros logo acima */
.sel-btn{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  border:0; background:var(--accent); color:#fff;
  min-height:38px; padding:0 14px; border-radius:99px;
  font-size:13.5px; font-weight:500; transition:.14s;
}
.sel-btn svg{width:12px; height:12px; flex:none; fill:none; stroke:#fff;
  stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; transition:transform .16s}
.sel-btn:hover{background:#333}
.sel-btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.sel-btn[aria-expanded="true"] svg{transform:rotate(180deg)}

/* position:fixed porque .scroll tem overflow:auto e recortaria o painel */
.sel-lista{
  position:fixed; z-index:50;
  margin:0; padding:5px; list-style:none;
  width:max-content; max-width:min(320px, 78vw);
  background:var(--paper); border:1px solid var(--line-2); border-radius:var(--r-md);
  box-shadow:0 14px 34px -12px rgb(var(--preto) / .32);
}
.sel-lista[hidden]{display:none}
.sel-lista li{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  padding:9px 11px; border-radius:var(--r-sm);
  font-size:15.3px; font-weight:400; line-height:1.25;
}
.sel-lista li:hover,.sel-lista li.foco{background:var(--cinza)}
.sel-lista li[aria-selected="true"]{font-weight:500}
.sel-lista li::before{
  content:''; flex:none; width:15px; height:15px; border-radius:99px;
  border:2px solid var(--line-2);
}
.sel-lista li[aria-selected="true"]::before{
  border-color:var(--accent); background:var(--accent); box-shadow:inset 0 0 0 3px var(--paper);
}
/* duas colunas de cards mais estreitos: cabe mais resultado na mesma tela */
.lista{
  /* a folga de cima é para a sombra do topo dos cards ter onde aparecer: encostados no
     "Ordenar por", eles ficavam sem respiro e a barra comia a sombra */
  padding:12px 20px 0; outline:none;
  display:grid; grid-template-columns:repeat(auto-fill, minmax(352px, 1fr));
  gap:10px; align-items:stretch;
  /* `auto` + o stretch acima: os cards lado a lado continuam da mesma altura, mas cada
     fileira tem a sua. Com `1fr`, abrir a semana inteira de UMA paróquia esticava a lista
     toda, porque o fr iguala todas as fileiras pela mais alta. */
  grid-auto-rows:auto;
}

.card{
  display:flex; flex-direction:column;
  background:var(--paper); border:0; border-radius:var(--r-md);
  padding:13px 14px; box-shadow:var(--relevo); transition:.15s box-shadow;
  scroll-margin-top:8px;
}
.card:hover{box-shadow:var(--relevo-alto)}
/* Selecionado e apontado continuam com anel, porque são ESTADO, não moldura de repouso:
   é o único jeito de dizer "é este" sem depender só da sombra, que todos têm.
   O relevo entra junto em cada estado, senão o card perderia a altura ao ser marcado. */
.card.is-sel{box-shadow:0 0 0 2px var(--accent), var(--relevo)}

/* card que acabou de ser apontado pelo mapa: pisca para o olho encontrar */
.card.is-alvo{
  box-shadow:0 0 0 3px var(--info-soft), var(--relevo);
  animation:achei 1.5s ease-out 1;
}
@keyframes achei{
  0%,100%{box-shadow:0 0 0 3px var(--info-soft), var(--relevo)}
  25%{box-shadow:0 0 0 8px rgb(18 87 168 / .22), var(--relevo)}
  60%{box-shadow:0 0 0 3px var(--info-soft), var(--relevo)}
}

.c-top{display:flex; align-items:flex-start; gap:11px}
.c-idx{
  flex:none; width:22px; height:22px; border-radius:99px; background:var(--pin);
  color:#fff; font-size:10.5px; font-weight:500; display:grid; place-items:center; margin-top:1px;
}
.c-main{flex:1; min-width:0}
.c-nome{font-size:16.5px; font-weight:500; letter-spacing:-.01em; line-height:1.3}
.c-bairro{
  display:inline-block; vertical-align:2px; margin-left:6px;
  font-size:11.5px; font-weight:500; letter-spacing:.05em; text-transform:uppercase;
  color:var(--accent); background:var(--accent-soft); border-radius:99px; padding:2px 8px;
}
.c-meta{font-size:13px; color:var(--ink-2); margin-top:4px; line-height:1.45}
.c-dist{
  flex:none; font-size:12.5px; font-weight:500; color:var(--accent);
  background:var(--accent-soft); border-radius:99px; padding:3px 9px; margin-top:1px;
  font-variant-numeric:tabular-nums;
}

/* azul = informação. Amarelo entra só quando falta 2 h ou menos: "corre, já vai começar" */
.c-next{
  margin-top:10px; display:flex; align-items:center; gap:8px;
  background:var(--info-soft); border-radius:99px; padding:3px 14px;
  min-height:var(--warn-h);
  font-size:13.5px; color:var(--info);
}
.c-next b{font-weight:500; font-variant-numeric:tabular-nums}
.c-next.atencao{background:var(--amarelo-soft); color:var(--amarelo)}

.c-dias{margin-top:11px; display:flex; flex-direction:column; gap:6px}
.c-dia{display:flex; gap:9px; align-items:baseline}
.c-dia dt{
  flex:none; width:38px; font-size:12.5px; font-weight:500; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3); padding-top:3px;
}
.c-dia dd{margin:0; display:flex; flex-wrap:wrap; gap:5px}
.hora{
  font-size:13.5px; font-weight:500; font-variant-numeric:tabular-nums;
  background:var(--cinza); color:var(--ink); border-radius:6px; padding:3px 8px;
}
.hora.hit{background:var(--info); color:#fff}   /* a próxima missa, em azul forte */
/* adoração não é missa: fica amarela para não ser confundida com um horário de missa */
.hora.adoracao{background:var(--amarelo-soft); color:var(--amarelo)}
.hora .obs{font-weight:400; opacity:.75; font-size:12px; margin-left:3px}
/* link de abrir/fechar: discreto de propósito, para não competir com as ações do rodapé */
.c-tudo{
  align-self:flex-start; display:inline-flex; align-items:center; gap:5px;
  margin:9px 0 0 -7px; padding:3px 7px; cursor:pointer; border:0; background:none;
  border-radius:99px; color:var(--ink-3); font-size:12.5px; transition:.14s;
}
.c-tudo:hover{background:var(--cinza); color:var(--ink)}
.c-tudo svg{width:12px; height:12px; fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; transition:transform .16s}
.c-tudo[aria-expanded="true"] svg{transform:rotate(180deg)}

/* margin-top:auto cola as ações no rodapé do card, já que todos têm a mesma altura */
.c-acoes{margin-top:auto; padding-top:11px;   /* sem risco separando os horários dos botões */
  display:flex; gap:7px; flex-wrap:wrap}
.c-dias + .c-acoes{margin-top:auto}
.c-acoes a,.c-acoes button{
  display:inline-flex; align-items:center; gap:5px; cursor:pointer; text-decoration:none;
  border:1px solid var(--linha-botao); background:var(--bone); color:var(--ink-2);
  min-height:38px; padding:0 11px; border-radius:99px;
  font-size:12.5px; font-weight:400; white-space:nowrap; transition:.13s;
}
.c-acoes a:hover,.c-acoes button:hover{border-color:var(--ink-3); color:var(--ink)}
.c-acoes svg{width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round}

/* ─────────────── modal de contato ─────────────── */
.modal{
  border:0; border-radius:var(--r-lg); padding:24px; max-width:420px; width:calc(100% - 32px);
  background:var(--paper); color:var(--ink); box-shadow:0 24px 60px -20px rgb(var(--preto) / .3);
}
.modal::backdrop{background:rgb(var(--preto) / .45); backdrop-filter:blur(2px)}
.modal h2{font-family:var(--display); font-size:21px; font-weight:500;
  letter-spacing:-.02em; line-height:1.2; padding-right:28px}
.modal-bairro{margin-top:4px; font-size:12.5px; font-weight:500; letter-spacing:.06em;
  text-transform:uppercase; color:var(--accent)}
.modal-x{
  position:absolute; top:14px; right:14px; width:32px; height:32px; cursor:pointer;
  border:0; background:none; color:var(--ink-3); font-size:24px; line-height:1;
  border-radius:99px; transition:.14s;
}
.modal-x:hover{background:var(--cinza); color:var(--ink)}
.modal-dl{
  margin:18px 0 0; display:grid; grid-template-columns:auto 1fr; gap:9px 14px;
  font-size:14px; line-height:1.45;
}
.modal-dl dt{font-size:12px; font-weight:500; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-3); padding-top:3px}
.modal-dl dd{margin:0; overflow-wrap:anywhere}
.modal-dl a{color:var(--info); font-weight:500; text-underline-offset:2px}
.copiar{
  display:inline-flex; align-items:center; gap:4px; vertical-align:1px; margin-left:8px;
  cursor:pointer; border:1px solid var(--linha-botao); background:var(--paper); color:var(--ink-3);
  padding:3px 9px; border-radius:99px; font-size:12px; font-weight:500; transition:.14s;
}
.copiar svg{width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round}
.copiar:hover{border-color:var(--ink-3); color:var(--ink)}
.copiar.ok{border-color:var(--accent); background:var(--accent); color:#fff}
.copiar.erro{border-color:var(--vermelho); color:var(--vermelho)}
.modal-vazio{grid-column:1/-1; color:var(--ink-3)}
.modal-rota{
  /* folga maior que a das linhas de contato: separa a ficha (o que a paróquia é)
     da ação (o que fazer com ela), em vez de virar mais um item da lista */
  margin-top:30px; display:flex; align-items:center; justify-content:center; gap:7px;
  background:var(--accent); color:#fff; text-decoration:none; font-size:14.5px; font-weight:500;
  min-height:46px; border-radius:99px; transition:.14s;
}
.modal-rota:hover{background:var(--ink)}

.modal-reportar{
  display:block; width:100%; margin-top:10px; cursor:pointer;
  border:0; background:none; color:var(--ink-3);
  padding:8px; font-size:13px; text-decoration:underline; text-underline-offset:3px;
  text-decoration-color:var(--line-2); transition:.14s;
}
.modal-reportar:hover{color:var(--amarelo); text-decoration-color:currentColor}

.campo{display:block; margin-top:14px; font-size:13px; color:var(--ink-2)}
.campo > span{display:block; margin-bottom:6px; font-weight:500}
.campo em{font-style:normal; color:var(--ink-3); font-weight:400}
.campo textarea,.campo input{
  width:100%; border:0; background:var(--cinza); border-radius:var(--r-md);
  padding:11px 13px; font-size:15px; color:var(--ink); outline:none; resize:vertical;
}
.campo textarea:focus,.campo input:focus{box-shadow:inset 0 0 0 2px var(--accent); background:var(--paper)}
#reportar-isca,#pesquisa-isca{position:absolute; left:-9999px; width:1px; height:1px; opacity:0}

/* ─────────────── pesquisa de satisfação ─────────────── */
.pesquisa-sub{margin-top:8px; font-size:14.5px; line-height:1.45; color:var(--ink-2)}
/* Onze colunas iguais: a escala tem de ser lida como uma régua, com todos os degraus
   do mesmo tamanho. Em grade e não em flex porque assim o 0 e o 10 ficam exatamente
   nas pontas, alinhados com os rótulos de baixo. */
/* minmax(0,1fr) e não 1fr: com `1fr` cada coluna se recusa a ficar menor que o próprio
   conteúdo, e no celular a régua estourava a largura do modal — o 9 e o 10 ficavam
   fora da tela. O zero no mínimo autoriza as colunas a encolherem de verdade. */
.nps{
  margin-top:16px; display:grid; grid-template-columns:repeat(11, minmax(0, 1fr)); gap:4px;
}
.nps button{
  aspect-ratio:1; min-width:0; display:grid; place-items:center; cursor:pointer;
  border:0; background:var(--cinza); color:var(--ink-2); border-radius:8px;
  font-size:13.5px; font-weight:500; font-variant-numeric:tabular-nums; transition:.12s;
}
.nps button:hover{background:rgb(var(--preto) / .14); color:var(--ink)}
.nps button[aria-checked="true"]{background:var(--accent); color:#fff}
.nps-pontas{
  display:flex; justify-content:space-between; margin-top:6px;
  font-size:12px; color:var(--ink-3);
}
#pesquisa .campo{margin-top:18px}
#pesquisa-enviar{width:100%; margin-top:18px}
#pesquisa-enviar[disabled]{opacity:.45; cursor:not-allowed}
.pesquisa-depois{
  display:block; width:100%; margin-top:10px; cursor:pointer;
  border:0; background:none; color:var(--ink-3); font-size:13.5px;
  padding:8px; border-radius:99px; transition:.14s;
}
.pesquisa-depois:hover{background:var(--cinza); color:var(--ink)}
/* obrigado: o formulário some e sobra só o agradecimento, sem fechar na cara */
#pesquisa.agradecendo form,#pesquisa.agradecendo .pesquisa-sub{display:none}

/* ── portas permanentes para a opinião ─────────────────────────────
   A caixa que aparece sozinha só pega quem acabou de achar o horário. Quem pensou em
   falar em outro momento — no meio da busca, ou depois de voltar de uma paróquia — não
   tinha por onde. São duas portas, uma por tela, porque as duas telas têm folgas
   diferentes. As duas somem para sempre depois de respondida: continuar pedindo a quem
   já falou é o jeito mais rápido de irritar. */

/* No COMPUTADOR, uma etiqueta colada na borda direita da janela, no canto de baixo.
   Em repouso é só o ícone — ocupa 42 px e não disputa nada com a lista; o texto abre
   quando o mouse chega, que é quando a pergunta "o que é isso?" existe. Fica ali o
   tempo todo de propósito: a vontade de falar aparece no meio da rolagem, não no fim.

   Embaixo, e não no meio da altura: no meio ela cruza a linha de leitura dos cards e
   fica em cima do trecho mais usado da barra de rolagem. O canto de baixo é o lugar
   onde o olho não passa procurando horário.

   O canto está livre: os controles do mapa moram na coluna da esquerda, e o balão
   amarelo de "atenção" fica ancorado dentro do mapa, não na janela. */
.opiniao-aba{display:none}
@media (min-width:901px){
  .opiniao-aba{
    position:fixed; right:0; bottom:26px; z-index:40;
    display:flex; align-items:center; gap:0; cursor:pointer;
    height:44px; padding:0 12px; border:0; border-radius:13px 0 0 13px;
    background:var(--paper); color:var(--ink-3);
    font-family:var(--sans); font-size:13px; line-height:1; white-space:nowrap;
    box-shadow:var(--relevo);
    transition:gap .22s ease, padding .22s ease, color .16s, box-shadow .16s;
  }
  .opiniao-aba svg{width:18px; height:18px; flex:none; fill:none;
    stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round}
  /* max-width e não display:none: só uma medida animável abre o texto deslizando.
     A largura de chegada é generosa — quem manda no tamanho final é o próprio texto. */
  .opiniao-aba span{
    max-width:0; overflow:hidden; opacity:0;
    transition:max-width .24s ease, opacity .18s ease;
  }
  .opiniao-aba:hover,.opiniao-aba:focus-visible{
    gap:9px; padding-right:16px; color:var(--ink); box-shadow:var(--relevo-alto);
  }
  .opiniao-aba:hover span,.opiniao-aba:focus-visible span{max-width:220px; opacity:1}
  /* depois de todas as regras acima, senão o display:flex vence o atributo hidden */
  .opiniao-aba[hidden]{display:none}
}

/* No CELULAR, no fim da lista. Nada pode ficar preso à tela ali: cobriria a alça do
   mapa ou uma fatia real dos resultados, numa tela onde cada linha é disputada. O fim
   da lista é o momento equivalente ao da etiqueta — quem rolou até aqui já viu o que
   veio ver, e é a mesma leitura de "tarefa cumprida" que abre a caixa sozinha. */
.opiniao-fim{
  display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; margin:0 0 18px; cursor:pointer;
  min-height:44px; padding:0 18px; border:0; border-radius:99px;
  background:var(--paper); color:var(--ink-2);
  font-family:var(--sans); font-size:14px; line-height:1;
  box-shadow:var(--relevo); transition:.14s;
}
.opiniao-fim svg{width:17px; height:17px; flex:none; fill:none;
  stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round}
.opiniao-fim:active{background:var(--bone-2)}
/* no computador quem faz esse papel é a etiqueta lateral: repetir aqui seria ruído */
@media (min-width:901px){ .opiniao-fim{display:none} }
.opiniao-fim[hidden]{display:none}
.campo-nota{margin-top:12px; font-size:12.5px; color:var(--ink-3); line-height:1.45}
#reportar-enviar{width:100%}
#reportar-enviar[disabled]{opacity:.55; cursor:progress}
.modal-rota svg{width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round}

.vazio{grid-column:1/-1; text-align:center; padding:44px 20px; color:var(--ink-3); font-size:14px}
.vazio b{display:block; color:var(--ink); font-size:16px; margin-bottom:5px; font-weight:500}

.rodape{padding:22px 20px 30px; color:var(--ink-3); font-size:13px; line-height:1.55}
.rodape strong{color:var(--ink-2)}
.rodape .fonte{margin-top:7px; font-size:11px; opacity:.8}

/* ─────────────── mobile ─────────────── */
@media (max-width:900px){
  :root{--top-h:58px}
  /* sem desfoque no celular: backdrop-filter numa barra grudada no topo obriga o
     navegador a redesenhar a faixa toda a cada quadro de rolagem, e é uma das fontes
     conhecidas de piscada no Safari do iPhone. Opaca, o efeito nem se nota. */
  .top{padding:0 14px; backdrop-filter:none; background:var(--paper)}
  .brand h1{font-size:20px}
  .top-actions .btn span{display:none}
  .top-actions .btn{padding:8px 10px}

  /* `auto 1fr`: a linha do mapa vale exatamente a altura dele, e TODA a sobra vai para
     a lista. Sem isso a grade repartia a sobra entre as duas linhas — com o mapa
     recolhido e poucos resultados, abria uma faixa vazia de uns 60 px entre a aba e os
     filtros, e a tela parecia ter o conteúdo boiando no meio em vez de começar em cima. */
  .shell{
    grid-template-columns:1fr; grid-template-rows:auto 1fr;
    height:auto; min-height:calc(100dvh - var(--top-h));
  }

  /* mapa recolhível: some ao rolar e vira uma aba de 40 px que o dedo alcança.
     --mapa-h é reescrita pelo JS enquanto a aba é arrastada; 44dvh é só o começo. */
  .map-pane{
    /* 50dvh, e não um valor qualquer: é exatamente a parada do meio. Assim o site já
       abre num dos três estados, em vez de numa altura que nenhum toque ou arrasto
       consegue reproduzir depois. */
    position:sticky; top:var(--top-h); z-index:30; height:var(--mapa-h, 50dvh); padding-bottom:24px;
    border-right:0; border-bottom:0;   /* sem risco entre a aba do mapa e os filtros */
    transition:height .26s ease;
  }
  /* durante o arrasto a altura tem que colar no dedo: animar aqui daria borracha */
  body.mapa-arrastando .map-pane{transition:none}

  /* Mapa no tamanho maior: a página para de rolar. `position:fixed` e não
     `overflow:hidden` porque o overflow no body é notoriamente furado no Safari do
     iPhone — a página continua rolando com o dedo. Fixo não tem como escapar. Como o
     JS leva a rolagem ao topo antes de travar, não há posição a perder. */
  body.mapa-cheio{position:fixed; inset:0; width:100%; overflow:hidden}
  /* O desenho do mapa vai até embaixo, passando POR TRÁS da aba. Antes ele parava na
     linha onde a aba começa, e aí, nos cantos arredondados, aparecia uma tira lisa da
     cor de fundo do painel — as duas bordinhas cinza-claro em cima dos cantos. Agora
     o que aparece ali é o próprio mapa, que é o que faz a folha parecer apoiada nele.
     A aba está numa camada acima, então só os cantos deixam ver o que há atrás. */
  .map-wrap{inset:0}
  body.mapa-off .map-pane{height:24px}
  body.mapa-off .map-wrap{opacity:0; pointer-events:none}

  /* A aba é o topo da folha, e a folha vai de ponta a ponta. Tentei antes deixá-la
     recuada 8 px de cada lado: com o mapa atrás dava a sensação de folha apoiada, mas
     assim que a lista rolava e o mapa saía de cena sobrava uma tira do fundo da página
     correndo pela lateral, que só parecia defeito. O canto arredondado sozinho já diz
     que é uma superfície por cima do mapa. */
  .mapa-aba{
    position:absolute; left:0; right:0; bottom:0; height:24px; z-index:2;
    display:flex; align-items:center; justify-content:center;
    border:0; background:var(--paper); border-radius:20px 20px 0 0;
    color:var(--accent); cursor:pointer; touch-action:none;
    transition:border-radius .2s ease, box-shadow .18s;
  }
  /* Parada, a aba não tem sombra: contra o azul do mapa e com o canto arredondado, ela
     já se destaca sozinha, e a sombra vazava uns 9 px para BAIXO, desenhando um risco
     cinza entre ela e os filtros — uma divisão que não existe, já que são a mesma
     folha. Rolando é outra história: aí há card passando por baixo, e a sombra conta
     isso. Mesma regra do resto do site: sombra só onde há algo escondido atrás. */
  body.rolou .mapa-aba{box-shadow:0 -3px 16px -4px rgb(var(--preto) / .16)}
  /* encostada no cabeçalho não há mais mapa atrás para a folha se destacar:
     o canto arredondado sai e ela se junta à barra de cima */
  body.mapa-off .mapa-aba{border-radius:0}
  .mapa-aba-puxador{
    position:absolute; top:5px; left:50%; transform:translateX(-50%);
    width:36px; height:4px; border-radius:99px; background:var(--line-2);
  }
  /* só a barrinha: puxar uma aba para abrir e fechar é gesto conhecido, o texto
     "Fechar mapa" era legenda do óbvio. O texto continua no HTML, invisível, porque
     o botão precisa de um nome para quem navega por leitor de tela. */
  .mapa-aba-txt{
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap;
  }
  .mapa-aba-puxador{top:50%; transform:translate(-50%,-50%); width:44px; height:5px}

  /* A seta entra só nos dois extremos, e no lugar da barrinha: as duas juntas seriam
     dois avisos para o mesmo gesto. Fechado, ela aponta para BAIXO — o caminho dali é
     puxar para revelar o mapa. Com o mapa cheio, aponta para CIMA, que é o caminho de
     volta para a lista. No meio ela some: ali os dois sentidos valem, e uma seta
     escolheria um deles sem motivo. */
  .mapa-aba-seta{
    display:none; width:20px; height:20px; fill:none; stroke:var(--ink-3);
    stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round;
    transition:transform .2s ease;
  }
  body.mapa-off .mapa-aba-puxador,
  body.mapa-cheio .mapa-aba-puxador{display:none}
  body.mapa-off .mapa-aba-seta,
  body.mapa-cheio .mapa-aba-seta{display:block}
  body.mapa-cheio .mapa-aba-seta{transform:rotate(180deg)}

  /* O painel descola das laterais e ganha canto arredondado com sombra: assim ele
     parece uma folha apoiada SOBRE o mapa, e não outra faixa colada nele. A faixa de
     fundo que aparece nas beiradas usa a cor do mapa, para a ilusão continuar
     valendo depois que a pessoa rola e o mapa some lá em cima. */
  /* As faixas de 8 px ao lado da folha não são pintadas de nada: elas simplesmente
     deixam ver o que está atrás — o mapa, onde há mapa, e o fundo da página no resto.

     Já tentei um degradê com a cor do mapa aqui, e o problema era esse: a faixa só
     combinava enquanto o azul do mapa estivesse atrás dela. Assim que a lista rolava e
     o mapa saía de cena, sobrava uma tira colorida sem motivo. Transparente funciona
     nos dois casos, porque não tenta imitar fundo nenhum. */
  body{background:transparent}
  /* o canto arredondado e a sombra ficam na aba, logo acima: repeti-los aqui criaria
     um degrau entre as duas partes da mesma folha */
  .list-pane{min-height:56dvh}
  .scroll{overflow:visible}

  /* os filtros acompanham a rolagem e param logo abaixo da aba do mapa,
     que a essa altura já se recolheu sozinha */
  .filters{
    /* --filtros-top acompanha a altura real do mapa: 24 px recolhido, cheia aberto.
       Fixo em 24 px, os filtros ficavam escondidos atrás do mapa aberto. */
    position:sticky; top:var(--filtros-top, calc(var(--top-h) + 24px)); z-index:25;
    /* topo curto: os dias sobem para junto da borda do painel e a faixa de filtros
       inteira encolhe, sobrando tela para os cards */
    padding:8px 10px 12px;
    /* No topo não há divisão nenhuma entre a busca e o "Ordenar por": os dois aparecem
       juntos e leem como um bloco só. O risco e a sombra cortavam esse bloco no meio. */
    border-bottom:0; box-shadow:none;
  }
  .filtros-caixa{padding:11px 12px; gap:13px}
  /* rolando, aí sim: os filtros ficam presos e precisam se separar dos cards que
     passam por baixo deles */
  body.rolou .filters{box-shadow:0 6px 16px -12px rgb(var(--preto) / .4)}
  /* "Ordenar por" não se prende no topo: ele pertence ao bloco de filtros e só faz
     sentido junto deles. Preso sozinho, virava uma faixa órfã em cima dos cards,
     ocupando altura de tela para uma decisão que já foi tomada. Rola junto com o resto
     e reaparece quando a pessoa volta ao começo da lista. */
  .list-head{position:static; box-shadow:none}
  /* com uma busca por nome ativa, a faixa de ordenação sai e devolve a altura dela
     para o card do resultado. O resumo fica: é ele que confirma quantas paróquias
     o nome digitado encontrou. */
  body.buscando .ordenar{display:none}
  /* a busca sai de cena na rolagem: o topo do celular é estreito demais para carregar
     um campo que ninguém está usando. Volta inteira quando a pessoa traz tudo de volta
     ao começo — e nunca some com o campo aberto, no meio de uma digitação */
  body.rolou .busca-toggle{display:none}
  /* A faixa do "Ordenar por" encolhe, e o corte sai todo de CIMA: em baixo a folga
     fica, para a pílula não encostar no primeiro card. Acima ela não faz falta — os
     filtros logo ali já têm a margem própria deles. */
  .list-head{padding-top:0; padding-bottom:10px}
  /* maior que os 13,5 px do computador: no celular ele é o único rótulo à vista nessa
     faixa, e sobra largura para ele ser lido de longe */
  .ordenar > span{font-size:16px}

  /* rolando com o mapa aberto, os filtros saem para os cards caberem ao lado do mapa;
     voltam assim que o mapa é fechado ou a lista volta ao topo */
  /* `visibility` e não `display`. Escondendo com display, o bloco saía do fluxo, a
     página encolhia uns 150 px e tudo abaixo dava um salto — e, com a lista curta, a
     rolagem se reacomodava, cruzava a marca de volta e o bloco reaparecia, piscando.
     Com visibility ele continua ocupando o lugar dele (que já ficou lá em cima, fora
     da tela) e só deixa de ser pintado: mesma tela livre para os cards, zero mudança
     de layout, nada para piscar. */
  body.filtros-off .filters{visibility:hidden}

  /* no celular a lista já mostra tudo: o recorte por enquadramento sai de cena
     (o iniciar() também desliga o filtro nesta largura) e sobra espaço nos filtros */
  .mapa-check{display:none}

  /* o card apontado pelo mapa precisa parar abaixo de tudo que fica fixo no topo */
  .card{scroll-margin-top:calc(var(--fixo, 160px) + 12px)}

  /* O anel preto do card selecionado existe para casar o card com o pin no mapa. Com o
     mapa fechado não há pin nenhum para casar: ele vira só uma marca preta sem
     explicação no meio da lista. Some, e o card fica com a sombra de sempre. */
  body.mapa-off .card.is-sel{box-shadow:var(--relevo)}

  /* em coluna única não há alinhamento lateral para preservar:
     cada card com a altura do próprio conteúdo economiza rolagem */
  .lista{grid-auto-rows:auto}

  /* as três ações dividem a largura toda do card: alvos bem maiores para o dedo */
  .c-acoes{margin-top:11px; gap:6px; flex-wrap:nowrap}
  /* flex:1 1 auto e não flex:1 — com base zero, "Como chegar" ficava cortado */
  .c-acoes a,.c-acoes button{
    flex:1 1 auto; justify-content:center;
    min-height:46px; padding:0 8px; font-size:13px;
  }
  .c-acoes svg{flex:none}
  .f-label{display:none}          /* sem espaço: os chips já se explicam */
  /* no toque os alvos crescem em vez de encolher */
  .chips button{min-height:44px; font-size:15px}
  #dias button{padding-inline:2px}
  /* "Limpar filtros" sobe para a linha de "Qualquer", encostado à direita;
     "Buscar por nome" desce sozinho, mais colado */
  #periodos{width:auto}
  /* 16px na vertical: a busca desce numa linha só dela e precisava respirar longe
     dos períodos, senão as duas coisas se liam como um bloco só */
  .f-line-wrap{gap:16px 10px}
  /* ocupam toda a faixa até o "Limpar", em quatro colunas iguais */
  .f-line-wrap #periodos{order:1; flex:1; min-width:0; width:auto;
    grid-template-columns:repeat(4, minmax(0, 1fr))}
  #periodos button{padding-inline:4px}
  .f-line-wrap .linkish-limpar{order:2; margin-left:auto}
  .f-line-wrap .busca-toggle{order:3; flex-basis:100%; min-height:34px; padding:0 12px}
  /* nesta largura os rótulos longos não cabem: entram as versões curtas */
  .so-largo{display:none}
  .so-estreito{display:inline}
  .c-acoes a,.c-acoes button{min-height:40px}
  /* "Ver todos" já tinha o mesmo tamanho da distância (12,5 px); o que fazia ele
     parecer menor era o peso e a cor mais claros. Sobe um pouco e ganha o mesmo peso
     do selo de distância, para os dois lerem igual. */
  .c-tudo{font-size:13.5px; font-weight:500}
  .list-head,.lista,.rodape{padding-left:14px; padding-right:14px}
  .lista{padding-top:0}   /* a folga do topo é coisa do computador, onde a barra é fixa */
  /* com duas ou três linhas a pílula vira um bloco muito alto: cantos suaves aqui */
  .tip{display:none}          /* sem hover no toque */
  .aviso{margin-left:14px; margin-right:14px; font-size:12.5px;
    border-radius:13px; padding:3px 6px 3px 12px}

  /* No celular o balão encosta na borda de cima da folha, ocupando a largura toda.
     `fixed` em vez de `absolute` porque o mapa aqui é curto e muda de altura no
     arrasto: preso à tela, o balão não some junto quando o mapa encolhe.
     z-index acima de 30 porque o mapa é 30 — abaixo disso ficaria atrás dele. */
  .aviso.flutua{
    position:fixed; left:14px; right:14px; z-index:31;
    /* --filtros-top marca o fim do mapa, que é o começo da LISTA — mas a aba com a
       alça (24 px) está dentro do mapa, logo acima disso. Somando os 24 da aba mais
       10 de folga, o balão para acima da folha inteira, em vez de cobrir a alça. */
    bottom:calc(100dvh - var(--filtros-top, 60%) + 34px);
    max-width:none;
  }

  /* alvo de toque de verdade para "Me achar no mapa" */
  .btn-mapa{height:40px; left:12px; top:12px; font-size:13.5px}

  /* onze colunas numa tela estreita dão ~24 px de largura cada. Quadrados, virariam
     alvos pequenos demais para o dedo: aqui eles deixam de ser quadrados e crescem na
     vertical, onde há espaço de sobra. */
  .nps{gap:3px}
  .nps button{aspect-ratio:auto; min-height:44px; font-size:13px; border-radius:7px}

  /* Ocultar/ampliar o mapa é coisa de computador: no celular quem manda é a aba
     "Fechar mapa". Fica no fim do arquivo de propósito — .btn-sq também declara
     display, e a regra que vem depois é a que vale. */
  .so-desktop{display:none}

  /* 38 px e não 44: o "Ordenar por" é um ajuste, não um filtro — não precisa do mesmo
     peso dos chips, e a faixa dele come altura do primeiro resultado */
  .sel-btn{min-height:38px; font-size:15px; padding:0 15px}
  .sel-lista li{font-size:16.7px; padding:11px 12px}
  .ordenar{width:100%; justify-content:space-between}
  .list-head{gap:8px}
  /* a contagem "N paróquias · N missas · dia" sai no mobile: ocupa uma linha inteira
     e a mesma informação já está visível nos filtros e na própria lista */
  .list-head h2{display:none}
  .busca-toggle,.linkish{min-height:40px; display:inline-flex; align-items:center}
  .busca-toggle{font-size:14px}
  .linkish{font-size:13.5px}
  /* 40 px para bater com a pílula "Fechar busca" ao lado. Os 16px de fonte ficam:
     abaixo disso o iPhone dá zoom sozinho ao tocar no campo, e a página inteira salta. */
  .search input{height:40px; font-size:16px}
  /* o botão já era maior aqui, mas o ícone tinha ficado no tamanho do computador —
     proporcionalmente ele aparecia MENOR no celular, justo onde se enxerga pior */
  .btn-sq{width:42px; height:42px; font-size:26px}
  .btn-sq svg{width:22px; height:22px}
  /* só o ícone aparece nesses botões, então ele pode ocupar bem mais o círculo */
  .top-actions .btn{min-height:44px; width:44px; padding:0; justify-content:center}
  .top-actions .btn svg{width:24px; height:24px; stroke-width:1.6}
}

@media (prefers-reduced-motion:reduce){
  *{transition:none !important; scroll-behavior:auto !important}
}
