/* Sistema de design partilhado por toda a app (pública, conta e admin).
   Tema claro é o valor por omissão em `:root` (nunca regride se o JS de
   tema falhar); `[data-theme="dark"]` em <html> sobrepõe os MESMOS nomes
   de variável — nunca inverter cores cruamente, cada tema tem a sua
   paleta. `data-theme` é escrito por /js/theme-inline.js, colado à mão
   como <script> inline no <head> de cada página, antes de qualquer
   <link rel="stylesheet">, para nunca haver flash do tema errado.

   REGRA DE COR (a razão de a paleta ser esta e não outra):
   1. Os DADOS são donos da rampa de custo (verde 120deg -> ambar 60deg ->
      vermelho 0deg, ver --cost-*). O custo é a quantidade principal da
      app, por isso nenhum elemento de interface usa essas matizes — senao
      competia com o significado.
   2. O INTERFACE usa a matiz que os dados não podem reclamar: 215deg (azul,
      a família do navy do logo), a 95deg do verde de custo mais próximo. O
      acento foi escolhido por exclusão, não por gosto. (Até 16/10/2026 era
      187deg, ciano-teal. Mudou com o logo novo, e o verde-lima do logo FICA
      SÓ NO LOGO: a 90deg cai no meio da rampa de custo, entre o verde 120deg
      e o âmbar 60deg, e um botão lima competiria com "barato" nos hexágonos.
      O navy exato também não serve de acento: tem contraste 1,2 com o texto
      do site, e ligações e texto ficavam indistinguíveis.)
   3. A rampa de custo é uma linguagem de PREENCHIMENTO, nunca de texto:
      medido, o verde da rampa sobre branco dá 2.6:1 e o ambar 2.0:1 —
      ilegíveis. A rampa pinta hexágonos, barras e pontos; o texto por
      cima é sempre tinta (--color-text).
   4. Estado da tomada e custo distinguem-se por FORMA (ponto redondo vs
      barra vertical), não só por matiz — antes eram ambos verde, e o
      verde queria dizer "está livre" e "é o preço" no mesmo painel.
   Contraste verificado: mínimo 4.36:1 (secundário sobre fundo afundado),
   tinta 12.8-16.4:1, acento 5.6-7.4:1 sobre as três superfícies de cada
   tema (medido a 16/10/2026), nos dois temas.

   Breakpoints (documentados aqui porque @media não lê custom properties —
   citar sempre estes valores, nunca inventar outros): 360px, 390px,
   768px (ponto já usado por panel.css, não renumerar), 1024px, 1440px. */

