/* =========================================================
   LIBERDADE FISCAL — DESIGN SYSTEM (Fase 1: Foundation)
   Mobile-first. Números > explicação > decoração.
   ========================================================= */

/* -----------------------------
   0. Tipografia — Poppins autoalojada
   ----------------------------- */
/* Ficheiros autoalojados em /fonts/ (ver fonts/README.md) — Poppins
   oficial (SIL OFL 1.1), descarregado do repositório google/fonts e
   convertido para woff2. Caso algum ficheiro falhe (p.ex. cache
   corrompida), estas declarações falham silenciosamente e a stack de
   sistema definida em --font-family-base assume o lugar — a app nunca
   fica sem texto por causa disto. */
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("./fonts/poppins-light.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/poppins-regular.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./fonts/poppins-semibold.woff2") format("woff2");
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./fonts/poppins-bold.woff2") format("woff2");
}

/* -----------------------------
   1. Tokens — paleta e identidade
   ----------------------------- */
:root {
  /* Paleta confirmada (secção 4 do CLAUDE.md) */
  --color-navy: #0D1321;      /* confiança / estrutura */
  --color-green: #22C55E;     /* liberdade / resultado — APENAS fundos, preenchimentos, ícones grandes. NUNCA como cor de texto (2,28:1 sobre branco, falha WCAG AA) */
  --color-green-text: #15803D; /* variante escura do verde — 4,54:1 sobre branco, cumpre AA. Usar sempre que o verde for cor de primeiro plano (texto, links, ícones pequenos, estado ativo) */
  --color-mint: #7EEBC1;      /* estados positivos */
  --color-gold: #F6C453;      /* atenção / dinheiro */
  --color-background: #F1F3F5;
  --color-white: #FFFFFF;

  /* Derivados funcionais */
  --color-text: var(--color-navy);
  --color-text-muted: #4B5566;
  --color-border: #D9DEE3;
  --color-danger: #E5484D;
  --color-focus-ring: #0D6EFD;

  /* Estados sobre navy (texto claro) */
  --color-text-on-navy: var(--color-white);
  --color-text-on-navy-muted: #AEB6C4;

  /* Base usada nas mesclas color-mix() de fundos "tintados" (cartões de
     estado, destaques). Em modo claro é branco; o bloco de modo escuro
     abaixo troca-a por uma superfície escura, para que estes fundos
     tintados continuem a fazer sentido sem inverter (P2-12). */
  --surface-tint: var(--color-white);

  /* Tipografía */
  --font-family-base: "Poppins", "Segoe UI", system-ui, -apple-system,
    Roboto, sans-serif;
  --font-weight-light: 300;
  --font-weight-regular: 400;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* Escala tipográfica — mobile-first */
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.5rem;
  --font-size-2xl: 2rem;
  --font-size-hero: 2.75rem; /* números principais, p.ex. Dia da Liberdade Fiscal */

  /* Espaçamento — base 4px */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* Raios e sombras */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --shadow-sm: 0 1px 2px rgba(13, 19, 33, 0.05), 0 1px 1px rgba(13, 19, 33, 0.04);
  --shadow-md: 0 8px 20px -6px rgba(13, 19, 33, 0.16), 0 2px 6px rgba(13, 19, 33, 0.06);
  --shadow-lg: 0 16px 36px -12px rgba(13, 19, 33, 0.22), 0 4px 10px rgba(13, 19, 33, 0.08);

  /* Tamanho tátil mínimo (WCAG 2.2 AA — 24x24 CSS px mínimo, 44px recomendado) */
  --tap-target-min: 44px;

  /* Layout */
  --content-max-width: 640px;
  --transition-base: 160ms ease;
}

/* -----------------------------
   1b. Modo escuro (P2-12, prefers-color-scheme)
   ----------------------------- */
