/* ════════════════════════════════════════════════════════════════
   RMF — CSS da home / index (mapa fullscreen)
   Extraído dos blocos <style> inline de indexbeta.html.

   A home segue o design system unificado do DESIGN.md (Material 3, primary
   #4B5C92, seed/brand #2563EB) — a MESMA paleta do rmf.css. As cores ficam
   centralizadas nos tokens --rmf-* e --md-sys-color-* logo abaixo (cada token
   = 1 valor; o tema escuro usa os tokens de sufixo -dk nos seus próprios blocos).

   Carregue DEPOIS do Tailwind (várias regras usam !important p/ vencê-lo):
     <link rel="stylesheet" href="/res/assets/css/index.css">
   Requer Font Awesome e a fonte Inter (res/fonts/fonts.css).
   ════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   Tokens de cor (--rmf-*) — paleta do app Flutter (seed #2563EB).
   Cada token equivale a UM valor literal; trocar aqui reflete no arquivo
   inteiro. Os sufixos -dk são os valores já usados nos blocos de tema
   escuro (a home mantém os dois mecanismos: @media e classe .dark).
   ════════════════════════════════════════════════════════════════ */
:root {
  /* Marca — primary #4B5C92, seed/brand #2563EB (DESIGN.md, igual ao rmf.css) */
  --rmf-brand:        #4B5C92;            /* primary (claro) */
  --rmf-brand-light:  #B7C0E5;            /* inverse-primary (acento claro) */
  --rmf-brand-300:    #B7C0E5;            /* acento no tema escuro */

  /* Neutros — régua M3 NEUTRA (sem tint slate), espelha on-surface/outline (DESIGN §2) */
  --rmf-white:        #FFFFFF;
  --rmf-ink:          #1C1B1F;            /* on-surface — texto forte/título */
  --rmf-ink-muted:    #45464C;            /* on-surface-variant — texto/ícone secundário */
  --rmf-ink-subtle:   #76777C;            /* outline — ícone/placeholder sutil */
  --rmf-ink-faint:    #9A9AA0;            /* neutro mais fraco (disabled/hint) */

  /* Estado ativo (chips / links / FAB) — família primary do m3 */
  --rmf-state-bg:     #DCE1FA;            /* primary-container (claro) */
  --rmf-state-fg:     #36426A;            /* texto sobre o container (claro) */
  --rmf-state-bg-dk:  #36426A;            /* primary-container (escuro) */
  --rmf-state-fg-dk:  #DCE1FA;            /* on-primary-container (escuro) */
  --rmf-state-bd-dk:  #B7C0E5;            /* inverse-primary (escuro) */

  /* Navegação ativa (rail / bottom-nav): acento via --rmf-select-fill (primary@12%)
     + --md-sys-color-primary — DESIGN §9/§3.2. Sem tokens próprios de cor. */

  /* Superfícies — NEUTRAS (sem tint lavanda/slate); escuro alinhado ao DESIGN §1 */
  --rmf-rail-bg:      #F4F4F5;            /* rail/bottom-nav (claro) — cinza neutro, destaca do branco */
  --rmf-pill-dk:      #26262B;            /* pill / ctrl-group (escuro) — lift neutro = surface-container-high */
  --rmf-dk-surface:   #0D0E13;            /* painéis/modais (escuro) = surface */
  --rmf-dk-surface-2: #141418;            /* rail/bottom-nav (escuro) — leve degrau sobre o surface */
  --rmf-dk-border:    #2A2A2F;            /* bordas/divisores (escuro) */
  --rmf-dk-on:        #C6C6CC;            /* texto/ícone (escuro) = on-surface-variant */
  --rmf-dk-on-2:      #E6E1E5;            /* texto forte (escuro) = on-surface */
}

/* ════════════════════════════════════════════════════════════════
   Rebrand — sobrescreve o azul do Tailwind pela família #4B5C92 (primary).
   Carregado DEPOIS do build do Tailwind, vence pelos vars:
     • --color-brand  → todas as utilities bg-brand/text-brand/…
     • escala --color-blue-* (usada nas utilities) → tons lavanda;
       o escopo claro/escuro é preservado (as utilities dark: já
       vivem em @media prefers-color-scheme).
     • --color-blue-700 = brand → hover:bg-blue-700 fica igual ao
       fundo: hover sem mudança de cor (só sombra/escala, p/ casar
       com os FABs).
   ════════════════════════════════════════════════════════════════ */
:root {
  /* !important garante que estes vars vençam o @layer theme do Tailwind,
     independente de ordem de carregamento (o build é preload+async). */
  --color-brand:       #4B5C92 !important;   /* primary (DESIGN.md, seed #2563EB) */
  --color-brand-light: #DCE1FA !important;   /* era #eff6ff (azul) → primary-container */
  --color-blue-50:  #ECEEFB !important;
  --color-blue-100: #DCE1FA !important;   /* primary-container */
  --color-blue-200: #C5CBEC !important;
  --color-blue-300: #B7C0E5 !important;   /* inverse-primary (acento dark) */
  --color-blue-400: #B7C0E5 !important;
  --color-blue-700: #4B5C92 !important;   /* = brand → neutraliza o hover */
  --color-blue-800: #36426A !important;   /* texto escuro (claro) / borda (escuro) */
  --color-blue-900: #2B3556 !important;
}


/* ════════════════════════════════════════════════════════════════
   Mapa, overlays, header flutuante, pill de busca e chips de modo
   ════════════════════════════════════════════════════════════════ */
#map {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}

.overlay-ativo {
            display: block !important;
            opacity: 1 !important;
            visibility: visible !important;
            z-index: 9999 !important;
        }
        .modal-ativo {
            transform: scale(1) !important;
        }

/* ════════════════════════════════════════════════════════════════
   Alinhamento visual com a home do app Flutter (Material 3 / seed #2563EB).
   O #map já é fullscreen; o header deixa de ser barra sólida e vira uma
   camada flutuante transparente — só a pill de busca e os chips de modo
   capturam toque, o resto deixa o mapa interagir por baixo.
   ════════════════════════════════════════════════════════════════ */
header.rmf-floating {
  background: transparent !important;
  border: none !important;
  display: flex !important;
  flex-direction: column;            /* mobile: busca em cima, chips embaixo (igual phone do Flutter) */
  align-items: stretch;
  gap: 8px;
  height: auto !important;
  padding: 8px !important;
  padding-top: calc(env(safe-area-inset-top, 0px) + 8px) !important;
  pointer-events: none;
}
header.rmf-floating > * { pointer-events: auto; }

/* Pill de busca — colorScheme.surface, radius full (DESIGN §6), elevation ~3 */
.rmf-pill {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  width: 100%;           /* mobile: largura cheia (override no ≥640) */
  min-width: 0;
  padding: 4px 6px;
  border-radius: var(--rmf-radius-full);
  background: var(--rmf-white);
  box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 2px 8px rgba(0,0,0,.14);
}
@media (prefers-color-scheme: dark) {
  .rmf-pill {
    background: var(--rmf-pill-dk);
    box-shadow: 0 2px 10px rgba(0,0,0,.55);
  }
}
.rmf-search-box {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  min-width: 0;
  gap: 8px;
  padding-left: 6px;
}
.rmf-search-ic { font-size: 14px; color: var(--rmf-ink-subtle); flex: none; }
.dark .rmf-search-ic { color: var(--rmf-ink-faint); }
/* Logo RMF como glifo de fonte (fa-rmf): cor segue o placeholder "Buscar cidade…",
   igual ao colorFilter do app no Flutter. */
.rmf-search-logo {
  width: 46px; height: 46px; flex: none;
  font-size: 40px;
  color: var(--rmf-ink-subtle);
  display: flex; align-items: center; justify-content: center;
}
@media (prefers-color-scheme: dark) { .rmf-search-logo { color: var(--rmf-dk-on); } }
.dark .rmf-search-logo { color: var(--rmf-dk-on); }
.rmf-search {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  border: none;
  background: transparent;
  outline: none;
  font-size: 15px;
  color: var(--rmf-ink);
}
.rmf-search::placeholder { color: var(--rmf-ink-subtle); }
@media (prefers-color-scheme: dark) {
  .rmf-search { color: var(--rmf-dk-on); }
  .rmf-search::placeholder { color: var(--rmf-dk-on); }
}
.rmf-search:disabled { opacity: .5; }

/* Ícones de ação dentro da pill — onSurfaceVariant */
.rmf-pill-icon {
  width: 40px; height: 40px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 9999px;
  background: transparent; cursor: pointer;
  color: var(--rmf-ink-muted); font-size: 16px;
  transition: background .15s, color .15s;
}
/* Material Icons têm padding interno no glifo: a 16px saem menores que o FA.
   Bump só para os ícones MI da pill (sparkles/bell/star). */
.rmf-pill-icon .mi { font-size: 22px; }
.rmf-pill-icon:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface) 6%, transparent); }
@media (prefers-color-scheme: dark) { .rmf-pill-icon { color: var(--rmf-dk-on); } }
.dark .rmf-pill-icon:hover { background: rgba(255,255,255,.08); }
/* Favoritos: mesma cor dos demais ícones da pill (era dourado #F59E0B) */
.rmf-pill-icon.rmf-clear { width: 32px; height: 32px; font-size: 13px; }
.rmf-pill-divider {
  flex: none; width: 1px; height: 20px; margin: 0 4px;
  background: var(--md-sys-color-outline-variant);
}

/* ── Balão de notificações: pequeno popover que aponta para o sino da pill,
   na cor da marca (substitui o antigo banner centralizado). ── */
.notif-balloon {
  position: absolute;
  top: calc(100% + 10px);
  left: 0; right: 0;
  z-index: 2100;
  pointer-events: none;            /* só o card recebe toques */
  opacity: 0;
  transform: translateY(-6px) scale(.96);
  transform-origin: top right;
  transition: opacity .24s ease, transform .24s cubic-bezier(.2,.8,.2,1);
}
.notif-balloon.hidden { display: none; }
.notif-balloon.is-open { opacity: 1; transform: translateY(0) scale(1); }
/* Seta (left definido via JS para cair exatamente sob o sino) */
.notif-balloon__arrow {
  position: absolute;
  top: -6px;                       /* metade superior fica acima do card → ponta p/ cima */
  width: 14px; height: 14px;
  margin-left: -7px;               /* centraliza no left calculado */
  background: var(--rmf-brand);
  border-radius: 3px 0 0 0;
  transform: rotate(45deg);
}
.notif-balloon__card {
  position: relative;
  pointer-events: auto;
  width: min(290px, calc(100% - 4px));
  margin-left: auto;               /* encosta à direita, perto do sino */
  padding: 14px 14px 12px;
  border-radius: var(--rmf-radius-lg);       /* popover → lg (DESIGN §6/§8) */
  background: var(--rmf-brand);
  color: var(--rmf-white);
  box-shadow: 0 8px 28px rgba(0,0,0,.28);
}
.notif-balloon__close {
  position: absolute; top: 8px; right: 8px;
  width: 26px; height: 26px; border: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.14); color: var(--rmf-white);
  font-size: 12px; cursor: pointer; transition: background .15s;
}
.notif-balloon__close:hover { background: rgba(255,255,255,.26); }
.notif-balloon__row { display: flex; align-items: flex-start; gap: 10px; padding-right: 22px; }
.notif-balloon__icon {
  flex: none; width: 34px; height: 34px; border-radius: var(--rmf-radius-sm);
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.16); color: var(--rmf-white); font-size: 15px;
}
.notif-balloon__text { min-width: 0; }
.notif-balloon__title { margin: 1px 0 2px; font-size: 13px; font-weight: 700; line-height: 1.2; color: var(--rmf-white); }
.notif-balloon__body { margin: 0; font-size: 11.5px; line-height: 1.35; color: rgba(255,255,255,.86); }
.notif-balloon__cta {
  margin-top: 11px; width: 100%; padding: 8px 12px; border: none; border-radius: var(--rmf-radius-md);
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: var(--rmf-white); color: var(--rmf-brand);
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; transition: opacity .15s;
}
.notif-balloon__cta:hover { opacity: .9; }
.notif-balloon__cta i { font-size: 12px; }

/* ════════════════════════════════════════════════════════════════
   DROPDOWN DA BUSCA — espelha o SearchOverlay do app (M3).
   Tile de Busca Avançada (tint de primary, some ao digitar), seções
   com header (ícone+rótulo+ação) e cards surfaceContainerHigh com
   divisores recuados. Tudo via tokens --md-sys-color-*, que já viram
   sozinhos no dark — sem variantes .dark aqui.
   ════════════════════════════════════════════════════════════════ */

