/**
 * Camada de UI/UX da tela de gestão de escolas (/gestao-escolas).
 *
 * Carregada depois do bundle para corrigir acessibilidade, densidade e
 * responsividade sem reconstruir o componente Angular.
 *
 * SOBRE !important NESTA FOLHA
 * O Tailwind deste projeto é gerado com a opção `important` ligada, então toda
 * classe utilitária presente no template (text-lg, max-w-lg, min-w-[50vw], mt-4)
 * já chega com !important. Uma regra própria sem !important perde para elas por
 * prioridade, não por especificidade. Por isso o !important aqui é a regra e não
 * a exceção — o que ele dispute está anotado por seção, não linha a linha.
 *
 * ORGANIZAÇÃO
 *   1. Tokens
 *   2. Base (foco visível)
 *   3. HUD do mapa
 *   4. Legenda e busca
 *   5. Diálogos — estrutura e dimensionamento
 *   6. Diálogos — cabeçalho, conteúdo e rodapé
 *   7. Diálogos — conteúdo por tipo (filtro, lista, resumo)
 *   8. Preferências do usuário
 *
 * Referências: WCAG 2.2 AA, heurísticas de Nielsen e padrões de HUD de mapa.
 *
 * Autoria: CUB3.
 */

/* ============================================================================
   1. TOKENS
   ========================================================================= */
:root {
  /* Cor -------------------------------------------------------------------
     Rosa de ação escurecido: o original #FF446D dava 3,33:1 com texto branco.
     Este tom mantém a identidade e mede 4,79:1, acima do mínimo AA. */
  --ux-acao-perigo: #d62d5a;
  --ux-acao-perigo-escuro: #b02348;
  --ux-texto-forte: #0f172a;
  --ux-texto-medio: #475569;
  --ux-texto-fraco: #64748b;
  --ux-foco: #0067c7;
  --ux-linha: rgba(15, 23, 42, 0.08);
  --ux-linha-forte: rgba(15, 23, 42, 0.16);
  --ux-realce: rgba(0, 103, 199, 0.1);

  /* Neutros da escala slate: base de toda superfície e contorno. */
  --ux-n0: #ffffff;
  --ux-n50: #f8fafc;
  --ux-n100: #f1f5f9;
  --ux-n200: #e2e8f0;
  --ux-n300: #cbd5e1;

  /* Anel de foco: substitui o outline duro por halo, padrão atual de campo. */
  /* Opacidade alta de proposito: dentro do campo este anel e o unico indicador
     de foco, porque o outline duro e suprimido ali (secao 2). */
  --ux-anel: 0 0 0 3px rgba(0, 103, 199, 0.32);
  --ux-anel-perigo: 0 0 0 3px rgba(214, 45, 90, 0.22);

  --ux-superficie-hud: rgba(255, 255, 255, 0.92);
  --ux-superficie-hud-borda: rgba(15, 23, 42, 0.12);

  /* Raio ------------------------------------------------------------------
     Escala única. Antes conviviam --ux-raio (14px), a escala --ux-raio-*
     espelhada do cub3-admin e treze valores crus espalhados pelo arquivo. */
  --ux-raio-sm: 0.625rem; /* 10px — botões dentro de cartão */
  --ux-raio-md: 0.75rem; /* 12px — botões de diálogo, campos, cartões */
  --ux-raio-lg: 0.875rem; /* 14px — HUD, blocos de total */
  --ux-raio-2xl: 1.5rem; /* 24px — superfície do diálogo */
  --ux-raio-folha: 1.125rem; /* 18px — topo do bottom sheet */
  --ux-raio-pilula: 999px;

  /* Movimento */
  --ux-dur-fast: 150ms;
  --ux-dur-normal: 250ms;
  --ux-ease-out: cubic-bezier(0, 0, 0.2, 1);

  /* Elevação */
  --ux-sombra-hud: 0 6px 24px rgba(15, 23, 42, 0.16);
  --ux-sombra-card:
    0 1px 2px 0 rgba(15, 23, 42, 0.06),
    0 0 0 1px rgba(15, 23, 42, 0.04);
  --ux-sombra-card-hover:
    0 12px 24px -8px rgba(15, 23, 42, 0.16),
    0 0 0 1px rgba(0, 103, 199, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  /* Elevação do diálogo em quatro camadas: contato curto, difusão média,
     profundidade longa e um hairline de contorno. Uma sombra só, dura, é o que
     mais denuncia interface datada. */
  --ux-sombra-dialogo:
    0 1px 2px rgba(15, 23, 42, 0.04),
    0 8px 16px -6px rgba(15, 23, 42, 0.1),
    0 32px 64px -24px rgba(15, 23, 42, 0.32),
    0 0 0 1px rgba(15, 23, 42, 0.05);

  --ux-sombra-acao: 0 1px 2px rgba(15, 23, 42, 0.08), 0 4px 12px -4px rgba(214, 45, 90, 0.4);

  /* Tipografia fluida, na escala do cub3-admin */
  --ux-fonte-md: clamp(1.125rem, 1rem + 0.625vw, 1.375rem);
  --ux-lh-dense: 1.2;
  --ux-ls-tight: -0.025em;

  /* Espaçamento */
  --ux-esp-2: 0.5rem;
  --ux-esp-3: 0.75rem;
  --ux-esp-4: 1rem;
  --ux-esp-5: 1.25rem;
  --ux-esp-6: 1.5rem;

  /* Medidas de interação */
  --ux-alvo-minimo: 44px;
  --ux-borda-segura: env(safe-area-inset-bottom, 0px);
}

/* ============================================================================
   2. BASE — foco visível (WCAG 2.4.7 e 2.4.11)
   O tema zera o outline dos botões Material, o que deixa a navegação por
   teclado sem rastro. Reposto apenas em :focus-visible, então o clique de
   mouse continua limpo.
   ========================================================================= */
app-escolas-mapeamento :focus-visible,
.mat-mdc-dialog-container :focus-visible {
  outline: 3px solid var(--ux-foco) !important;
  outline-offset: 2px !important;
  border-radius: 6px;
}

/* Dentro de um campo, o anel do wrapper (regra .mat-focused, secao 7.1) ja e o
   indicador de foco, e com contraste suficiente. Somar o outline duro desenha
   duas marcacoes concentricas em volta do mesmo controle. O outline so e
   suprimido onde o anel comprovadamente o substitui. */
.mat-mdc-dialog-container mat-form-field .mat-mdc-select:focus-visible,
.mat-mdc-dialog-container mat-form-field input:focus-visible {
  outline: none !important;
}

.mat-mdc-dialog-container .mdc-tab:focus-visible {
  outline-offset: -3px !important;
}

/* ============================================================================
   3. HUD DO MAPA
   Em telefone a faixa ocupava 12,6% da tela e os dois botões colidiam com o
   título. Vira uma barra translúcida com o título em uma linha e os botões
   sempre acessíveis.
   ========================================================================= */
/* O recorte precisa ser desligado explicitamente: o overflow:hidden não vem
   desta folha, e sim do próprio componente cub3-card, então remover a
   declaração daqui não bastava — o painel de sugestões existia com a caixa
   certa e simplesmente não era pintado. A barra de progresso abaixo foi
   reescrita para não depender de recorte. */
app-escolas-mapeamento .filter-pricing {
  position: relative;
  overflow: visible !important;
  background: var(--ux-superficie-hud) !important;
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border: 1px solid var(--ux-superficie-hud-borda);
  border-radius: var(--ux-raio-lg);
  box-shadow: var(--ux-sombra-hud);
  padding: 0.625rem 0.75rem !important;
  gap: var(--ux-esp-2);
}

/* A barra fica sobre o mapa; sem opacidade reduzida o texto continua legível. */
app-escolas-mapeamento .opacity-8 {
  opacity: 1 !important;
  padding: var(--ux-esp-2) !important;
  padding-top: max(var(--ux-esp-2), env(safe-area-inset-top, 0px)) !important;
  pointer-events: none;
}

app-escolas-mapeamento .opacity-8 > * {
  pointer-events: auto;
}

/* Título: uma linha com reticências em vez de três linhas empilhadas. */
app-escolas-mapeamento .filter-pricing .font-medium.text-primary {
  font-size: 0.9375rem;
  line-height: 1.3;
  font-weight: 600;
  color: var(--ux-texto-forte);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1 1 auto;
}

/* O título saiu da vista para dar o espaço central à busca, mas continua no DOM
   como heading de nível 1 — é o único cabeçalho da página, e removê-lo deixaria
   o documento sem estrutura para quem navega por cabeçalhos. Este é o recorte
   padrão de conteúdo visualmente oculto: some da tela, permanece no leitor. */
app-escolas-mapeamento .filter-pricing [data-ux-titulo='oculto'] {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* A linha divisória existia para preencher o vão entre título e botões. Com a
   busca ocupando esse espaço, ela virou ruído. */
app-escolas-mapeamento .filter-pricing .border-b-2 {
  display: none;
}

/* ----------------------------------------------------------------------------
   Busca promovida à barra superior
   O campo é o mesmo que vivia dentro da legenda: o script move o nó, e por isso
   o autocomplete de endereço e o binding do Angular seguem intactos.
   ------------------------------------------------------------------------- */
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] {
  position: relative; /* âncora do painel de sugestões */
  flex: 1 1 auto;
  min-width: 0;
  max-width: 32rem;
  margin-inline: 0.75rem;
}

/* ----------------------------------------------------------------------------
   Sugestões de escola
   Painel próprio, exibido acima do painel de endereços do Google. O do Google
   não aceita itens estranhos, então as duas listas não se misturam: esta fica
   por cima e a de endereços é deslocada para baixo dela.
   ------------------------------------------------------------------------- */
.ux-sugestoes {
  position: absolute;
  z-index: 1001;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 19rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.375rem;
  background: var(--ux-n0);
  border: 1px solid var(--ux-n200);
  border-radius: var(--ux-raio-md);
  box-shadow: var(--ux-sombra-dialogo);
}

.ux-sugestoes__titulo {
  padding: 0.375rem 0.5rem 0.25rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ux-texto-fraco);
}

