/* ---------------------------------------------------------------------------
   O Radar: a página que põe a referência de quem procura ao centro.

   Carrega-se **depois** de styles.css e não reescreve um único token: as
   cores, os raios e a sombra são os do site, e a página segue o comutador de
   tema como a dos anúncios. Só o ecrã circular é escuro nos dois temas, e
   isso está em `.instrumento`, que vive em styles.css porque é uma superfície
   do site e não uma invenção desta folha.

   Nada aqui usa `style=` na marcação nem fontes de terceiros: a CSP publicada
   (web/_headers) é `style-src 'self'; script-src 'self'`. Onde um valor tem de
   ser dinâmico (o diâmetro do ecrã, a posição de uma pega), o JS escreve-o
   numa custom property pelo CSSOM, que não é marcação.
   --------------------------------------------------------------------------- */

:root {
  /* Medidas, não cores. Medidas pelo JS (a altura do cabeçalho); os valores
     aqui são só o arranque. */
  --cab-h: 96px;
  --lado: 250px;
  --folga: 16px;
}

body.radar { background: var(--page); }

/* ------------------------------- cabeçalho -------------------------------- */

/* O cabeçalho é o do site: `.topo`, `.topo-linha`, `.marca`, `.navegacao` e
   `.tema` vivem em styles.css e são os mesmos dos Anúncios. Aqui fica só o
   que é desta página — a linha de leitura, por baixo dessa linha. */

/* A linha de leitura é do site e vive em styles.css: os Anúncios usam-na para
   dizer o que a tabela mostra. Aqui só o que a põe debaixo do cabeçalho. */
.leitura { padding-bottom: 4px; }

/* -------------------------------- consola ---------------------------------
   Uma coluna de instrumento e não duas: o que era filtro subiu para a barra do
   topo, e o que sobra ao lado do ecrã é o alcance e o âmbito. O ecrã fica com
   a largura que isso liberta.

   O diâmetro continua a ser o menor de dois limites — o que a largura deixa e
   o que a altura deixa — para o círculo nunca ser cortado em baixo. A barra de
   filtros entra na conta da altura pelo `--cab-h`, que o JS mede. O piso de
   360 px existe para que num portátil baixo o círculo continue a ser um
   instrumento e não uma moeda; aí a página rola, que é o mal menor. */
.consola {
  --diam: max(360px, min(
    min(100vw, 1500px) - 32px - var(--lado) - var(--folga),
    100vh - var(--cab-h) - 24px
  ));
  display: grid;
  /* A coluna tem um tecto e não `1fr`: com `1fr` ficava com tudo o que sobrava
     — oitocentos píxeis para dois cartões — e lia-se como uma página por
     acabar. Com tecto, o que sobra fica à volta das duas colunas, que é
     espaço, não buraco. */
  grid-template-columns: auto minmax(var(--lado), 340px);
  justify-content: center;
  gap: 10px var(--folga); align-items: start;
}
.painel-instr {
  display: flex; flex-direction: column; gap: 10px;
  max-height: var(--diam); overflow-y: auto; scrollbar-width: thin; padding: 2px;
}

/* -------------------------------- ecrã ------------------------------------ */

.ecra-cx {
  position: relative; display: flex; align-items: center; justify-content: center;
  /* Guardadas antes de o âmbito escuro do ecrã as reescrever: são a superfície
     da página, e é com elas que se desenha o anel à volta do círculo, para ele
     assentar na página em vez de flutuar. */
  --pag-surface-1: var(--surface-1);
  --pag-border: var(--border);
}
/* `.instrumento` (styles.css) é o que o faz escuro nos dois temas. O anel à
   volta é da cor da página, e é ele que costura o círculo ao resto: sem ele,
   no tema claro, o ecrã lê-se como um buraco. */
.ecra-quadro {
  position: relative; width: var(--diam); height: var(--diam);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, var(--surface-1) 0%, var(--page) 72%);
  border: 1px solid var(--text-muted);
  box-shadow: 0 0 0 6px var(--pag-surface-1), 0 0 0 7px var(--pag-border), var(--sombra);
  overflow: hidden;
}
.ecra-quadro canvas, .ecra-quadro svg {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
}
.ecra-quadro canvas { touch-action: none; }
#ecra-pontos { cursor: crosshair; }
.ecra-svg { pointer-events: none; }