/* Busca Avançada: tile com leve tint de primary; ícone e título em primary. */
.rmf-adv-tile {
  display: flex; align-items: center; gap: 12px;
  margin: 8px; padding: 12px 14px;
  width: calc(100% - 16px);
  border: none; cursor: pointer; text-align: left;
  border-radius: var(--rmf-radius-md);
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
  transition: background .15s;
}
.rmf-adv-tile:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 15%, transparent);
}
.rmf-adv-tile__ic   { flex: none; font-size: 20px; color: var(--md-sys-color-primary); }
.rmf-adv-tile__body { min-width: 0; flex: 1; }
.rmf-adv-tile__title{ font-size: 14px; font-weight: 600; color: var(--md-sys-color-primary); }
.rmf-adv-tile__sub  { font-size: 12px; margin-top: 1px; color: var(--md-sys-color-on-surface-variant); }
.rmf-adv-tile__chev { flex: none; font-size: 13px; color: var(--md-sys-color-on-surface-variant); }

/* Header de seção (Buscas recentes / Resultados). */
.rmf-srch-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px 6px;
}
.rmf-srch-head__ic    { font-size: 15px; color: var(--md-sys-color-on-surface-variant); }
.rmf-srch-head__label { flex: 1; font-size: 13px; font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
.rmf-srch-head__action {
  flex: none; border: none; background: none; cursor: pointer;
  padding: 4px 8px; border-radius: 8px;
  font-size: 13px; font-weight: 600; color: var(--md-sys-color-primary);
}
.rmf-srch-head__action:hover { background: color-mix(in srgb, var(--md-sys-color-primary) 10%, transparent); }

/* Card que envolve a lista (recentes/resultados). */
.rmf-srch-card {
  margin: 0 8px 8px; border-radius: var(--rmf-radius-md); overflow: hidden;
  background: var(--md-sys-color-surface-container-high);
}

/* Item da lista. Divisor recuado (estilo Google Maps): alinhado após o ícone. */
.rmf-srch-item {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 6px 10px 14px; cursor: pointer;
  transition: background .12s;
}
.rmf-srch-item:hover,
.rmf-srch-item.rmf-sel { background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent); }
.rmf-srch-item:not(:first-child)::before {
  content: ''; position: absolute; left: 44px; right: 0; top: 0; height: 1px;
  background: var(--md-sys-color-outline-variant);
}
.rmf-srch-item__ic   { flex: none; width: 18px; text-align: center; font-size: 16px; color: var(--md-sys-color-on-surface-variant); }
.rmf-srch-item__body { min-width: 0; flex: 1; }
.rmf-srch-item__title{ font-size: 14px; font-weight: 600; color: var(--md-sys-color-on-surface);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rmf-srch-item__sub  { font-size: 12px; margin-top: 1px; color: var(--md-sys-color-on-surface-variant);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rmf-srch-item__del {
  flex: none; width: 32px; height: 32px; border: none; background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9999px; font-size: 13px; color: var(--md-sys-color-on-surface-variant);
  transition: background .12s, color .12s;
}
.rmf-srch-item__del:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); color: var(--md-sys-color-on-surface); }

/* Spinner enquanto busca. */
.rmf-srch-loading { display: flex; justify-content: center; padding: 22px; font-size: 20px; color: var(--md-sys-color-primary); }

/* Estado vazio (nenhuma cidade encontrada). */
.rmf-srch-hint { padding: 24px 22px; text-align: center; }
.rmf-srch-hint__ic    { font-size: 32px; color: var(--md-sys-color-outline); }
.rmf-srch-hint__title { margin-top: 10px; font-size: 15px; font-weight: 600; color: var(--md-sys-color-on-surface); }
.rmf-srch-hint__body  { margin-top: 4px; font-size: 12.5px; line-height: 1.45; color: var(--md-sys-color-on-surface-variant); }
.rmf-srch-hint__btn {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 14px; padding: 8px 16px; border: none; cursor: pointer;
  border-radius: 9999px; font-size: 13px; font-weight: 600;
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
}
.rmf-srch-hint__btn:hover { filter: brightness(0.97); }

/* Chips de modo — mode_chips_bar (radius 18, ativo = primaryContainer) */
.rmf-chips {
  display: flex; align-items: center; gap: 8px;
  width: 100%;           /* mobile: linha própria abaixo da busca (override no ≥640) */
  min-width: 0;
  padding: 4px 2px;      /* folga vertical pra sombra dos chips não cortar */
  overflow-x: auto;
  -ms-overflow-style: none; scrollbar-width: none;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}
.rmf-chips::-webkit-scrollbar { display: none; }
/* Estado ocultado quando qualquer modal/painel está aberto. */
.rmf-chips.chips-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
/* No mobile os chips são uma 2ª linha, exatamente onde os painéis sobem; só
   visibility:hidden deixaria-os invisíveis mas ocupando a camada (z-1100) por
   cima do cabeçalho (X/share). display:none remove-os de vez do hit-testing.
   No desktop os chips ficam na linha da busca (não sobrepõem o painel) e usar
   display:none faria a pill esticar/“pular” — por isso só aplicamos no mobile. */
@media (max-width: 639px) {
  .rmf-chips.chips-hidden { display: none; }
  /* Full-bleed: a barra rola de borda a borda da tela (sensação de scroll
     "infinito"). Margens negativas cancelam o padding 8px do header; o padding
     interno mantém o 1º/último chip recuados em repouso, mas a pista de scroll
     vai até a borda — sem os "cantos transparentes" que cortavam o movimento. */
  .rmf-chips {
    width: auto;             /* SEM isto, width:100% + margens negativas fica sobre-restringido
                                e o margin-right:-8px é ignorado → recuo de ~16px na direita */
    margin-left: -8px;
    margin-right: -8px;
    padding-left: 8px;
    padding-right: 0;        /* o último chip cola na borda da tela (infinito) */
    scroll-padding-left: 8px;
  }
}
.rmf-chips .tab-btn {
  display: inline-flex; align-items: center; gap: 6px;
  white-space: nowrap; flex: none;
  height: 32px; padding: 0 12px;
  border-radius: 18px;
  font-size: 13px; font-weight: 600; line-height: 1;
  background: var(--rmf-white); color: var(--rmf-ink);
  border: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 60%, transparent);
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.rmf-chips .tab-btn i { font-size: 14px; }
@media (prefers-color-scheme: dark) {
  .rmf-chips .tab-btn {
    background: var(--rmf-dk-surface);
    color: var(--rmf-dk-on-2);
    border-color: var(--rmf-dk-border);
  }
}
.rmf-chips .tab-btn.tab-active {
  background: var(--rmf-state-bg);
  color: var(--rmf-state-fg);
  border-color: var(--rmf-brand);
  box-shadow: 0 2px 5px rgba(0,0,0,.18);
}
/* Chip de modo desabilitado (SLE × Amador são mutuamente exclusivos: ativar um
   bloqueia o outro). syncRadioChips() espelha o .disabled do <input> oculto. */
.rmf-chips .tab-btn.chip-disabled {
  opacity: .4;
  pointer-events: none;
}
@media (prefers-color-scheme: dark) {
  .rmf-chips .tab-btn.tab-active {
    background: var(--rmf-state-bg-dk);
    color: var(--rmf-state-fg-dk);
    border-color: var(--rmf-state-bd-dk);
    box-shadow: 0 2px 5px rgba(0,0,0,.35);
  }
}

/* Fade de rolagem: mask-image nas bordas indica chips além das bordas visíveis. */
.rmf-chips[data-fade="right"] {
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
  mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
}
.rmf-chips[data-fade="left"] {
  -webkit-mask-image: linear-gradient(to right, transparent, black 24px);
  mask-image: linear-gradient(to right, transparent, black 24px);
}
.rmf-chips[data-fade="both"] {
  -webkit-mask-image: linear-gradient(to right, transparent, black 24px, black calc(100% - 24px), transparent);
  mask-image: linear-gradient(to right, transparent, black 24px, black calc(100% - 24px), transparent);
}

/* ≥640px (tablet/desktop): busca à esquerda, chips à direita na mesma linha.
   Abaixo disso a coluna do header empilha os chips sob a busca (phone). */
@media (min-width: 640px) {
  header.rmf-floating { flex-direction: row; align-items: center; }
  /* flex-basis FIXO (não 'auto'): com basis no conteúdo, mostrar/ocultar o
     #search-spinner (um .rmf-pill-icon de 40px) mudava a largura-conteúdo da pill
     e ela "crescia" disputando espaço com os chips. Com basis = --search-w a
     largura externa independe do conteúdo interno (o search-box é que encolhe). */
  .rmf-pill { flex: 1 1 var(--search-w, 480px); width: auto; max-width: var(--search-w, 480px); }
  /* Cresce pra preencher o vão entre a busca e o botão "Baixar app" (sem isto,
     flex:0 1 auto deixava o espaço sobrando virar recuo via margin-left:auto do
     CTA). À direita, margem negativa cancela o gap:8px do header → o último chip
     encosta no botão e o scroll vai até a borda. À esquerda, a margem negativa
     estende a PISTA de scroll por baixo da busca, mas o padding-left igual empurra
     o 1º chip de volta pra fora em repouso → ele só desliza pra dentro NO SCROLL
     (mesmo full-bleed do mobile). */
  .rmf-chips {
    flex: 1 1 auto; width: auto;
    margin-left: -14px;
    margin-right: -8px;
    padding-left: 14px;
    padding-right: 8px;
    scroll-padding-left: 14px;
    scroll-padding-right: 8px;
  }
}

/* CTA "Baixar app" — botão de AÇÃO (não filtro): preenchido com a cor da marca
   e cantos mais retos (10px vs. 18px dos chips). SÓ NO DESKTOP: fica à direita,
   logo após a barra de chips (que cresce com flex:1 e encosta no botão).
   No mobile o CTA vive na bottom-nav (botão .bn-cta ao lado do "Mais").
   Some junto com os chips quando abre painel/modal (classe .chips-hidden). */
.rmf-getapp {
  display: none;                      /* mobile: oculto (CTA vive na bottom-nav) */
  align-items: center; gap: 11px;
  flex: none; white-space: nowrap;
  height: auto; padding: 7px 24px;    /* mais alto (2 linhas) e mais largo lateralmente */
  border-radius: var(--rmf-radius-md); /* CTA → md (cantos mais quadrados que os chips) */
  color: #fff; background: var(--rmf-brand);
  border: 1px solid var(--rmf-brand);
  box-shadow: 0 2px 6px rgba(75,92,146,.35);
  cursor: pointer;
  transition: filter .15s, box-shadow .15s, transform .05s, opacity .22s ease, visibility .22s ease;
}
.rmf-getapp i { font-size: 20px; }
/* Bloco de texto em 2 linhas: título + subtítulo */
.rmf-getapp .getapp-text { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; }
.rmf-getapp .getapp-title { font-size: 14px; font-weight: 700; line-height: 1.15; }
.rmf-getapp .getapp-sub { font-size: 10.5px; font-weight: 500; line-height: 1.1; opacity: .85; }
.rmf-getapp:hover { filter: brightness(1.08); box-shadow: 0 3px 10px rgba(75,92,146,.45); }
.rmf-getapp:active { transform: translateY(1px); }
.rmf-getapp.chips-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
@media (min-width: 640px) {
  /* Sem margin-left:auto: margens automáticas absorvem o espaço livre ANTES do
     flex-grow, então deixá-la aqui impediria a barra de chips de crescer (e o vão
     voltaria). Os chips agora preenchem até aqui e o CTA cola logo após eles. */
  .rmf-getapp { display: inline-flex; flex: none; }   /* desktop: canto direito, após os chips */
}

/* Botão CTA na bottom-nav (mobile) — cor e forma diferentes dos demais itens:
   ícone preenchido com a marca (vs. transparente) e rótulo na cor da marca.
   Compacto (flex:none) pra não espremer os outros 4 itens da navbar.
   Escondido no app nativo via .getapp-entry (ver JS). */
.bn-cta { flex: 0 0 auto; padding: 6px 12px; }
.bn-cta .bn-ic {
  width: 46px;
  background: var(--rmf-brand);
  color: #fff;
  border-radius: 12px;                /* forma um pouco mais quadrada que os 16px dos demais */
  box-shadow: 0 2px 6px rgba(75,92,146,.4);
}
.bn-cta .bn-lbl { color: var(--rmf-brand); font-weight: 700; white-space: nowrap; }
.bn-cta:active .bn-ic { filter: brightness(1.1); }
@media (prefers-color-scheme: dark) {
  .bn-cta .bn-lbl { color: var(--rmf-brand-300); }
}