/* Archivo Variable (OFL, Omnibus-Type — ver fonts/OFL.txt): um só ficheiro
   de 88 KB com dois eixos, wght 100-900 e wdth 62-125%. O eixo de largura
   dá as formas estreitas dos rótulos densos (filtros, barra inferior,
   tabelas) sem precisar de uma segunda família. Verificado no ficheiro:
   tem a feature `tnum`, que é o que permite alinhar os preços na vertical
   numa lista (ver css/price.css). Subset latino — cobre todos os
   caracteres portugueses e o €. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("/fonts/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Superfícies */
  --color-bg: #ecf0f0;
  --color-bg-elevated: #ffffff;
  --color-bg-sunken: #dde5e6;

  /* Texto */
  --color-text: #122227;
  --color-text-muted: #5a6b6f;
  --color-text-inverse: #ffffff;

  /* Marca (215deg, escolhido por exclusão — ver REGRA DE COR) */
  --color-accent: #2c5896;
  --color-accent-hover: #254a7e;
  --color-accent-active: #1c385f;
  --color-accent-bg: #dae4f1;

  /* Estados funcionais. Usados como PREENCHIMENTO (pontos, badges), não
     como cor de texto sobre fundo claro — ver REGRA DE COR 3. */
  --color-success: #1a7f37;
  --color-success-bg: #e2f6e9;
  --color-warning: #8a5400;
  --color-warning-bg: #fef3d6;
  --color-error: #a92e1f;
  --color-error-bg: #fde2e2;

  /* Rampa de custo — a linguagem de cor dos DADOS. Os mesmos três pontos
     que js/cost-scale.js interpola por valor; declarados aqui para a legenda,
     as barras de preço e o mapa falarem a mesma língua. */
  --cost-low: hsl(120, 65%, 45%);
  --cost-mid: hsl(60, 65%, 45%);
  --cost-high: hsl(0, 65%, 45%);
  /* O valor que costColor() devolve quando NÃO há intervalo para comparar
     (um só valor, ou diferenças abaixo da guarda de amplitude do grid):
     verde-médio, nem o extremo barato nem o caro. */
  --cost-neutral: hsl(90, 55%, 45%);
  /* Contorno que separa células vizinhas do grid, lido por js/hexgrid.js —
     é chrome, por isso segue o tema (ao contrário da rampa acima). */
  --hexgrid-stroke: #ffffff;

  /* Categorias (não magnitudes): a política de preço de um operador em
     admin/operator-prices.html. Fora da rampa de custo E fora da matiz do
     acento, para não se confundir com nenhuma das duas. */
  --color-policy-flat: #6b4fa8;

  /* Bordas / overlays / foco */
  --color-border: #c3d0d2;
  --color-border-strong: #93a6a9;
  --color-overlay: rgba(10, 24, 28, 0.45);
  --color-focus-ring: #2c5896;

  /* Tipografia */
  --font-sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Escala de razão 1,2 a partir de 1rem, com nomes por PAPEL (não por
     tamanho): o papel sobrevive a um reajuste da escala, "md" não. */
  --text-micro: 0.694rem;
  --text-small: 0.833rem;
  --text-body: 1rem;
  --text-lead: 1.2rem;
  --text-title: 1.44rem;
  --text-head: 1.728rem;
  --text-price: 1.728rem;
  --text-price-lg: 2.074rem;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;

  /* font-stretch, do eixo wdth da Archivo: "dense" para rótulos onde falta
     espaço, em vez de encolher mais o tamanho. */
  --width-normal: 100%;
  --width-dense: 86%;

  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  /* Raios, por papel: folha/bottom-sheet, painel, campo, pílula. */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --radius: var(--radius-md); /* alias — nome antigo, mantido */

  /* Sombras: só para o que de facto flutua sobre o mapa. O resto usa um
     fio de borda — dar a mesma sombra suave a tudo é o que faz um
     interface parecer um kit de cartões. */
  --shadow-sm: 0 1px 2px rgba(10, 24, 28, 0.08);
  --shadow-md: 0 2px 8px rgba(10, 24, 28, 0.12);
  --shadow-lg: 0 8px 28px rgba(10, 24, 28, 0.22);

  /* Néon e vidro — ver css/effects.css ------------------------------------
     Gramática trazida do projeto Sardal: um só acento conduz todos os
     efeitos, exposto como triplo "r, g, b" porque rgba() não sabe compor
     alpha a partir de um hex guardado numa variável. --neon-rgb TEM de
     acompanhar --color-accent — estão lado a lado por essa razão.

     O brilho é parameterizado por tema de propósito: um halo largo sobre
     branco lê-se como mancha cinzenta, não como néon — luz só brilha no
     escuro. No tema claro o anel de 1px e o fundo tintado fazem o trabalho
     e o brilho fica curto; no escuro abre-se por inteiro.

     --neon-ink é a cor que o texto toma no hover, e no tema claro é o
     acento ESCURO: medido, o acento normal sobre o seu próprio fundo
     tintado cai a 3,9:1 numa superfície afundada, enquanto o escuro se
     mantém acima de 5:1 em qualquer das três superfícies. */
  --neon-rgb: 44, 88, 150;
  --neon-ink: #254a7e;
  --neon-tint: 0.12;
  --neon-ring: 0.9;
  --neon-glow: 0 0 10px -2px rgba(var(--neon-rgb), 0.5);
  --neon-glow-strong: 0 0 16px -3px rgba(var(--neon-rgb), 0.62);

  /* O vidro precisa de algo com cor por trás para ter o que desfocar — aqui
     são os tiles do mapa, que é a condição ideal da receita. A tinta sobre
     o painel translúcido mede 14,5-16:1 sobre tiles de papel, parque ou
     água, por isso dá para ser generoso com a translucidez. */
  --glass-rgb: 255, 255, 255;
  --glass-alpha: 0.78;
  --glass-blur: blur(20px) saturate(1.4);
  --glass-edge: rgba(255, 255, 255, 0.5);

  /* Mesma curva de saída do Sardal, para as interações terem todas o mesmo
     "peso" ao responder. */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* O botão de fechar um painel ou uma gaveta. Está aqui, e não em cada
     componente, porque são dois componentes diferentes a precisar da mesma
     medida: o × dos painéis do mapa (css/panel.css) e o da gaveta da conta e
     do admin (css/app-shell.css). É também a medida de que o conteúdo se
     afasta, para não lhe ficar debaixo. */
  --close-size: 2.2rem;

  /* Camadas, de baixo para cima. São três e não duas por uma razão concreta:
     o painel de filtros estava no mesmo nível do menu do mapa, e com
     z-index igual quem ganha é quem vem depois no HTML — os filtros ficavam
     por cima do menu aberto. A ordem tem de vir do que as coisas SÃO:
     cromado fixo da página (filtros, legenda do heatmap) por baixo, painéis
     que se abrem por cima dele, e o que flutua sobre tudo (botões de abrir,
     escurecimento) no topo. */
  --z-chrome: 1000;
  --z-panel: 1100;
  --z-overlay: 1200;
}