.ux-sugestao {
  display: flex;
  align-items: center;
  gap: var(--ux-esp-2);
  min-height: var(--ux-alvo-minimo);
  padding: 0.375rem 0.5rem;
  border-radius: var(--ux-raio-sm);
  cursor: pointer;
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out);
}

/* O item ativo pelo teclado e o item sob o ponteiro recebem o mesmo destaque,
   para que navegar por seta e por mouse pareçam a mesma coisa. */
.ux-sugestao:hover,
.ux-sugestao--ativa {
  background: var(--ux-n100);
}

.ux-sugestao .ux-detalhe__icone {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: var(--ux-texto-fraco);
}

.ux-sugestao__texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}

.ux-sugestao__nome {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ux-texto-forte);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ux-sugestao__apoio {
  font-size: 0.75rem;
  color: var(--ux-texto-fraco);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O painel próprio do Google fica oculto: as predições agora são pedidas por
   AutocompleteService e desenhadas na seção "Endereços" do painel único, junto
   das escolas. Manter os dois à mostra duplicaria a mesma lista.
   O autocomplete nativo também é silenciado no script, para que a consulta não
   seja feita duas vezes a cada tecla. */
.pac-container {
  display: none !important;
}

/* ----------------------------------------------------------------------------
   Rótulos das escolas sobre o mapa
   Os marcadores são iguais dentro de cada porte: sem o nome ao lado, so o
   clique diz qual escola é qual. A camada é desenhada por OverlayView e só
   aparece quando poucas escolas estão à vista.
   ------------------------------------------------------------------------- */
/* A badge é filha do próprio marcador: acompanha o ícone pelo posicionamento
   que o Google já aplica, sem nenhum cálculo por quadro. Fica escondida quando
   há marcadores demais na tela, caso em que os nomes se sobreporiam. */

/* O marcador do Google mede 40x40 e vem com overflow:hidden, que recortava a
   badge inteira — ela existia no DOM, com 111x22, e simplesmente não aparecia.
   O recorte é liberado só nos marcadores que receberam rótulo, e não em toda a
   camada do mapa. */
.gm-style [data-ux-rotulado='1'] {
  overflow: visible !important;
}
:root[data-ux-rotulos='densos'] .ux-rotulo-escola {
  display: none;
}

.ux-rotulo-escola {
  position: absolute;
  left: 50%;
  top: 0;
  /* Sobe acima do ícone para não cobri-lo. */
  transform: translate(-50%, -125%);
  max-width: 11rem;
  padding: 0.1875rem 0.4375rem;
  border-radius: var(--ux-raio-sm);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid rgba(15, 23, 42, 0.1);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.18);
  color: var(--ux-texto-forte);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

@media (max-width: 639px) {
  .ux-rotulo-escola {
    max-width: 8rem;
    font-size: 0.625rem;
  }
}

/* Crédito obrigatório do Places quando as predições são exibidas em interface
   própria: a licença do serviço exige a atribuição visível. */
.ux-sugestoes__credito {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.375rem;
  padding: 0.375rem 0.5rem 0.125rem;
  font-size: 0.6875rem;
  color: var(--ux-texto-fraco);
}

.ux-sugestoes__credito img {
  height: 12px;
  width: auto;
}

/* O campo carrega o utilitário .mt-10 do template, que reservava 40px acima dele
   dentro da legenda. Na barra esse vão não tem função e empurrava a altura. */
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-form-field {
  width: 100%;
  margin-top: 0 !important;
}

/* O mat-form-field reserva uma faixa abaixo do campo para mensagem de erro ou
   dica. A busca não emite nenhuma das duas, e a faixa custava 106px de altura
   à barra — espaço que em telefone sai direto do mapa. */
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-form-field-subscript-wrapper {
  display: none !important;
}

/* Barra de busca em pílula, no padrão de mapa: contorno discreto que só ganha
   peso no foco. */
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-text-field-wrapper {
  background: var(--ux-n0) !important;
  border-radius: var(--ux-raio-pilula) !important;
  border: none !important;
  transition: box-shadow var(--ux-dur-fast) var(--ux-ease-out);
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-notched-outline__leading,
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-notched-outline__notch,
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-notched-outline__trailing {
  border-color: var(--ux-n200) !important;
  border-width: 1.5px !important;
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-notched-outline__leading {
  border-radius: var(--ux-raio-pilula) 0 0 var(--ux-raio-pilula) !important;
  width: 1.25rem !important;
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-notched-outline__trailing {
  border-radius: 0 var(--ux-raio-pilula) var(--ux-raio-pilula) 0 !important;
}

app-escolas-mapeamento
  .filter-pricing
  [data-ux-busca-hud]
  .mat-mdc-form-field.mat-focused
  .mdc-notched-outline__leading,
app-escolas-mapeamento
  .filter-pricing
  [data-ux-busca-hud]
  .mat-mdc-form-field.mat-focused
  .mdc-notched-outline__notch,
app-escolas-mapeamento
  .filter-pricing
  [data-ux-busca-hud]
  .mat-mdc-form-field.mat-focused
  .mdc-notched-outline__trailing {
  border-color: var(--ux-foco) !important;
}

app-escolas-mapeamento
  .filter-pricing
  [data-ux-busca-hud]
  .mat-mdc-form-field.mat-focused
  .mat-mdc-text-field-wrapper {
  box-shadow: var(--ux-anel);
}

/* O rótulo flutuante duplicaria o texto do campo vazio; o nome acessível é
   garantido por aria-label, aplicado pelo script. */
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mdc-floating-label,
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-floating-label {
  display: none !important;
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-form-field-infix {
  min-height: var(--ux-alvo-minimo);
  display: flex;
  align-items: center;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] input {
  font-size: 0.9375rem;
}

app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] .mat-mdc-form-field-icon-prefix mat-icon,
app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] mat-icon {
  color: var(--ux-texto-fraco);
}

/* Em telefone a busca ganha a linha inteira, abaixo dos botões de ação. */
@media (max-width: 767px) {
  app-escolas-mapeamento .filter-pricing .flex.items-center {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }

  /* Sem `order`: a busca ocupa o lugar que era do título, no topo, e os botões
     descem para a linha seguinte por quebra natural. */
  app-escolas-mapeamento .filter-pricing [data-ux-busca-hud] {
    flex: 1 1 100%;
    max-width: none;
    margin-inline: 0;
  }
}

/* Botões da HUD: alvo de 44px e contraste AA. */
app-escolas-mapeamento .filter-pricing button.mdc-button {
  min-height: var(--ux-alvo-minimo);
  min-width: var(--ux-alvo-minimo);
  border-radius: var(--ux-raio-pilula);
  font-weight: 600;
  letter-spacing: 0;
  flex: 0 0 auto;
}

/* Em telefone o rótulo do botão dá lugar ao ícone, que já é autoexplicativo
   com o nome acessível preservado em aria-label. */
@media (max-width: 639px) {
  app-escolas-mapeamento .filter-pricing button.mdc-button {
    padding: 0 var(--ux-esp-3);
  }

  app-escolas-mapeamento .filter-pricing button.mdc-button .mdc-button__label,
  app-escolas-mapeamento
    .filter-pricing
    button.mdc-button
    > span:not(.mat-icon):not(.mat-mdc-button-persistent-ripple):not(.mat-mdc-button-touch-target):not(.mat-mdc-focus-indicator):not(.mat-ripple) {
    display: none;
  }

  app-escolas-mapeamento .filter-pricing button.mdc-button mat-icon {
    margin: 0;
  }
}

/* Feedback de carregamento (Nielsen 1). O relatório leva alguns segundos e a
   tela não dava sinal algum; enquanto carrega o componente desabilita os botões
   da barra, e essa condição alimenta a barra de progresso. */
/* A faixa desliza por background-position, e não por translateX. O translate
   levava o pseudo-elemento para fora da barra e exigia overflow:hidden no pai —
   que por sua vez recortaria o painel de sugestões. Deslocar o fundo mantém o
   elemento dentro da caixa e dispensa o recorte. */
app-escolas-mapeamento .filter-pricing:has(button[disabled])::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 3px;
  background-image: linear-gradient(90deg, transparent, var(--ux-foco), transparent);
  background-size: 45% 100%;
  background-repeat: no-repeat;
  animation: ux-carregando 1.1s ease-in-out infinite;
}

@keyframes ux-carregando {
  0% {
    background-position: -45% 0;
  }
  100% {
    background-position: 145% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  app-escolas-mapeamento .filter-pricing:has(button[disabled])::before {
    animation: none;
    background: var(--ux-foco);
    opacity: 0.6;
  }
}

/* ============================================================================
   4. LEGENDA E BUSCA
   O painel tinha largura fixa de 250px, texto de 9,6px e ficava solto sobre o
   mapa. Em telefone ancora no rodapé ocupando a largura útil; em tela grande
   volta a ser um painel lateral.
   ========================================================================= */
/* A busca saiu daqui para a barra superior; o contêiner de grade que a
   embrulhava fica sem conteúdo útil. */
#legenda [data-ux-vazio] {
  display: none !important;
}

#legenda {
  position: absolute !important;
  z-index: 999 !important;
  left: auto !important;
  right: var(--ux-esp-3) !important;
  bottom: calc(var(--ux-esp-3) + var(--ux-borda-segura)) !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: 15rem !important;
  max-height: 46vh;
  overflow-y: auto !important;
  overscroll-behavior: contain;
  padding: 0.5rem 0.625rem !important;
  background: rgba(255, 255, 255, 0.82) !important;
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border: 1px solid rgba(15, 23, 42, 0.08) !important;
  border-radius: var(--ux-raio-md) !important;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.1) !important;
  transition: max-height var(--ux-dur-normal) var(--ux-ease-out),
    background-color var(--ux-dur-fast) var(--ux-ease-out);
}