/* ════════════════════════════════════════════════════════════════
   Navegação principal (rail desktop / bottom-nav mobile / sheet "Mais")
   ════════════════════════════════════════════════════════════════ */
/* ============================================================
   NAVEGAÇÃO PRINCIPAL
   - Desktop/tablet (≥640px): rail vertical à ESQUERDA (72px),
     protegido por safe-area-inset-left/bottom.
   - Mobile (<640px): barra inferior, protegida por
     safe-area-inset-bottom.
   ============================================================ */
:root {
  --rail-w: 0px;                                       /* mobile: sem rail */
  --bottomnav-h: calc(60px + env(safe-area-inset-bottom, 0px));
  --search-w: 480px;                                   /* largura da caixa de busca (pill) no desktop */
}
@media (min-width: 640px) {
  :root {
    --rail-w: calc(78px + env(safe-area-inset-left, 0px));
    --bottomnav-h: 0px;                                /* desktop: sem barra inferior */
  }
}

/* Esconde a navegação até o app ficar pronto */
body:not(.app-ready) #rmf-rail,
body:not(.app-ready) #rmf-bottomnav { display: none !important; }

/* Loading do mapa = spinner na caixa de busca (substitui o splash grande) */
#loading { display: none !important; }
/* Barrinha indeterminada do mapa (.lpb "vai e volta") removida: o único
   indicador de carregamento agora é o spinner na caixa de busca. */
#map-progress-bar { display: none !important; }
/* Spinner da busca: aparece na carga inicial (até app-ready) e sempre que o
   mapa estiver carregando tiles (.map-loading espelha o dataloading/idle). */
/* Cor herdada de .rmf-pill-icon (mesma dos demais ícones da caixa de busca). */
#search-spinner { display: none; }
body:not(.app-ready) #search-spinner,
body.map-loading #search-spinner { display: flex; }

/* ---------- Rail vertical (desktop/tablet) ---------- */
#rmf-rail { display: none; }
@media (min-width: 640px) {
  #rmf-rail {
    position: fixed;
    top: 0;                                            /* vai até o topo, protegido pelo safe-inset abaixo */
    left: 0;
    bottom: 0;
    width: var(--rail-w);
    z-index: 890;                                      /* header é transparente+pointer-none, então o rail aparece/clica por baixo dele */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 0;
    padding-top: calc(10px + env(safe-area-inset-top, 0px));
    padding-left: env(safe-area-inset-left, 0px);
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--rmf-rail-bg);
    /* Sem linha divisória: separação pela cor da superfície (DESIGN §9). */
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: none;
  }
  #rmf-rail::-webkit-scrollbar { display: none; }
  /* Busca (header) começa depois do rail */
  header.rmf-floating { padding-left: calc(var(--rail-w) + 8px) !important; }
}
@media (min-width: 640px) and (prefers-color-scheme: dark) {
  #rmf-rail {
    background: var(--rmf-dk-surface-2);
  }
}
#rmf-rail .rail-spacer { flex: 1 1 auto; }
#rmf-rail .rail-sep {
  width: 40px; height: 1px; margin: 6px 0;
  background: var(--md-sys-color-outline-variant);
}
@media (prefers-color-scheme: dark) { #rmf-rail .rail-sep { background: var(--md-sys-color-outline-variant); } }

/* Item com rótulo (Novidades / Estatísticas / Dados) */
/* Acento de seleção §9/§3.2: indicador primary@12% + ícone primary; rótulo
   onSurface (ativo) / onSurfaceVariant (repouso). Tokens theme-aware → sem
   bloco @media dark (a paleta já vira sozinha no escuro). */
.rail-btn {
  width: 74px;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 0 4px;
  border: none; background: transparent; cursor: pointer;
  color: var(--md-sys-color-on-surface-variant);     /* repouso: rótulo + ícone */
  -webkit-tap-highlight-color: transparent;
}
.rail-btn .rail-ic {
  width: 56px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--rmf-radius-full); font-size: 18px;   /* pílula indicadora (stadium) */
  transition: background .15s, color .15s;
}
.rail-btn .rail-lbl {
  font-size: 10px; font-weight: 600; line-height: 1;
  white-space: nowrap; letter-spacing: -0.2px;
}
.rail-btn:hover .rail-ic { background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); color: var(--md-sys-color-primary); }
.rail-btn.rail-active { color: var(--md-sys-color-on-surface); }     /* rótulo ativo */
.rail-btn.rail-active .rail-ic { background: var(--rmf-select-fill); color: var(--md-sys-color-primary); }

/* Item só ícone (Notificações / Instalação / Feedback / Sobre) */
.rail-mini {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; cursor: pointer;
  border-radius: 9999px; color: var(--md-sys-color-on-surface-variant); font-size: 17px;
  transition: background .15s, color .15s;
  -webkit-tap-highlight-color: transparent;
}
.rail-mini:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface) 6%, transparent); color: var(--md-sys-color-primary); }

/* ---------- Barra inferior (mobile) ---------- */
#rmf-bottomnav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 889; /* acima do #app-install-banner (888): o banner desliza vindo de trás da navbar */
  display: flex;
  align-items: stretch;
  height: var(--bottomnav-h);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--rmf-rail-bg);
  /* Sem linha divisória: separação pela cor da superfície (DESIGN §9). */
}
@media (prefers-color-scheme: dark) {
  #rmf-bottomnav {
    background: var(--rmf-dk-surface-2);
  }
}
@media (min-width: 640px) { #rmf-bottomnav { display: none; } }

.bn-btn {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: none; background: transparent; cursor: pointer;
  color: var(--md-sys-color-on-surface-variant); padding: 6px 0;   /* repouso: rótulo + ícone */
  -webkit-tap-highlight-color: transparent;
}
.bn-btn .bn-ic {
  width: 56px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--rmf-radius-full); font-size: 18px;   /* pílula indicadora (stadium) */
  transition: background .15s, color .15s;
}
.bn-btn .bn-lbl { font-size: 11px; font-weight: 600; line-height: 1; }
.bn-btn.bn-active { color: var(--md-sys-color-on-surface); }     /* rótulo ativo */
.bn-btn.bn-active .bn-ic { background: var(--rmf-select-fill); color: var(--md-sys-color-primary); }

/* ---------- Bottom-sheet "Mais" (mobile) ---------- */
#rmf-more-overlay {
  position: fixed; inset: 0; z-index: 5200;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 50%, transparent);
  opacity: 0; transition: opacity .3s;
}
#rmf-more-overlay.open { opacity: 1; }
#rmf-more-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 5201;
  background: var(--rmf-white);
  border-radius: 20px 20px 0 0;
  padding: 8px 12px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -10px 30px rgba(0,0,0,.2);
  transform: translateY(100%);
  transition: transform .3s ease;
  max-height: 80vh;
  overflow-y: auto;
}
#rmf-more-overlay.open #rmf-more-sheet { transform: translateY(0); }
@media (prefers-color-scheme: dark) { #rmf-more-sheet { background: var(--rmf-dk-surface); } }
@media (min-width: 640px) { #rmf-more-overlay { display: none !important; } }
.more-grabber {
  width: 36px; height: 4px; border-radius: 9999px;
  background: var(--md-sys-color-outline-variant); margin: 6px auto 10px;
}
.more-item {
  display: flex; align-items: center; gap: 14px;
  width: 100%; padding: 14px 12px;
  border: none; background: transparent; cursor: pointer;
  border-radius: var(--rmf-radius-md); text-align: left;
  font-size: 15px; font-weight: 500; color: var(--rmf-ink);
}
.more-item i { width: 22px; text-align: center; font-size: 17px; color: var(--rmf-ink-subtle); }
.more-item:hover { background: rgba(75,92,146,.07); }
@media (prefers-color-scheme: dark) {
  .more-item { color: var(--rmf-dk-on-2); }
  .more-item i { color: var(--rmf-ink-faint); }
  .more-item:hover { background: rgba(183,192,229,.12); }
}

/* ---------- MapLibre ctrl-group: estilo alinhado à pill da busca ---------- */
.maplibregl-ctrl-group {
  background: var(--rmf-white) !important;
  border-radius: var(--rmf-radius-md) !important;
  box-shadow: none !important;
  overflow: hidden !important;
}
.maplibregl-ctrl-group button {
  background-color: transparent !important;
}
.maplibregl-ctrl-group button + button {
  border-top-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent) !important;
}
.maplibregl-ctrl-group button:hover {
  background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 6%, transparent) !important;
}
@media (prefers-color-scheme: dark) {
  .maplibregl-ctrl-group {
    background: var(--rmf-pill-dk) !important;
    box-shadow: none !important;
  }
  .maplibregl-ctrl-group button + button { border-top-color: var(--rmf-dk-border) !important; }
  .maplibregl-ctrl-group button:hover    { background-color: rgba(255,255,255,.08) !important; }
  .maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) opacity(.77); }
}
.dark .maplibregl-ctrl-group {
  background: var(--rmf-pill-dk) !important;
  box-shadow: none !important;
}
.dark .maplibregl-ctrl-group button + button { border-top-color: var(--rmf-dk-border) !important; }
.dark .maplibregl-ctrl-group button:hover    { background-color: rgba(255,255,255,.08) !important; }
.dark .maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) opacity(.77); }

/* ---------- Acomoda controles do mapa / FABs ---------- */
/* Desktop: empurra os controles bottom-left para a direita do rail. */
@media (min-width: 640px) {
  .maplibregl-ctrl-bottom-left { margin-left: var(--rail-w) !important; }
}
/* Mobile: sobe controles bottom-left e as FABs acima da barra inferior. */
@media (max-width: 639px) {
  .maplibregl-ctrl-bottom-left { margin-bottom: calc(var(--bottomnav-h) + var(--fab-extra-bottom, 0px) + var(--banner-fab-bottom, 0px)) !important; transition: margin-bottom 300ms ease-in-out; }
  #erb-fabs, #radio-fabs, #fiber-fabs, #amateur-fabs {
    bottom: calc(1.5rem + 60px + env(safe-area-inset-bottom) + var(--fab-extra-bottom, 0px) + var(--banner-fab-bottom, 0px)) !important;
    transition: bottom 300ms ease-in-out;
  }
}