/* Segue a preferência do sistema operativo do utilizador — não há
   comutador manual na app (menos um estado para gerir e testar; a
   generalidade dos utilizadores já define isto ao nível do SO/browser).
   Reaproveita a mesma paleta da identidade (navy/green/mint/gold), só
   troca os papéis de fundo/superfície/texto — os tokens semânticos
   (--color-text, --color-border, etc.) garantem que os componentes não
   precisam de saber que há um modo escuro, só os tokens mudam. */
@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #0B0F17;
    --color-white: #161C28; /* "branco" semântico = superfície de cartão em modo escuro */
    --color-text: #EDEFF2;
    --color-text-muted: #A7AFBC;
    --color-border: #2B3444;
    --color-danger: #FF6B6E; /* aclarado — #E5484D não cumpre 4,5:1 sobre fundo escuro */
    --color-focus-ring: #6EA8FE; /* aclarado — mesma razão */
    --color-green-text: #4ADE80; /* aclarado — #15803D fica sub-contrastado sobre fundo escuro */

    --color-text-on-navy: var(--color-white);
    --color-text-on-navy-muted: #AEB6C4;

    --surface-tint: #1D2534;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 1px rgba(0, 0, 0, 0.28);
    --shadow-md: 0 8px 20px -6px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 16px 36px -12px rgba(0, 0, 0, 0.65), 0 4px 10px rgba(0, 0, 0, 0.4);
  }

  /* .app-header e outros blocos que usam var(--color-navy) como fundo
     fixo (não var(--color-background)) mantêm-se escuros nos dois
     modos por desenho — já eram escuros em modo claro, por isso não
     precisam de ajuste aqui. */
}

/* -----------------------------
   2. Reset base
   ----------------------------- */
/* O atributo [hidden] tem a mesma especificidade que uma classe (ex.:
   .taximetro-field { display: flex }) — sem !important, uma classe
   com display definido no MESMO elemento pode "ganhar" ao hidden e o
   elemento continua visível apesar do atributo (bug real encontrado
   no seletor de concelho do IMI: escondia-o com .hidden = true, mas
   .taximetro-field { display: flex } sobrepunha-se). Esta regra
   garante que [hidden] esconde sempre, em qualquer elemento. */
[hidden] {
  display: none !important;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-base);
  line-height: 1.5;
  color: var(--color-text);
  background-color: var(--color-background);
  min-height: 100vh; /* fallback para navegadores sem suporte a unidades dinâmicas */
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  max-width: 100%;
  display: block;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

button,
input,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

a {
  color: var(--color-green-text);
  text-decoration-thickness: 2px;
}

/* Botão com aparência de link — usado para navegação secundária fora
   do fluxo principal (ex.: "Os teus dados" no footer). É um <button>,
   não um <a>, porque não navega para um URL — troca a hash da rota via
   JS, tal como os itens do nav principal. */
.link-button {
  background: none;
  border: none;
  padding: 0;
  color: var(--color-green-text);
  font: inherit;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  cursor: pointer;
  min-height: var(--tap-target-min);
}

.link-button:hover {
  color: var(--color-text);
}

.app-footer__links {
  margin-top: var(--space-2);
  /* Mesmo tamanho do disclaimer logo acima (--font-size-xs), para os
     dois textos do footer ficarem visualmente homogéneos — antes
     .link-button herdava o tamanho base (1rem) do <p>, maior do que
     o disclaimer (0,75rem), pedido do autor para igualar. */
  font-size: var(--font-size-xs);
}

/* -----------------------------
   3. Acessibilidade — foco, motion, tátil
   ----------------------------- */
:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Alvo tátil mínimo — aplicado apenas a controlos de ação, NUNCA a
   links dentro de texto corrido (ex: parágrafos de metodologia com
   links para a Autoridade Tributária), onde forçar 44px de altura
   quebraria o interlineado. */
button,
[role="button"],
input,
select,
summary,
a.btn,
.app-nav a,
.app-nav__item {
  min-height: var(--tap-target-min);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  background: var(--color-navy);
  color: var(--color-white);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  z-index: 1000;
  transition: top var(--transition-base);
}

.skip-link:focus {
  top: var(--space-2);
}

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

/* -----------------------------
   4. Tipografía
   ----------------------------- */