/* Sobre o mapa, o painel deve informar sem disputar atenção: fica discreto em
   repouso e ganha opacidade quando o ponteiro chega ou o foco entra. */
#legenda:hover,
#legenda:focus-within {
  background: rgba(255, 255, 255, 0.96) !important;
}

@media (min-width: 768px) {
  #legenda {
    right: var(--ux-esp-5) !important;
    bottom: calc(var(--ux-esp-5) + var(--ux-borda-segura)) !important;
    max-width: 16rem !important;
    max-height: 60vh;
  }
}

/* --- Cabeçalho e controle de recolher ------------------------------------ */
#legenda [data-ux-legenda-cabecalho] {
  display: flex !important;
  align-items: center;
  gap: var(--ux-esp-2);
  margin: 0 !important;
}

#legenda [data-ux-legenda-cabecalho] .text-primary.font-bold,
#legenda [data-ux-legenda-cabecalho] span {
  font-size: 0.6875rem !important;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ux-texto-fraco) !important;
  flex: 1 1 auto;
}

.ux-legenda-alternar {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin: -6px -6px -6px 0;
  padding: 0;
  border: 0;
  border-radius: var(--ux-raio-sm);
  background: transparent;
  color: var(--ux-texto-fraco);
  cursor: pointer;
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out),
    transform var(--ux-dur-normal) var(--ux-ease-out);
}

.ux-legenda-alternar:hover {
  background: rgba(15, 23, 42, 0.06);
  color: var(--ux-texto-forte);
}

.ux-legenda-alternar svg {
  width: 15px;
  height: 15px;
}

/* A seta aponta para baixo quando há o que recolher e vira para cima quando o
   painel está fechado, indicando a direção da ação. */
#legenda[data-ux-recolhida] .ux-legenda-alternar {
  transform: rotate(180deg);
}

/* O alvo é ampliado por pseudo-elemento, ancorado no próprio botão — com
   position:relative apenas no cabeçalho, ele se fixava no contêiner e a área
   não acompanhava o controle.

   A ampliação para 44px é parcial de propósito: #legenda tem overflow-y:auto e
   recorta o que passa da caixa, então a área extra vale nas laterais e para
   baixo, não acima. O botão em si mede 32px, acima do mínimo de 24px da WCAG
   2.5.8 (AA); os 44px da guideline CUB3 são preferenciais e cedem aqui à
   compactação pedida para o painel. */
.ux-legenda-alternar::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: var(--ux-alvo-minimo);
  height: var(--ux-alvo-minimo);
}

/* --- Estado recolhido ----------------------------------------------------- */
#legenda[data-ux-recolhida] {
  max-height: none;
}

#legenda[data-ux-recolhida] ul > li:not([data-ux-legenda-cabecalho]) {
  display: none !important;
}

/* Compactação em telefone: o painel disputava quase metade da tela com o mapa.
   A busca segue em linha própria e os quatro tipos de escola passam a ocupar
   duas colunas, o que corta a altura da lista pela metade. */
@media (max-width: 767px) {
  #legenda {
    left: auto !important;
    max-width: 12.5rem !important;
    max-height: 34vh;
    padding: 0.5rem 0.625rem !important;
  }

  /* O container da busca declara grid-cols-2 e o filho pede col-span-6, então o
     campo ficava preso a duas trilhas e sobrava largura. */
  #legenda > .grid {
    display: block !important;
    margin-top: 0 !important;
  }

  /* mt-10 reservava 2,5rem de vão morto acima do campo de busca. */
  #legenda .mt-10 {
    margin-top: 0 !important;
  }

  /* Coluna única em telefone. As duas colunas existiam para encurtar um painel
     que também carregava a busca; sem ela, duas colunas apenas espremem os
     rótulos ("Escola de pequeno porte/anex o") sem ganho de altura relevante. */
  #legenda ul {
    display: block !important;
  }

  #legenda ul > li.mt-1 {
    margin-top: 0 !important;
  }

  #legenda .text-xs {
    font-size: 0.75rem !important;
    line-height: 1.25 !important;
  }

  #legenda li img,
  #legenda img.w-20 {
    width: 18px !important;
    max-width: 18px !important;
  }
}