/* ════════════════════════════════════════════════════════════════
   CSS crítico — tela de carregamento (loading)
   ════════════════════════════════════════════════════════════════ */
  
  /* CSS Crítico - RMF Brasil Loading */
  :root {
    --bg-load: #FFFFFF;     /* = surface neutro (DESIGN §1) */
    --text-load: var(--rmf-ink);
    --brand: var(--rmf-brand); /* Azul brand */
    /* Mobile: pill (52px) + gap (8px) + chips (40px) + padding (8+8px) = 116px */
    --header-h: calc(116px + env(safe-area-inset-top, 0px));
    --top-inset: env(safe-area-inset-top, 0px);
  }

  /* Desktop: pill e chips em linha única → 8px + 52px + 8px = 68px */
  @media (min-width: 640px) {
    :root {
      --header-h: calc(68px + env(safe-area-inset-top, 0px));
    }
  }

  /* ── Window Controls Overlay (PWA instalado no desktop) ──────────────
     Com display_override "window-controls-overlay" no manifest, o SO mescla
     a barra de título ao conteúdo: desenha os botões da janela
     (fechar/min/maximizar) POR CIMA da página, numa faixa no topo, e expõe a
     geometria livre via env(titlebar-area-*). O header continua flutuante
     (transparente sobre o mapa) e NÃO muda de lugar — a caixa de busca fica
     exatamente onde já estava. Só fazemos:
       1. reservar à direita a largura ocupada pelos controles da janela, p/ os
          chips e o CTA não ficarem por baixo deles. O cálculo usa
          titlebar-area-x/width e zera sozinho quando os controles estão do
          outro lado (sem env suportado, o fallback também resulta em 8px);
       2. deixar o espaço VAZIO do header arrastar a janela (app-region:drag),
          mantendo pill, chips, botões e inputs clicáveis (no-drag);
       3. proteger o topo do rail: empurra seu conteúdo abaixo da faixa de
          título p/ os controles do SO não cobrirem o 1º item — vale p/
          controles à esquerda (macOS, sobre o rail) e é folga inócua quando
          estão à direita.
     A busca NÃO precisa de recuo à esquerda: o próprio rail (var(--rail-w)
     ≈ 78px) já a afasta de eventuais controles nesse canto — por isso não
     mexemos no padding-left/top dela.
     --header-h segue o valor responsivo (68px desktop); o ResizeObserver no
     JS o reescreve com a altura real após o load. */
  @media (display-mode: window-controls-overlay) {
    :root {
      /* O rail acompanha a largura do overlay: cresce só o NECESSÁRIO p/ bater
         a mesma largura da faixa de controles do macOS (titlebar-area-x). Se o
         rail (78px) já for mais largo, fica como está — por isso max(), não
         soma. A busca usa var(--rail-w) no padding-left → acompanha sozinha.
         Controles à direita (Windows/Linux) → titlebar-area-x = 0 → rail intacto. */
      --rail-w: max(calc(78px + env(safe-area-inset-left, 0px)), env(titlebar-area-x, 0px));
    }
    header.rmf-floating {
      /* reserva à direita a faixa dos controles da janela (zera quando não
         estão nesse lado) + a folga padrão de 8px; a busca, à esquerda, não
         se move */
      padding-right: calc(100% - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100%) + 8px) !important;
      /* a banda de arrasto vai do topo até a base da caixa de busca (52px da
         pill + 8px do padding-top) — bem mais que a barra de título fina do SO,
         dando uma pegada confortável p/ mover a janela. Pill/chips/botões/input
         seguem no-drag (clicáveis), por isso o arrasto só pega o espaço vazio. */
      min-height: calc(52px + 8px) !important;
      /* o espaço vazio arrasta a janela; precisa ser hit-testável p/ isso */
      -webkit-app-region: drag;
      app-region: drag;
      pointer-events: auto;
    }
    /* controles continuam interativos e não movem a janela */
    header.rmf-floating .rmf-pill,
    header.rmf-floating .rmf-chips,
    header.rmf-floating .rmf-getapp,
    header.rmf-floating button,
    header.rmf-floating input,
    header.rmf-floating a {
      -webkit-app-region: no-drag;
      app-region: no-drag;
    }
    /* Rail (desktop): protege a altura — começa abaixo da faixa de título p/
       os controles do SO não cobrirem o item do topo. A largura é tratada pelo
       --rail-w acima (a barra só ALARGA; os ícones, centralizados, seguem
       junto). titlebar-area-height some (=0) quando não há overlay. */
    #rmf-rail {
      padding-top: calc(10px + env(titlebar-area-height, 0px)) !important;
    }
    /* Suaviza a faixa de controles do lado DIREITO (Windows/Linux): prolonga a
       cor do rail p/ dentro do conteúdo com um degradê radial ancorado no canto
       sup. direito, esvaindo p/ baixo e p/ a esquerda — a faixa "some" no mapa
       em vez de cortar reto. A largura = faixa de controles à direita; quando
       eles não estão deste lado (ex.: macOS, titlebar-area-x>0) ela vira 0 e o
       pseudo colapsa (sem sombra). pointer-events:none p/ não pegar o drag. */
    header.rmf-floating::after {
      content: "";
      position: absolute;
      top: env(titlebar-area-y, 0px);
      right: 0;
      /* O prolongamento ACOMPANHA o WCO: o pseudo tem 3× a área da faixa
         (largura dos controles à direita × altura do título), ancorado no canto
         sup. direito — estende 2× largura p/ a esquerda e 2× altura p/ baixo,
         dentro do conteúdo. O gradiente fica sólido sobre a faixa E um pouco
         além (45%) — sem degrau na emenda com o retângulo do SO — e esvai num
         trecho longo (até 100%) → some quase invisível no mapa.
         Some (0) quando não há overlay desse lado. */
      width: calc((100% - env(titlebar-area-x, 0px) - env(titlebar-area-width, 100%)) * 3);
      height: calc(env(titlebar-area-height, 0px) * 3);
      pointer-events: none;
      /* z-index negativo: dentro do stacking context do header (fixed + z-[1100],
         fundo transparente), o degradê pinta atrás dos filhos — fica ATRÁS do
         botão GetApp e dos chips, mas ainda sobre o mapa. */
      z-index: -1;
      background: radial-gradient(100% 100% at 100% 0%, var(--rmf-rail-bg) 45%, transparent 100%);
    }
    .dark header.rmf-floating::after {
      background: radial-gradient(100% 100% at 100% 0%, var(--rmf-dk-surface-2) 45%, transparent 100%);
    }
  }
  /* Mesma suavização da faixa de controles, no escuro por preferência do SO. */
  @media (display-mode: window-controls-overlay) and (prefers-color-scheme: dark) {
    header.rmf-floating::after {
      background: radial-gradient(100% 100% at 100% 0%, var(--rmf-dk-surface-2) 45%, transparent 100%);
    }
  }

  /* Suporte nativo e instantâneo ao Dark Mode */
  @media (prefers-color-scheme: dark) {
    :root {
      --bg-load: #0D0E13;     /* = surface escuro neutro (DESIGN §1) */
      --text-load: var(--rmf-white);
    }
  }

  /* Garante que o header (área da barra de status iOS) já tenha a cor correta
     antes do Tailwind carregar, evitando flash de cor diferente no safe-area. */
  header {
    background-color: var(--bg-load);
  }

  /* iOS PWA pinta a área da status bar / safe-area com o background do
     <html>/<body>. Sem isso, o iPhone mostra branco (UA default) ou o
     slate-100 do Tailwind, criando faixas de cor diferente do header. */
  html, body {
    background-color: var(--bg-load);
  }

  /* Container Principal */
  #loading {
    position: fixed; 
    bottom: 0; left: 0; right: 0;
    top: var(--header-h);
    z-index: 1000;
    background-color: var(--bg-load);
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    justify-content: center;
    /* Fonte do sistema (não bloqueia a renderização esperando o arquivo de fonte) */
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    transition: opacity 0.5s ease-out;
  }

  /* Animação do Ping (Bolinha pulsando) */
  @keyframes rmf-ping {
    75%, 100% { transform: scale(2); opacity: 0; }
  }
  #loading .animate-ping {
    position: absolute; inset: 0; border-radius: 9999px;
    background-color: rgba(75,92,146, 0.3);
    animation: rmf-ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
  }

  /* Tipografia Base */
  #loading .text-2xl { 
    font-size: 1.5rem; 
    font-weight: 300; 
    color: var(--text-load); 
    margin-bottom: 0.5rem; 
    letter-spacing: -0.025em;
  }
  #loading .text-2xl b { font-weight: 700; color: var(--brand); margin-left: 0.25rem; }
  
  #loading #lmsg { 
    font-size: 10px; 
    font-weight: 700; 
    text-transform: uppercase; 
    letter-spacing: 0.1em; 
    color: var(--rmf-ink-faint); 
    margin-bottom: 1.5rem; 
  }

  /* Barra de Progresso */
  #loading .w-64 { 
    width: 16rem; 
    height: 0.5rem; 
    border-radius: 9999px; 
    background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent); 
    overflow: hidden; 
  }
  #loading .lpb { 
    height: 100%; 
    border-radius: 9999px; 
    background: linear-gradient(to right, var(--brand), var(--rmf-brand-light)); 
    box-shadow: 0 0 10px rgba(75,92,146,0.5); 
    width: 5%; /* Largura inicial mínima para mostrar que está vivo */
    transition: width 0.2s ease-out; 
  }


/* ════════════════════════════════════════════════════════════════
   FABs, animações e painéis deslizantes (detalhes / filtros)
   ════════════════════════════════════════════════════════════════ */
/* FAB containers: gap entre botões não captura cliques (vai pro mapa);
   só os botões filhos respondem. Equivale a [&>*]:pointer-events-auto do
   Tailwind v4, escrito em CSS puro porque o CSS estático servido pode não
   ter o arbitrary selector compilado. */
#erb-fabs > *, #radio-fabs > *, #fiber-fabs > *, #amateur-fabs > * { pointer-events: auto; }

/* Animação suave para as abas do Modal */
  @keyframes fadeInTab {
    from { 
      opacity: 0; 
      transform: translateY(8px); 
    }
    to { 
      opacity: 1; 
      transform: translateY(0); 
    }
  }
  .animate-fade-in {
    animation: fadeInTab 0.25s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  }

  @keyframes ai-wand-pulse {
    0%, 100% { background-color: transparent; color: var(--md-sys-color-on-surface-variant); }
    50%       { background-color: var(--rmf-select-fill); color: var(--rmf-brand); }
  }
  .dark .ai-wand-pulse {
    animation: ai-wand-pulse-dark 0.7s ease-in-out 1;
  }
  @keyframes ai-wand-pulse-dark {
    0%, 100% { background-color: transparent; color: var(--md-sys-color-on-surface-variant); }
    50%       { background-color: var(--rmf-select-fill); color: var(--md-sys-color-primary); }
  }
  .ai-wand-pulse {
    animation: ai-wand-pulse 0.7s ease-in-out 1;
  }

  @keyframes bell-shake {
    0%   { transform: rotate(0); }
    12%  { transform: rotate(-20deg); }
    24%  { transform: rotate(20deg); }
    36%  { transform: rotate(-15deg); }
    48%  { transform: rotate(15deg); }
    60%  { transform: rotate(-8deg); }
    72%  { transform: rotate(8deg); }
    85%  { transform: rotate(-3deg); }
    100% { transform: rotate(0); }
  }
  .bell-shake {
    animation: bell-shake 0.85s ease-in-out 1;
    transform-origin: top center;
    display: inline-block;
  }

  .fp-tab-active { background: white; color: var(--rmf-brand); box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
  .dark .fp-tab-active { background: var(--rmf-ink); color: var(--rmf-brand-light); }

  /* Capacitor (Android WebView): backdrop-filter é caro — desabilita e deixa
     o fundo semi-opaco do Tailwind (bg-slate-900/70 etc.) cobrir o efeito. */
  html.is-capacitor .backdrop-blur-sm,
  html.is-capacitor .backdrop-blur,
  html.is-capacitor .backdrop-blur-md,
  html.is-capacitor .backdrop-blur-lg {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* Promove para camada de composição GPU os elementos que animam com mais
     frequência (entradas/saídas de menu, modais e transições de página). */
  #side-menu,
  #side-menu-overlay,
  #subpage-overlay,
  #page-transition,
  #api-modal,
  #api-modal-overlay,
  #update-modal,
  #update-modal-overlay,
  #settings-modal,
  #settings-modal-overlay,
  #push-invite-banner {
    will-change: transform, opacity;
  }

  /* Painéis de Filtros (baixo→cima): animam via transform translateY (compositor GPU).
     O JS continua trocando `.dp-open` / `.panel-open` — só reagimos a elas. */
  #dp, #radio-dp, #fiber-dp, #city-dp,
  #fp, #radio-fp, #fiber-fp, #amateur-fp {
    transition-property: transform !important;
    transition-duration: 300ms;
    transition-timing-function: ease-in-out;
    will-change: transform;
  }
  /* Painéis de Detalhes (Estação ERB / Rádio-TV / Enlace de Fibra / Cidade): ficam
     APÓS o rail (left:--rail-w) e ABAIXO da busca (top:--header-h), surgindo
     de baixo pra cima via translateY (transform = compositor GPU, eficiente). */
  #dp, #radio-dp, #fiber-dp, #city-dp {
    z-index: 901 !important;
    left: var(--rail-w) !important;
    top: calc(env(safe-area-inset-top, 0px) + 116px) !important;
    border-top-left-radius: var(--rmf-radius-lg);
    border-top-right-radius: var(--rmf-radius-lg);
    border-bottom-right-radius: 0;
    border-right-width: 0;
    transform: translateY(100%);
  }
  #city-dp { z-index: 100 !important; }
  @media (min-width: 640px) {
    #dp, #radio-dp, #fiber-dp, #city-dp {
      top: calc(env(safe-area-inset-top, 0px) + 68px) !important;
      left: var(--dp-left, calc(var(--rail-w) + 8px)) !important;
      width: var(--dp-width, var(--search-w));
    }
  }
  #dp, #radio-dp, #fiber-dp, #city-dp { overflow: hidden; }
  #dp.dp-open, #radio-dp.dp-open, #fiber-dp.dp-open, #city-dp.dp-open {
    transform: translateY(0);
    will-change: auto;
  }
  #city-dp.city-dp-peek {
    transform: translateY(calc(100% - 52px)) !important;
  }
  #city-dp.dp-open #city-dp-expand { display: none; }
  /* Mobile: painel acima da barra de navegação inferior */
  #city-dp { bottom: var(--bottomnav-h) !important; border-radius: var(--rmf-radius-lg) var(--rmf-radius-lg) 0 0 !important; }
  @media (min-width: 640px) {
    /* Desktop: centralizado na área de conteúdo (excluindo rail) */
    #city-dp {
      left: calc((100vw + var(--rail-w) - var(--dp-width, var(--search-w))) / 2) !important;
      bottom: 0 !important;
      border-radius: var(--rmf-radius-lg) var(--rmf-radius-lg) 0 0 !important;
    }
  }
  #fp, #radio-fp, #fiber-fp, #amateur-fp {
    right: 0 !important;
    /* Mesmo mecanismo dos dp panels: fallback CSS até o ResizeObserver
       medir e injetar o valor real via setProperty(...,'important'). */
    top: calc(env(safe-area-inset-top, 0px) + 116px) !important;
    border-top-left-radius: var(--rmf-radius-lg);
    border-top-right-radius: var(--rmf-radius-lg);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    overflow: hidden;
    transform: translateY(100%);
  }
  @media (min-width: 640px) {
    #fp, #radio-fp, #fiber-fp, #amateur-fp { top: calc(env(safe-area-inset-top, 0px) + 68px) !important; }
  }
  #fp.panel-open, #radio-fp.panel-open, #fiber-fp.panel-open, #amateur-fp.panel-open {
    transform: translateY(0);
    will-change: auto;
  }