h1,
h2,
h3,
h4 {
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  margin: 0 0 var(--space-3);
  color: var(--color-text);
}

h1 {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
}

h2 {
  font-size: var(--font-size-xl);
}

h3 {
  font-size: var(--font-size-lg);
}

p {
  margin: 0 0 var(--space-4);
  color: var(--color-text-muted);
}

/* Números principales — Dia da Liberdade Fiscal, resultados de Taxímetro */
.stat-hero {
  font-size: var(--font-size-hero);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat-hero--green {
  color: var(--color-green-text);
}

.stat-label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

/* Auditoria de marca 23/08/2026 (hallazgo H-1): .stat-label é para
   etiquetas curtas de 2-5 palavras ("SALÁRIO LÍQUIDO MENSAL
   ESTIMADO") — em maiúsculas sustidas, frases completas ficam mais
   difíceis de ler (~10-20% mais lentas) e soam a estar "gritadas",
   o oposto do tom de confiança que a marca quer transmitir,
   especialmente nas notas de privacidade. .stat-caption é a mesma
   posição visual (legenda pequena e muted por baixo de um número ou
   grupo), mas em minúsculas normais — usar sempre que o texto for
   uma frase, não uma etiqueta curta. */
.stat-caption {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* Variante mais pequena do stat-hero, para números grandes repetidos
   várias vezes num só ecrã (ex.: "Para onde vão os impostos", uma
   rúbrica a seguir à outra) — o stat-hero completo é pensado para
   aparecer uma única vez por ecrã. */
.stat-hero-small {
  font-size: var(--font-size-xl, 1.75rem);
  font-weight: var(--font-weight-bold);
  color: var(--color-text);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  margin: var(--space-1) 0;
}

/* "Para onde vão os impostos" (22/08/2026) — cada rúbrica com um
   pequeno espaçamento e separador entre si dentro do bloco de
   detalhe. */
.gasto-publico-rubrica {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.gasto-publico-rubrica:last-child {
  border-bottom: none;
}

.gasto-publico-rubrica h3 {
  margin: 0 0 var(--space-1) 0;
  font-size: var(--font-size-base);
}

/* -----------------------------
   5. Layout base
   ----------------------------- */
.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh; /* fallback para navegadores sem suporte a unidades dinâmicas */
  min-height: 100dvh;
}

.app-header {
  background-color: var(--color-navy);
  color: var(--color-text-on-navy);
  padding: var(--space-4) var(--space-5);
  /* Auditoria 23/08/2026 (equipa iOS/Android): viewport-fit=cover +
     apple-mobile-web-app-status-bar-style=black-translucent (ambos em
     index.html) fazem o conteúdo desenhar por baixo da status bar/notch
     em iPhones com Face ID quando a app está instalada em modo
     standalone — sem isto, o logo e o nome da app ficam parcialmente
     tapados. env() com fallback 0px para browsers sem suporte. */
  padding-top: max(var(--space-4), env(safe-area-inset-top));
}

.app-header__brand-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.app-header__logo {
  height: 48px;
  width: auto;
  flex-shrink: 0;
}

@media (min-width: 640px) {
  .app-header__logo {
    height: 56px;
  }
}

.app-header__brand {
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-xl);
  color: var(--color-white);
  margin: 0;
}

.app-header__claim {
  font-size: var(--font-size-sm);
  color: var(--color-text-on-navy-muted);
  margin: 0;
}

.app-main {
  flex: 1;
  width: 100%;
  max-width: var(--content-max-width);
  margin: 0 auto;
  padding: var(--space-5) var(--space-4) var(--space-8);
  /* Auditoria de marca 23/08/2026 (hallazgo H-4): em ecrãs com pouco
     conteúdo (ex.: landing do Quiz, "Antes de começares") sobrava uma
     zona cinzenta vazia enorme antes do rodapé em viewports mais
     largos que um telemóvel (tablet/desktop) — parecia um ecrã a
     meio de carregar, não uma decisão de design. justify-content:
     center só tem efeito quando o conteúdo é mais baixo que o espaço
     disponível; em ecrãs com muito conteúdo (a maioria) não muda nada. */
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.app-footer {
  /* Linha divisória (23/08/2026, hallazgo H-2): o footer segue-se
     imediatamente ao ecrã de onboarding.js e ao de dia-liberdade.js,
     ambos terminados com este mesmo texto de disclaimer — sem
     separação visual, lia-se como um eco literal. Esta borda garante
     que o footer se lê sempre como uma secção nova, mesmo quando o
     ecrã anterior também termina em disclaimer. */
  border-top: 1px solid var(--color-border);
  padding: var(--space-5) var(--space-5) 0;
  max-width: var(--content-max-width);
  margin: 0 auto;
  width: 100%;
}

.app-footer__aviso-label {
  margin: 0 0 var(--space-1);
}

.app-footer .disclaimer {
  margin-top: 0;
  border-top: none;
  padding-top: 0;
}

/* Nota de "última revisão" dos dados fiscais (19/08/2026) — texto
   pequeno e discreto, claramente secundário face ao disclaimer legal
   acima (que é a informação obrigatória, esta é só transparência
   extra). Preenchida via JS (app.js, initDataFreshnessNote) — fica
   vazia até lá, por isso não reserva espaço fixo. */
.app-footer__revisao {
  margin: var(--space-2) 0 0;
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}
.app-footer__revisao:empty {
  display: none;
}

/* Aviso de copyright (23/08/2026, a pedido do autor) — mesma
   discrição visual que a nota de revisão de dados acima; é
   informação de rodapé, não algo que compita com o disclaimer legal. */
.app-footer__copyright {
  margin: var(--space-2) 0 var(--space-4);
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}

/* Doação voluntária (01/09/2026) — a única exceção à regra de "sem
   vinculação comercial visível" (CLAUDE.md secção 1). Deliberadamente
   discreta: mesmo tamanho/peso que os outros links de rodapé, não um
   botão destacado — não é um CTA a competir pela atenção, é só uma
   porta aberta para quem já decidiu que quer apoiar. */
.app-footer__support {
  margin-top: var(--space-2);
  /* Um pouco maior que o resto do rodapé (--font-size-sm em vez de
     --font-size-xs) a pedido do autor, 01/09/2026 — ainda discreto,
     mas deixa de se confundir visualmente com a nota de copyright. */
  font-size: var(--font-size-sm);
}

.footer-support-link {
  color: var(--color-green-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer-support-link:hover {
  color: var(--color-text);
}

/* Segunda presença do link de apoio (01/09/2026, a pedido do autor:
   "podríamos ponerlo en otros sitios, discreto") — formato de pastilha
   com contorno, para os momentos de maior satisfação do utilizador
   (depois de ver o resultado do Dia da Liberdade Fiscal, depois de
   terminar o quiz). Deliberadamente não preenchido/sólido — um badge
   sólido competiria visualmente com os CTAs reais do ecrã (Partilhar,
   Repetir o quiz); o contorno fica presente sem se disfarçar de botão
   principal. */
.support-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-4);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  border: 1px solid var(--color-mint);
  color: var(--color-green-text);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  background: transparent;
}

.support-pill:hover {
  background-color: var(--color-mint);
  color: var(--color-navy);
}

.app-nav {
  display: flex;
  justify-content: space-around;
  align-items: center;
  gap: var(--space-1);
  background-color: var(--color-white);
  border-top: 1px solid var(--color-border);
  padding: var(--space-2) var(--space-2);
  /* Mesmo motivo do .app-header acima: sem isto, o home indicator dos
     iPhones sem botão físico (X em diante) fica sobreposto aos itens
     de navegação em modo standalone. */
  padding-bottom: max(var(--space-2), env(safe-area-inset-bottom));
  position: sticky;
  bottom: 0;
  z-index: 10;
}

.app-nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  flex: 1;
  min-height: var(--tap-target-min);
  border: none;
  border-top: 3px solid transparent; /* reserva espaço fixo — evita "salto" ao ativar */
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  transition: color var(--transition-base), background-color var(--transition-base),
    border-color var(--transition-base);
}

.app-nav__icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 26px;
  border-radius: 999px;
  background-color: transparent;
  transition: background-color var(--transition-base);
}