/* O CSS do componente usa "text-overflow:hidden", que não é valor válido e não
   faz nada. O texto da legenda precisa quebrar, não ser cortado. */
#legenda span {
  display: block;
  width: 100%;
  white-space: normal !important;
  text-overflow: clip !important;
  overflow-wrap: anywhere;
}

/* 9,6px era pequeno demais para leitura em campo; 12,8px mantém legibilidade
   num painel que agora ocupa bem menos espaço. */
/* O peso 700 vem do utilitário .font-bold do template, que o Tailwind deste
   projeto emite com !important — daí a necessidade de repetir o marcador aqui.
   Numa legenda de referência, texto em negrito compete com o mapa sem
   necessidade: ela é consultada, não lida. */
#legenda .text-xs {
  font-size: 0.8rem !important;
  line-height: 1.3 !important;
  font-weight: 500 !important;
  color: var(--ux-texto-medio) !important;
}

#legenda li:not([data-ux-legenda-cabecalho]).flex.flex-row.items-center {
  gap: 0.375rem;
  padding-block: 0.0625rem;
  margin-top: 0 !important;
  align-items: center;
}

#legenda li img,
#legenda img.w-20 {
  width: 20px !important;
  max-width: 20px !important;
  height: auto;
  flex: 0 0 auto;
}

/* Campo de busca de endereço: alvo confortável e contorno perceptível. */
#legenda .mat-mdc-form-field,
app-escolas-mapeamento .cub3-mat-no-subscript {
  width: 100%;
}

#legenda input.mat-mdc-input-element,
app-escolas-mapeamento input[name='filtroBusca'] {
  min-height: 34px;
  font-size: 1rem; /* 16px evita o zoom automático do iOS ao focar */
}

#legenda .mat-mdc-text-field-wrapper {
  min-height: var(--ux-alvo-minimo);
}

#legenda .mat-mdc-form-field-infix {
  min-height: var(--ux-alvo-minimo);
  display: flex;
  align-items: center;
  padding-top: var(--ux-esp-2) !important;
  padding-bottom: var(--ux-esp-2) !important;
}

/* ============================================================================
   5. DIÁLOGOS — ESTRUTURA E DIMENSIONAMENTO

   A cadeia do MatDialog tem quatro caixas aninhadas:
     .cdk-overlay-pane > .mat-mdc-dialog-container
       > .mdc-dialog__container > .mdc-dialog__surface

   Duas correções estruturais concentram-se aqui.

   a) min-width. O Material fixa min-width na cadeia a partir da largura
      intrínseca do conteúdo, e min-width prevalece sobre max-width — então o
      limite do painel era ignorado e a superfície transbordava. A regra base
      zera isso para toda a cadeia, de uma vez, em vez de repetir a lista de
      seletores em cada faixa como antes.

   b) padding. A superfície chega com padding de 24px de origem não localizável
      no CSSOM (nenhuma regra legível casa com ela; não há folhas adotadas), e
      cada slot interno — título, conteúdo e ações — traz outros 24px. Eram 48px
      de recuo por lado: 96px dos 375 de um telefone, 25,6% da largura gasta em
      margem interna. Zerar o padding da superfície devolve esses 48px ao
      conteúdo; o recuo passa a viver só nos slots. Medido: o título do diálogo
      de lista foi de 327px para 375px.
   ========================================================================= */
.cdk-overlay-pane > mat-dialog-container,
.mat-mdc-dialog-container,
.mat-mdc-dialog-container .mdc-dialog__container,
.mat-mdc-dialog-container .mdc-dialog__surface,
.mat-mdc-dialog-container .mat-mdc-dialog-surface {
  min-width: 0 !important;
  max-width: 100% !important;
  width: 100% !important;
}

/* Um único nível de recuo: o dos slots. Ver (b) acima. */
.mat-mdc-dialog-container .mdc-dialog__surface,
.mat-mdc-dialog-container .mat-mdc-dialog-surface {
  padding: 0 !important;
  background: var(--ux-n0) !important;
  box-shadow: var(--ux-sombra-dialogo) !important;
  contain: layout style;
  isolation: isolate;
}

/* O véu escurece e desfoca o mapa colorido atrás, para o diálogo ficar como
   único plano em foco. O cinza chapado do Material quase não separava os dois. */
.cdk-overlay-backdrop.cdk-overlay-dark-backdrop,
.cdk-overlay-dark-backdrop {
  background: rgba(2, 6, 23, 0.6) !important;
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}

/* min-w-[50vw] no conteúdo empurrava a superfície para além do painel: o painel
   media 640px e a superfície, 896px. */
.mat-mdc-dialog-content.min-w-\[50vw\] {
  min-width: 0 !important;
}

/* Entrada curta e contida: sobe alguns pixels em vez de escalar a partir do
   centro, o que reduz a sensação de salto. */
@media (prefers-reduced-motion: no-preference) {
  .mat-mdc-dialog-container .mdc-dialog__surface {
    animation: ux-dialogo-entrada var(--ux-dur-normal) var(--ux-ease-out);
  }
}