/* ════════════════════════════════════════════════════════════════
   Paleta dark personalizada (fundo #0D0E13 / bordas #2A2A2F — tokens --rmf-dk-*)
   ════════════════════════════════════════════════════════════════ */
@media (prefers-color-scheme: dark) {

  /* ── 1. Fundo principal: painéis laterais + modais centrais ── */
  #fp, #radio-fp, #fiber-fp, #amateur-fp,
  #dp, #radio-dp,  #fiber-dp,
  #side-menu,
  #ai-modal, #settings-modal, #about-modal,
  #signal-modal,  #api-modal {
    background-color: var(--rmf-dk-surface) !important;
  }

  /* ── 2. Borda lateral dos painéis deslizantes ── */
  #fp, #radio-fp, #fiber-fp, #amateur-fp,
  #dp, #radio-dp,  #fiber-dp {
    border-color: var(--rmf-dk-border) !important;
  }

  /* ── 3. Cabeçalhos internos (primeiro .shrink-0) ── */
  #fp    > .shrink-0, #radio-fp  > .shrink-0, #fiber-fp  > .shrink-0, #amateur-fp > .shrink-0,
  #dp    > .shrink-0, #radio-dp  > .shrink-0, #fiber-dp  > .shrink-0,
  #side-menu > .shrink-0 {
    background-color: var(--rmf-dk-surface) !important;
    border-color:     var(--rmf-dk-border) !important;
  }

  /* ── 4. Divisores h-px dentro dos painéis ── */
  #fp .h-px,    #radio-fp .h-px,  #fiber-fp .h-px,  #amateur-fp .h-px,
  #dp .h-px,    #radio-dp .h-px,  #fiber-dp .h-px,
  #side-menu .h-px {
    background-color: var(--rmf-dk-border) !important;
  }

  /* ── 5. Todas as bordas neutras dentro dos painéis laterais ── */
  #fp    .border-b, #fp    .border-t, #fp    .border,
  #radio-fp .border-b, #radio-fp .border-t, #radio-fp .border,
  #fiber-fp .border-b, #fiber-fp .border-t, #fiber-fp .border,
  #amateur-fp .border-b, #amateur-fp .border-t, #amateur-fp .border,
  #dp    .border-b, #dp    .border-t, #dp    .border,
  #radio-dp .border-b, #radio-dp .border-t, #radio-dp .border,
  #fiber-dp .border-b, #fiber-dp .border-t, #fiber-dp .border,
  #side-menu .border-b, #side-menu .border-t, #side-menu .border {
    border-color: var(--rmf-dk-border) !important;
  }

  /* ── 6. Separador do header nos modais centrais ── */
  #ai-modal      > div:first-child,
  #settings-modal > div:first-child,
  #about-modal   > div:first-child,
  #signal-modal  > div:first-child,
  #api-modal     > div:first-child {
    border-color: var(--rmf-dk-border) !important;
  }

  #city-input::placeholder,
  #af-search::placeholder {
    color: var(--rmf-dk-on) !important;
  }

  #city-input,
  #af-search {
    background-color: var(--rmf-dk-surface) !important;
    color: var(--rmf-dk-on-2) !important;
  }

}

/* ════════════════════════════════════════════════════════════════
   Painéis deslizantes (Detalhes da Estação / Rádio-TV / Fibra / Cidade /
   Filtros) — CORES do DESIGN §8, theme-aware (claro + escuro pelos tokens):
   shell e cabeçalho = modalSurface (surface); bordas e divisores =
   outlineVariant. Sobrescreve as classes Tailwind slate (bg-slate-50/white,
   border-slate-*, h-px bg-slate-100/800). O #city-dp já nasce com tokens.
   (As regras equivalentes no bloco @media dark acima ficam redundantes.)
   ════════════════════════════════════════════════════════════════ */
#dp, #radio-dp, #fiber-dp,
#fp, #radio-fp, #fiber-fp, #amateur-fp {
  background-color: var(--md-sys-color-surface) !important;
  border-color: var(--md-sys-color-outline-variant) !important;
}
/* Cabeçalho fixo (.shrink-0) — mesma surface, sem o tom slate translúcido */
#dp > .shrink-0, #radio-dp > .shrink-0, #fiber-dp > .shrink-0,
#fp > .shrink-0, #radio-fp > .shrink-0, #fiber-fp > .shrink-0, #amateur-fp > .shrink-0 {
  background-color: var(--md-sys-color-surface) !important;
  border-color: var(--md-sys-color-outline-variant) !important;
}
/* Divisores h-px dentro dos painéis (a cor é o background do <div> de 1px) */
#dp .h-px, #radio-dp .h-px, #fiber-dp .h-px,
#fp .h-px, #radio-fp .h-px, #fiber-fp .h-px, #amateur-fp .h-px {
  background-color: var(--md-sys-color-outline-variant) !important;
}
/* Bordas neutras internas (.border / .border-b / .border-t) */
#dp .border, #dp .border-b, #dp .border-t,
#radio-dp .border, #radio-dp .border-b, #radio-dp .border-t,
#fiber-dp .border, #fiber-dp .border-b, #fiber-dp .border-t,
#fp .border, #fp .border-b, #fp .border-t,
#radio-fp .border, #radio-fp .border-b, #radio-fp .border-t,
#fiber-fp .border, #fiber-fp .border-b, #fiber-fp .border-t,
#amateur-fp .border, #amateur-fp .border-b, #amateur-fp .border-t {
  border-color: var(--md-sys-color-outline-variant) !important;
}

/* Altura máxima dos popups do mapa: limita pelo espaço abaixo do header+chips */
.popup-scroll {
  max-height: min(320px, calc(100dvh - var(--header-h) - 60px));
}

/* ════════════════════════════════════════════════════════════════
   Popups do mapa (maplibre) + dropdown de busca (#search-results).
   Os modais grandes já são tratados no bloco acima; aqui trazemos os
   popups/dropdown pra mesma superfície/borda da paleta do app no dark.
   (No claro permanecem brancos — superfície neutra padrão.)
   ════════════════════════════════════════════════════════════════ */
@media (prefers-color-scheme: dark) {
  /* Superfície: wrapper do popup + divs internas (bg-white / bg-slate-*) */
  .maplibregl-popup-content,
  .maplibregl-popup-content [class*="bg-white"],
  .maplibregl-popup-content [class*="bg-slate-800"],
  .maplibregl-popup-content [class*="bg-slate-900"],   /* ex.: input #fav-name-input */
  #search-results,
  #search-results [class*="bg-white"],
  #search-results [class*="bg-slate-900"],
  #dp [class*="bg-white"],
  #dp [class*="bg-slate-800"],
  #dp [class*="bg-slate-900"] {
    background-color: var(--rmf-dk-surface) !important;
  }

  /* Catch-all: qualquer uso de slate-700 (bordas, border-y, divide-*, scrollbar,
     hover) dentro de popups/dropdown/painéis/modais resolve como a borda índigo
     do app. Robusto (não depende da classe de largura) e seguro — slate-700 NÃO
     é superfície (essas usam slate-800/900). */
  .maplibregl-popup-content, #search-results,
  #dp, #radio-dp, #fiber-dp, #fp, #radio-fp, #fiber-fp, #amateur-fp,
  #side-menu, #ai-modal, #settings-modal, #about-modal, #signal-modal, #api-modal {
    --color-slate-700: var(--rmf-dk-border) !important;
  }

  /* Bico (tip) do popup — era #fff; cor por âncora */
  .maplibregl-popup-anchor-top        .maplibregl-popup-tip,
  .maplibregl-popup-anchor-top-left   .maplibregl-popup-tip,
  .maplibregl-popup-anchor-top-right  .maplibregl-popup-tip { border-bottom-color: var(--rmf-dk-surface) !important; }
  .maplibregl-popup-anchor-bottom       .maplibregl-popup-tip,
  .maplibregl-popup-anchor-bottom-left  .maplibregl-popup-tip,
  .maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip { border-top-color: var(--rmf-dk-surface) !important; }
  .maplibregl-popup-anchor-left  .maplibregl-popup-tip { border-right-color: var(--rmf-dk-surface) !important; }
  .maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color:  var(--rmf-dk-surface) !important; }

  /* Bordas neutras internas (border / border-b / border-t em slate) */
  .maplibregl-popup-content .border, .maplibregl-popup-content .border-b, .maplibregl-popup-content .border-t,
  #search-results, /* o próprio container tem `border` */
  #search-results .border, #search-results .border-b, #search-results .border-t {
    border-color: var(--rmf-dk-border) !important;
  }

  /* Hover dos itens (era slate-700/800) → tom elevado sutil */
  #search-results .sr-item:hover,
  .maplibregl-popup-content .group:hover {
    background-color: var(--rmf-dk-border) !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   Estado ativo de FAB — mesmas cores dos chips ativados (light & dark)
   ════════════════════════════════════════════════════════════════ */
  /* Light mode: chip/FAB ativo = primary-container (--rmf-state-*) + borda primary */
  .link-active,
  #btn-gps.active {
    background-color: var(--rmf-state-bg) !important;
    color: var(--rmf-state-fg) !important;
    border-color: var(--rmf-brand) !important;
  }
  #btn-gps:hover { color: var(--rmf-state-fg) !important; }

  /* Dark mode: chip active = rgb(54,67,116) bg / rgb(214,219,246) text / rgb(149,161,211) border */
  @media (prefers-color-scheme: dark) {
    #btn-gps.active {
      background-color: var(--rmf-state-bg-dk) !important;
      color: var(--rmf-state-fg-dk) !important;
      border-color: var(--rmf-state-bd-dk) !important;
    }
    #btn-gps:hover { color: var(--rmf-state-fg-dk) !important; }
  }