.app-nav__icon {
  width: 21px;
  height: 21px;
  flex-shrink: 0;
}

/* Estado ativo: nunca só cor (WCAG 1.4.1 — uso do cor).
   Quatro sinais independentes: cor de texto AA-compliant, peso
   tipográfico maior, barra superior sólida, e cápsula de fundo atrás
   do ícone. */
.app-nav__item[aria-current="page"] {
  color: var(--color-green-text);
  font-weight: var(--font-weight-bold);
  border-top-color: var(--color-green-text);
}

.app-nav__item[aria-current="page"] .app-nav__icon-wrap {
  background-color: color-mix(in srgb, var(--color-green) 20%, var(--surface-tint));
}

.app-nav__item:hover {
  background-color: var(--color-background);
}

.app-nav__item:hover .app-nav__icon-wrap {
  background-color: color-mix(in srgb, var(--color-navy) 6%, var(--surface-tint));
}

.app-nav__item[aria-current="page"]:hover .app-nav__icon-wrap {
  background-color: color-mix(in srgb, var(--color-green) 26%, var(--surface-tint));
}

/* -----------------------------
   6. Componentes base
   ----------------------------- */
.card {
  background-color: var(--color-white);
  border: 1px solid rgba(13, 19, 33, 0.05);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--space-4);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-target-min);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  border: none;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: transform var(--transition-base), box-shadow var(--transition-base),
    background-color var(--transition-base), border-color var(--transition-base);
}