@keyframes ux-dialogo-entrada {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --- Telefone: folha ancorada no rodapé ---------------------------------- */
@media (max-width: 639px) {
  .cdk-overlay-pane[data-ux-dialogo],
  .cdk-overlay-pane:has(> .mat-mdc-dialog-container) {
    position: absolute !important;
    inset: auto 0 0 0 !important;
    width: 100vw !important;
    max-width: 100vw !important;
  }

  .cdk-overlay-pane[data-ux-dialogo] > .mat-mdc-dialog-container {
    padding: 0 !important;
  }

  .mat-mdc-dialog-container .mdc-dialog__surface,
  .mat-mdc-dialog-container .mat-mdc-dialog-surface {
    border-radius: var(--ux-raio-folha) var(--ux-raio-folha) 0 0 !important;
    max-height: 92vh;
  }

  /* Teto do corpo rolável, coordenado com os 92vh da superfície acima. */
  .mat-mdc-dialog-content {
    max-height: 68vh !important;
  }

  .mat-mdc-dialog-content.min-w-\[50vw\] {
    min-width: 100% !important;
  }
}

/* --- Tela grande: painel centrado, largura por tipo ----------------------- */
/* O tipo é marcado pelo script em data-ux-dialogo. A decisão de largura fica
   aqui, e não no script, porque media query reavalia sozinha quando a janela
   muda de faixa, sem depender de evento de resize — quatro mecanismos de evento
   (resize, orientationchange, matchMedia, ResizeObserver) foram testados e
   nenhum disparou de forma confiável com o diálogo já aberto. */
@media (min-width: 640px) {
  .cdk-overlay-pane[data-ux-dialogo] {
    width: 100% !important;
  }

  .cdk-overlay-pane[data-ux-dialogo='filtro'] {
    max-width: 40rem !important;
  }

  /* A lista precisa de mais largura para nome e ações na mesma linha. */
  .cdk-overlay-pane[data-ux-dialogo='lista'] {
    max-width: 56rem !important;
  }

  .cdk-overlay-pane[data-ux-dialogo='resumo'] {
    max-width: 44rem !important;
  }

  .mat-mdc-dialog-container .mdc-dialog__surface,
  .mat-mdc-dialog-container .mat-mdc-dialog-surface {
    border-radius: var(--ux-raio-2xl) !important;
  }
}

/* ============================================================================
   6. DIÁLOGOS — CABEÇALHO, CONTEÚDO E RODAPÉ
   ========================================================================= */
.mat-mdc-dialog-container .mat-mdc-dialog-title {
  font-size: var(--ux-fonte-md);
  line-height: var(--ux-lh-dense);
  font-weight: 700;
  letter-spacing: var(--ux-ls-tight);
  color: var(--ux-texto-forte) !important;
  padding: 1.75rem 1.75rem 1.25rem !important;
  align-items: center;
  gap: var(--ux-esp-3);
}

/* O Material reserva um pseudo-elemento de linha de base que abre um vão. */
.mat-mdc-dialog-container .mat-mdc-dialog-title::before {
  display: none;
}

/* O título do resumo é um h1 direto; os demais são div com h1 dentro. */
.mat-mdc-dialog-container .mat-mdc-dialog-title h1 {
  font-size: inherit;
  font-weight: inherit;
  color: inherit !important;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Ação do cabeçalho, como "Mapear nova escola". */
.mat-mdc-dialog-container .mat-mdc-dialog-title button {
  min-height: var(--ux-alvo-minimo);
  border-radius: var(--ux-raio-md);
  font-weight: 600;
  flex: 0 0 auto;
}

/* Em telefone o título e a ação não cabem lado a lado: o botão reserva 232px
   dos 327 disponíveis e espreme o h1 em três linhas de 75px. Passam a ocupar
   uma linha cada. */
@media (max-width: 639px) {
  .mat-mdc-dialog-container .mat-mdc-dialog-title {
    flex-wrap: wrap;
    row-gap: 0.875rem;
  }

  .mat-mdc-dialog-container .mat-mdc-dialog-title h1 {
    flex: 1 1 100%;
    white-space: normal;
  }

  .mat-mdc-dialog-container .mat-mdc-dialog-title button {
    flex: 1 1 100%;
    margin-left: 0 !important;
  }

  /* O X do sheet é exceção à regra acima: ela existe para a ação larga do
     cabeçalho da lista ("Mapear nova escola"), e aplicada ao X o empurrava para
     uma linha só dele, com o título sozinho na linha de cima. */
  .mat-mdc-dialog-container .mat-mdc-dialog-title button.ux-sheet-fechar {
    flex: 0 0 auto;
    /* min-* e não width/height: a regra genérica de botão do cabeçalho define
       min-height e venceria uma altura simples, deixando o alvo em 35px. */
    min-width: var(--ux-alvo-minimo);
    min-height: var(--ux-alvo-minimo);
    width: var(--ux-alvo-minimo);
    height: var(--ux-alvo-minimo);
    margin-left: auto !important;
  }
}

.mat-mdc-dialog-container .mat-mdc-dialog-content {
  padding: 0 1.75rem !important;
}

/* Sem rodapé de ações, o conteúdo encostaria na borda inferior da folha. */
.mat-mdc-dialog-container .mat-mdc-dialog-content:last-child {
  padding-bottom: calc(1.75rem + var(--ux-borda-segura)) !important;
}

/* Rodapé: ações agrupadas à direita, na ordem neutra → principal. Antes ficavam
   jogadas nas duas pontas, o que separa visualmente um par que é lido junto e
   obriga o olho a atravessar a largura inteira do diálogo. */
.mat-mdc-dialog-container .mat-mdc-dialog-actions {
  gap: var(--ux-esp-3);
  padding: 1.25rem 1.75rem calc(1.25rem + var(--ux-borda-segura)) !important;
  border-top: 1px solid var(--ux-linha);
  background: var(--ux-n50);
  justify-content: flex-end;
}

.mat-mdc-dialog-container .mat-mdc-dialog-actions button {
  min-height: var(--ux-alvo-minimo);
  border-radius: var(--ux-raio-md);
  font-weight: 600;
  letter-spacing: 0;
  padding-inline: var(--ux-esp-5);
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out),
    box-shadow var(--ux-dur-fast) var(--ux-ease-out),
    transform var(--ux-dur-fast) var(--ux-ease-out);
}

/* Papel do botão — marcado pelo script em data-ux-acao.
   Antes a distinção era `button.mat-warn:not(.ml-auto)`: o tema mat-warn veste
   tanto "Salvar filtro", que é a ação principal, quanto "Fechar", que é neutra,
   e o desempate vinha de .ml-auto — uma classe de posicionamento. Amarrar
   semântica a uma classe de layout quebra assim que alguém reposiciona o botão. */
.mat-mdc-dialog-container .mat-mdc-dialog-actions button[data-ux-acao='principal'] {
  margin-left: 0 !important;
  order: 2;
  box-shadow: var(--ux-sombra-acao);
}

.mat-mdc-dialog-container .mat-mdc-dialog-actions button[data-ux-acao='principal']:hover {
  transform: translateY(-1px);
}

.mat-mdc-dialog-container .mat-mdc-dialog-actions button[data-ux-acao='principal']:active {
  transform: translateY(0);
}

.mat-mdc-dialog-container .mat-mdc-dialog-actions button[data-ux-acao='neutra'] {
  order: 1;
  background: var(--ux-n0) !important;
  color: var(--ux-texto-medio) !important;
  border: 1px solid var(--ux-n200);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.mat-mdc-dialog-container .mat-mdc-dialog-actions button[data-ux-acao='neutra']:hover {
  background: var(--ux-n100) !important;
  border-color: var(--ux-n300);
  color: var(--ux-texto-forte) !important;
}

/* Ação destrutiva/primária de tema warn, quando não neutralizada acima. */
app-escolas-mapeamento button.mat-warn,
app-escolas-mapeamento button.mat-mdc-unelevated-button.mat-warn,
.mat-mdc-dialog-container button.mat-warn:not([data-ux-acao='neutra']) {
  background-color: var(--ux-acao-perigo) !important;
  color: #fff !important;
}

app-escolas-mapeamento button.mat-warn:hover,
.mat-mdc-dialog-container button.mat-warn:not([data-ux-acao='neutra']):hover {
  background-color: var(--ux-acao-perigo-escuro) !important;
}

/* O amarelo de destaque não alcança contraste suficiente com texto claro;
   escurecer o texto resolve sem trocar a cor da marca. */
.mat-mdc-dialog-container button.mat-accent,
app-escolas-mapeamento button.mat-accent {
  color: #3f3357 !important;
}

/* Compatibilidade: o template ainda posiciona alguns botões por utilitário. */
.mat-mdc-dialog-container .mat-mdc-dialog-actions button.mr-auto {
  margin-right: 0 !important;
  order: 2;
}

/* Passo único do stepper. Os diálogos usam mat-stepper com um passo só, e o
   cabeçalho renderiza um marcador "1" com o rótulo "Filtro" ou "Listagens" —
   ruído, porque não há segundo passo para onde navegar. */
.mat-mdc-dialog-container .mat-horizontal-stepper-header-container {
  display: none;
}

.mat-mdc-dialog-container .mat-horizontal-content-container {
  padding: var(--ux-esp-2) 0 0 !important;
}

/* ============================================================================
   7. DIÁLOGOS — CONTEÚDO POR TIPO
   ========================================================================= */

/* --- 7.1 Filtro: campos de seleção ---------------------------------------
   Os campos são mat-form-field no modo `outlined`: o contorno é desenhado por
   três peças irmãs (leading, notch, trailing) do .mdc-notched-outline, e o
   rótulo mora dentro do notch, recortando a borda superior. Estilizar a borda
   no .mat-mdc-text-field-wrapper produziria contorno duplo, e deslocar o rótulo
   por transform o arranca do entalhe. O contorno nativo é que deve ser vestido.

   O que muda: fundo branco no lugar do cinza, contorno mais claro e espesso,
   raio alinhado ao resto do sistema, foco por anel em vez de borda grossa e
   rótulo com tamanho e peso legíveis no lugar do azul de 10px. */
.mat-mdc-dialog-container .mat-mdc-text-field-wrapper {
  background: var(--ux-n0) !important;
  border: none !important;
  border-radius: var(--ux-raio-md) !important;
  transition: box-shadow var(--ux-dur-fast) var(--ux-ease-out);
}

.mat-mdc-dialog-container .mdc-notched-outline__leading,
.mat-mdc-dialog-container .mdc-notched-outline__notch,
.mat-mdc-dialog-container .mdc-notched-outline__trailing {
  border-color: var(--ux-n200) !important;
  border-width: 1.5px !important;
  transition: border-color var(--ux-dur-fast) var(--ux-ease-out);
}

.mat-mdc-dialog-container .mdc-notched-outline__leading {
  border-radius: var(--ux-raio-md) 0 0 var(--ux-raio-md) !important;
  width: var(--ux-raio-md) !important;
}

.mat-mdc-dialog-container .mdc-notched-outline__trailing {
  border-radius: 0 var(--ux-raio-md) var(--ux-raio-md) 0 !important;
}

.mat-mdc-dialog-container .mat-mdc-form-field:hover .mdc-notched-outline__leading,
.mat-mdc-dialog-container .mat-mdc-form-field:hover .mdc-notched-outline__notch,
.mat-mdc-dialog-container .mat-mdc-form-field:hover .mdc-notched-outline__trailing {
  border-color: var(--ux-n300) !important;
}

.mat-mdc-dialog-container .mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,
.mat-mdc-dialog-container .mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,
.mat-mdc-dialog-container .mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing {
  border-color: var(--ux-foco) !important;
  border-width: 1.5px !important;
}

.mat-mdc-dialog-container .mat-mdc-form-field.mat-focused .mat-mdc-text-field-wrapper {
  box-shadow: var(--ux-anel);
}

/* Rótulo no entalhe: mantém a posição nativa e só ganha legibilidade. */
.mat-mdc-dialog-container .mdc-floating-label,
.mat-mdc-dialog-container .mat-mdc-floating-label {
  font-size: 0.8125rem !important;
  font-weight: 600 !important;
  letter-spacing: 0 !important;
  color: var(--ux-texto-medio) !important;
}

.mat-mdc-dialog-container .mat-mdc-form-field.mat-focused .mdc-floating-label {
  color: var(--ux-foco) !important;
}

.mat-mdc-dialog-container .mat-mdc-form-field-infix {
  min-height: var(--ux-alvo-minimo);
  display: flex;
  align-items: center;
}

.mat-mdc-dialog-container .mat-mdc-select-value-text,
.mat-mdc-dialog-container .mat-mdc-select-placeholder {
  font-weight: 500;
  font-size: 0.9375rem;
  color: var(--ux-texto-forte);
}

.mat-mdc-dialog-container .mat-mdc-select-arrow svg {
  color: var(--ux-texto-fraco);
}

/* Duas colunas em tela confortável: seis campos empilhados ocupavam quase a
   altura inteira da janela e obrigavam a rolar um formulário curto.
   O !important é obrigatório aqui: o utilitário .grid-cols-1 do template já
   declara grid-template-columns com !important, por causa da opção `important`
   do Tailwind deste projeto. */
.mat-mdc-dialog-container .grid.grid-cols-1.gap-1 {
  gap: 1.5rem 1.25rem !important;
  padding-top: var(--ux-esp-2);
}

@media (min-width: 640px) {
  .mat-mdc-dialog-container .grid.grid-cols-1.gap-1 {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* --- 7.2 Lista: cartões de escola ---------------------------------------- */
/* Cada cartão tinha 96px de altura com o nome no topo e os botões embaixo, o
   que deixava uma faixa vazia no meio. Nome e ações dividem a mesma linha. */
.mat-mdc-dialog-container cub3-card.mb-2 {
  border-radius: var(--ux-raio-lg) !important;
  background: var(--ux-n0) !important;
  border: 1px solid var(--ux-n200);
  box-shadow: var(--ux-sombra-card) !important;
  padding: 0.875rem var(--ux-esp-4) !important;
  margin-bottom: 0.625rem !important;
  transition-property: box-shadow, transform, border-color;
  transition-duration: var(--ux-dur-normal);
  transition-timing-function: var(--ux-ease-out);
  will-change: transform;
}

/* Microinteração do design system: sobe 2px e cresce 0,5% no hover. */
.mat-mdc-dialog-container cub3-card.mb-2:hover,
.mat-mdc-dialog-container cub3-card.mb-2:focus-within {
  border-color: rgba(0, 103, 199, 0.22);
  box-shadow: var(--ux-sombra-card-hover) !important;
  transform: translateY(-2px) scale(1.005);
}

.mat-mdc-dialog-container cub3-card.mb-2:active {
  transform: translateY(-1px) scale(1.002);
  transition-duration: var(--ux-dur-fast);
}

.mat-mdc-dialog-container cub3-card.mb-2 .font-bold.text-secondary {
  font-size: 0.9375rem;
  line-height: 1.35;
  color: var(--ux-texto-forte) !important;
  flex: 1 1 auto;
  min-width: 0;
}

.mat-mdc-dialog-container cub3-card.mb-2 button {
  min-height: var(--ux-alvo-minimo);
  border-radius: var(--ux-raio-sm);
  font-weight: 600;
}

/* Em telefone as duas ações ocupam a linha inteira e dividem o espaço, em vez
   de ficarem espremidas à direita e vazarem o cartão. */
@media (max-width: 639px) {
  .mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col > .w-full.flex.justify-end {
    justify-content: stretch !important;
    gap: var(--ux-esp-2);
    margin-top: 0.625rem;
  }

  .mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col > .w-full.flex.justify-end button {
    flex: 1 1 0;
    min-width: 0;
    margin: 0 !important;
  }
}

/* Em tela confortável o cartão vira uma grade de duas colunas: identidade à
   esquerda (nome, etiquetas e detalhes) e ações à direita, centradas na altura.
   Uma versão anterior usava flex-direction:row, que funcionava quando só havia
   nome e botões, mas empurraria os detalhes para a mesma linha das ações. */
@media (min-width: 640px) {
  .mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'identidade acoes'
      'detalhes acoes';
    align-items: center;
    column-gap: var(--ux-esp-4);
    row-gap: 0.375rem;
  }

  .mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col > .font-bold.text-secondary {
    grid-area: identidade;
  }

  .mat-mdc-dialog-container cub3-card.mb-2 .ux-cartao-detalhes {
    grid-area: detalhes;
  }

  .mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col > .w-full.flex.justify-end {
    grid-area: acoes;
    width: auto !important;
    flex: 0 0 auto;
  }
}

/* --- Cartão enriquecido ---------------------------------------------------
   O template do bundle só imprime o nome da escola, então a lista era uma
   coluna de 98 nomes sem nada que distinguisse um do outro: nem onde fica, nem
   de que porte é, nem como falar com ela. Os campos abaixo são inseridos pelo
   script a partir da resposta de escolas/relatorio, que já os trazia. */
/* min-width:auto é o padrão de item flex e grid, e impede o filho de encolher
   abaixo da largura intrínseca do conteúdo: com um endereço longo, o cartão
   transbordava 51px e cortava o botão de ação. O zero precisa ser declarado em
   toda a cadeia, porque basta um elo com auto para travar a redução. */
.mat-mdc-dialog-container cub3-card.mb-2,
.mat-mdc-dialog-container cub3-card.mb-2 > .flex-auto.flex-col,
.mat-mdc-dialog-container cub3-card.mb-2 .ux-cartao-detalhes,
.mat-mdc-dialog-container cub3-card.mb-2 .ux-etiquetas,
.mat-mdc-dialog-container cub3-card.mb-2 .ux-detalhes,
.mat-mdc-dialog-container cub3-card.mb-2 .ux-detalhe {
  min-width: 0;
}

.mat-mdc-dialog-container .ux-cartao-detalhes {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-top: 0.375rem;
  min-width: 0;
}

.mat-mdc-dialog-container .ux-etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.mat-mdc-dialog-container .ux-etiqueta {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: var(--ux-raio-pilula);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
}

/* Cada variante combina cor de fundo e de texto com contraste AA sobre branco;
   o texto da etiqueta nunca é o único portador do sentido, porque o rótulo
   também está escrito por extenso. */
.mat-mdc-dialog-container .ux-etiqueta--porte {
  background: rgba(0, 103, 199, 0.1);
  color: #0055a6;
}

.mat-mdc-dialog-container .ux-etiqueta--zona {
  background: rgba(180, 83, 9, 0.1);
  color: #9a4a08;
}

.mat-mdc-dialog-container .ux-etiqueta--aee {
  background: rgba(21, 128, 61, 0.12);
  color: #15803d;
}

.mat-mdc-dialog-container .ux-etiqueta--ocupacao {
  background: var(--ux-n100);
  color: var(--ux-texto-medio);
}

.mat-mdc-dialog-container .ux-etiqueta--inativa {
  background: rgba(190, 18, 60, 0.1);
  color: #a11040;
}

.mat-mdc-dialog-container .ux-detalhes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  min-width: 0;
}

.mat-mdc-dialog-container .ux-detalhe {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  min-width: 0;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ux-texto-medio);
}

.mat-mdc-dialog-container .ux-detalhe__icone {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  color: var(--ux-texto-fraco);
}

/* O endereço é o campo mais longo e o único que precisa ceder: corta com
   reticências em vez de esticar o cartão. */
.mat-mdc-dialog-container .ux-detalhe__valor {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- 7.3 Resumo: padrão de sheet ------------------------------------------
   O detalhamento da escola deixa de ser um diálogo centrado e passa a abrir
   como painel ancorado à borda: side sheet à direita em tela grande, bottom
   sheet no telefone. A escolha combina com a natureza do conteúdo — é um
   detalhe sobre algo que continua na tela, e o mapa permanece visível ao lado
   em vez de ficar coberto por uma caixa no meio.

   Tudo aqui é escopado a [data-ux-dialogo='resumo']: o filtro e a lista seguem
   centrados, e uma regra vazada mudaria os três de uma vez.
   ------------------------------------------------------------------------- */
@media (min-width: 640px) {
  .cdk-overlay-pane[data-ux-dialogo='resumo'] {
    position: fixed !important;
    inset: 0 0 0 auto !important;
    width: 100% !important;
    max-width: 30rem !important;
    height: 100% !important;
    max-height: 100% !important;
  }

  .cdk-overlay-pane[data-ux-dialogo='resumo'] > .mat-mdc-dialog-container,
  .cdk-overlay-pane[data-ux-dialogo='resumo'] .mdc-dialog__container {
    height: 100% !important;
    max-height: 100% !important;
    padding: 0 !important;
  }

  .cdk-overlay-pane[data-ux-dialogo='resumo'] .mdc-dialog__surface,
  .cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-surface {
    display: flex;
    flex-direction: column;
    height: 100% !important;
    max-height: 100% !important;
    /* Só o lado que encosta na tela perde o raio. */
    border-radius: var(--ux-raio-2xl) 0 0 var(--ux-raio-2xl) !important;
  }

  /* Desliza da borda em vez de surgir do centro: o movimento conta de onde o
     painel veio. Sem opacidade na animação — animar opacity a partir de zero
     deixa o painel invisível enquanto a aba estiver em segundo plano, onde o
     navegador congela animações. */
  @media (prefers-reduced-motion: no-preference) {
    .cdk-overlay-pane[data-ux-dialogo='resumo'] .mdc-dialog__surface {
      animation: ux-sheet-entrada var(--ux-dur-normal) var(--ux-ease-out);
    }
  }
}

@keyframes ux-sheet-entrada {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}

/* O corpo rola sozinho; cabeçalho e rodapé ficam ancorados. Num sheet de altura
   cheia, deixar o rodapé rolar junto esconderia a ação principal. */
.cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-content {
  flex: 1 1 auto;
  max-height: none !important;
  overscroll-behavior: contain;
}

.cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-title {
  flex: 0 0 auto;
  border-bottom: 1px solid var(--ux-linha);
}

.cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-actions {
  flex: 0 0 auto;
}

/* Fechar no canto do cabeçalho: num painel de altura cheia a ação do rodapé
   fica longe e some se o conteúdo for longo. Delega no botão "Fechar". */
.ux-sheet-fechar {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ux-alvo-minimo);
  height: var(--ux-alvo-minimo);
  margin-left: auto;
  margin-right: -0.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--ux-raio-md);
  background: transparent;
  color: var(--ux-texto-fraco);
  cursor: pointer;
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out),
    color var(--ux-dur-fast) var(--ux-ease-out);
}