/* ════════════════════════════════════════════════════════════════
   IA do RMF — chips, sugestões e bolhas de chat do modal
   ════════════════════════════════════════════════════════════════ */
  /* Log e estado vazio */
  .ai-log { padding: 12px; display: flex; flex-direction: column; gap: 2px; background: var(--md-sys-color-surface-container-low); }
  .ai-empty { display: flex; flex-direction: column; align-items: center; padding: 24px 20px 16px; }
  .ai-empty__icon { font-size: 64px; color: color-mix(in srgb, var(--md-sys-color-primary) 70%, transparent); }
  .ai-empty__title { margin-top: 12px; font-size: 18px; font-weight: 600; color: var(--md-sys-color-on-surface); text-align: center; }
  .ai-empty__sub { margin-top: 6px; font-size: 13px; line-height: 1.5; color: var(--md-sys-color-on-surface-variant); text-align: center; max-width: 22rem; }
  .ai-empty__label { align-self: flex-start; margin-top: 20px; margin-bottom: 8px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--md-sys-color-on-surface-variant); }
  .ai-empty__chips { align-self: stretch; display: flex; flex-wrap: wrap; gap: 8px; }
  .ai-chip-suggest {
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-family: inherit;
    padding: 7px 14px; border-radius: 100px; font-size: 13px; font-weight: 500;
    background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface);
    border: 1px solid var(--md-sys-color-outline-variant); transition: background .15s;
  }
  .ai-chip-suggest:hover { background: var(--md-sys-color-surface-container-highest); }
  .ai-chip-suggest i { font-size: 12px; color: var(--md-sys-color-primary); }

  /* Bolhas de chat */
  .ai-row { display: flex; padding: 4px 0; }
  .ai-row--user { justify-content: flex-end; }
  .ai-row--bot  { justify-content: flex-start; }
  .ai-bubble { max-width: 78%; padding: 10px 14px; font-size: 13.5px; line-height: 1.4; word-wrap: break-word; overflow-wrap: anywhere; }
  .ai-bubble--user  { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); border-radius: 16px 16px 4px 16px; white-space: pre-wrap; }
  .ai-bubble--bot   { background: var(--md-sys-color-surface-container-highest); color: var(--md-sys-color-on-surface); border-radius: 16px 16px 16px 4px; }
  .ai-bubble--error { background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); border-radius: 16px 16px 16px 4px; }
  .ai-bubble p { margin: 0 0 6px; } .ai-bubble p:last-child { margin-bottom: 0; }
  .ai-bubble a { color: var(--md-sys-color-primary); text-decoration: underline; font-weight: 600; }
  .ai-bubble strong { font-weight: 700; }
  .ai-bubble em { font-style: italic; }
  .ai-bubble ul { margin: 4px 0; padding-left: 18px; } .ai-bubble li { margin: 2px 0; }
  .ai-bubble code { font-family: ui-monospace, monospace; font-size: .92em; background: color-mix(in srgb, var(--md-sys-color-on-surface) 9%, transparent); padding: 1px 5px; border-radius: 6px; }

  /* Botão de ação (aplicar no mapa) dentro da bolha */
  .ai-action-btn {
    display: inline-flex; align-items: center; gap: 8px; margin-top: 10px; cursor: pointer; font: inherit;
    height: 38px; padding: 0 16px; border-radius: 100px; border: none; font-size: 13px; font-weight: 600;
    background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); transition: filter .15s;
  }
  .ai-action-btn:hover:not(:disabled) { filter: brightness(1.06); }
  .ai-action-btn:disabled { opacity: .6; cursor: default; }

  /* Chips de pergunta sugerida abaixo da resposta */
  .ai-followups { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
  .ai-followup {
    display: inline-flex; align-items: center; gap: 5px; cursor: pointer; font-family: inherit;
    padding: 6px 10px; border-radius: 14px; font-size: 12.5px; font-weight: 600; border: none; text-align: left;
    background: color-mix(in srgb, var(--md-sys-color-primary) 10%, transparent); color: var(--md-sys-color-primary);
  }
  .ai-followup i { font-size: 11px; }

  /* Chips de filtros aplicados (check) */
  .ai-applied { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
  .ai-applied__chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 8px; border-radius: 10px; font-size: 11px; font-weight: 600;
    background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent); color: var(--md-sys-color-primary);
  }
  .ai-applied__chip i { font-size: 10px; opacity: .9; }

  /* Bolha "digitando" (spinner) */
  .ai-typing { display: inline-flex; align-items: center; justify-content: center; padding: 13px 15px; border-radius: 16px 16px 16px 4px; background: var(--md-sys-color-surface-container-high); }
  .ai-typing i { color: var(--md-sys-color-primary); font-size: 14px; }

  /* Bolha de status com shimmer (estilo Claude Code) */
  .ai-status { padding: 12px 15px; border-radius: 16px 16px 16px 4px; background: var(--md-sys-color-surface-container-high); font-size: 13.5px; font-weight: 500; line-height: 1.4; }
  .ai-status__text {
    background: linear-gradient(100deg,
      var(--md-sys-color-on-surface-variant) 35%,
      var(--md-sys-color-on-surface) 50%,
      var(--md-sys-color-on-surface-variant) 65%);
    background-size: 220% 100%;
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
    animation: ai-shimmer 1.4s linear infinite;
  }
  @keyframes ai-shimmer { from { background-position: 180% 0; } to { background-position: -80% 0; } }
  @supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .ai-status__text { color: var(--md-sys-color-on-surface-variant); -webkit-text-fill-color: currentColor; animation: none; background: none; }
  }

  /* Composer */
  .ai-composer { display: flex; align-items: flex-end; gap: 8px; padding: 8px 12px 12px; flex-shrink: 0; }
  .ai-input {
    flex: 1; min-width: 0; resize: none; font: inherit; font-size: 14px; line-height: 1.4;
    padding: 13px 16px; border-radius: 24px; border: none; outline: none; max-height: 120px;
    background: var(--md-sys-color-surface-container-highest); color: var(--md-sys-color-on-surface);
  }
  .ai-input::placeholder { color: var(--md-sys-color-on-surface-variant); }
  .ai-send {
    flex-shrink: 0; width: 48px; height: 48px; border-radius: 50%; border: none; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; font-size: 15px;
    background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); transition: filter .15s;
  }
  .ai-send:hover:not(:disabled) { filter: brightness(1.06); }
  .ai-send:disabled { opacity: .5; cursor: not-allowed; }

/* ─── Marcador "gerado por IA": ícone sparkle clicável + balão ───
   Renderizado em runtime por rmfAiFlag em app-vector.js (popups), não é
   FOUC-crítico, por isso vive aqui e não no <style> inline do HTML. */