.btn:active {
  transform: scale(0.98) translateY(1px);
}

.btn--primary {
  background-color: var(--color-green);
  color: var(--color-navy);
  box-shadow: 0 3px 10px -2px rgba(34, 197, 94, 0.45);
}

.btn--primary:hover {
  background-color: #1EA854;
  box-shadow: 0 6px 16px -3px rgba(34, 197, 94, 0.5);
  transform: translateY(-1px);
}

.btn--primary:active {
  box-shadow: 0 2px 6px -2px rgba(34, 197, 94, 0.45);
}

.btn--secondary {
  background-color: var(--color-white);
  color: var(--color-text);
  border: 2px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}

.btn--secondary:hover {
  border-color: var(--color-text);
  background-color: var(--color-background);
  transform: translateY(-1px);
}

.btn--gold {
  background-color: var(--color-gold);
  color: var(--color-navy);
  box-shadow: 0 3px 10px -2px rgba(246, 196, 83, 0.5);
}

.btn--gold:hover {
  background-color: #F0B32E;
  box-shadow: 0 6px 16px -3px rgba(246, 196, 83, 0.55);
  transform: translateY(-1px);
}

/* Separador visual entre blocos de ações do ecrã de resultado do Dia
   da Liberdade Fiscal (22/08/2026) — só uma linha subtil, sem peso
   visual a mais. */
.dia-liberdade-separador {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-4) 0;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

.badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  background-color: var(--color-mint);
  color: var(--color-navy);
}

/* Variantes do .badge para o Glossário fiscal (19/08/2026) — mesmo
   princípio de transparência já usado nos ficheiros de dados
   (verified/ESTIMATE/UNKNOWN), agora visível ao utilizador final. */
.badge--verified {
  background-color: var(--color-mint);
  color: var(--color-navy);
}
.badge--estimate {
  background-color: var(--color-gold);
  color: var(--color-navy);
}
.badge--unknown {
  background-color: var(--color-border);
  color: var(--color-text-muted);
}

.glossario-entrada {
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.glossario-entrada:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}
.glossario-entrada summary {
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
}
.glossario-entrada .badge {
  margin: var(--space-2) 0;
}

.disclaimer {
  font-size: var(--font-size-xs);
  line-height: 1.55;
  color: var(--color-text-muted);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-3);
  margin-top: var(--space-6);
}