.ux-sheet-fechar:hover {
  background: var(--ux-n100);
  color: var(--ux-texto-forte);
}

.ux-sheet-fechar svg {
  width: 18px;
  height: 18px;
}

/* Alça do bottom sheet no telefone: sinaliza que o painel vem da borda e pode
   ser dispensado, sem depender de o usuário procurar o botão. */
@media (max-width: 639px) {
  .cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-title::after {
    content: '';
    position: absolute;
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    width: 2.25rem;
    height: 0.25rem;
    border-radius: var(--ux-raio-pilula);
    background: var(--ux-n300);
  }

  .cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-title {
    padding-top: 1.5rem !important;
  }
}

/* --- 7.4 Resumo: abas ----------------------------------------------------- */
/* Quatro abas não cabem na largura de um telefone; o padrão passa a ser rolagem
   horizontal com indicador visível e alvo de 44px. */
/* Segmented control no lugar do sublinhado do Material: as abas viram um grupo
   de pílulas sobre um trilho, e a ativa é uma pastilha branca elevada. Além de
   ser o padrão atual, funciona melhor aqui — são quatro abas curtas que cabem
   lado a lado, e o sublinhado fino sumia sobre fundo claro. */
.mat-mdc-dialog-container .mat-mdc-tab-header {
  border-bottom: none;
  background: var(--ux-n100);
  border-radius: var(--ux-raio-md);
  padding: 0.25rem;
  margin-top: var(--ux-esp-2);
}