.ai-flag{cursor:pointer;color:var(--md-sys-color-primary,#4B5C92);font-size:.9em;line-height:1;vertical-align:baseline}
.ai-flag:focus-visible{outline:2px solid var(--md-sys-color-primary,#4B5C92);outline-offset:2px;border-radius:3px}
.ai-tip{position:fixed;z-index:10050;max-width:240px;display:flex;align-items:center;gap:.4rem;
  padding:.5rem .65rem;border-radius:.6rem;font-size:12px;line-height:1.3;font-weight:500;
  background:var(--md-sys-color-inverse-surface,#2f3036);color:var(--md-sys-color-inverse-on-surface,#f1f0f7);
  box-shadow:0 6px 20px rgba(0,0,0,.28);opacity:0;transform:translateY(4px);
  transition:opacity .14s ease,transform .14s ease;pointer-events:none}
.ai-tip.is-open{opacity:1;transform:translateY(0)}
.ai-tip__icon{color:var(--md-sys-color-primary,#aebbff);font-size:13px;flex:0 0 auto}
.ai-tip__text{white-space:pre-line}
.ai-tip__arrow{position:absolute;bottom:-4px;width:9px;height:9px;background:inherit;
  transform:translateX(-50%) rotate(45deg)}
.ai-tip--below .ai-tip__arrow{bottom:auto;top:-4px}

/* ─── Pílulas de overlay da barra de busca (IA, Filtro URL, Amadores) ─── */
/* Base estrutural compartilhada */
.ia-pill-overlay, .link-pill-overlay {
  position: absolute; inset: 0; z-index: 3; border-radius: var(--rmf-radius-full);
  display: flex; align-items: center; gap: 10px; padding: 0 14px 0 16px;
  cursor: pointer; overflow: hidden;
}
.ia-pill-overlay.hidden, .link-pill-overlay.hidden { display: none; }
.ia-pill-overlay__icon, .link-pill-overlay__icon { font-size: 15px; flex-shrink: 0; }
.ia-pill-overlay__text, .link-pill-overlay__text {
  flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ia-pill-overlay__close, .link-pill-overlay__close { font-size: 14px; flex-shrink: 0; opacity: .75; }
/* IA: gradiente shimmer animado (primary ↔ tertiary) */
@keyframes ia-shimmer {
  from { background-position:   0% 50%; }
  to   { background-position: 100% 50%; }
}
.ia-pill-overlay {
  color: #fff;
  background: linear-gradient(135deg,
    var(--md-sys-color-primary)  0%,
    var(--md-sys-color-tertiary) 50%,
    var(--md-sys-color-primary)  100%
  );
  background-size: 300% 100%;
  animation: ia-shimmer 2.4s linear infinite;
}
/* Link (filtro URL / camada de amadores): cor terciária sólida, sem animação */
.link-pill-overlay {
  color: var(--md-sys-color-on-tertiary-container);
  background: var(--md-sys-color-tertiary-container);
}
/* Busca por parser determinístico (sem IA): a pílula de IA veste o look de
   Filtro — sólido terciário, sem gradiente nem shimmer. Reserva o visual de IA
   só pra quando a IA realmente entrou em ação. */
.ia-pill-overlay--filter {
  color: var(--md-sys-color-on-tertiary-container);
  background: var(--md-sys-color-tertiary-container);
  animation: none;
}

/* ─── Busca natural (IA na barra de pesquisa) ─── */
/* Linha "Buscar com IA" no topo do dropdown: tint terciário pra destacar da lista
   de cidades, ícone varinha com o gradiente primary↔tertiary (igual à pílula). */
.rmf-srch-ai {
  display: flex; align-items: center; gap: 12px;
  margin: 8px; padding: 12px 14px;
  width: calc(100% - 16px);
  border: none; cursor: pointer; text-align: left;
  border-radius: var(--rmf-radius-md);
  background: color-mix(in srgb, var(--md-sys-color-tertiary) 12%, transparent);
  transition: background .15s;
}
.rmf-srch-ai:hover,
.rmf-srch-ai.rmf-sel { background: color-mix(in srgb, var(--md-sys-color-tertiary) 20%, transparent); }
.rmf-srch-ai__ic {
  flex: none; font-size: 18px;
  background: linear-gradient(120deg, var(--md-sys-color-primary), var(--md-sys-color-tertiary));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--md-sys-color-primary);
}
.rmf-srch-ai__body  { min-width: 0; flex: 1; }
.rmf-srch-ai__title { font-size: 14px; font-weight: 600; color: var(--md-sys-color-on-surface); }
.rmf-srch-ai__sub {
  font-size: 12px; margin-top: 1px; color: var(--md-sys-color-on-surface-variant);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rmf-srch-ai__chev { flex: none; font-size: 13px; color: var(--md-sys-color-tertiary); }

/* Estado "pensando": anel de gradiente varrendo a borda da pílula de busca
   enquanto a IA interpreta — mesmo gradiente/keyframes da pílula de IA. */
.rmf-pill.is-ai-thinking::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 2px;
  background: linear-gradient(100deg,
    var(--md-sys-color-primary) 0%,
    var(--md-sys-color-tertiary) 50%,
    var(--md-sys-color-primary) 100%);
  background-size: 220% 100%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
  animation: ia-shimmer 1.4s linear infinite;
  pointer-events: none; z-index: 4;
}
@media (prefers-reduced-motion: reduce) {
  .rmf-pill.is-ai-thinking::after { animation: none; }
}

/* ════════════════════════════════════════════════════════════════
   Marca d'água do mapa (© OpenStreetMap © CARTO)
   As classes Tailwind usavam slate-800/700/400 (cinza-azulado) que
   destoava da nova superfície dark do mapa (near-black). Aqui as cores
   passam a usar os tokens --rmf-* (id > utility, sem !important).
   ════════════════════════════════════════════════════════════════ */
#osm-watermark {
  color: var(--rmf-ink-subtle);                 /* outline #76777C */
  background-color: color-mix(in srgb, var(--md-sys-color-surface) 90%, transparent);
  border-color: var(--md-sys-color-outline-variant);   /* borda clara */
}
#osm-watermark:hover { color: var(--rmf-brand); }   /* primary #4B5C92 */

@media (prefers-color-scheme: dark) {
  #osm-watermark {
    color: var(--rmf-dk-on);                    /* on-surface-variant #C6C6CC */
    background-color: color-mix(in srgb, var(--rmf-dk-surface) 90%, transparent);  /* = surface #0D0E13 */
    border-color: var(--rmf-dk-border);         /* #2A2A2F */
  }
  #osm-watermark:hover { color: var(--rmf-brand-300); }  /* #B7C0E5 acento dark */
}

/* Atribuição "sobe" pro topo (desktop): quando o botão "Baixar app" está
   oculto E os chips terminam antes da borda direita, o canto sup. direito
   sobre o mapa fica vago — a atribuição ocupa esse espaço em vez de ficar
   abaixo do header. A classe .wm-raised é alternada por JS (updateWatermarkRaise),
   que confirma que há folga horizontal antes de subir. O transition-all do
   elemento (Tailwind) anima o deslocamento. */
@media (min-width: 640px) {
  /* !important: o elemento traz o top inline no HTML (style="top: calc(...)"),
     que vence qualquer seletor de stylesheet — só !important sobrepõe. */
  #osm-watermark.wm-raised {
    top: calc(22px + env(safe-area-inset-top, 0px)) !important;
  }
}
/* WCO: subida, mas NÃO sobre os controles da janela. No Windows/Linux os
   botões (min/fechar) ficam no canto sup. direito — exatamente onde o
   watermark encosta. Desce pra logo abaixo da faixa de título (titlebar-area-
   height) + folga. No macOS (controles à esquerda) só assenta um pouco mais
   baixo, sem prejuízo. */
@media (display-mode: window-controls-overlay) and (min-width: 640px) {
  #osm-watermark.wm-raised {
    top: calc(env(titlebar-area-height, 0px) + 6px) !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   Tokens M3 + sistema de modais nv-modal — paleta CANÔNICA do DESIGN.md
   (primary #4B5C92, seed/brand #2563EB). Idêntica à do rmf.css (fonte
   única do design system): a home do mapa fala a mesma língua de cor que
   o resto do app. ⚠️ Trocar a marca: aqui.
   ════════════════════════════════════════════════════════════════ */
:root {
  /* ─── Marca — primary derivado de #4B5C92, seed/brand #2563EB ─── */
  --md-rmf-brand: #2563EB;            /* seed do tema + AppStatus.info — NÃO usar cru em componentes */
  --md-sys-color-primary: #4B5C92;
  --md-sys-color-on-primary: #FFFFFF;
  --md-sys-color-primary-container: #DCE1FA;
  --md-sys-color-on-primary-container: #0A1633;
  --md-sys-color-inverse-primary: #B7C0E5;

  --md-sys-color-secondary: #595E72;
  --md-sys-color-on-secondary: #FFFFFF;
  --md-sys-color-secondary-container: #DEE1F4;
  --md-sys-color-on-secondary-container: #161B2C;

  --md-sys-color-tertiary: #74566D;
  --md-sys-color-on-tertiary: #FFFFFF;
  --md-sys-color-tertiary-container: #FED7F2;
  --md-sys-color-on-tertiary-container: #2B1228;

  /* ─── Status (Tailwind-500, fixo nos dois temas) — color / fill 12% / border 40% (DESIGN §4) ─── */
  --rmf-danger:  #EF4444;
  --rmf-warning: #F59E0B;
  --rmf-success: #22C55E;
  --rmf-info:    #2563EB;
  --rmf-danger-fill:    color-mix(in srgb, var(--rmf-danger)  12%, transparent);
  --rmf-warning-fill:   color-mix(in srgb, var(--rmf-warning) 12%, transparent);
  --rmf-success-fill:   color-mix(in srgb, var(--rmf-success) 12%, transparent);
  --rmf-info-fill:      color-mix(in srgb, var(--rmf-info)    12%, transparent);
  --rmf-danger-border:  color-mix(in srgb, var(--rmf-danger)  40%, transparent);
  --rmf-warning-border: color-mix(in srgb, var(--rmf-warning) 40%, transparent);
  --rmf-success-border: color-mix(in srgb, var(--rmf-success) 40%, transparent);
  --rmf-info-border:    color-mix(in srgb, var(--rmf-info)    40%, transparent);

  /* M3 error remapeado p/ o status danger (componentes herdam) */
  --md-sys-color-error: var(--rmf-danger);
  --md-sys-color-on-error: #FFFFFF;
  --md-sys-color-error-container: var(--rmf-danger-fill);
  --md-sys-color-on-error-container: var(--rmf-danger);

  /* ─── Superfícies NEUTRAS — lift sem tint (DESIGN §1) ─── */
  --md-sys-color-background: #FFFFFF;
  --md-sys-color-on-background: #1C1B1F;
  --md-sys-color-surface: #FFFFFF;
  --md-sys-color-on-surface: #1C1B1F;
  --md-sys-color-surface-variant: #E3E2E6;
  --md-sys-color-on-surface-variant: #45464C;
  --md-sys-color-surface-tint: #4B5C92;

  --md-sys-color-outline: #76777C;
  --md-sys-color-outline-variant: #C7C6CC;
  --md-sys-color-shadow: #000000;
  --md-sys-color-scrim: #000000;

  --md-sys-color-inverse-surface: #303034;
  --md-sys-color-inverse-on-surface: #F4F0F4;

  --md-sys-color-surface-container-lowest: #FFFFFF;
  --md-sys-color-surface-container-low: #F7F7F7;     /* bloco/card (modalBlock) */
  --md-sys-color-surface-container: #F1F1F2;
  --md-sys-color-surface-container-high: #ECECED;
  --md-sys-color-surface-container-highest: #E3E2E8; /* acento DENTRO do bloco */

  /* Sucesso / aviso remapeados p/ status (fill 12% + texto = color 500) */
  --md-sys-color-success: var(--rmf-success);
  --md-sys-color-success-container: var(--rmf-success-fill);
  --md-sys-color-on-success-container: var(--rmf-success);

  --md-sys-color-warning: var(--rmf-warning);
  --md-sys-color-warning-container: var(--rmf-warning-fill);
  --md-sys-color-on-warning-container: var(--rmf-warning);

  /* Acento de seleção/ativo — primary @ 12% (chips, indicador, toggles) — DESIGN §3.2 */
  --rmf-select-fill: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);

  /* Raios — escala única (DESIGN §6): sm 8 / md 12 / lg 20 / full 999 */
  --rmf-radius-sm: 8px;
  --rmf-radius-md: 12px;
  --rmf-radius-lg: 20px;
  --rmf-radius-full: 999px;

  /* Elevação (DESIGN §7): elev-1 = sombra sutil de card; elev-2 = hover;
     elev-modal = modal/sheet/popup. surfaceTint transparente → só sombra. */
  --rmf-elev-1: 0 1px 3px rgba(0,0,0,.10), 0 1px 2px rgba(0,0,0,.06);
  --rmf-elev-2: 0 2px 6px rgba(0,0,0,.12), 0 1px 3px rgba(0,0,0,.08);
  --rmf-elev-modal: 0 12px 32px rgba(0,0,0,.28), 0 4px 12px rgba(0,0,0,.16);

  /* App bar — degrau "scrolled-under" (DESIGN §8.1): assenta ~no modalBlock. */
  --md-rmf-appbar-scrolled: #F0F0F0;
}

@media (prefers-color-scheme: dark) {
  :root {
    --md-sys-color-primary: #B7C0E5;
    --md-sys-color-on-primary: #202B53;
    --md-sys-color-primary-container: #36426A;
    --md-sys-color-on-primary-container: #DCE1FA;
    --md-sys-color-inverse-primary: #4B5C92;

    --md-sys-color-secondary: #C1C5DC;
    --md-sys-color-on-secondary: #2B3041;
    --md-sys-color-secondary-container: #424658;
    --md-sys-color-on-secondary-container: #DEE1F4;

    --md-sys-color-tertiary: #E2BCD3;
    --md-sys-color-on-tertiary: #43273E;
    --md-sys-color-tertiary-container: #5B3D55;
    --md-sys-color-on-tertiary-container: #FED7F2;

    /* Status — mesmo Tailwind-500 dos dois temas (--rmf-* herdados do :root) */
    --md-sys-color-error: var(--rmf-danger);
    --md-sys-color-on-error: #FFFFFF;
    --md-sys-color-error-container: var(--rmf-danger-fill);
    --md-sys-color-on-error-container: var(--rmf-danger);

    /* Superfícies neutras (escuro) — DESIGN §1 */
    --md-sys-color-background: #0D0E13;
    --md-sys-color-on-background: #E6E1E5;
    --md-sys-color-surface: #0D0E13;
    --md-sys-color-on-surface: #E6E1E5;
    --md-sys-color-surface-variant: #45464A;
    --md-sys-color-on-surface-variant: #C6C6CC;
    --md-sys-color-surface-tint: #B7C0E5;

    --md-sys-color-outline: #8F9099;
    --md-sys-color-outline-variant: #45464A;

    --md-sys-color-inverse-surface: #E6E1E5;
    --md-sys-color-inverse-on-surface: #303034;

    --md-sys-color-surface-container-lowest: #0D0E13;
    --md-sys-color-surface-container-low: #1C1C21;     /* bloco/card (modalBlock) */
    --md-sys-color-surface-container: #1F1F24;
    --md-sys-color-surface-container-high: #26262B;
    --md-sys-color-surface-container-highest: #2A2A2F; /* acento DENTRO do bloco */

    --md-sys-color-success: var(--rmf-success);
    --md-sys-color-success-container: var(--rmf-success-fill);
    --md-sys-color-on-success-container: var(--rmf-success);

    --md-sys-color-warning: var(--rmf-warning);
    --md-sys-color-warning-container: var(--rmf-warning-fill);
    --md-sys-color-on-warning-container: var(--rmf-warning);

    --md-rmf-appbar-scrolled: #1B1C21;
  }
}

.nv-modal {
  position: fixed; inset: 0; z-index: 2000; padding: 16px;
  display: flex; align-items: center; justify-content: center;
  /* Scrim sólido — preto ~54% (default M3, DESIGN §8). Sem blur: o realce
     vem do scrim + elevação, não de desfoque. */
  background: color-mix(in srgb, var(--md-sys-color-scrim) 54%, transparent);
  transition: opacity .2s;
}
.nv-modal.hidden { display: none; }
.nv-modal__panel {
  width: 100%; max-width: 28rem; max-height: 90vh; display: flex; flex-direction: column;
  border-radius: var(--rmf-radius-lg); overflow: hidden; transition: transform .2s;
  /* Fundo = modalSurface (= surface), cor sólida (DESIGN §8). Blocos internos
     (.nv-row/.nv-panel) sobem para surface-container-low. Elevação 12 = só sombra. */
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  box-shadow: var(--rmf-elev-modal);
}
.nv-modal__panel--lg { max-width: 32rem; }
.nv-modal__panel.scale-95 { transform: scale(.95); }
.nv-modal__head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 20px; flex-shrink: 0;
  /* Linha de limite embaixo do header — delimita a zona fixa do corpo (DESIGN §8). */
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.nv-modal__title { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: 700; color: var(--md-sys-color-on-surface); }
.nv-modal__title i { color: var(--md-sys-color-primary); }
.nv-modal__actions { display: flex; align-items: center; gap: 4px; }
.nv-modal__body { padding: 20px; display: flex; flex-direction: column; gap: 16px; overflow-y: auto; }
.nv-modal__map { position: relative; width: 100%; height: 11rem; flex-shrink: 0; overflow: hidden; background: var(--md-sys-color-surface-container-high); }
.nv-modal__info { flex: 1; padding: 16px; display: flex; flex-direction: column; gap: 8px; overflow: auto; max-height: 20rem; font-size: 14px; color: var(--md-sys-color-on-surface); }
.nv-modal__foot { padding: 12px 16px; flex-shrink: 0; border-top: 1px solid var(--md-sys-color-outline-variant); display: flex; justify-content: flex-end; }

/* .ibtn é escopado em .nv-modal (e .nv-body) pra não tocar o botão homônimo
   dos modais próprios do host index no modo SPA. */
.nv-modal .ibtn, .nv-body .ibtn {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; cursor: pointer; border: none;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--md-sys-color-on-surface-variant); background: transparent; transition: background .15s;
}
.nv-modal .ibtn:hover, .nv-body .ibtn:hover { background: var(--md-sys-color-surface-container-highest); }
.nv-modal .ibtn--filled, .nv-body .ibtn--filled { background: var(--md-sys-color-surface-container-highest); }
.nv-modal .ibtn--sm, .nv-body .ibtn--sm { width: 32px; height: 32px; }

/* Campos de formulário (modais) */
.nv-field { display: flex; flex-direction: column; gap: 6px; }
.nv-field__label { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--md-sys-color-on-surface-variant); }
.nv-control { position: relative; }
.nv-control select, .nv-control input, .nv-input {
  width: 100%; height: 44px; padding: 0 14px; font: inherit; font-size: 14px;
  border-radius: 12px; border: 1px solid var(--md-sys-color-outline);
  background: var(--md-sys-color-surface-container-low); color: var(--md-sys-color-on-surface);
}
.nv-control select { appearance: none; padding-right: 38px; cursor: pointer; }
.nv-control select:focus, .nv-control input:focus, .nv-input:focus {
  outline: none; border-color: var(--md-sys-color-primary);
  box-shadow: 0 0 0 1px var(--md-sys-color-primary);
}
.nv-control__chevron { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); pointer-events: none; font-size: 12px; color: var(--md-sys-color-on-surface-variant); }
.nv-control--search input { padding-left: 38px; }
.nv-control__search-ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); pointer-events: none; font-size: 13px; color: var(--md-sys-color-on-surface-variant); }

/* Botões dos modais */
.nv-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 0 20px; border-radius: 100px; cursor: pointer; font: inherit;
  font-size: 14px; font-weight: 600; border: 1px solid transparent; transition: background .15s, filter .15s;
}
.nv-btn--filled { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.nv-btn--filled:hover { filter: brightness(1.05); }
.nv-btn--tonal { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); }
.nv-btn--outline { background: transparent; color: var(--md-sys-color-on-surface); border-color: var(--md-sys-color-outline); }
.nv-btn--outline:hover { background: var(--md-sys-color-surface-container-high); }
.nv-btn--block { width: 100%; }
.nv-btn--sm { height: 36px; padding: 0 14px; font-size: 12px; }