/* Nota de ajuda "solta" dentro de um fluxo (ex.: explicação de uma
   categoria ou de um imposto especial) — mais visível que .disclaimer
   simples, sem soar a aviso legal. */
.info-note {
  display: block; /* usada também em <span> (impostos-anuais.js) — sem
    isto o padding/border-left não ocupava a largura toda */
  font-size: var(--font-size-xs);
  line-height: 1.55;
  color: var(--color-text-muted);
  background-color: color-mix(in srgb, var(--color-mint) 16%, var(--surface-tint));
  border-left: 3px solid var(--color-green-text);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: var(--space-2) var(--space-3);
  margin: var(--space-2) 0 0;
}

/* -----------------------------
   6b. Quiz
   ----------------------------- */
.quiz-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: var(--space-4) 0;
}

.quiz-option {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-white);
  font-weight: var(--font-weight-regular);
  cursor: pointer;
  transition: border-color var(--transition-base), background-color var(--transition-base);
}

.quiz-option:hover:not(:disabled) {
  border-color: var(--color-green-text);
}

.quiz-option:disabled {
  cursor: default;
}

/* Feedback nunca depende só da cor: as opções corretas/incorretas
   também mudam de ícone textual (ver ✓/✗ no badge de feedback) e de
   espessura de contorno. */
.quiz-option--correct {
  border-color: var(--color-green-text);
  border-width: 3px;
  background-color: color-mix(in srgb, var(--color-mint) 30%, var(--surface-tint));
}

/* Mensagens de erro de validação (role="alert") — antes definidas via
   estilo inline (erroEl.style.color = ...), movidas para uma classe
   para permitir uma CSP sem 'unsafe-inline' em style-src onde possível
   (Auditoria 2026-08, hallazgo M-2). */
.form-error {
  color: var(--color-danger);
}

/* Idem para o <noscript> de index.html. */
.card--noscript {
  margin: var(--space-5);
}

.quiz-option--incorrect {
  border-color: var(--color-danger);
  border-width: 3px;
}

.quiz-feedback--incorrect {
  background-color: color-mix(in srgb, var(--color-danger) 15%, var(--surface-tint));
  color: var(--color-text);
}

/* -----------------------------
   6c. Taxímetro
   ----------------------------- */
.taximetro-mode-toggle {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.taximetro-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}

.taximetro-field label {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
}

/* Prefixo de moeda dentro do campo — em vez de deixar "quanto gastas
   por mês (€)?" só na label, o próprio símbolo aparece dentro do
   campo, junto ao número, como em qualquer app financeira bem
   acabada. */
.input-euro {
  position: relative;
}

.input-euro::before {
  content: "€";
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-semibold);
  pointer-events: none;
}

.input-euro input {
  padding-left: calc(var(--space-3) + 14px) !important;
}

.taximetro-field input,
.taximetro-field select {
  padding: var(--space-2) var(--space-3);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: var(--color-white);
  min-height: var(--tap-target-min);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.taximetro-field input:hover,
.taximetro-field select:hover {
  border-color: #B9C1CC;
}

.taximetro-field input:focus,
.taximetro-field select:focus {
  border-color: var(--color-green-text);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-green) 22%, transparent);
}

.taximetro-dependentes {
  margin-bottom: var(--space-4);
}

.taximetro-dependente-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-2);
}

.taximetro-dependente-row input {
  width: 80px;
  padding: var(--space-2);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-sm);
  min-height: var(--tap-target-min);
}

.taximetro-cadeia {
  margin: var(--space-4) 0;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2) var(--space-4);
}

.taximetro-cadeia dt {
  color: var(--color-text-muted);
}

.taximetro-cadeia dd {
  margin: 0;
  text-align: right;
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

.taximetro-escaloes {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-3) 0;
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
}