/* No sheet as abas acompanham a rolagem: com altura cheia, o conteúdo de uma
   aba passa de uma tela e o usuário perderia de vista onde está.
   O fundo opaco é obrigatório — sem ele o conteúdo transparece por baixo. */
.cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-tab-header {
  position: sticky;
  top: 0;
  z-index: 2;
  margin-top: 0;
  background: var(--ux-n100);
  box-shadow: 0 0 0 0.5rem var(--ux-n0);
}

.cdk-overlay-pane[data-ux-dialogo='resumo'] .mat-mdc-dialog-content {
  padding-top: 0.75rem !important;
}

.mat-mdc-dialog-container .mat-mdc-tab-labels {
  gap: 0.25rem;
}

/* 44px de altura, e não 40: o alvo estendido por pseudo-elemento nao e medido
   por ferramenta de auditoria nem por quem toca a tela com precisao reduzida.
   O desenho continua compacto porque o trilho tem so 0,25rem de folga. */
.mat-mdc-dialog-container .mdc-tab {
  position: relative;
  min-height: var(--ux-alvo-minimo) !important;
  height: var(--ux-alvo-minimo) !important;
  min-width: auto !important;
  padding: 0 0.875rem !important;
  border-radius: calc(var(--ux-raio-md) - 0.25rem);
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out),
    box-shadow var(--ux-dur-fast) var(--ux-ease-out);
}

.mat-mdc-dialog-container .mdc-tab:hover {
  background: rgba(255, 255, 255, 0.6);
}

/* A pastilha ativa é branca e elevada; o peso do rótulo também muda, para não
   depender só da cor (WCAG 1.4.1). */
.mat-mdc-dialog-container .mdc-tab--active {
  background: var(--ux-n0);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.1);
}

.mat-mdc-dialog-container .mdc-tab__text-label {
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ux-texto-fraco) !important;
}

.mat-mdc-dialog-container .mdc-tab--active .mdc-tab__text-label {
  font-weight: 700;
  color: var(--ux-texto-forte) !important;
}

/* O trilho substitui o indicador; mantê-lo desenharia duas marcações. */
.mat-mdc-dialog-container .mat-mdc-tab-header .mdc-tab-indicator {
  display: none !important;
}