/* Modal de alertas: lista de cidades + sugestões */
.nv-alert-intro { font-size: 12px; line-height: 1.6; color: var(--md-sys-color-on-surface-variant); }
.nv-city-add { display: flex; gap: 8px; }
.nv-suggestions {
  position: absolute; left: 0; right: 0; top: 100%; margin-top: 4px; z-index: 50;
  max-height: 12rem; overflow-y: auto; list-style: none; padding: 0; margin-bottom: 0;
  border-radius: 12px; border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-high); font-size: 14px;
}
.nv-suggestions.hidden { display: none; }
/* Itens da lista de sugestões — renderizados pelo app-notifications.js com
   classes Tailwind (inexistentes no standalone). Escopado em .nv-body. */
.nv-body #city-suggestions li {
  list-style: none; display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px; cursor: pointer; color: var(--md-sys-color-on-surface);
  border-bottom: 1px solid var(--md-sys-color-outline-variant); transition: background .12s;
}
.nv-body #city-suggestions li:last-child { border-bottom: 0; }
.nv-body #city-suggestions li:hover { background: var(--md-sys-color-surface-container-high); }
.nv-body #city-suggestions li span:last-child { font-size: 12px; color: var(--md-sys-color-on-surface-variant); }

.nv-city-list { display: flex; flex-wrap: wrap; gap: 8px; min-height: 2rem; list-style: none; padding: 0; margin: 0; }

/* ─── Chips de cidade do modal de Notificações ───────────────────────
   Renderizados pelo app-notifications.js (compartilhado, NÃO reescrito): o
   próprio <li> É o chip (classes Tailwind inline) com o nome + <span> da UF +
   um <button> de remover. Estado vazio = <li class="... italic">. No SPA o
   Tailwind do host resolve; no standalone (sem Tailwind) recriamos o estilo
   aqui, ESCOPADO em .nv-body pra não tocar a UI do host. */
.nv-body #city-list > li {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  height: 28px; padding: 0 6px 0 12px; border-radius: 100px;
  font-size: 12px; font-weight: 500; line-height: 1;
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
/* Estado vazio ("Nenhuma cidade cadastrada.") — não é chip */
.nv-body #city-list > li.italic {
  background: transparent; color: var(--md-sys-color-on-surface-variant);
  height: auto; padding: 4px; font-style: italic; font-weight: 400;
}
.nv-body #city-list > li > span { opacity: .7; font-size: 10px; }
/* Botão de remover (×) dentro do chip */
.nv-body #city-list > li button {
  width: 18px; height: 18px; flex-shrink: 0; padding: 0;
  border: none; cursor: pointer; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: inherit; opacity: .75; transition: background .15s, opacity .15s;
}
.nv-body #city-list > li button:hover {
  opacity: 1; background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container);
}
.nv-divider { padding-top: 16px; border-top: 1px solid var(--md-sys-color-outline-variant); }
.nv-toggle-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; cursor: pointer; }
.nv-toggle-row__txt { flex: 1; padding-right: 4px; }
.nv-toggle-row__txt strong { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--md-sys-color-on-surface); }
.nv-toggle-row__txt strong i { color: var(--md-sys-color-primary); }
.nv-toggle-row__txt span { display: block; font-size: 11px; margin-top: 2px; line-height: 1.5; color: var(--md-sys-color-on-surface-variant); }
/* Linhas/painéis de conteúdo interno dos modais (substituem os cards
   bg-white/slate por superfícies tokenizadas M3). */
.nv-row, .nv-panel {
  padding: 12px; border-radius: 12px;
  background: var(--md-sys-color-surface-container-low);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.nv-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; transition: border-color .15s; }
.nv-row:hover { border-color: var(--md-sys-color-primary); }
.nv-row__t { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--md-sys-color-on-surface); }
.nv-row__t i { color: var(--md-sys-color-primary); }
.nv-row__d { font-size: 10px; margin-top: 2px; color: var(--md-sys-color-on-surface-variant); }
.nv-row__chev { color: var(--md-sys-color-on-surface-variant); transition: color .15s; }
.nv-row:hover .nv-row__chev { color: var(--md-sys-color-primary); }
.nv-panel__label { font-size: 9px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--md-sys-color-on-surface-variant); margin-bottom: 8px; padding: 0 4px; }

/* ─── Painéis de detalhe: blocos = Card (DESIGN §10) ─────────────────
   Os blocos dos painéis de detalhe — Detalhes da Estação (#dp-bd),
   Estação Rádio/TV (#radio-dp-bd) e Enlace de Fibra (#fiber-dp-bd) —
   deixam de ser quadrados com borda e viram Card: fundo modalBlock
   (= surface-container-low, já herdado do .nv-panel) + sombra de elevação
   1 (DESIGN §7), SEM borda. border-color transparente mantém a largura de
   1px do .nv-panel → zero deslocamento de layout, o espaçamento original é
   preservado; só a aparência (borda → sombra) muda. O painel amador
   (#dp-bd, blocos inline) é neutralizado no app-privateradios.js. */
#dp-bd .nv-panel,
#radio-dp-bd .nv-panel,
#fiber-dp-bd .nv-panel {
  border-color: transparent;
  box-shadow: var(--rmf-elev-1);
}

.nv-modal__section { display: flex; flex-direction: column; gap: 16px; }
.nv-modal__section.hidden { display: none; }
.nv-modal__actions-row { display: flex; gap: 8px; padding-top: 4px; }
.nv-modal__actions-row .nv-btn { flex: 1; }

/* Conteúdo dos modais ERB/TV (info renderizada pelo JS) */
.nv-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; font-size: 12px; color: var(--md-sys-color-on-surface-variant); }
.nv-info-grid > div { display: flex; align-items: center; gap: 6px; }
.nv-info-grid .col-span-2 { grid-column: span 2; }
.nv-info-grid i { flex-shrink: 0; opacity: .7; }
.nv-info-grid .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nv-info-freq {
  padding: 8px 12px; border-radius: 12px; font-size: 12px;
  background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface-variant);
}
.nv-info-freq__head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.nv-info-freq__head i { color: var(--md-sys-color-primary); }

/* ── App Install Banner (mobile web, acima da bottom-nav) ── */
#app-install-banner {
  display: none;
  position: fixed; left: 0; right: 0; bottom: var(--bottomnav-h); z-index: 888;
  align-items: center; gap: 10px;
  padding: 10px 14px;
  background: var(--md-sys-color-surface-container-high);
  border-top: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: 0 -2px 16px rgba(0,0,0,.14);
  transform: translateY(100%);
  transition: transform .3s cubic-bezier(.4,0,.2,1);
}
#app-install-banner.visible { transform: translateY(0); }
@media (min-width: 640px) { #app-install-banner { display: none !important; } }
@media (prefers-color-scheme: dark) {
  #app-install-banner { box-shadow: 0 -2px 16px rgba(0,0,0,.35); }
}
.app-banner__title { font-size: 13px; font-weight: 700; color: var(--md-sys-color-on-surface); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-banner__sub   { font-size: 11px; color: var(--md-sys-color-on-surface-variant); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.app-banner__cta {
  flex-shrink: 0; padding: 7px 18px; border-radius: 20px;
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--rmf-brand); color: #fff;
  font-size: 13px; font-weight: 700; border: none; cursor: pointer;
  box-shadow: 0 2px 6px rgba(75,92,146,.35);
  transition: filter .15s;
}
.app-banner__cta-ic { display: block; flex-shrink: 0; }
.app-banner__cta:active { filter: brightness(1.1); }
.app-banner__close {
  flex-shrink: 0; width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; cursor: pointer;
  color: var(--md-sys-color-on-surface-variant); font-size: 14px; border-radius: 50%;
}
.app-banner__close:hover { background: var(--md-sys-color-surface-container-highest); }

/* ── Ícones da direita da pill: colapsam como AnimatedSize (260ms easeInOut) ── */
#pill-icons-right {
  display: flex; align-items: center; gap: 2px; flex: none;
  max-width: 250px; overflow: hidden;
  transition: max-width 260ms ease-in-out, opacity 260ms ease-in-out;
}
.search-brand-mode #pill-icons-right { max-width: 0; opacity: 0; }

/* ── Watermark na pill: logo lerpa p/ centro, "Buscar…" sai p/ cima,
   "Redes Móveis Fixas" entra de cima — fiel ao Flutter (260/220ms). ── */
#search-brand {
  position: absolute; inset: 0; z-index: 5;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--rmf-radius-full);
  background: var(--rmf-white);
  pointer-events: none; user-select: none;
  opacity: 0;
  transition: opacity 260ms ease-in-out;
}
@media (prefers-color-scheme: dark) { #search-brand { background: var(--rmf-pill-dk); } }
.dark #search-brand { background: var(--rmf-pill-dk); }
.search-brand-mode #search-brand { opacity: 1; }

#search-brand-inner { display: flex; align-items: center; gap: 9px; }
#search-brand-inner .fa-rmf { flex-shrink: 0; font-size: 38px; color: var(--rmf-ink-subtle); }
@media (prefers-color-scheme: dark) { #search-brand-inner .fa-rmf { color: var(--rmf-dk-on); } }
.dark #search-brand-inner .fa-rmf { color: var(--rmf-dk-on); }

/* Slot do texto: display:grid empilha os dois spans na mesma célula;
   a célula dimensiona-se pelo texto mais largo ("Redes Móveis Fixas").
   overflow:hidden recorta o span que está fora dos limites durante a animação. */
#search-brand-slot {
  display: grid;
  align-items: center;
}
#search-brand-slot > span { grid-area: 1/1; white-space: nowrap; font-size: 15px; }
#search-brand-from { color: var(--rmf-ink-subtle); font-weight: 400; }
#search-brand-to   { color: var(--rmf-ink-muted); font-weight: 600; letter-spacing: .01em;
                     opacity: 0; }
@media (prefers-color-scheme: dark) {
  #search-brand-from { color: var(--rmf-dk-on); opacity: .65; }
  #search-brand-to   { color: var(--rmf-dk-on); }
}
.dark #search-brand-from { color: var(--rmf-dk-on); opacity: .65; }
.dark #search-brand-to   { color: var(--rmf-dk-on); }

/* Logo: parte da posição original (--brand-logo-offset calculado em JS).
   cubic-bezier com leve overshoot = sensação de "caminhar e chegar". */
@keyframes brand-logo-walk {
  from { transform: translateX(var(--brand-logo-offset, -70px)); }
  to   { transform: translateX(0); }
}
/* "Buscar…" sai para cima; "Redes Móveis Fixas" entra vindo de cima */
@keyframes brand-from-exit {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(10px); opacity: 0; }
}
@keyframes brand-to-enter {
  from { transform: translateX(-10px); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}

.search-brand-mode #search-brand-inner { animation: brand-logo-walk  260ms ease-in-out forwards; }
.search-brand-mode #search-brand-from  { animation: brand-from-exit  220ms ease-in-out forwards; }
.search-brand-mode #search-brand-to    { animation: brand-to-enter   220ms ease-in-out forwards; }

/* Reversão: modal fecha → logo volta à esquerda, "Buscar…" reaparece.
   search-brand-exit é adicionado com search-brand-mode ainda presente;
   após 280ms o JS remove ambas. */
@keyframes brand-logo-walk-out {
  from { transform: translateX(0); }
  to   { transform: translateX(var(--brand-logo-offset, -70px)); }
}
@keyframes brand-from-enter-rev {
  from { transform: translateX(10px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@keyframes brand-to-exit-rev {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(10px); opacity: 0; }
}

.search-brand-exit #search-brand       { opacity: 0 !important; }
.search-brand-exit #pill-icons-right   { max-width: 250px !important; opacity: 1 !important; }
.search-brand-exit #search-brand-inner { animation: brand-logo-walk-out  260ms ease-in-out forwards; }
.search-brand-exit #search-brand-from  { animation: brand-from-enter-rev 220ms ease-in-out forwards; }
.search-brand-exit #search-brand-to    { animation: brand-to-exit-rev    220ms ease-in-out forwards; }

/* ── Toast "Dados da Anatel": fundo sólido no dark (evita translucidez 20%) ── */
@media (prefers-color-scheme: dark) {
  #data-warning-toast      { background-color: #78350f; border-color: #b45309; }
  #data-warning-toast p,
  #data-warning-toast b    { color: #fde68a; }
}