:root[data-theme="dark"] {
  --color-bg: #0c181b;
  --color-bg-elevated: #15262a;
  --color-bg-sunken: #081216;

  --color-text: #e4ebec;
  --color-text-muted: #9baeb2;
  --color-text-inverse: #0c181b;

  --color-accent: #74a4e7;
  --color-accent-hover: #9dc0f1;
  --color-accent-active: #4987df;
  --color-accent-bg: #18283f;

  --color-success: #3ecf72;
  --color-success-bg: rgba(62, 207, 114, 0.15);
  --color-warning: #e0a84a;
  --color-warning-bg: rgba(224, 168, 74, 0.15);
  --color-error: #ef6a5a;
  --color-error-bg: rgba(239, 106, 90, 0.15);

  /* A rampa de custo NÃO muda com o tema: é dado, não chrome. Só o
     contorno dos hexágonos e o chrome da legenda seguem os tokens. */
  --hexgrid-stroke: #0c181b;
  --color-policy-flat: #b89ce8;

  /* É aqui que o néon ganha a vida que no tema claro não pode ter. */
  --neon-rgb: 116, 164, 231;
  --neon-ink: #74a4e7;
  --neon-tint: 0.16;
  --neon-glow: 0 0 20px -4px rgba(var(--neon-rgb), 0.85);
  --neon-glow-strong: 0 0 26px -5px rgba(var(--neon-rgb), 0.95);

  --glass-rgb: 21, 38, 42;
  --glass-alpha: 0.68;
  --glass-edge: rgba(255, 255, 255, 0.12);

  --color-border: #2b3f45;
  --color-border-strong: #44616a;
  --color-overlay: rgba(0, 0, 0, 0.6);
  --color-focus-ring: #9dc0f1;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.6);
}

/* Base global mínima — cada página continua a definir o resto no seu
   próprio CSS, isto só garante que body/elementos sem estilo próprio
   seguem o tema em vez de ficarem brancos/pretos a tapar tudo. */
body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  line-height: var(--leading-normal);
}

/* A família não é herdada por controlos de formulário — sem isto, inputs,
   selects e botões ficavam no tipo de letra do sistema enquanto o resto da
   app usa a Archivo. */
input,
select,
textarea,
button {
  font-family: inherit;
}

:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Ícones do sprite partilhado (app/static/img/icons.svg, injetado por
   /js/icons.js) — seguem a cor do texto envolvente via currentColor. */
.icon {
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.15em;
  flex-shrink: 0;
}

/* Botão de alternância de tema — mesmo componente em toda a app. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-bg-elevated);
  color: var(--color-text-muted);
  cursor: pointer;
  flex-shrink: 0;
}
.theme-toggle:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* ── O logo ───────────────────────────────────────────────────────────────
   Duas imagens, uma por tema, trocadas por [data-theme] — o MESMO atributo que
   o resto da paleta usa, e não por prefers-color-scheme: o tema do site é um
   alternador manual e pode contrariar o do sistema operativo (ver o bloco de
   tema no topo de cada página). O logo claro é navy e verde; o escuro é branco
   e verde, porque navy sobre o fundo escuro tem contraste 1,3 (ilegível).
   Ficheiros gerados por scripts/gerar_marca.py. */
.marca-logo { display: inline-block; height: auto; vertical-align: middle; }
.marca-logo-escuro { display: none; }
:root[data-theme="dark"] .marca-logo-claro { display: none; }
:root[data-theme="dark"] .marca-logo-escuro { display: inline-block; }