/* A altura de 40px é menor que o alvo de 44px, então a área de toque é
   estendida sem alterar a caixa visual (WCAG 2.5.8). */
.mat-mdc-dialog-container .mdc-tab::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  top: 50%;
  height: var(--ux-alvo-minimo);
  transform: translateY(-50%);
}

.mat-mdc-dialog-container .mat-mdc-tab-body-content {
  padding-top: 0.25rem;
  overscroll-behavior: contain;
}

/* --- 7.4 Resumo: corpo ---------------------------------------------------- */
/* O conteúdo vivia num cartão de 512px centrado dentro de uma superfície de
   896px, com moldura branca sobre moldura branca e 43% da largura ociosa. */
.mat-mdc-dialog-container .max-w-lg.mx-auto.bg-white {
  max-width: none !important;
  width: 100% !important;
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
}

.mat-mdc-dialog-container .min-h-\[50vh\] {
  min-height: 0 !important;
}

/* Cabeçalho do resumo: os dois rótulos eram posicionados de forma absoluta e se
   sobrepunham com nome de distrito longo. Viram pílulas em fluxo normal. */
.mat-mdc-dialog-container .flex-col.text-md.font-bold.items-center {
  align-items: flex-start !important;
  text-align: left !important;
}

.mat-mdc-dialog-container .label-txt {
  position: static !important;
  display: inline-block;
  max-width: 100% !important;
  white-space: normal !important;
  background: var(--ux-realce) !important;
  color: var(--ux-foco);
  font-weight: 600;
  font-size: 0.8125rem;
  padding: 0.25rem 0.625rem !important;
  border-radius: var(--ux-raio-pilula) !important;
}

.mat-mdc-dialog-container .label-float {
  position: static !important;
  float: none !important;
  display: inline-block;
  margin-left: 0.375rem;
  font-size: 0.75rem;
  padding: 0.25rem var(--ux-esp-2) !important;
  border-radius: var(--ux-raio-pilula) !important;
}

/* Linhas de contato. Uma versão anterior declarava este mesmo seletor duas
   vezes, com min-height 32px e 44px em disputa; vale o alvo de 44px. */
.mat-mdc-dialog-container .mat-mdc-tab-body-content .flex.items-center.text-sm {
  min-height: var(--ux-alvo-minimo);
  gap: 0;
  line-height: 1.45;
  padding-block: 0.125rem;
}

/* Ícone em bolha suave, como nas referências. */
.mat-mdc-dialog-container .mat-mdc-tab-body-content .flex.items-center.text-sm > mat-icon {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  padding: 6px;
  border-radius: var(--ux-raio-pilula);
  background: var(--ux-realce);
  color: var(--ux-foco) !important;
  font-size: 20px;
  line-height: 20px;
  margin-right: 0.625rem !important;
}

.mat-mdc-dialog-container .mat-mdc-tab-body-content .flex.items-center.text-sm .font-bold {
  color: var(--ux-texto-medio);
  font-weight: 600;
  margin-right: 0.375rem !important;
}

/* Blocos de total: contorno em vez de fundo cinza chapado. */
.mat-mdc-dialog-container .grid.grid-cols-2.gap-4 > .flex.flex-col.items-center {
  background: #fff !important;
  border: 1px solid rgba(15, 23, 42, 0.1);
  border-radius: var(--ux-raio-lg);
  box-shadow: none !important;
  padding: 0.875rem var(--ux-esp-3) !important;
  gap: 0.25rem;
}

.mat-mdc-dialog-container .grid.grid-cols-2.gap-4 .text-lg {
  font-size: 1.5rem !important;
  font-weight: 700 !important;
  color: var(--ux-texto-forte) !important;
  line-height: 1.2 !important;
}

/* Total sem valor mostra um traço, em vez de um branco que parece defeito de
   carregamento. O dado não vem da procedure hoje. */
.mat-mdc-dialog-container .grid.grid-cols-2.gap-4 .text-lg:empty::after {
  content: '—';
  color: var(--ux-texto-medio);
  font-weight: 500;
}

/* Etiquetas de etapa e infraestrutura como pílulas. */
.mat-mdc-dialog-container .inline-block.bg-zinc-100.rounded-full {
  background: rgba(0, 103, 199, 0.08) !important;
  color: var(--ux-texto-forte) !important;
  font-size: 0.75rem;
  font-weight: 500;
  padding: 0.3125rem 0.6875rem !important;
  line-height: 1.3;
}

/* --- Conteúdo das abas do resumo -----------------------------------------
   Contatos acionáveis, pares em lista de definição e estado vazio explícito.
   ------------------------------------------------------------------------- */

/* O contato inteiro vira alvo: linha cheia, com altura de toque confortável,
   em vez de um trecho de texto pequeno no meio da frase. */
.mat-mdc-dialog-container .ux-linha-acao {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--ux-alvo-minimo);
  padding: 0.25rem 0.5rem;
  margin-inline: -0.5rem;
  border-radius: var(--ux-raio-md);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--ux-dur-fast) var(--ux-ease-out);
}

.mat-mdc-dialog-container .ux-linha-acao:hover {
  background: var(--ux-n100);
}

/* Sublinhado só no foco e no hover do valor: o contato precisa parecer clicável
   sem transformar a aba num bloco de links azuis. */
.mat-mdc-dialog-container .ux-linha-acao:hover .font-bold + *,
.mat-mdc-dialog-container .ux-linha-acao:focus-visible {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Pares rótulo/valor da infraestrutura. Em telefone é uma coluna; a partir de
   480px o painel comporta duas, o que encurta a lista de 32 itens pela metade. */
.mat-mdc-dialog-container .ux-pares {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.625rem 1.25rem;
  margin: 0.25rem 0 0;
  padding: 0;
}

@media (min-width: 480px) {
  .mat-mdc-dialog-container .ux-pares {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.mat-mdc-dialog-container .ux-pares__rotulo {
  margin: 0;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ux-texto-fraco);
  line-height: 1.3;
}

.mat-mdc-dialog-container .ux-pares__valor {
  margin: 0 0 0.125rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ux-texto-forte);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.mat-mdc-dialog-container .ux-aba-vazia {
  margin: 0.75rem 0;
  padding: 1rem;
  border: 1px dashed var(--ux-n200);
  border-radius: var(--ux-raio-md);
  background: var(--ux-n50);
  color: var(--ux-texto-medio);
  font-size: 0.875rem;
  text-align: center;
}

/* --- 7.5 Estados vazios --------------------------------------------------- */
.mat-mdc-dialog-container .mat-mdc-tab-body-content:empty::after {
  content: 'Sem informação cadastrada para esta escola.';
  display: block;
  padding: var(--ux-esp-4) 0;
  color: var(--ux-texto-medio);
  font-size: 0.875rem;
}

/* A aba do diretor traz só um ícone quando o gestor não está cadastrado. */
.mat-mdc-dialog-container
  .mat-mdc-tab-body-content
  > .mt-4:has(> .flex.items-center:only-child:empty)::after {
  content: 'Gestor não informado para esta escola.';
  display: block;
  color: var(--ux-texto-medio);
  font-size: 0.875rem;
}

/* ============================================================================
   8. PREFERÊNCIAS DO USUÁRIO
   ========================================================================= */
/* Movimento reduzido (WCAG 2.3.3) */
@media (prefers-reduced-motion: reduce) {
  app-escolas-mapeamento *,
  .mat-mdc-dialog-container * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .mat-mdc-dialog-container cub3-card.mb-2:hover,
  .mat-mdc-dialog-container cub3-card.mb-2:focus-within,
  .mat-mdc-dialog-container cub3-card.mb-2:active {
    transform: none;
  }
}

/* Alto contraste */
@media (prefers-contrast: more) {
  :root {
    --ux-superficie-hud: #ffffff;
    --ux-superficie-hud-borda: #0f172a;
  }

  app-escolas-mapeamento .filter-pricing,
  #legenda {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