/* Os anéis e os eixos são grelha, e a grelha do site já tem nome. */
.anel { fill: none; stroke: var(--baseline); stroke-width: 1; }
.anel-forte { stroke: var(--text-muted); stroke-opacity: 0.55; }
.eixo { stroke: var(--grid); stroke-width: 1; }
.rot { fill: var(--text-muted); font-size: 15px; }
.rot-n { fill: var(--series-1); font-size: 17px; font-weight: 700; }
.centro { fill: var(--series-4); stroke: var(--page); stroke-width: 3; }
/* A rotação é do SVG (`animateTransform`, em radar.js) e não daqui: uma
   animação CSS precisava de `transform-origin` em percentagens da viewBox, que
   o Safari resolve contra a caixa do elemento — a cunha orbitava em vez de
   varrer. Aqui fica só a cor. */
.varrimento path { fill: url(#varr); }
/* O varrimento é o realce do site e não uma cor só desta página. Em CSS o
   `stop-color` ganha ao atributo do SVG, e é assim que um gradiente chega a
   um token. */
#varr stop { stop-color: var(--series-1); }

/* legenda nos cantos vazios do quadrado (o círculo é inscrito) */
.canto {
  position: absolute; top: 2px; font-size: 0.72rem; color: var(--text-secondary);
  line-height: 1.45; max-width: 22%;
}
.canto-esq { left: 2px; }
.canto-dir { right: 2px; text-align: right; }
.canto h4 {
  margin: 0 0 3px; font: 600 0.64rem inherit; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--text-muted);
}
.canto div { white-space: nowrap; }
.canto i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.canto-dir i { margin: 0 0 0 6px; }
.canto .pisca { background: var(--series-1); animation: piscar-leg 1.4s ease-in-out infinite; }
.canto .eco-cor { background: var(--text-muted); opacity: 0.55; }
.canto .sem-cor { background: transparent; border: 1px dashed var(--text-muted); }
@keyframes piscar-leg { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
/* quando os cantos não chegam, a legenda vai para o topo da consola direita */
.consola.leg-painel .canto { position: static; max-width: none; text-align: left; margin: 0; }
.consola.leg-painel .canto-dir i { margin: 0 6px 0 0; }
.leg-topo {
  display: flex; gap: 8px 20px; flex-wrap: wrap; padding: 8px 12px;
  border: 1px solid var(--border); border-radius: var(--raio-bloco); background: var(--surface-1);
}
/* Uma caixa vazia lê-se como um bloco que não carregou. */
.leg-topo:not(:has(> :not(.oculto))) { display: none; }

/* O que era a consola de filtros — os comutadores, os deslizadores duplos, os
   LEDs das bandas, a caixa da origem — desapareceu com os instrumentos: era
   uma segunda interface para os filtros que a barra do topo já dá. O que
   sobra é a coluna, aqui em baixo. */

/* --------------------- a coluna do instrumento ------------------------------
   O alcance e o âmbito, ao lado do ecrã circular. Fica aqui e não em
   styles.css porque só esta página a usa: os Gráficos não levaram coluna
   nenhuma — o que é próprio deles é a janela, e os campos que a escrevem já
   vivem debaixo do plano, encostados à coisa que controlam.

   O que **não** está aqui é uma segunda interface de filtros. Isso existiu —
   eram as consolas deste ecrã — e foi o que este vocabulário substituiu: cada
   cartão é navegação dentro da vista ou uma conta do que está carregado, e
   tudo o que corta anúncios está na barra do topo.
   --------------------------------------------------------------------------- */

.instr {
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--raio-bloco);
  padding: 9px 12px 10px;
}
.instr h3 {
  margin: 0 0 6px; font: 600 0.64rem inherit; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--text-muted);
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
}
.instr h3 .val {
  color: var(--text-primary); font-size: 0.78rem; letter-spacing: 0;
  text-transform: none; font-weight: 600; text-align: right;
}
/* O mostrador: um número com um ponto aceso ao lado. Diz quantos anúncios
   ficam fora do ecrã. */