.taximetro-escaloes caption {
  text-align: left;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.taximetro-escaloes th,
.taximetro-escaloes td {
  padding: var(--space-2) var(--space-3);
  text-align: right;
  border-bottom: 1px solid var(--color-border);
}

.taximetro-escaloes th:first-child,
.taximetro-escaloes td:first-child {
  text-align: left;
}

.taximetro-escaloes thead th {
  color: var(--color-text-muted);
  font-weight: var(--font-weight-semibold);
  background-color: var(--color-background);
}

.taximetro-escaloes tbody tr:nth-child(even) {
  background-color: color-mix(in srgb, var(--color-background) 55%, var(--surface-tint));
}

.taximetro-escaloes tbody tr:last-child th,
.taximetro-escaloes tbody tr:last-child td {
  border-bottom: none;
}

/* -----------------------------
   6d. Onboarding (região)
   ----------------------------- */
.onboarding-regioes {
  border: none;
  padding: 0;
  margin: var(--space-4) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.onboarding-regioes legend {
  font-weight: var(--font-weight-semibold);
  padding: 0;
  margin-bottom: var(--space-2);
}

.onboarding-regiao-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  min-height: var(--tap-target-min);
  transition: border-color var(--transition-base);
}

.onboarding-regiao-option:has(input:checked) {
  border-color: var(--color-green-text);
  border-width: 3px;
}

.onboarding-regiao-option:has(input:focus-visible) {
  outline: 2px solid var(--color-navy);
  outline-offset: 2px;
}

.onboarding-regiao-option input {
  min-width: 20px;
  min-height: 20px;
}

/* -----------------------------
   6d-bis. Boas-vindas (storytelling de marca, ver
   modules/boas-vindas.js) — ecrã de apresentação, não de formulário,
   por isso não usa .card (fundo próprio, sem sombra de cartão).
   ----------------------------- */
.welcome-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-6) 0 var(--space-4);
}

.welcome-hero__logo {
  height: 96px;
  width: auto;
  margin-bottom: var(--space-4);
}

.welcome-hero__heading {
  font-size: var(--font-size-xl);
  margin: 0 0 var(--space-3);
}

.welcome-hero__proposito {
  color: var(--color-text);
  max-width: 52ch;
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-base);
}

.welcome-hero__lead {
  color: var(--color-text-muted);
  max-width: 46ch;
  margin: 0 0 var(--space-6);
}

.welcome-promises {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  width: 100%;
  margin-bottom: var(--space-6);
}

@media (min-width: 560px) {
  .welcome-promises {
    grid-template-columns: 1fr 1fr;
  }
}

.welcome-promise {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  text-align: left;
}

.welcome-promise__icon {
  color: var(--color-green-text);
  margin-bottom: var(--space-2);
}

.welcome-promise__titulo {
  font-size: var(--font-size-base);
  margin: 0 0 var(--space-1);
}

.welcome-promise__texto {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  margin: 0;
}

.welcome-hero__opcao {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.welcome-hero__opcao input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.welcome-hero__cta {
  width: 100%;
  max-width: 320px;
}

/* -----------------------------
   6e. Faturas / Gastos
   ----------------------------- */
.gastos-categoria-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.gastos-categoria-header h2 {
  margin: 0;
}

.gastos-categoria-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background-color: color-mix(in srgb, var(--color-mint) 35%, var(--surface-tint));
  color: var(--color-green-text);
}

.gastos-categoria-icon svg {
  width: 22px;
  height: 22px;
}

.gastos-exemplos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0 0 var(--space-4);
}

.gastos-exemplo-chip {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  background-color: var(--color-background);
  border-radius: 999px;
  padding: 3px var(--space-3);
}
.faturas-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-4);
}

/* Usado nos ecrãs de Rendimentos e Taxas para agrupar os botões de
   ação (ex.: "Guardar e avançar" / "Simular outro valor") — sem esta
   regra os botões ficam encostados uns aos outros (sem gap), porque
   são anexados via DOM sem nós de texto/espaço entre eles. */
.taximetro-botoes {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-4);
}