.instr .corte {
  margin-top: 7px; font: 600 0.66rem inherit; color: var(--banda-vermelho);
  letter-spacing: 0.04em; display: flex; align-items: center; gap: 6px;
}
.instr .corte::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 6px currentColor;
}
.instr .corte.zero { color: var(--text-muted); opacity: 0.6; }
.instr .corte.zero::before { box-shadow: none; }
.instr .mini { font-size: 0.68rem; color: var(--text-muted); margin: 2px 0 0; }
.instr .linha { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* O desenho dos campos vem da família dos controlos, aqui em cima. */
.instr input[type="number"] { width: 7ch; text-align: right; }
.instr input[type="text"] { width: 100%; min-width: 0; }
.instr select { width: 100%; }
.instr .ambito { font-size: 0.7rem; color: var(--text-secondary); line-height: 1.45; margin: 0; }

/* Teclas: os alcances. O contorno, a superfície e o realce vêm da família dos
   controlos (styles.css) — a mesma do `.op` dos Anúncios. Aqui só as medidas.

   Havia aqui mais duas regras, `.tecla .n` e `.tecla-larga`, para as teclas de
   saltar para o distrito do lado. Saíram com elas. */
.teclas { display: flex; gap: 4px; flex-wrap: wrap; }
.tecla {
  min-width: 32px; height: 30px; padding: 0 8px;
  flex-direction: column; justify-content: center; font-size: 0.78rem;
}

/* --------------------------- os mais próximos -----------------------------
   A grelha e o cartão vêm de styles.css e são partilhados com a lista dos
   Gráficos — o que se faz aqui é dar-lhes mais espaço, sem tocar na folha
   comum: as regras abaixo estão todas debaixo de `.lista-perto`, e o Plano
   continua com o cartão que tinha.

   Porquê mais espaço: com quatro colunas de 300 px e um título de portal lá
   dentro, tudo o que era texto acabava em reticências. O cartão perdeu o
   título (ver `desenharLista`, em radar.js) e ganhou o €/m²; estas regras dão
   ao que sobrou largura para caber inteiro. --------------------------------- */

.lista-perto { margin-top: 20px; }
.lista-perto h2 {
  font: 600 0.7rem inherit; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text-muted); margin: 0 0 8px;
}
/* 320 e não 300: com 300 sobravam ~130 px para o meio do cartão e o nome de
   um concelho como «Vila Nova de Gaia» já não cabia. */
.lista-perto .contactos { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 8px; }
.lista-perto .contacto { grid-template-columns: 62px minmax(0, 1fr) auto; gap: 12px; padding: 10px 12px; }
.lista-perto .contacto .d { font-variant-numeric: tabular-nums; }
/* A coluna do dinheiro passa a duas linhas: o preço em cima, o €/m² por baixo,
   os dois encostados à direita. Grelha e não flex-column porque a bolinha da
   banda tem de ficar ao lado do preço e não por cima do €/m². */
.lista-perto .contacto .p {
  display: grid; grid-template-columns: auto auto; justify-content: end;
  align-items: center; gap: 0 6px; text-align: right;
}
.lista-perto .contacto .p small {
  grid-column: 2; font-size: 0.68rem; font-weight: 500; color: var(--text-muted);
  letter-spacing: 0.02em;
}
/* O concelho e os distintivos dos portais na mesma linha, alinhados pelo meio
   das letras. */
.lista-perto .contacto .m { display: flex; align-items: center; gap: 5px; }
.lista-perto .contacto .m .logo-fonte { flex: none; border-radius: 3px; }

/* -------------------------------- telemóvel ------------------------------- */

@media (max-width: 1000px) {
  .consola {
    --diam: max(300px, min(100vw - 36px, 100vh - var(--cab-h) - 40px));
    grid-template-columns: 1fr;
  }
  /* o ecrã primeiro, a legenda a seguir, os instrumentos por baixo */
  .ecra-cx { order: -1; flex-wrap: wrap; }
  .ecra-cx .canto {
    position: static; max-width: none; flex: 1 1 45%; text-align: left; margin-top: 8px;
  }
  .ecra-cx .canto-dir i { margin: 0 6px 0 0; }
  .painel-instr { display: grid; grid-template-columns: 1fr 1fr; max-height: none; overflow: visible; }
}
@media (max-width: 640px) {
  .vista-pagina { padding: 0 10px 32px; }
  .topo-linha { padding: 10px 0 6px; }
  .painel-instr { grid-template-columns: 1fr; }
  .consola { --diam: max(280px, min(100vw - 20px, 100vh - var(--cab-h) - 24px)); }
  .ecra-quadro { box-shadow: 0 0 0 4px var(--pag-surface-1), 0 0 0 5px var(--pag-border); }
}

@media (prefers-reduced-motion: reduce) {
  /* A bolinha da legenda fica, quieta: é uma chave de leitura, não um efeito.
     O varrimento nem chega a ser desenhado com movimento reduzido (radar.js);
     esta regra só apanha o caso de a preferência mudar com a página aberta. */
  .canto .pisca { animation: none; }
  .varrimento { display: none; }
}