.taximetro-perguntas {
  margin-top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.faturas-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.faturas-list-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.faturas-list-item:last-child {
  border-bottom: none;
}

/* -----------------------------
   6f. Benchmark OCDE
   ----------------------------- */
.benchmark-lista {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.benchmark-linha {
  display: grid;
  grid-template-columns: 8rem 1fr auto;
  align-items: center;
  gap: var(--space-3);
}

.benchmark-linha__label {
  font-size: var(--font-size-sm);
}

.benchmark-linha__barra-wrapper {
  display: block;
  background-color: var(--color-border);
  border-radius: 999px;
  overflow: hidden;
  height: 16px;
}

.benchmark-linha__barra {
  display: block;
  height: 100%;
  background-color: var(--color-green);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0));
  border-radius: 999px;
  transition: width 480ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .benchmark-linha__barra {
    transition: none;
  }
}

.benchmark-linha__valor {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums;
  min-width: 3.5rem;
  text-align: right;
}

.benchmark-linha--portugal .benchmark-linha__barra {
  background-color: var(--color-gold);
}

.benchmark-linha--media .benchmark-linha__barra {
  background-color: var(--color-navy);
  opacity: 0.6;
}

.benchmark-linha--utilizador .benchmark-linha__barra {
  background-color: var(--color-mint);
}

.benchmark-linha--portugal .benchmark-linha__label,
.benchmark-linha--utilizador .benchmark-linha__label {
  font-weight: var(--font-weight-semibold);
}

/* -----------------------------
   6g. Dia da Liberdade — ilustração de resultado
   ----------------------------- */
.dia-liberdade-ilustracao {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 0 var(--space-4);
  padding: var(--space-4) 0;
  background-image: radial-gradient(
    circle,
    color-mix(in srgb, var(--color-mint) 30%, transparent) 0%,
    transparent 70%
  );
}

.dia-liberdade-ilustracao svg {
  filter: drop-shadow(0 8px 16px rgba(13, 19, 33, 0.14));
}

/* -----------------------------
   6h. Dia da Liberdade — comparativa com períodos anteriores (P3-14)
   ----------------------------- */
.dia-liberdade-comparativa {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.dia-liberdade-comparativa table {
  margin-bottom: var(--space-3);
}

/* -----------------------------
   7. Estado offline
   ----------------------------- */
.offline-banner {
  display: none;
  background-color: var(--color-gold);
  color: var(--color-navy);
  text-align: center;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  padding: var(--space-2);
}

.offline-banner[data-visible="true"] {
  display: block;
}

/* -----------------------------
   8. Responsive — desktop
   ----------------------------- */
@media (min-width: 768px) {
  :root {
    --font-size-hero: 3.5rem;
  }

  .app-main {
    padding-top: var(--space-6);
  }

  .app-nav {
    justify-content: center;
    gap: var(--space-6);
  }

  .app-nav__item {
    flex: 0 0 auto;
    min-width: 96px;
  }
}

/* -----------------------------
   8. Impressão / exportação PDF (roadmap P3-16)
   ----------------------------- */
/* Sem nova dependência: usa "Guardar como PDF" nativo do diálogo de
   impressão do browser. .no-print esconde o chrome da app (cabeçalho,
   navegação inferior, rodapé, banner offline, skip-link) e qualquer
   ação/botão que não faça sentido num documento estático — usada em
   qualquer ecrã, não só no Dia da Liberdade Fiscal, para que a
   impressão de qualquer página fique sempre limpa. */
@media print {
  .no-print {
    display: none !important;
  }

  body {
    background: var(--color-white);
  }

  .app-main {
    padding: 0;
  }

  .card {
    box-shadow: none;
    border: none;
    padding: 0;
  }

  /* Garante que a metodologia ("Como chegámos a este número?") sai
     sempre impressa, mesmo que o <details> não tenha sido clicado —
     dia-liberdade.js já força .open = true antes de chamar
     window.print(), isto é um reforço via CSS para qualquer outro
     <details> que apareça num ecrã impresso no futuro. */
  details:not([open]) summary ~ * {
    display: block;
  }

  a[href]::after {
    content: "";
  }
}
