/* ═══════════════════════════════════════════════════════════════════════════
 * mocosense · estilo.css — folha única, dois fronts, quatro combinações
 *
 * Uma só folha serve o mocoengine (denso, operacional) e o mocosense (arejado,
 * comercial). O interruptor é um atributo na raiz:
 *
 *     <html data-tema="engine">   ou   <html data-tema="sense">
 *     <html data-modo="claro">    ou   <html data-modo="escuro">
 *
 * Sem `data-modo`, o sistema operativo decide. Sem `data-tema`, vale o sense.
 *
 * A REGRA QUE SEPARA AS LINGUAGENS, e não se negoceia:
 *   O relevo é para o que se toca e para o que contém. Nunca para o que se lê.
 * O vidro é a mesma regra com outra matéria: entra só no chrome que PASSA POR
 * CIMA de conteúdo — a barra superior e os painéis flutuantes, e mais nada.
 * Nunca sobre um número, uma célula, um gráfico, uma linha de tabela, um
 * cabeçalho de tabela ou uma aba.
 *
 * O QUE MUDA EM RELAÇÃO À FOLHA ANTERIOR, e é matéria de doutrina:
 *   1. Nenhuma cor carrega juízo. As três cores de confiança passam a ser
 *      exclusivas do selo de `estado_confianca`. O `.delta` deixa de ser verde
 *      e vermelho (carregava juízo sobre a direcção do número, e o quinto valor
 *      proíbe-o); a poupança deixa de ser verde; o chip «bom» desaparece.
 *      O sinal — «+», «−» — é o portador, e sobrevive ao alto contraste.
 *   2. Toda a tipografia sobre o creme redefine a sua própria tinta: o
 *      `--secundario` media 6,17:1 sobre o creme e o `--fraca` 6,44:1, ambos AA
 *      e não AAA, dentro do componente `<Formula>` que é núcleo do produto.
 *   3. O tema escuro é novo e está medido, não estimado.
 *
 * O QUE MUDA NESTA REVISÃO — 18 de Agosto:
 *   4. O FRONT PÚBLICO PASSA A VIVER NESTA FOLHA. Havia uma cópia paralela do
 *      estilo dentro de `sense.js`, injectada por CSSOM, com paleta, escala de
 *      espaço e escala tipográfica próprias — e, por essa via, sem tema escuro,
 *      sem folha de impressão, sem alto contraste e com alvos de toque abaixo
 *      dos 44px. Está morta. O que o front público tem a mais está no ponto 20,
 *      escrito com estes tokens e mais nenhuns.
 *   5. O VIDRO PASSA DE QUATRO SUPERFÍCIES A DUAS, e o `saturate(180%)` sai do
 *      desfoque. Saem o cabeçalho de tabela fixo — eram doze desfoques na mesma
 *      imagem, a recompor-se a cada píxel de rolagem, no gesto que mais se faz
 *      num telemóvel — e a aba activa, que é vidro sobre vidro. A conta refeita,
 *      elemento a elemento, está no ponto 06.
 *   6. Alvos de toque de 44px em toda a parte. O botão secundário media 38px, o
 *      botão dentro de tabela 30px e o botão de período 32px.
 *   7. A folha de impressão passa a forçar o tema claro, a abrir as caixas de
 *      rolagem e a repetir o cabeçalho da tabela em cada página.
 *
 * ÍNDICE
 *   01 · tipos de letra          08 · <Valor>            15 · preços
 *   02 · paleta clara            09 · <SeloConfianca>    16 · <FichaFonte>
 *   03 · paleta escura           10 · <Formula>          17 · entrada
 *   04 · densidade dos temas     11 · <TabelaDensa>      18 · marca
 *   05 · base e tipografia       12 · vazio · esqueleto  19 · acessibilidade
 *   06 · a trama · o vidro       13 · <Grafico>          20 · a montra
 *   07 · estrutura               14 · controlos
 * ═══════════════════════════════════════════════════════════════════════════ */


/* ── 01 · tipos de letra ─────────────────────────────────────────────────────
 * Servidos do próprio Worker. A CSP não deixa entrar nada de fora, e é bem
 * assim: uma folha de estilo que depende de um CDN depende de terceiros para
 * mostrar um número que dizemos ser verificável. */

@font-face {
  font-family: 'Stack Sans Notch';
  src: url('/marca/stacksansnotch.woff2') format('woff2-variations');
  font-weight: 200 700;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/marca/plex-regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/marca/plex-medium.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}


/* ── 02 · paleta clara ───────────────────────────────────────────────────────
 * Contraste medido, nunca estimado. Os pares, contra os três fundos do sistema
 * — fundo #F6F1E6, superfície #FFFFFF, creme #E8DDC8:
 *
 *   tinta       #14140F   16,40 · 18,47 · 13,73    AAA
 *   secundário  #514E46    7,37 ·  8,31 ·  6,17    AAA salvo sobre creme
 *   azul-moco   #173D64    9,87 · 11,12 ·  8,27    AAA
 *   forte       #0F4D27    8,83 ·  9,95 ·  7,39    AAA
 *   média       #6F3206    8,73 ·  9,84 ·  7,31    AAA
 *   fraca       #961616    7,69 ·  8,67 ·  6,44    AAA salvo sobre creme
 *
 * As duas excepções resolvem-se no ponto 10: a superfície creme redefine a sua
 * própria tinta, e tudo o que lá dentro se escreve herda o valor corrigido.
 * O âmbar mede 4,46:1 sobre o fundo — não serve texto pequeno em lado nenhum e
 * não é usado para isso; serve traço de foco e marca de avaria, que são
 * elementos não-textuais com alvo de 3:1. */

:root {
  color-scheme: light;

  /* marca */
  --azul-moco: #173d64;
  --creme-moco: #e8ddc8;
  --azul-2: #3e6b96;        /* formas e títulos grandes · nunca texto pequeno */
  --ambar: #b45309;         /* acento · máximo 5% da superfície · foco */

  /* superfícies e tinta
   *
   * A SUPERFÍCIE PASSOU A FRIA A 20-08-2026, por decisão do dono. A montra
   * era creme quente (#f6f1e6) e o motor cinza-azul; ficam os dois no mesmo
   * frio, que é o dos tokens do sistema em `ds/cores.css`.
   *
   * O que a decisão troca, dito por extenso para não se perder: perde-se um
   * pouco da distinção angolana que o creme dava, e ganha-se a leitura de um
   * instrumento de dados — que é o que o produto é e o que os compradores
   * institucionais reconhecem. O creme NÃO desaparece: continua a ser a
   * superfície de marca (`--creme-moco`), nos cartões e nos painéis que a
   * marca assina. Deixa de ser o chão.
   *
   * O azul da marca e as três cores de confiança não mudam um dígito — são as
   * mesmas na montra e no motor, e é isso que mantém os dois reconhecíveis
   * como a mesma casa. */
  --fundo: #f0f3f5;
  --superficie: #f8fafb;
  --tinta: #14140f;
  --secundario: #4c5561;
  --linha: #dde3ea;

  /* tinta corrigida para dentro da superfície creme — ver ponto 10 */
  --secundario-creme: #454239;   /* 7,46:1 sobre #E8DDC8 */
  --fraca-creme: #851111;        /* 7,48:1 sobre #E8DDC8 */

  /* confiança — pertencem ao <SeloConfianca> e a mais nada */
  --forte: #0f4d27;
  --media: #6f3206;
  --fraca: #961616;

  /* escala de dados — cinco degraus, nunca uma cor fora dela */
  --dados-1: #173d64;
  --dados-2: #2c5580;
  --dados-3: #4a749c;
  --dados-4: #7098bc;
  --dados-5: #a3bfd6;

  /* relevo — monocromático, derivado da própria superfície */
  --relevo-claro: #fffdf7;
  --relevo-escuro: #d9d2c2;

  /* vidro — a matéria do chrome. A opacidade não é gosto: é o valor mínimo a
   * que o texto de apoio ainda mede 7:1 quando passa por baixo do vidro a
   * coisa mais escura da página.
   *
   * CORRIGIDO A 18 DE AGOSTO, e é uma correcção de número, não de gosto. Estava
   * 0,86 com a nota «apoio 7,33:1». Recalculado: o composto de 0,86 sobre a
   * tinta `#14140F` é `#DEDCD7`, e o `--secundario` mede aí 6,06:1 — AA, não
   * AAA. A folha afirmava um número que não tinha sido medido. Foi.
   *
   *      0,86 → 6,06    0,90 → 6,66    0,92 → 6,90
   *      0,93 → 7,10  ← o primeiro valor que cumpre a regra da casa
   *
   * Fica 0,93. O desfoque continua a fazer-se e continua a ver-se o que passa
   * por baixo; o que se perde é transparência a mais que nunca esteve em AAA. */
  --vidro-fundo: rgba(255, 253, 247, 0.93);
  --vidro-borda: rgba(255, 253, 247, 0.72);
  --vidro-brilho: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --vidro-solido: #fbf8f0;       /* o mesmo lugar, sem desfoque */
}

/* ── 03 · paleta escura ──────────────────────────────────────────────────────
 * Contra os três fundos escuros — fundo #12161C, superfície #1A1F27,
 * elevado #242A33:
 *
 *   tinta       #F1ECE0   15,39 · 14,04 · 12,25    AAA
 *   secundário  #BCB8AD    9,16 ·  8,35 ·  7,29    AAA
 *   azul-claro  #AECBE4   10,77 ·  9,82 ·  8,57    AAA
 *   forte       #86DBA8   10,98 · 10,02 ·  8,74    AAA
 *   média       #E8AD5C    9,13 ·  8,32 ·  7,26    AAA
 *   fraca       #F3A09A    8,91 ·  8,12 ·  7,09    AAA
 *   âmbar       #F0B163    9,66 ·  8,80 ·  7,69    AAA
 *
 * O azul-moco não sobrevive ao escuro: a #12161C mede 1,7:1. O papel de cor de
 * número passa para o quinto degrau da escala de dados aclarado, que é cor da
 * casa e não uma invenção. A escala de dados inverte-se, para que o degrau mais
 * pesado continue a ser o mais legível contra o seu fundo. */

@media (prefers-color-scheme: dark) {
  :root:not([data-modo='claro']) {
    color-scheme: dark;
    /* O VIDRO TAMBÉM TEM DE MUDAR DE TEMA, e até 20-08-2026 não mudava.
     * `--vidro-2` estava definido uma só vez, em ds/vidro.css, com um claro
     * fixo. A barra fixa ficava com fundo claro nos dois temas — e o texto
     * dela vem de `--secundario`, que aqui é claro. Medido: a frase que é o
     * posicionamento da casa, «Angola publica os números. Nós fazemos a conta
     * que falta.», dava 1,85:1 a 11px. O mínimo é 4,5:1. A frase que define o
     * produto estava escrita em tinta quase invisível. */
    --vidro-1: rgba(18, 22, 28, 0.46);
    --vidro-2: rgba(18, 22, 28, 0.82);
    --vidro-marca: rgba(232, 221, 200, 0.10);
    --vidro-fio: inset 1.5px 1.5px 0 rgba(255,255,255,0.06), inset -1px -1px 0 rgba(0,0,0,0.35);
    --vidro-sombra: 10px 14px 28px rgba(0, 0, 0, 0.42);
    --azul-moco: #aecbe4;
    --creme-moco: #242a33;
    --azul-2: #7ba7cc;
    --ambar: #f0b163;
    --fundo: #12161c;
    --superficie: #1a1f27;
    --tinta: #f1ece0;
    --secundario: #bcb8ad;
    --linha: #313945;
    --secundario-creme: #bcb8ad;
    --fraca-creme: #f3a09a;
    --forte: #86dba8;
    --media: #e8ad5c;
    --fraca: #f3a09a;
    --dados-1: #aecbe4;
    --dados-2: #8fb3d4;
    --dados-3: #6f97bd;
    --dados-4: #517ca4;
    --dados-5: #37628b;
    --relevo-claro: #1e242d;
    --relevo-escuro: #080b0f;
    --vidro-fundo: rgba(18, 22, 28, 0.9);
    --vidro-borda: rgba(174, 203, 228, 0.2);
    --vidro-brilho: inset 0 1px 0 rgba(174, 203, 228, 0.16);
    --vidro-solido: #171c23;
  }
}

/* O mesmo bloco outra vez, para que o atributo vença nos dois sentidos: quem
 * escolhe escuro num sistema claro tem de o obter, e quem escolhe claro num
 * sistema escuro também. Repetir é a única forma de não pôr a definição única
 * de uma cor dentro de uma media query. */
:root[data-modo='escuro'] {
  color-scheme: dark;
  /* O VIDRO TAMBÉM TEM DE MUDAR DE TEMA, e até 20-08-2026 não mudava.
   * `--vidro-2` estava definido uma só vez, em ds/vidro.css, com um claro
   * fixo. A barra fixa ficava com fundo claro nos dois temas — e o texto
   * dela vem de `--secundario`, que aqui é claro. Medido: a frase que é o
   * posicionamento da casa, «Angola publica os números. Nós fazemos a conta
   * que falta.», dava 1,85:1 a 11px. O mínimo é 4,5:1. A frase que define o
   * produto estava escrita em tinta quase invisível. */
  --vidro-1: rgba(18, 22, 28, 0.46);
  --vidro-2: rgba(18, 22, 28, 0.82);
  --vidro-marca: rgba(232, 221, 200, 0.10);
  --vidro-fio: inset 1.5px 1.5px 0 rgba(255,255,255,0.06), inset -1px -1px 0 rgba(0,0,0,0.35);
  --vidro-sombra: 10px 14px 28px rgba(0, 0, 0, 0.42);
  --azul-moco: #aecbe4;
  --creme-moco: #242a33;
  --azul-2: #7ba7cc;
  --ambar: #f0b163;
  --fundo: #12161c;
  --superficie: #1a1f27;
  --tinta: #f1ece0;
  --secundario: #bcb8ad;
  --linha: #313945;
  --secundario-creme: #bcb8ad;
  --fraca-creme: #f3a09a;
  --forte: #86dba8;
  --media: #e8ad5c;
  --fraca: #f3a09a;
  --dados-1: #aecbe4;
  --dados-2: #8fb3d4;
  --dados-3: #6f97bd;
  --dados-4: #517ca4;
  --dados-5: #37628b;
  --relevo-claro: #1e242d;
  --relevo-escuro: #080b0f;
  --vidro-fundo: rgba(18, 22, 28, 0.9);
  --vidro-borda: rgba(174, 203, 228, 0.2);
  --vidro-brilho: inset 0 1px 0 rgba(174, 203, 228, 0.16);
  --vidro-solido: #171c23;
}


/* ── 04 · densidade dos temas ────────────────────────────────────────────────
 * O engine é uma bancada de trabalho: mais linhas no ecrã, menos ar, medida
 * mais larga. O sense é a montra: a medida de leitura de 1180px que a marca
 * fixou, e o ar que uma página comercial precisa.
 *
 * O tema NÃO multiplica a escala de 4 por um factor — isso produzia 3px, 9px,
 * 18px, valores que não existem no sistema. O que o tema faz é apontar cada
 * medida semântica para outro degrau da MESMA escala. Nenhum valor sai da
 * escala 4·8·12·16·24·32·48·64·96, e nenhum tamanho de letra sai de
 * 11·13·15·20·28·40·64. */

:root {
  /* espaçamento — escala de 4, fixa */
  --e1: 4px;  --e2: 8px;  --e3: 12px; --e4: 16px;
  --e5: 24px; --e6: 32px; --e7: 48px; --e8: 64px; --e9: 96px;

  /* tipografia — escala fixa */
  --t1: 11px; --t2: 13px; --t3: 15px; --t4: 20px;
  --t5: 28px; --t6: 40px; --t7: 64px;

  /* A monoespaçada é do sistema, e é a única família que não servimos nós: um
   * hash, um caminho e um cabeçalho HTTP querem a letra que a máquina do leitor
   * já usa para código, e transferir mais um ficheiro para isso seria pagar
   * 40 kB por um gosto. */
  --mono: ui-monospace, 'SFMono-Regular', 'Cascadia Mono', Menlo, Consolas, monospace;

  /* raios — até 16px no chrome, nunca mais de 6px em superfície de dados */
  --raio-chrome: 16px;
  --raio-controlo: 10px;
  --raio-dados: 6px;

  --relevo-1: 3px 3px 6px var(--relevo-escuro), -3px -3px 6px var(--relevo-claro);
  --relevo-2: 6px 6px 12px var(--relevo-escuro), -6px -6px 12px var(--relevo-claro);
  --relevo-in: inset 4px 4px 8px var(--relevo-escuro), inset -4px -4px 8px var(--relevo-claro);

  /* O desfoque perdeu o `saturate(180%)`. A saturação não acrescentava
   * legibilidade nenhuma — acrescentava um segundo passo de composição sobre a
   * mesma área, e num telemóvel de gama média isso paga-se em milissegundos por
   * imagem. Sai por ordem do PMO. O desfoque fica; é ele que faz o vidro. */
  --vidro-desfoque: blur(20px);
  --transicao: 150ms ease-out;

  /* ── o tema por omissão é o sense ── */
  --largura-maxima: 1180px;
  --pad-pagina: var(--e5);
  --pad-painel: var(--e5);
  --pad-cartao: var(--e4);
  --gap-grelha: var(--e4);
  --gap-seccao: var(--e5);
  --celula-y: var(--e3);
  --celula-x: var(--e4);
  --coluna-minima: 260px;
  --t-corpo: var(--t3);
  --t-apoio: var(--t2);
  --t-tabela: var(--t2);
  --lh-corpo: 1.55;
  /* Os extremos do clamp são sempre degraus da escala. O clamp interpola entre
   * dois degraus; não inventa um oitavo tamanho. */
  --t-numero: clamp(var(--t5), 1.1rem + 2.4vw, var(--t6));
  --t-heroi:  clamp(var(--t6), 1.6rem + 3.4vw, var(--t7));
  --t-h1: var(--t5);
  --t-h2: var(--t4);
}

:root[data-tema='engine'] {
  --largura-maxima: 1440px;   /* bancada, não medida de leitura */
  --pad-pagina: var(--e4);
  --pad-painel: var(--e4);
  --pad-cartao: var(--e3);
  --gap-grelha: var(--e3);
  --gap-seccao: var(--e4);
  --celula-y: var(--e2);
  --celula-x: var(--e3);
  --coluna-minima: 220px;
  --t-corpo: var(--t2);
  --t-apoio: var(--t1);
  --t-tabela: var(--t2);
  --lh-corpo: 1.45;
  --t-numero: clamp(var(--t4), 0.8rem + 1.6vw, var(--t5));
  --t-heroi:  clamp(var(--t5), 1.1rem + 2.4vw, var(--t6));
  --t-h1: var(--t4);
  --t-h2: var(--t3);
}


/* ── 05 · base e tipografia ──────────────────────────────────────────────── */

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

/* O atributo `hidden` vale display:none, mas qualquer regra de autor com
 * `display` vence-o — e as nossas têm. Sem isto, o ecrã de entrada ficava
 * desenhado por cima da app depois de entrar. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--fundo);
  color: var(--tinta);
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
  font-size: var(--t-corpo);
  line-height: var(--lh-corpo);
  /* Os algarismos mandam. `912,6291` e `Kz 2.650.000` compõem-se com a mesma
   * largura de coluna em toda a app, e não só nas tabelas. */
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  -webkit-font-smoothing: antialiased;
}

/* Reforço explícito onde há números, para o caso de uma família herdar mal. */
table, .valor, .numero, .preco, .contagem, .serie, .eixo,
input, output, code, time {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

h1, h2, h3, .wordmark, .numero {
  font-family: 'Stack Sans Notch', 'IBM Plex Sans', sans-serif;
  margin: 0;
}
h1, h2, h3 { color: var(--azul-moco); letter-spacing: -0.02em; text-wrap: balance; }
h1 { font-size: var(--t-h1); font-weight: 600; line-height: 1.15; }
h2 { font-size: var(--t-h2); font-weight: 600; line-height: 1.2; }
h3 { font-size: var(--t-corpo); font-weight: 600; line-height: 1.3; }

p { text-wrap: pretty; }

a {
  color: var(--azul-moco);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover { text-decoration-thickness: 2px; }

/* O foco é traço sólido de 2px em âmbar, sempre — nunca relevo, nunca só cor
 * de fundo. Sobrevive ao alto contraste e ao vidro. */
:focus-visible {
  outline: 2px solid var(--ambar);
  outline-offset: 2px;
  border-radius: var(--raio-dados);
}

.etiqueta, .rotulo {
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario);
  font-weight: 500;
}

/* `.miudo` é o nome do front público para a mesma coisa. Mesmo selector, não
 * uma segunda definição. */
.nota, .miudo { margin: 0 0 var(--e4); max-width: 68ch; font-size: var(--t-apoio); color: var(--secundario); }
.leitura{ margin: 0 0 var(--e4); max-width: 68ch; font-size: var(--t-corpo); color: var(--tinta); }
.miudo:last-child { margin-block-end: 0; }

/* Escada tonal — hierarquia por desvanecimento, não por peso. Serve séries
 * antigas e a parte não confirmada de uma frase. O passo mínimo é 0,72 porque
 * abaixo disso o texto sai do AAA sobre os fundos do sistema. */
.escada > * { opacity: 1; }
.escada > * + * { opacity: 0.86; }
.escada > * + * + * { opacity: 0.72; }


/* ── 06 · a trama e o vidro ──────────────────────────────────────────────────
 *
 * A TRAMA. As linhas horizontais que constroem o Moco não ficam no logótipo:
 * são separadores, fundo de gráfico, esqueleto, estado vazio. Densificam com a
 * importância, e ao crescer a área cresce o número de linhas, nunca a espessura
 * de cada uma. Desenham-se gravadas, porque a montanha em espaço negativo é por
 * natureza uma forma em baixo-relevo. */

.trama {
  background-image: repeating-linear-gradient(
    to bottom,
    var(--relevo-escuro) 0 1px,
    transparent 1px var(--trama-passo, 8px));
  opacity: 0.5;
}
.trama-densa { --trama-passo: 4px; }
.trama-larga { --trama-passo: 14px; }

.separador {
  height: 8px;
  border: 0;
  margin: var(--gap-seccao) 0;
  background-image: repeating-linear-gradient(
    to bottom, var(--relevo-escuro) 0 1px, transparent 1px 4px);
  opacity: 0.45;
}

/* ─────────────────────────────────────────────────────────────────── O VIDRO
 *
 * A CONTA, e é a conta pedida — elemento a elemento, porque «quatro por cento»
 * sem a lista é uma alegação. Esta conta foi REFEITA: o vidro era quatro e
 * passa a dois.
 *
 * O QUE SAIU, e porquê. Por ordem do PMO saem os dois sítios que se repetem
 * dentro da mesma imagem:
 *
 *   · `.tabela thead th` — o cabeçalho fixo. Uma tabela de doze colunas eram
 *     DOZE superfícies de desfoque na mesma imagem, cada uma a recompor-se a
 *     cada píxel de rolagem, e a rolagem de tabela é justamente o gesto mais
 *     usado num telemóvel. Passa a superfície creme opaca: continua a tapar as
 *     linhas por baixo (é opaca, tapa melhor), continua a distinguir-se do
 *     corpo da tabela, e não custa uma recomposição.
 *   · `nav.abas button[aria-current='page']` — a aba activa. Não passa por cima
 *     de conteúdo nenhum: assenta na barra superior, que JÁ é vidro. Vidro
 *     sobre vidro é desfoque a desfazer desfoque. Passa a relevo gravado, que é
 *     a linguagem da casa para «carregado».
 *   · e o `saturate(180%)` sai do próprio `--vidro-desfoque`, nos dois que
 *     ficam. Ver ponto 04.
 *
 * DOIS LEVAM VIDRO, e são os dois que passam por cima de conteúdo:
 *      1 · .topo                          a barra superior, fixa ao rolar
 *      2 · .flutuante, dialog, [popover]  os painéis flutuantes
 *
 * OS OUTROS CINQUENTA, que pintam superfície e ficam sem vidro:
 *      3 body · 4 .trama · 5 .separador · 6 .abas button em repouso ·
 *      7 .abas button[aria-current] · 8 .painel · 9 dialog::backdrop ·
 *     10 .valor · 11 .proveniencia code · 12 .selo::before · 13 .formula ·
 *     14 .chip · 15 .chip.neutro · 16 .aviso · 17 .envolve-tabela e .rolo ·
 *     18 .tabela thead th · 19 .tabela td · 20 .vazio · 21 .vazio::before ·
 *     22 .fechado · 23 .fechado::before · 24 .esqueleto · 25 .grafico ·
 *     26 .periodo button · 27 button.accao · 28 input · 29 select ·
 *     30 textarea · 31 .cartao-conta · 32 .cartao-poupanca · 33 .ficha-fonte ·
 *     34 .entrada form · 35 .barra-indice · 36 .barra-poupanca ·
 *     37 .barra-placar · 38 .barra-cheia · 39 .barra-cheia.incompleta ·
 *     40 .barra-placar .barra-fundo · 41 .legenda .chave i ·
 *     — e as onze do ponto 20, que é o front público:
 *     42 .saltar · 43 .ancora-apoio · 44 .ancora-apoio > div · 45 .recibo ·
 *     46 .prova · 47 .caixa · 48 .celulas · 49 .celula · 50 .cartao-categoria ·
 *     51 .citacao · 52 .comutador button
 *
 *     2 ÷ 52 = 3,8 %
 *
 * Três vírgula oito, e não quatro redondos, porque a conta é a conta.
 *
 * NÃO EXISTE UMA CLASSE `.vidro` NESTA FOLHA, e é de propósito. Uma classe
 * utilitária de vidro é um convite a colá-la num cartão de número na primeira
 * pressa. Os dois sítios estão nomeados um a um; um terceiro exige editar esta
 * folha e refazer esta conta.
 *
 * A REGRA. Nunca sob um número, uma célula de dados, um eixo de gráfico, uma
 * linha de tabela, um cabeçalho de tabela ou uma aba — pela mesma razão que o
 * relevo também lá não está: o que se lê fica plano e em AAA.
 *
 * O CONTRASTE SOBRE VIDRO, medido no pior caso — a coisa mais escura da página
 * a passar por baixo do vidro, sem o desfoque a ajudar. Composto por cima da
 * tinta, que é o pior fundo possível:
 *      claro,  93 %  (composto #EFEDE7):  tinta 15,78 · apoio 7,10 · azul 9,50
 *      escuro, 90 %  (composto #282B30):  tinta 12,05 · apoio 7,17 · azul 8,43
 *
 * O VALOR CLARO MUDOU DE 86 % PARA 93 %, e a razão é que o número anterior
 * estava errado. A folha dizia «apoio 7,33» a 86 %; recalculado, media 6,06 —
 * AA, não AAA. Não foi arredondamento: foi um valor estimado escrito no lugar
 * de um valor medido. A escada inteira, para que a próxima pessoa não tenha de
 * a refazer:
 *      82 % → 5,55   ·   86 % → 6,06   ·   90 % → 6,66
 *      92 % → 6,90   ·   93 % → 7,10   ·   95 % → 7,35
 * A opacidade não é gosto: é o valor a que o vidro ainda cumpre a regra da casa.
 * Se não cumprisse, não havia vidro.
 *
 * Tirar o `saturate` não mexe nestes valores: a saturação altera croma, não
 * luminância, e o contraste WCAG é luminância.
 *
 * A DEGRADAÇÃO. A declaração base de cada superfície de vidro é SÓLIDA. O vidro
 * só entra dentro de um `@supports`. Assim nenhum motor precisa de perceber o
 * `not` para acertar, e o Safari, que durante anos só percebeu a forma com
 * prefixo, é servido pelo mesmo bloco. O vidro é enfeite; a estrutura está
 * inteira sem ele. */


/* ── 07 · estrutura ──────────────────────────────────────────────────────── */

.pagina {
  max-width: var(--largura-maxima);
  margin-inline: auto;
  padding: 0 var(--pad-pagina) var(--e9);
}

/* A barra superior é o primeiro dos quatro vidros. É fixa porque num painel de
 * dados a navegação tem de estar onde a mão está, e é de vidro porque é a única
 * superfície que passa por cima de conteúdo enquanto se rola. */
.topo {
  position: sticky;
  inset-block-start: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--e4);
  flex-wrap: wrap;
  padding: var(--e3) var(--pad-pagina);
  margin-inline: calc(var(--pad-pagina) * -1);
  margin-block-end: var(--gap-seccao);
  border-inline: 0;
  border-block-start: 0;
  border-end-start-radius: var(--raio-chrome);
  border-end-end-radius: var(--raio-chrome);
  /* vidro 1/4 */
  background: var(--vidro-solido);
  border-block-end: 1px solid var(--vidro-borda);
  box-shadow: var(--vidro-brilho);
}
.topo img { height: 30px; width: auto; }

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .topo {
    background: var(--vidro-fundo);
    -webkit-backdrop-filter: var(--vidro-desfoque);
    backdrop-filter: var(--vidro-desfoque);
  }
}
/* Quem pediu menos transparência recebe menos transparência, nos quatro sítios.
 * Não é preferência decorativa: há gente para quem o fundo em movimento por
 * baixo do texto é exactamente o que impede a leitura. */
@media (prefers-reduced-transparency: reduce) {
  .topo {
    background: var(--vidro-solido);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

nav.abas {
  display: flex;
  gap: var(--e2);
  flex-wrap: wrap;
  margin-inline-start: auto;
}
nav.abas button {
  font: inherit;
  font-size: var(--t2);
  color: var(--azul-moco);
  background: var(--fundo);
  border: 1px solid transparent;
  padding: var(--e2) var(--e4);
  border-radius: var(--raio-controlo);
  box-shadow: var(--relevo-1);
  cursor: pointer;
  transition: box-shadow var(--transicao);
  min-height: 44px;      /* alvo de toque */
}
nav.abas button:hover { box-shadow: var(--relevo-2); }

/* A aba activa JÁ NÃO É VIDRO. Assenta na barra superior, que é vidro: vidro
 * sobre vidro é desfoque a desfazer desfoque, e são n abas a recompor-se em
 * cada imagem por nada. Fica relevo gravado — a linguagem da casa para «isto
 * está carregado» — sobre superfície opaca. O estado continua a não depender da
 * matéria: leva peso 500 e leva `aria-current`, que é o que sobrevive ao alto
 * contraste, ao ecrã monocromático e ao leitor de ecrã. */
nav.abas button[aria-current='page'] {
  font-weight: 500;
  background: var(--superficie);
  border-color: var(--linha);
  box-shadow: var(--relevo-in);
}

.painel {
  container-type: inline-size;
  background: var(--fundo);
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-2);
  padding: var(--pad-painel);
  margin-block-end: var(--gap-seccao);
}
.painel > header {
  display: flex;
  align-items: baseline;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-block-end: var(--e4);
}

/* `min(100%, …)` na coluna mínima é o que impede o transbordo a 360px: sem
 * isso, uma coluna de 260px numa página de 336px úteis empurra a barra
 * horizontal para a página inteira. */
.grelha,
.cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--coluna-minima)), 1fr));
  gap: var(--gap-grelha);
}
.cartoes { grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--coluna-minima)), 1fr)); }
.cartoes.largos    { --coluna-minima: 340px; }
.cartoes.poupancas { --coluna-minima: 300px; }

.accoes { display: flex; gap: var(--e3); margin-block-end: var(--e4); flex-wrap: wrap; }

/* Painéis flutuantes — o terceiro vidro. Serve o `dialog`, o `popover` nativo e
 * qualquer camada que a app levante por cima do conteúdo. */
.flutuante,
dialog,
[popover] {
  border: 1px solid var(--vidro-borda);
  border-radius: var(--raio-chrome);
  padding: var(--pad-painel);
  color: var(--tinta);
  max-width: min(90vw, 560px);
  background: var(--vidro-solido);
  box-shadow: var(--vidro-brilho), var(--relevo-2);
}
dialog::backdrop { background: rgb(20 20 15 / 0.32); }

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .flutuante, dialog, [popover] {
    background: var(--vidro-fundo);
    -webkit-backdrop-filter: var(--vidro-desfoque);
    backdrop-filter: var(--vidro-desfoque);
  }
}
@media (prefers-reduced-transparency: reduce) {
  .flutuante, dialog, [popover] {
    background: var(--vidro-solido);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}


/* ── 08 · <Valor> ────────────────────────────────────────────────────────────
 * O componente mais importante. O número domina por escala — o salto é
 * enorme-contra-pequeno, nunca intermédio. Sem caixa, sem borda cinzenta:
 * assenta numa superfície com relevo e, lá dentro, tudo é plano. A proveniência
 * abre a um toque em vez de estar sempre a competir com o número. */

.valor {
  container-type: inline-size;
  background: var(--fundo);
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-1);
  padding: var(--pad-cartao);
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  min-width: 0;
}
.valor .rotulo { letter-spacing: 0.08em; }

.valor .numero {
  font-size: var(--t-numero);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--azul-moco);
  min-width: 0;
  overflow-wrap: normal;
}
.valor .numero.heroi   { font-size: var(--t-heroi); }
.valor .numero.pequeno { font-size: var(--t4); }

.valor .unidade {
  font-size: var(--t-apoio);
  color: var(--secundario);
  font-weight: 400;
  letter-spacing: 0;
}
.valor .meta {
  font-size: var(--t1);
  color: var(--secundario);
  display: flex;
  gap: var(--e2);
  align-items: center;
  flex-wrap: wrap;
}
/* Botão de texto. A área de toque são 44px de altura mesmo quando a letra tem
 * 11px — consegue-se com `padding-block` e não empurra o cartão, porque o
 * `.meta` é uma linha flex e o botão só ocupa a altura que a linha já tem. */
.valor .meta button {
  font: inherit;
  background: none;
  border: 0;
  color: var(--azul-moco);
  cursor: pointer;
  padding: var(--e3) 0;
  min-height: 44px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.valor .proveniencia {
  margin-block-start: var(--e2);
  padding-block-start: var(--e2);
  font-size: var(--t2);
  color: var(--tinta);
  display: grid;
  gap: var(--e1);
  border-block-start: 1px solid var(--linha);
  background: transparent;
}
.valor .proveniencia dt {
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario);
}
.valor .proveniencia dd { margin: 0 0 var(--e2); overflow-wrap: anywhere; }
.valor .proveniencia code {
  font-size: var(--t1);
  background: var(--creme-moco);
  color: var(--secundario-creme);
  padding: 1px var(--e1);
  border-radius: 3px;
}

/* Num contentor estreito o número desce um degrau em vez de partir a linha. */
@container (max-width: 240px) {
  .valor .numero { font-size: var(--t4); }
  .valor .numero.heroi { font-size: var(--t5); }
}

/* A variação. Sem cor: o sinal é o portador, e o sinal sobrevive a um ecrã a
 * preto e branco, a um daltónico e a um screenshot impresso. Pintar a subida de
 * verde e a descida de vermelho seria julgar o número — e para metade dos
 * indicadores desta base a subida é má notícia. */
.delta {
  font-size: var(--t-apoio);
  font-weight: 500;
  color: var(--tinta);
  white-space: nowrap;
}
.delta::before { content: attr(data-sinal) ' '; }
.delta.parado { color: var(--secundario); }

/* Dois selos lado a lado — confiança e retenção. */
.valor-estado { display: inline-flex; gap: var(--e2); flex-wrap: wrap; align-items: center; }


/* ── 09 · <SeloConfianca> ────────────────────────────────────────────────────
 * Cor semântica mais texto, nunca só cor. Sem borda e sem relevo — é para ler,
 * não para tocar. Um valor de confiança fraca mostra-se com a mesma clareza de
 * um forte; não se esconde e não se pinta de alarme.
 *
 * Estas três cores não aparecem em mais lado nenhum desta folha. */
.selo {
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  white-space: nowrap;
}
/* O ponto acompanha o texto; nunca o substitui. */
.selo::before {
  content: '';
  inline-size: 6px;
  block-size: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.selo.forte { color: var(--forte); }
.selo.media { color: var(--media); }
.selo.fraca { color: var(--fraca); }

/* Dentro da superfície creme o selo fraco usa a tinta corrigida. */
.formula .selo.fraca, .chip .selo.fraca { color: var(--fraca-creme); }

/* Licença e plano NÃO são confiança, e por isso NÃO tocam nas três cores acima.
 * A cópia paralela do front público pintava `.selo.livre` com o mesmo verde do
 * `forte` — uma licença livre passava a ler-se como «dado de confiança forte»,
 * que é exactamente o juízo que a folha proíbe. Ficam em azul de marca e em
 * tinta de apoio; a palavra é que diz o que são.
 *      azul-moco  9,87 (fundo) · 11,12 (superfície) · 8,27 (creme)   AAA
 *      secundário 7,37 · 8,31 — e sobre creme herda o `--secundario-creme` */
.selo.livre { color: var(--azul-moco); }
.selo.plano { color: var(--secundario); }


/* ── 10 · <Formula> e superfícies creme ──────────────────────────────────────
 * Sempre visível, nunca colapsada. A superfície creme redefine a sua própria
 * tinta de apoio: sobre #E8DDC8 o `--secundario` media 6,17:1, que é AA, e este
 * componente é núcleo do produto. Tudo o que se escreve aqui dentro herda o
 * valor corrigido, sem que ninguém tenha de se lembrar disso outra vez. */
.formula,
.chip,
.aviso {
  --secundario: var(--secundario-creme);
  --fraca: var(--fraca-creme);
}

.formula {
  background: var(--creme-moco);
  border-radius: var(--raio-dados);
  padding: var(--e3);
  font-size: var(--t2);
  line-height: 1.5;
  color: var(--tinta);
  overflow-wrap: anywhere;
}

/* Etiqueta plana. Superfície de dados: raio de 6px, sem sombra, sem juízo — não
 * há chip «bom» nem chip «mau». Um chip diz o que a coisa é. */
.chip {
  display: inline-block;
  padding: 2px var(--e2);
  border-radius: var(--raio-dados);
  background: var(--creme-moco);
  color: var(--tinta);
  font-size: var(--t1);
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* O chip neutro leva tinta corrente, não tinta de apoio: sobre `--linha` o
 * apoio media 5,88:1 no tema escuro. Um chip distingue-se pelo fundo; não
 * precisa também de apagar a letra. */
.chip.neutro { background: var(--linha); color: var(--tinta); }

.aviso {
  border-radius: var(--raio-dados);
  padding: var(--e3);
  font-size: var(--t-apoio);
  background: var(--creme-moco);
  color: var(--tinta);
}
/* Uma avaria do sistema não é um juízo sobre o dado: é um facto sobre nós. Leva
 * a marca do acento — traço não-textual, 4,46:1 sobre o fundo, acima dos 3:1 —
 * e leva a palavra. O texto continua em tinta corrente. */
.aviso.mau {
  border-inline-start: 3px solid var(--ambar);
  padding-inline-start: var(--e3);
  font-weight: 500;
}


/* ── 11 · <TabelaDensa> ──────────────────────────────────────────────────────
 * Linhas de 1px, sem zebra, algarismos tabulares, cabeçalho a 11px maiúsculas.
 * Plana sobre um painel com relevo — não uma grelha de teclas.
 *
 * A tabela rola dentro do próprio contentor e nunca empurra a página:
 * `overscroll-behavior: contain` impede o encadeamento do gesto, que é o que
 * faz a página inteira saltar quando se chega ao fim da tabela no telemóvel.
 *
 * O contentor precisa de `tabindex="0"` no HTML para que quem navega por teclado
 * o possa rolar. É a única coisa que esta folha não consegue dar sozinha. */

/* `.rolo` é o nome que o front público dá a esta mesma caixa. Não é um segundo
 * componente — é o mesmo componente com o nome que o mocosense já usava, e por
 * isso entra no mesmo selector em vez de ganhar uma definição paralela. */
.envolve-tabela,
.rolo {
  overflow: auto;
  overscroll-behavior: contain;
  border-radius: var(--raio-dados);
  background: var(--superficie);
  max-block-size: var(--altura-tabela, none);
}
.envolve-tabela.alta, .rolo { --altura-tabela: clamp(320px, 60vh, 720px); }
.envolve-tabela:focus-visible, .rolo:focus-visible { outline-offset: 0; }

/* `separate` e não `collapse`: com `collapse` o browser desenha as bordas na
 * tabela e não nas células, e o cabeçalho fixo perde a sua linha ao rolar. */
.tabela {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--t-tabela);
}
.tabela caption {
  text-align: start;
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario);
  padding: var(--e2) var(--celula-x);
}
/* O cabeçalho fixo JÁ NÃO É VIDRO, e esta é a mudança que mais se sente na mão.
 * Uma tabela de doze colunas punha doze superfícies de desfoque na mesma imagem,
 * todas a recompor-se a cada píxel de rolagem, no gesto que mais se faz num
 * telemóvel. Passa a superfície creme OPACA — que aliás tapa melhor as linhas
 * por baixo do que 86 % de vidro tapava — e a tinta de apoio passa à corrigida
 * para creme, que é o que a põe em AAA:
 *      claro:  #454239 sobre #E8DDC8 = 7,46:1
 *      escuro: #BCB8AD sobre #242A33 = 7,29:1 */
.tabela thead th {
  position: sticky;
  inset-block-start: 0;
  z-index: 2;
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario-creme);
  font-weight: 500;
  text-align: end;
  padding: var(--celula-y) var(--celula-x);
  white-space: nowrap;
  background: var(--creme-moco);
  box-shadow: inset 0 -1px 0 var(--linha);
}

.tabela th:first-child, .tabela td:first-child { text-align: start; }
.tabela td {
  padding: var(--celula-y) var(--celula-x);
  border-block-end: 1px solid var(--linha);
  text-align: end;
  white-space: nowrap;
  background: var(--superficie);
}
.tabela tbody tr:last-child td { border-block-end: 0; }
.tabela .destaque { font-weight: 500; color: var(--azul-moco); }
.tabela td.texto { white-space: normal; min-width: 20ch; }

/* Primeira coluna fixa na horizontal, para tabelas largas. Opcional: pede
 * `.tabela.presa` no HTML. */
.tabela.presa td:first-child,
.tabela.presa th:first-child {
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
}
.tabela.presa thead th:first-child { z-index: 3; }

/* Dentro de uma tabela, um botão é chrome dentro de dados: encolhe na LETRA e
 * no espaço à volta, nunca no alvo. Media 30px, que era metade de um dedo.
 * A área continua nos 44px; o que encolheu foi o que se vê. */
.tabela .accoes { gap: var(--e2); margin: 0; }
.tabela .accao.secundaria {
  min-height: 44px;
  padding: var(--e1) var(--e3);
  font-size: var(--t2);
}


/* ── 12 · <EstadoVazio>, <Esqueleto>, <Fechado> ──────────────────────────────
 * O estado vazio tem a mesma dignidade da célula cheia: a mesma superfície, o
 * mesmo raio, a mesma medida de leitura, o mesmo peso na grelha. Explica porquê
 * não há dados e o que falta. Nunca uma tabela de exemplo, nunca um número
 * inventado para tapar o buraco. */

.vazio, .fechado {
  position: relative;
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-in);
  padding: var(--e6) var(--pad-painel);
  min-block-size: 120px;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--e2);
  text-align: center;
  color: var(--tinta);
  font-size: var(--t-apoio);
  overflow: hidden;
}
.vazio::before, .fechado::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    to bottom, var(--relevo-escuro) 0 1px, transparent 1px 10px);
  opacity: 0.25;
  pointer-events: none;
}
.vazio > *, .fechado > * { position: relative; }
.vazio p, .fechado p { margin: 0; max-width: 46ch; color: var(--secundario); }
/* O motivo é texto corrente em AAA, não uma nota de rodapé apagada. */
.vazio .motivo, .fechado .motivo { color: var(--tinta); max-width: 46ch; }

/* Carregamento com a trama em movimento lento. Nunca um spinner genérico. */
.esqueleto {
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-in);
  min-block-size: 120px;
  background-image: repeating-linear-gradient(
    to bottom, var(--relevo-escuro) 0 1px, transparent 1px 8px);
  background-size: 100% 200%;
  animation: respirar 2.4s ease-in-out infinite;
}
@keyframes respirar {
  0%, 100% { background-position: 0 0; opacity: 0.35; }
  50%      { background-position: 0 8px; opacity: 0.6; }
}


/* ── 13 · <Grafico> ──────────────────────────────────────────────────────────
 * Linha de 1,5px, grelha discreta, eixo à direita, sem legenda quando há uma só
 * série. O contentor ganha relevo; a linha e os eixos ficam planos. */

.grafico {
  container-type: inline-size;
  background: var(--fundo);
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-1);
  padding: var(--pad-cartao);
}
.grafico svg { display: block; width: 100%; height: auto; }
.grafico .linha  { fill: none; stroke: var(--dados-1); stroke-width: 1.5; }
.grafico .grelha { stroke: var(--linha); stroke-width: 1; }
/* Os eixos são números: leem-se. 11px é o degrau da escala, não 10. */
.grafico .eixo { font-size: var(--t1); fill: var(--secundario); }

/* A forma acompanha a cor, sempre: cinco séries distinguem-se pelo traço mesmo
 * num ecrã monocromático. Cada degrau publica a sua cor em `--cor-serie`, para
 * que a MESMA classe sirva o traço, o ponto e a marca da legenda — um nome,
 * três usos, e nenhuma cor escrita em JavaScript. */
.serie-1 { --cor-serie: var(--dados-1); stroke: var(--cor-serie); stroke-dasharray: none; }
.serie-2 { --cor-serie: var(--dados-2); stroke: var(--cor-serie); stroke-dasharray: 6 3; }
.serie-3 { --cor-serie: var(--dados-3); stroke: var(--cor-serie); stroke-dasharray: 2 3; }
.serie-4 { --cor-serie: var(--dados-4); stroke: var(--cor-serie); stroke-dasharray: 9 3 2 3; }
.serie-5 { --cor-serie: var(--dados-5); stroke: var(--cor-serie); stroke-dasharray: 1 4; }

/* Os pontos de uma série pintam-se, não se traçam — e não levam tracejado, que
 * num círculo de 2px de raio só faria sujidade. */
circle.serie-1, circle.serie-2, circle.serie-3, circle.serie-4, circle.serie-5 {
  fill: var(--cor-serie);
  stroke: none;
  stroke-dasharray: none;
}

.periodo { display: flex; gap: var(--e1); flex-wrap: wrap; }
.periodo button {
  font: inherit;
  font-size: var(--t1);
  background: var(--fundo);
  border: 0;
  color: var(--azul-moco);
  padding: var(--e2) var(--e3);
  border-radius: var(--raio-controlo);
  box-shadow: var(--relevo-1);
  cursor: pointer;
  min-height: 44px;   /* media 32px · alvo de toque */
  min-width: 44px;
}
.periodo button[aria-pressed='true'] { box-shadow: var(--relevo-in); font-weight: 500; }

/* A legenda só existe quando há mais do que uma fonte a medir a mesma série.
 * Plana, pequena, com o nome por extenso — uma cor sem nome obriga a adivinhar. */
.legenda { display: flex; flex-wrap: wrap; gap: var(--e4); margin-block-start: var(--e2); }
.legenda .chave { display: inline-flex; align-items: center; gap: var(--e2); font-size: var(--t2); color: var(--secundario); }
.legenda .chave i { inline-size: 14px; block-size: 2px; border-radius: 1px; display: inline-block; background: currentColor; }

.escala-dados { display: flex; gap: 2px; }
.escala-dados span { inline-size: var(--e4); block-size: var(--e2); background: var(--dados-3); }


/* ── 14 · controlos e formulários ────────────────────────────────────────── */

button.accao, input, select, textarea {
  font: inherit;
  font-size: var(--t-corpo);
  color: var(--tinta);
  background: var(--fundo);
  border: 0;
  border-radius: var(--raio-controlo);
  padding: var(--e3) var(--e4);
  min-height: 44px;
  width: 100%;
}
input, select, textarea { box-shadow: var(--relevo-in); }
input::placeholder, textarea::placeholder { color: var(--secundario); opacity: 1; }

button.accao {
  box-shadow: var(--relevo-1);
  color: var(--azul-moco);
  font-weight: 500;
  cursor: pointer;
  width: auto;
  transition: box-shadow var(--transicao);
}
button.accao:hover  { box-shadow: var(--relevo-2); }
button.accao:active { box-shadow: var(--relevo-in); }
/* Desactivado leva texto, não só menos sombra. */
button.accao[disabled] {
  color: var(--secundario);
  cursor: default;
  box-shadow: var(--relevo-in);
}
button.accao[disabled]::after { content: ' · indisponível'; font-weight: 400; font-size: var(--t1); }

/* O botão secundário media 38px e estava abaixo do alvo. Passa a 44px como
 * todos os outros: o alvo de toque não tem hierarquia — a hierarquia é o peso
 * da letra e a sombra, não o tamanho da área que o dedo tem de acertar. */
.accao.secundaria {
  font-weight: 400;
  color: var(--secundario);
  min-height: 44px;
  padding: var(--e2) var(--e4);
}

label { display: block; margin-block-end: var(--e3); max-width: 640px; }
label > span { display: block; margin-block-end: var(--e1); }
form .accao { margin-block-start: var(--e3); }

.procura { display: flex; gap: var(--e3); flex-wrap: wrap; }
.procura input { flex: 1 1 260px; width: auto; min-width: 0; }


/* ── 15 · presença digital e preços ──────────────────────────────────────────
 * A regra do sistema aplicada a dois módulos inteiros: relevo no que se toca e
 * no que contém — o cartão, o campo, o botão. Plano no que se lê — o número, a
 * barra, a tabela, o chip. */

.cartao-conta,
.cartao-poupanca,
.ficha-fonte {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  background: var(--fundo);
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-1);
  padding: var(--pad-cartao);
  min-width: 0;
  transition: box-shadow var(--transicao);
}
.cartao-conta, .cartao-poupanca { cursor: pointer; }
.cartao-conta:hover, .cartao-poupanca:hover { box-shadow: var(--relevo-2); }
.cartao-conta:active, .cartao-poupanca:active { box-shadow: var(--relevo-in); }

.cartao-conta h3,
.cartao-poupanca h3,
.ficha-fonte h3 { font-size: var(--t-corpo); font-weight: 500; line-height: 1.3; overflow-wrap: anywhere; }

.cartao-topo { display: flex; justify-content: space-between; align-items: baseline; gap: var(--e2); flex-wrap: wrap; }
.identificador { font-size: var(--t2); color: var(--secundario); overflow-wrap: anywhere; }

.cartao-numeros { display: flex; gap: var(--e4); margin-block-start: var(--e2); flex-wrap: wrap; }
.cartao-numeros > div { display: flex; flex-direction: column; min-width: 0; }
/* `.medida` é o nome do front público para o mesmo número grande. */
.numero, .medida {
  font-family: 'Stack Sans Notch', 'IBM Plex Sans', sans-serif;
  font-size: var(--t-numero);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--azul-moco);
}
.numero.pequeno, .medida.pequeno { font-size: var(--t4); }

/* A tira de números do cabeçalho de módulo. Plana sobre o painel: são dados, e
 * o painel já é o relevo que os contém. */
.tira-numeros {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e6);
  margin-block-end: var(--gap-seccao);
  padding-block-end: var(--e4);
  border-block-end: 1px solid var(--linha);
}
.numero-tira { display: flex; flex-direction: column; min-width: 0; }
.rotulo.tenue, .rotulo.com-lojas { text-transform: none; letter-spacing: 0; font-size: var(--t2); }

/* Barras. Superfície de dados: planas, raio pequeno, sem sombra, sem cor de
 * juízo — o azul da escala de dados e mais nada. */
.barra-indice, .barra-poupanca, .barra-placar {
  position: relative;
  block-size: 6px;
  border-radius: 3px;
  background: var(--linha);
  overflow: hidden;
  margin-block-start: var(--e1);
}
.barra-placar { block-size: 10px; border-radius: 5px; }
.barra-cheia  { block-size: 100%; background: var(--dados-1); }
.barra-placar .barra-fundo,
.barra-placar .barra-cheia { position: absolute; inset: 0 auto 0 0; block-size: 100%; border-radius: 5px; }
.barra-placar .barra-fundo { background: var(--dados-5); }

/* Um índice a que faltam componentes não pode parecer igual a um completo: a
 * trama diz que está incompleto sem depender de cor nenhuma. */
.barra-cheia.incompleta {
  background: repeating-linear-gradient(
    45deg, var(--dados-4) 0 3px, var(--fundo) 3px 6px);
}
.nota-falha { font-size: var(--t2); line-height: 1.35; color: var(--tinta); font-weight: 500; }

/* O número que domina no módulo de preços é a POUPANÇA — é a resposta à
 * pergunta que traz alguém aqui. Em azul de marca, não em verde: pintá-la de
 * verde seria dizer «boa notícia», e isso é o juízo que o quinto valor proíbe. */
.poupanca-numero, .variante-poupanca {
  display: flex;
  align-items: baseline;
  gap: var(--e2);
  margin-block-start: var(--e2);
  flex-wrap: wrap;
}
.poupanca-numero .numero, .variante-poupanca .numero { color: var(--azul-moco); }
.poupanca-numero .unidade { font-size: var(--t-apoio); color: var(--secundario); }

/* O confronto: duas lojas lado a lado, cada preço colado ao nome da sua loja —
 * um preço sem a loja ao lado não diz nada. */
.confronto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 130px), 1fr));
  gap: var(--e3);
  margin-block-start: var(--e3);
  padding-block-start: var(--e3);
  border-block-start: 1px solid var(--linha);
}
.confronto .lado { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.confronto .rotulo { text-transform: none; letter-spacing: 0; font-size: var(--t2); overflow-wrap: anywhere; }
.confronto .preco { font-size: var(--t-corpo); font-weight: 500; color: var(--tinta); }
/* O mais barato leva peso e leva a palavra. Não leva cor: o preço mais alto não
 * é um erro nem uma culpa — é o preço de outra loja. */
.confronto .lado.barato .preco { font-weight: 700; }
.confronto .lado.barato .rotulo::after { content: ' · mais barato'; color: var(--secundario); }
.confronto .preco.riscado { text-decoration: line-through; color: var(--secundario); }

.placar { display: flex; flex-direction: column; gap: var(--e3); }
.linha-placar {
  display: grid;
  grid-template-columns: minmax(120px, 180px) 1fr auto;
  align-items: center;
  gap: var(--e4);
}
.linha-placar .nome-loja { font-size: var(--t2); overflow-wrap: anywhere; }
.linha-placar .contagem { font-size: var(--t2); color: var(--secundario); white-space: nowrap; }

.variante { padding: var(--e4) 0; border-block-end: 1px solid var(--linha); }
.variante:last-child { border-block-end: 0; }
.variante-cabeca { display: flex; align-items: center; gap: var(--e3); margin-block-end: var(--e2); flex-wrap: wrap; }
.variante-cabeca h3 { font-size: var(--t-h2); }
.variante-poupanca .rotulo { text-transform: none; letter-spacing: 0; font-size: var(--t-apoio); }

@container (max-width: 320px) {
  .linha-placar { grid-template-columns: 1fr; gap: var(--e1); }
  .cartao-numeros { gap: var(--e3); }
}


/* ── 16 · <FichaFonte>, respostas, gerir ─────────────────────────────────── */

.ficha-fonte { cursor: default; }
.ficha-fonte .proveniencia { margin-block-start: var(--e2); }
.ficha-fonte .numero { color: var(--azul-moco); }

.pedidos { display: flex; flex-direction: column; gap: var(--e1); margin-block-start: var(--e2); }
.pedido { font-size: var(--t1); color: var(--secundario); overflow-wrap: anywhere; line-height: 1.4; }

/* A palavra de quem responde. Plana, com a mesma dignidade do resto do texto:
 * marcá-la com cor ou caixa seria comentá-la, e isso não nos compete. */
.resposta-integral {
  margin: var(--e4) 0;
  padding-inline-start: var(--e4);
  border-inline-start: 2px solid var(--azul-moco);
  font-size: var(--t-corpo);
  line-height: 1.6;
  max-width: 78ch;
  white-space: pre-wrap;
  color: var(--tinta);
}

.regra { padding: var(--e3) 0; border-block-end: 1px solid var(--linha); }
.regra:last-child { border-block-end: 0; }
.regra p { margin: var(--e1) 0 0; font-size: var(--t-apoio); line-height: 1.5; max-width: 84ch; color: var(--tinta); }


/* ── 17 · entrada ────────────────────────────────────────────────────────── */

.entrada { min-block-size: 100dvh; display: grid; place-items: center; padding: var(--e5); }
.entrada form {
  width: min(360px, 100%);
  background: var(--fundo);
  border-radius: var(--raio-chrome);
  box-shadow: var(--relevo-2);
  padding: var(--e6);
}
.entrada img { height: 34px; width: auto; margin-block-end: var(--e5); }


/* ── 18 · marca ──────────────────────────────────────────────────────────────
 * O backoffice é o mocoengine; o mocosense é a marca comercial e vive no front
 * público. Pôr o logótipo do sense no engine confundiria as duas camadas logo à
 * entrada, que é precisamente a distinção que este produto tem de manter clara.
 * A imagem substitui o texto quando existir; até lá, o texto É a marca. */

/* A marca é um link para a raiz, e um link é um alvo de toque: 44px de altura
 * mesmo com um logótipo de 26px lá dentro. Media 30px e falhava — um logótipo
 * não fica isento da regra só por ser a marca. */
.marca {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  min-height: 44px;
}
.marca img { height: 26px; width: auto; }
.marca img + .wordmark { display: none; }
/* Quando a imagem falha, o JavaScript põe-lhe `hidden` e é ESTA regra que faz o
 * texto aparecer. O script não escreve `display` nenhum: quem decide o que se
 * vê é a folha, e o script limita-se a dizer o que aconteceu. */
.marca img[hidden] + .wordmark { display: inline-block; }

.wordmark {
  font-size: var(--t5);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--secundario);
  white-space: nowrap;
}
.wordmark i { font-style: normal; font-weight: 300; }
.wordmark b { font-weight: 700; color: var(--tinta); }


/* ── 19 · acessibilidade, limites e movimento ────────────────────────────────
 *
 * Três media queries de largura em toda a folha, e não mais: o resto resolve-se
 * com clamp(), auto-fit e container queries. A de 640px existe porque abaixo
 * dela a página precisa de menos margem e a barra superior precisa de deixar as
 * abas passar para baixo — nenhuma das duas coisas se resolve por contentor,
 * porque dependem do ecrã e não da caixa. */

@media (max-width: 640px) {
  :root { --pad-pagina: var(--e3); }
  .topo { gap: var(--e2); padding-inline: var(--e3); }
  nav.abas { margin-inline-start: 0; width: 100%; overflow-x: auto; overscroll-behavior-x: contain; flex-wrap: nowrap; }
  nav.abas button { flex: none; }
  .tira-numeros { gap: var(--e4); }
}

/* A 4K a medida de leitura não cresce — cresce a margem. Um número a 64px numa
 * linha de 3000px não se lê melhor; lê-se pior. O que cresce é o ar. */
@media (min-width: 2200px) {
  :root { --pad-pagina: var(--e8); }
}

/* Com o relevo e o vidro suprimidos, a interface continua legível e navegável.
 * O vidro é enfeite: aqui desaparece inteiro e nada se perde. */
@media (prefers-contrast: more), (forced-colors: active) {
  .painel, .valor, .grafico, .cartao-conta, .cartao-poupanca, .ficha-fonte,
  nav.abas button, button.accao, input, select, textarea, .entrada form,
  .caixa, .recibo, .cartao-categoria, .comutador button {
    box-shadow: none;
    border: 1px solid var(--tinta);
    background: var(--superficie);
  }
  .topo, .flutuante, dialog, [popover] {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--superficie);
    border: 1px solid var(--tinta);
    box-shadow: none;
  }
  .tabela thead th { background: var(--superficie); box-shadow: inset 0 -2px 0 var(--tinta); }
  nav.abas button[aria-current='page'],
  .comutador button[aria-pressed='true'] { border-width: 2px; font-weight: 500; }
  .vazio, .esqueleto, .fechado { box-shadow: none; border: 1px dashed var(--secundario); }
  .vazio::before, .fechado::before { display: none; }
  .ancora-apoio > div, .celula, .prova { border: 1px solid var(--tinta); }
  .trama-svg, .cadeia .trama { display: none; }
}

/* Nada entra a saltar, nada pisca. Suprimido o movimento, o esqueleto fica uma
 * superfície gravada parada — continua a dizer «está a carregar» pela forma. */
@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;
  }
  .esqueleto { opacity: 0.45; }
}

/* Impressão: sobrevive ao screenshot e ao papel. Sem relevo, sem vidro, tinta a
 * preto, e a proveniência aberta — se alguém imprime um número nosso, a fonte
 * vai junto. */
@media print {
  /* A impressão força o tema claro, aconteça o que acontecer no ecrã: um tema
   * escuro impresso é uma folha preta e um tinteiro gasto.
   *
   * OS TRÊS SELECTORES SÃO OBRIGATÓRIOS, e a razão é especificidade — que uma
   * media query NÃO altera. O bloco escuro do ponto 03 usa
   * `:root:not([data-modo='claro'])`, que pesa (0,2,0); um `:root` sozinho pesa
   * (0,1,0) e PERDE, mesmo estando dentro de `@media print` e mesmo vindo
   * depois no ficheiro. Sem esta linha, quem tivesse o sistema em escuro e não
   * tivesse escolhido «claro» à mão imprimia uma página preta — e não descobria
   * porquê, porque no ecrã estava tudo bem.
   *
   *   `:root`                          cobre o sistema claro
   *   `:root:not([data-modo='claro'])` bate o bloco do ponto 03, empate a (0,2,0)
   *                                    resolvido pela ordem no ficheiro
   *   `:root[data-modo='escuro']`      bate a escolha explícita de escuro */
  :root,
  :root:not([data-modo='claro']),
  :root[data-modo='escuro'] {
    color-scheme: light;
    --fundo: #ffffff; --superficie: #ffffff; --creme-moco: #ffffff;
    --tinta: #000000; --secundario: #333333; --secundario-creme: #333333;
    --azul-moco: #10314f; --linha: #767676;
    --relevo-escuro: #999999; --relevo-claro: #ffffff;
    --relevo-1: none; --relevo-2: none; --relevo-in: none;
    --vidro-fundo: #ffffff; --vidro-solido: #ffffff;
    --vidro-borda: #767676; --vidro-brilho: none;
    --dados-1: #10314f; --dados-2: #345a7d; --dados-3: #5c7f9e;
    --dados-4: #8aa5bc; --dados-5: #b9cad8;
  }
  body { background: #fff; color: #000; }
  /* Fora: o que é chrome e o que só serve para tocar. O comutador de tema não
   * tem sentido nenhum em papel, o saltar-para-o-conteúdo também não. */
  .topo, nav.abas, .atalhos, .periodo, .accoes, .comutador, .saltar,
  .botoes, #controlos-catalogo, .procura, .linha-forma, .chave-caixa { display: none !important; }
  .painel, .valor, .grafico, .cartao-conta, .cartao-poupanca, .ficha-fonte,
  .caixa, .recibo, .celula, .ancora-apoio > div, .cartao-categoria {
    box-shadow: none;
    border: 1px solid #767676;
    break-inside: avoid;
  }
  /* A proveniência abre-se: se alguém imprime um número nosso, a fonte vai
   * junto. Um número impresso sem fonte é o produto ao contrário. */
  .valor .proveniencia[hidden], .celulas[hidden], .prova[hidden] { display: block !important; }
  [hidden].imprime-sempre { display: block !important; }
  /* As caixas de rolagem abrem por inteiro: uma tabela de 210 séries impressa
   * com 60vh de altura imprime 12 linhas e mente sobre as outras 198. */
  .envolve-tabela, .rolo { overflow: visible !important; max-block-size: none !important; }
  .tabela thead th { position: static; background: #fff; box-shadow: inset 0 -1px 0 #000; }
  .tabela { break-inside: auto; }
  .tabela thead { display: table-header-group; }   /* repete-se em cada página */
  .tabela tr { break-inside: avoid; }
  /* A trama não se imprime — é relevo, e o relevo não existe em papel. */
  .trama, .separador, .vazio::before, .fechado::before, .esqueleto { background-image: none; }
  .vazio, .fechado { border: 1px dashed #767676; }
  /* Cada faixa do front público começa onde consegue e não parte um cabeçalho
   * da sua matéria. */
  h1, h2, h3 { break-after: avoid; color: #000; }
  .faixa { break-inside: auto; }
  .ancora { break-after: avoid; }
  /* O endereço de um link sai por extenso: em papel, um link é uma promessa que
   * ninguém pode clicar. Só os que apontam para fora — os âncoras internos
   * imprimiriam `#catalogo` e não diriam nada. */
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: var(--t1); word-break: break-all; }
  @page { margin: 14mm; }
}


/* ── 20 · a montra · /sense.html ─────────────────────────────────────────────
 *
 * O QUE ESTE PONTO ERA E O QUE PASSA A SER.
 *
 * Era o estilo de uma página que explicava a canalização: barra de estado,
 * relógio do motor, comutador de tema, tabela de pedidos. Quem chegava lia o
 * nome da tecnologia antes de ver um número. Essa página morreu por juízo do
 * CEO, e o ponto 20 morre com ela — o que fica aqui é a MONTRA: a capa onde a
 * manchete é um número, a prova aberta até ao documento, as quatro categorias
 * com o denominador escrito, o mapa do que se mede e do que ainda não se mede,
 * a assinatura, os planos, o método e o rodapé.
 *
 * NADA AQUI INVENTA UMA COR, UM ESPAÇO OU UM TAMANHO DE LETRA. Tudo sai dos
 * tokens dos pontos 02, 03 e 04 e dos sete ficheiros de `/ds/`, que esta página
 * liga por <link> antes desta folha. `style-src 'self'` autoriza-os; nenhum
 * deles precisa de excepção, e nenhum byte de CSS vive dentro do JavaScript.
 *
 * AS DUAS BANDAS QUE NÃO SEGUEM O SISTEMA OPERATIVO, e é decisão de desenho.
 * A aurora é matéria clara e o `--escuro` é matéria escura: são superfícies de
 * marca, não temas. Uma banda dessas não pode herdar a tinta do modo, senão em
 * modo escuro escreve-se creme sobre creme. Por isso `.banda-luz` e
 * `.banda-escura` REDECLARAM a paleta medida do ponto 02 e do ponto 03 — os
 * mesmos hexadecimais, já medidos ali, sem uma cor nova. O resto da página
 * segue o sistema operativo como sempre seguiu.
 *
 * O VIDRO ENTRA UMA VEZ E SÓ UMA: a barra fixa. Nunca sobre um número, uma
 * célula ou um gráfico — a regra do cabeçalho desta folha, aplicada à letra. */


/* ── 20.1 · saltar para o conteúdo ─────────────────────────────────────────── */

.saltar {
  position: absolute;
  inset-inline-start: -9999px;
  inset-block-start: 0;
  z-index: 60;
  padding: var(--e3) var(--e5);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--superficie);
  color: var(--azul-moco);
  font-weight: 500;
  text-decoration: none;
  border-radius: var(--raio-controlo);
  box-shadow: var(--relevo-2);
}
.saltar:focus { inset-inline-start: var(--e3); inset-block-start: var(--e3); }

/* A âncora de uma secção nunca fica por baixo da barra fixa. */
html:has(.barra) { scroll-padding-block-start: 88px; }


/* ── 20.2 · a barra fixa · o único vidro da página ───────────────────────────
 * `--vidro-2` + `--vidro-desfoque` + `--vidro-fio`, que é o uso que o sistema
 * autoriza: chrome que passa por cima de conteúdo. Cai para superfície opaca
 * onde o desfoque não existe (guarda em `/ds/vidro.css`) e onde o leitor pediu
 * menos transparência. */

.barra {
  position: sticky;
  inset-block-start: 0;
  z-index: 50;
  background: var(--vidro-2, rgba(245,247,250,0.78));
  -webkit-backdrop-filter: var(--vidro-desfoque);
  backdrop-filter: var(--vidro-desfoque);
  box-shadow: var(--vidro-fio, inset 1.5px 1.5px 0 rgba(255,255,255,0.9),inset -1px -1px 0 rgba(23,61,100,0.12)), 0 1px 0 rgba(23, 61, 100, 0.08);
}
/* Quem pede menos transparência recebe fundo sólido — e o fundo sólido vem do
 * token da superfície, não de um claro escrito à mão. Com o literal, a barra
 * ficava clara no tema escuro e levava o texto secundário claro com ela. */
@media (prefers-reduced-transparency: reduce) {
  .barra {
    background: var(--superficie);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

.barra-dentro {
  max-width: var(--largura-maxima);
  margin-inline: auto;
  padding: var(--e2) var(--pad-pagina);
  display: flex;
  align-items: center;
  gap: var(--e4);
  min-height: 64px;
}

/* A FRASE DE POSICIONAMENTO VAI POR BAIXO DO LOCKUP, como a especificação
 * manda, e é por isso que o lockup e a frase vivem num bloco só. Em corpo 11
 * com entrelinha apertada, a frase ocupa a mesma altura que o lockup já ocupava
 * sozinho: a barra não cresce, e quem chega lê o que a casa faz antes de ler os
 * nomes das secções.
 *
 * Abaixo de 980px sai. Não é conteúdo que se perca — repete-se por extenso no
 * rodapé — e o que fica na barra estreita são as duas coisas que não têm
 * substituto: o preço e a entrada. */
.barra-marca { display: flex; flex-direction: column; gap: 2px; flex: none; min-inline-size: 0; }
.barra-posicionamento {
  margin: 0;
  font-size: var(--t1);
  line-height: 1.2;
  color: var(--secundario);
  max-inline-size: 34ch;
}
@media (max-width: 980px) { .barra-posicionamento { display: none; } }

/* O lockup horizontal, azul, à esquerda. A imagem é a marca; o wordmark ao lado
 * é o recuo de quem não recebe imagens, e some quando a imagem carrega. */
.barra .marca {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  min-height: 44px;
  flex: none;
  text-decoration: none;
  color: #173d64;
}
.barra .marca img { block-size: 26px; inline-size: auto; display: block; }
.barra .marca .wordmark { font-size: var(--t4); color: #454239; }
.barra .marca .wordmark b { color: #173d64; }

.barra-pilulas {
  display: flex;
  align-items: center;
  gap: var(--e1);
  margin-inline-start: auto;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.barra-pilulas::-webkit-scrollbar { display: none; }
/* POR TOKEN E NÃO POR VALOR ESCRITO À MÃO. Estas três cores estavam em
 * hexadecimal literal, e um literal não muda de tema: no escuro, as quatro
 * pílulas da navegação ficavam a #454239 sobre #1a1f27 — 1,65:1, quando o
 * mínimo é 4,5. Eram os únicos quatro elementos reprovados de setecentos
 * analisados, e reprovavam desde antes da paleta mudar. */
.barra-pilulas .pilula { flex: none; color: var(--secundario); }
.barra-pilulas .pilula:hover {
  background: color-mix(in srgb, var(--azul-moco) 7%, transparent);
  color: var(--azul-moco);
}
.barra-pilulas .pilula.entrar {
  background: #173d64;
  border-color: #173d64;
  color: #f5f7fa;
  font-weight: 600;
}
.barra-pilulas .pilula.entrar:hover { background: #0f2a46; color: #ffffff; }

@media (max-width: 720px) {
  .barra-dentro { flex-wrap: wrap; gap: var(--e2); padding-block-end: var(--e1); }
  .barra-pilulas { margin-inline: calc(var(--pad-pagina) * -1); padding-inline: var(--pad-pagina); width: 100vw; }
}

/* A 360px a barra media 496px de conteúdo dentro de 360px de ecrã, com
 * `overflow-x:auto` e a barra de deslocamento escondida. O resultado media-se:
 * «Planos» acabava a 401px e «Entrar» a 484px — os DOIS controlos comerciais
 * desta página ficavam fora do ecrã, sem uma aresta cortada que dissesse que
 * havia mais para o lado. Num telemóvel, o botão que leva ao dinheiro não pode
 * depender de o visitante adivinhar que aquela tira de 44px se arrasta.
 *
 * As quatro âncoras de secção são as que saem, e saem sem perda: as secções
 * aparecem pela mesma ordem a quem desce a página, e num ecrã estreito descer é
 * o gesto natural. Ficam as duas que não têm substituto — o preço e a entrada. */
@media (max-width: 560px) {
  .barra-pilulas { overflow-x: visible; width: auto; margin-inline: 0; padding-inline: 0; }
  .barra-pilulas .pilula[href="#montra"],
  .barra-pilulas .pilula[href="#prova"],
  .barra-pilulas .pilula[href="#categorias"],
  .barra-pilulas .pilula[href="#cobertura"] { display: none; }
  .barra-pilulas .pilula { padding-inline: var(--e4); }
}


/* ── 20.3 · as bandas ────────────────────────────────────────────────────────
 * Uma banda sangra até às margens do ecrã; o conteúdo dela centra-se na medida
 * de leitura de 1180px que a marca fixou. */

.banda { padding-block: var(--e9); }
.banda > .pagina { padding-block-end: 0; }
.banda + .banda { border-block-start: 1px solid var(--linha); }
.banda-escura + .banda,
.banda + .banda-escura,
.banda-luz + .banda { border-block-start: 0; }

.banda-titulo {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t-h1);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--azul-moco);
  max-inline-size: 22ch;
  margin-block-end: var(--e3);
  text-wrap: balance;
}
.banda-chapeu {
  font-size: var(--t-corpo);
  line-height: var(--lh-corpo);
  color: var(--tinta);
  max-inline-size: 62ch;
  margin-block-end: var(--e6);
}

/* A paleta medida do ponto 02, redeclarada para uma banda que é sempre clara. */
.banda-luz {
  --fundo: #f6f1e6;
  --superficie: #ffffff;
  --tinta: #14140f;
  --secundario: #454239;
  --linha: #e3ded2;
  --azul-moco: #173d64;
  --azul-2: #3e6b96;
  --ambar: #b45309;
  --creme-moco: #e8ddc8;
  --secundario-creme: #454239;
  --fraca-creme: #851111;
  --forte: #0f4d27;
  --media: #6f3206;
  --fraca: #961616;
  --dados-1: #173d64; --dados-2: #2c5580; --dados-3: #4a749c;
  --dados-4: #7098bc; --dados-5: #a3bfd6;
  --relevo-claro: #fffdf7;
  --relevo-escuro: #d9d2c2;
  color: var(--tinta);
}

/* A paleta medida do ponto 03, redeclarada para uma banda que é sempre escura.
 * Contra `--escuro` #0B1119 e `--escuro-2` #141E2A:
 *      tinta       #F1ECE0   17,5 · 14,6   AAA
 *      secundário  #BCB8AD   10,4 ·  8,7   AAA
 *      azul-claro  #AECBE4   12,2 · 10,2   AAA
 *      forte       #86DBA8   12,5 · 10,4   AAA
 *      média       #E8AD5C   10,4 ·  8,7   AAA
 *      fraca       #F3A09A   10,1 ·  8,4   AAA */
.banda-escura {
  --fundo: var(--escuro, #0B1119);
  --superficie: var(--escuro-2, #141E2A);
  --tinta: #f1ece0;
  --secundario: #bcb8ad;
  --linha: var(--escuro-linha, rgba(232,221,200,0.16));
  --azul-moco: #aecbe4;
  --azul-2: #7ba7cc;
  --ambar: #f0b163;
  --creme-moco: #e8ddc8;
  --secundario-creme: #454239;
  --fraca-creme: #851111;
  --forte: #86dba8;
  --media: #e8ad5c;
  --fraca: #f3a09a;
  --dados-1: #aecbe4; --dados-2: #8fb3d4; --dados-3: #6f97bd;
  --dados-4: #517ca4; --dados-5: #37628b;
  --relevo-claro: #1a2432;
  --relevo-escuro: #05080d;
  background: var(--escuro, #0B1119);
  color: var(--tinta);
}

/* A placa da fórmula é SEMPRE creme, e por isso leva sempre a tinta medida
 * para o creme — mesmo quando a banda que a contém é escura. Sem isto, uma
 * fórmula na banda escura escrevia-se a #F1ECE0 sobre #E8DDC8. */
.banda-escura .formula,
.banda-escura .chip,
.banda-escura .aviso {
  --tinta: #14140f;
  --azul-moco: #173d64;
  --forte: #0f4d27;
  --media: #6f3206;
  --fraca: #851111;
  color: #14140f;
}


/* ── 20.4 · a capa · a manchete é um número ──────────────────────────────────
 * `.aurora .grao .borda-concava` com `.puxador`, tal como o sistema define. Os
 * três são de `/ds/aurora.css` e não se redesenham aqui.
 *
 * A TINTA DA ETIQUETA NÃO É A TINTA DE APOIO. No sítio mais carregado da
 * aurora — 34% de âmbar sobre #EDF1F4, composto #D9BBA4 — o `--secundario`
 * mede 5,57:1, que é AA e não AAA. A tinta corrente mede 10,24:1 no mesmo
 * sítio. A etiqueta da capa leva tinta corrente e distingue-se pelo tamanho e
 * pelo espacejamento, não por estar apagada. */

.capa {
  position: relative;
  padding-block: var(--e9) calc(var(--e9) + var(--entalhe-altura, 24px));
}
.capa .etiqueta { color: var(--tinta); }

/* 56px é a medida da especificação. Não é um degrau novo: é o valor que o
 * clamp entrega na medida de leitura, entre o 40 e o 64 da escala. */
.capa-titulo {
  font-family: var(--fonte-display, inherit);
  font-size: clamp(var(--t6), 1.2rem + 3.4vw, var(--t7));
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--azul-moco);
  max-inline-size: 14ch;
  margin-block: var(--e3) var(--e5);
  text-wrap: balance;
}
.capa-chapeu {
  font-size: var(--t4);
  line-height: 1.45;
  max-inline-size: 54ch;
  margin-block-end: var(--e7);
  color: var(--tinta);
}
.capa-nota { margin-block-start: var(--e5); max-inline-size: 72ch; }

.capa-cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--e5);
  align-items: stretch;
}


/* ── 20.5 · os dois cartões que vendem ───────────────────────────────────────
 * Superfície opaca, relevo, raio de cartão. Nunca vidro: por baixo destes
 * cartões passa um número. */

.cartao-venda {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  background: var(--cartao, #FCFDFE);
  border-radius: var(--raio-cartao, 32px);
  box-shadow: var(--cartao-sombra, 0 1px 2px rgba(11,17,25,0.04),0 16px 32px rgba(11,17,25,0.09),inset 1px 1px 0 rgba(255,255,255,0.9));
  padding: var(--e6);
  min-inline-size: 0;
}
.cartao-venda.destacado {
  background: var(--creme-moco);
  box-shadow: 0 1px 2px rgba(11, 17, 25, 0.06), 0 20px 40px rgba(11, 17, 25, 0.14),
              inset 1px 1px 0 rgba(255, 255, 255, 0.7);
}
.cartao-venda.destacado { --secundario: var(--secundario-creme); --fraca: var(--fraca-creme); }

/* A placa da fórmula é creme, e o cartão destacado também. Creme sobre creme
 * deixa de ser placa e passa a mancha: dentro deste cartão a placa assenta em
 * superfície, onde a tinta corrente mede 18,47:1. */
.cartao-venda.destacado .formula {
  background: var(--superficie);
  --secundario: #514e46;
  --fraca: var(--fraca-creme);
}
.cartao-venda .etiqueta { color: var(--tinta); max-inline-size: 30ch; }

/* O número da capa e o número da prova são o mesmo componente: a parte inteira
 * grande, a parte decimal um degrau abaixo e em tinta de apoio, a unidade a
 * seguir. Números tabulares, sempre — um preço que dança ao mudar de dígito
 * não se lê em coluna. */
.medida-grande {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 var(--e2);
  font-family: var(--fonte-display, inherit);
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--azul-moco);
  line-height: 1;
}
.medida-grande .inteiro { font-size: var(--t-heroi); }
.medida-grande .decimal { font-size: var(--t5); color: var(--secundario); letter-spacing: -0.01em; }
.medida-grande .unidade {
  font-family: var(--fonte-texto, inherit);
  font-size: var(--t4);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--tinta);
}
@container (max-width: 340px) {
  .medida-grande .inteiro { font-size: var(--t6); }
  .medida-grande .decimal { font-size: var(--t4); }
}

.cartao-extremos {
  display: grid;
  gap: var(--e2);
  margin-block-start: var(--e2);
}
.extremo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e3);
  padding-block: var(--e2);
  border-block-end: 1px solid rgba(20, 20, 15, 0.12);
  font-size: var(--t-corpo);
}
.extremo:last-child { border-block-end: 0; }
.extremo .quem { font-weight: 500; min-inline-size: 0; overflow-wrap: anywhere; }
.extremo .quanto { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--azul-moco); font-weight: 500; }
.extremo .papel { display: block; font-size: var(--t1); font-weight: 400; color: var(--secundario); text-transform: uppercase; letter-spacing: 0.06em; }

/* A proveniência de um número: origem nomeada, data, selo e fórmula. Vive
 * agarrada ao número e nunca dentro de um botão «ver detalhes» — é ela o
 * argumento comercial. */
.proveniencia {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e2) var(--e3);
  margin-block-start: auto;
  padding-block-start: var(--e3);
  font-size: var(--t-apoio);
  color: var(--secundario);
}
/* O ponto separador é tinta de apoio, não linha: sobre creme a `--linha`
 * mede 1,2:1 e desaparece, e um separador invisível deixa duas afirmações
 * coladas uma à outra.
 *
 * E o ponto DESENHA-SE, não se escreve como elemento próprio. Enquanto foi um
 * `<span>` irmão, era uma caixa que o `flex-wrap` podia mandar sozinha para o
 * fim de uma linha: nos cartões da capa, a 361px de largura, lia-se
 * «Banco Millennium Atlântico ·» / «referência de 17-08-2026 ·» /
 * «CONFIANÇA FORTE ·» — três pontos pendurados no vazio, cada um a prometer
 * uma coisa que vinha na linha de baixo. Colado por `::before` ao item que
 * separa, o ponto viaja com ele e nunca sobra. */
.proveniencia > *:not(:first-child):not(a):not(button)::before {
  content: '·';
  margin-inline-end: var(--e3);
  color: inherit;
}
.proveniencia a { color: var(--azul-moco); text-underline-offset: 3px; }

.abrir-documento {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  min-height: 44px;
  padding: 0 var(--e4);
  border-radius: var(--raio-pilula, 999px);
  border: 1px solid currentColor;
  background: transparent;
  color: var(--azul-moco);
  font: inherit;
  font-size: var(--t-apoio);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transicao);
}
.abrir-documento:hover { background: rgba(23, 61, 100, 0.08); color: var(--azul-moco); }

/* A mini-série. SVG desenhado à mão, sem eixo e sem grelha: é a forma do
 * número nos últimos dias, não um gráfico de análise. */
.mini-serie { display: block; inline-size: 100%; block-size: auto; }
.mini-serie-legenda {
  display: flex;
  justify-content: space-between;
  gap: var(--e3);
  font-size: var(--t1);
  color: var(--secundario);
  font-variant-numeric: tabular-nums;
}


/* ── 20.5b · O CARTÃO FRIO DA CAPA ───────────────────────────────────────────
 *
 * A capa tem dois cartões e a especificação chama-lhes «variante destacada» e
 * «variante fria». O destacado é creme e já existia. O frio é `--aurora-fria`,
 * o único sítio da página onde esse gradiente aparece — e é essa unicidade que
 * o torna hierarquia em vez de decoração: aurora quente na banda inteira,
 * aurora fria uma vez só, azul chapado nos dois cartões da montra, superfície
 * branca em tudo o resto. Quatro degraus, e cada um diz uma coisa.
 *
 * O GRÃO ENTRA AQUI E É AQUI QUE ELE SERVE. `--aurora-fria` são quatro
 * gradientes radiais sobre um linear: a maior área desta página coberta por
 * interpolação de cor, e é exactamente onde um ecrã de 8 bits desenha as bandas
 * que fazem um gradiente parecer plástico. O `.grao` de `/ds/aurora.css` põe
 * ruído a `soft-light` por cima e as bandas desaparecem.
 *
 * O CONTRASTE, MEDIDO E NÃO ESTIMADO. O fundo mais claro de `--aurora-fria` é
 * `#4A749C`, o topo do linear; o mais escuro é `#173D64`. Com tinta branca:
 *
 *      #FFFFFF sobre #173D64 .... 11,12:1   (já medido no ponto 02)
 *      #FFFFFF sobre #4A749C ....  5,49:1   ← e é este que manda
 *
 * 5,49 não é 7:1. Não se aceita, e não se resolve escurecendo o gradiente da
 * marca: resolve-se pondo o gradiente no CONTORNO e o azul chapado no corpo. O
 * anel de 3px mostra a aurora fria, o texto assenta em `#173D64`, e os 11,12:1
 * valem no cartão inteiro em vez de valerem num canto. É a mesma decisão que a
 * barra fixa tomou com o vidro: o efeito existe onde não passa texto por baixo. */

.cartao-venda.fria {
  background-color: #173d64;
  border: 3px solid transparent;
  background-origin: border-box;
  background-clip: padding-box, border-box;
  background-image: linear-gradient(#173d64, #173d64), var(--aurora-fria);
  box-shadow: 0 1px 2px rgba(11, 17, 25, 0.06), 0 20px 40px rgba(11, 17, 25, 0.18);
  --tinta: #ffffff;
  --secundario: #e8ddc8;
  color: #ffffff;
}
.cartao-venda.fria .etiqueta { color: #e8ddc8; }
.cartao-venda.fria .medida-grande { color: #ffffff; }
.cartao-venda.fria .medida-grande .decimal,
.cartao-venda.fria .medida-grande .unidade { color: #e8ddc8; }
.cartao-venda.fria .texto-corrente { color: #e8ddc8; }
.cartao-venda.fria .por-recolher { color: #e8ddc8; }
.cartao-venda.fria .por-recolher::before { color: #ffffff; }

/* A PROVENIÊNCIA DE UM CARTÃO AZUL ASSENTA EM CREME, e não é gosto — é a única
 * forma de os três selos de confiança continuarem a medir 7:1.
 *
 * Medido, sobre `#173D64`: o `--forte` da banda escura, #86DBA8, dá 6,73:1, e o
 * `--media`, #E8AD5C, dá 5,60:1. Os dois falham a régua da casa. Repintá-los
 * inventaria duas cores novas, e este sistema não inventa cores. A placa creme
 * resolve-o sem inventar nada: dentro dela vale a paleta clara já medida no
 * ponto 02 — tinta 13,73 · secundário-creme 7,46 · azul-moco 8,27 · forte 7,39
 * · média 7,31 · fraca-creme 7,48. Todos acima de 7:1, todos já medidos.
 *
 * É o mesmo mecanismo que `.banda-escura .formula` já usava, e pela mesma
 * razão: a placa creme é superfície de marca, e uma superfície de marca leva
 * sempre a tinta que foi medida para ela. */
.cartao-venda.fria .proveniencia,
.cartao-montra.azul .proveniencia {
  background: #e8ddc8;
  border-radius: var(--raio-dados);
  padding: var(--e3) var(--e4);
  margin-block-start: auto;
  --tinta: #14140f;
  --secundario: #454239;
  --azul-moco: #173d64;
  --forte: #0f4d27;
  --media: #6f3206;
  --fraca: #851111;
  color: #14140f;
}
.cartao-venda.fria .proveniencia a,
.cartao-montra.azul .proveniencia a { color: #173d64; }
.cartao-venda.fria .proveniencia .abrir-documento,
.cartao-montra.azul .proveniencia .abrir-documento { color: #173d64; }


/* ── 20.5c · A MONTRA · SEIS CARTÕES, DOIS AZUIS ─────────────────────────────
 *
 * A REGRA DO AZUL, e existe escrita para não ser renegociada cartão a cartão:
 * LEVA AZUL O NÚMERO QUE NÃO EXISTE FORA DAQUI. Os cartões de preços, de moeda
 * e de crédito são contas sobre folhas que a origem publica — quem tiver o
 * boletim e paciência refá-las. Os dois de inclusão são a subtracção e a
 * distância que o próprio inquérito deixou por fazer: não há folha nenhuma no
 * mundo onde esses dois números estejam escritos.
 *
 * DOIS EM SEIS, e o número importa tanto como a regra. O azul distingue; se
 * fosse de todos não distinguia nada, e um terço é o limite a partir do qual a
 * excepção começa a parecer o padrão. Caem nas posições 3 e 5 da grelha, o que
 * numa fila de três os põe em diagonal — ritmo, e não uma tira de cor.
 *
 * O CONTRASTE, MEDIDO. Corpo `--azul-moco` #173D64, chapado e sem gradiente:
 *
 *      #FFFFFF sobre #173D64 .... 11,12:1   ← o número
 *      #E8DDC8 sobre #173D64 ....  8,27:1   ← tudo o resto
 *
 * Os dois já estão medidos no ponto 02 desta folha; o contraste é simétrico e
 * por isso são os mesmos números, lidos ao contrário. Ambos acima de 7:1, e
 * nenhuma cor nova entrou no sistema.
 *
 * O NÚMERO É A COISA MAIS CLARA DO CARTÃO e o resto é creme. Não há aqui texto
 * «apagado»: o apoio distingue-se pelo TAMANHO e pelo ESPACEJAMENTO, que é a
 * mesma decisão que a etiqueta da capa já tinha tomado no ponto 20.4 e pela
 * mesma razão — sobre superfície de marca, apagar texto é a maneira mais rápida
 * de sair da régua sem dar por isso.
 *
 * O GRÃO NOS CARTÕES AZUIS, E ONDE NÃO O PUS. Um azul chapado de 32px de raio é
 * a superfície mais lisa desta página; o grão dá-lhe a mesma matéria da capa e
 * amarra os dois sítios onde a marca fala mais alto. NÃO o pus nos quatro
 * cartões brancos — superfície de leitura, e ruído por baixo de uma frase é
 * ruído dentro da frase. NÃO o pus na banda escura da prova, que é onde vivem o
 * selo e a fórmula em monoespaçada, e é aí que o ruído mais custa. NÃO o pus na
 * barra fixa, porque o vidro já é uma camada de composição e duas seriam duas.
 * E NÃO o pus em nenhuma superfície de dados — nem na linha dos pontos mensais,
 * nem na mini-série, nem no mapa de cobertura: ruído por cima de um número é
 * ruído dentro do número, e é o número que esta casa vende. */

.grelha-montra {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--e5);
  align-items: stretch;
}

/* A SUPERFÍCIE É `--superficie` E NÃO `--cartao`, e a diferença mede-se.
 *
 * `--cartao` vem de `/ds/aurora.css` e é um valor só, `#FCFDFE`: não sabe que
 * existe modo escuro. Os cartões da capa podem usá-lo porque vivem dentro de
 * `.banda-luz`, que redeclara a paleta clara inteira à volta deles. A montra
 * NÃO vive numa banda de marca — vive numa banda normal, que segue o sistema
 * operativo de quem lê.
 *
 * MEDIDO no ensaio, com o sistema em modo escuro: o cartão saía a `#FCFDFE`
 * com a tinta do modo escuro por herança, `#F1ECE0` — creme sobre branco,
 * 1,06:1. Os seis cartões da montra ficavam ilegíveis para quem tem o
 * telemóvel em escuro, que em Angola é muita gente. É o mesmo defeito que o
 * ponto 20 desta folha já descreve em cima («senão em modo escuro escreve-se
 * creme sobre creme»), noutro sítio.
 *
 * `--superficie` é o token que sabe as duas paletas: `#FFFFFF` no claro, onde a
 * tinta mede 18,47:1, e `#1A1F27` no escuro, onde mede 14,04:1. Os dois já
 * estão medidos nos pontos 02 e 03. O raio e a sombra continuam a ser os do
 * cartão, que é o que a especificação pede. */
.cartao-montra {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  background: var(--superficie);
  border-radius: var(--raio-cartao, 32px);
  box-shadow: var(--cartao-sombra, 0 1px 2px rgba(11,17,25,0.04),0 16px 32px rgba(11,17,25,0.09),inset 1px 1px 0 rgba(255,255,255,0.9));
  padding: var(--e6);
  min-inline-size: 0;
}

/* O AZUL É FIXO E NÃO É O TOKEN, pela mesma razão que `.banda-luz` e
 * `.banda-escura` fixam as suas paletas: isto é uma SUPERFÍCIE DE MARCA, não
 * uma superfície do modo. No escuro, `--azul-moco` passa a `#AECBE4` — um azul
 * claro, que é o que um azul tem de ser quando é TINTA sobre fundo escuro. Como
 * FUNDO, com a tinta branca por cima, media 1,4:1.
 *
 * Medido no ensaio, e apanhado antes de sair: os dois cartões azuis saíam a
 * branco sobre `#AECBE4`. Fica `#173D64` escrito por extenso, nos dois modos, e
 * com ele ficam os 11,12:1 e os 8,27:1 que foram medidos para ele. */
.cartao-montra.azul {
  background: #173d64;
  box-shadow: 0 1px 2px rgba(11, 17, 25, 0.06), 0 20px 40px rgba(11, 17, 25, 0.18);
  --tinta: #ffffff;
  --secundario: #e8ddc8;
  --linha: rgba(232, 221, 200, 0.28);
  color: #ffffff;
}
.cartao-montra.azul .etiqueta,
.cartao-montra.azul .montra-frase,
.cartao-montra.azul .miudo { color: #e8ddc8; }
.cartao-montra.azul .montra-titulo { color: #ffffff; }
.cartao-montra.azul .medida-grande { color: #ffffff; }
.cartao-montra.azul .medida-grande .decimal,
.cartao-montra.azul .medida-grande .unidade { color: #e8ddc8; }
.cartao-montra.azul .extremo { border-block-end-color: rgba(232, 221, 200, 0.28); }
.cartao-montra.azul .extremo .quanto { color: #ffffff; }
.cartao-montra.azul .extremo .papel { color: #e8ddc8; }
.cartao-montra.azul .por-recolher { color: #e8ddc8; }
.cartao-montra.azul .por-recolher::before { color: #ffffff; }

.montra-topo {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-block-size: 28px;
}
.montra-topo .etiqueta { color: var(--secundario); }
.cartao-montra .montra-titulo {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.15;
  color: var(--azul-moco);
  margin: 0;
  max-inline-size: 24ch;
  text-wrap: balance;
}
.montra-frase { margin: 0; font-size: var(--t-corpo); line-height: 1.5; max-inline-size: 46ch; }
.cartao-montra .miudo { margin: 0; font-size: var(--t1); color: var(--secundario); }
.montra-espera {
  margin-block-start: var(--e6);
  font-size: var(--t-corpo);
  color: var(--secundario);
  max-inline-size: 68ch;
}
.montra-espera:empty { display: none; }
.montra-regra {
  margin-block-start: var(--e4);
  font-size: var(--t-apoio);
  color: var(--secundario);
  max-inline-size: 78ch;
}

/* O selo de que um número foi calculado por nós. Não é um botão — não abre
 * nada — e por isso não tem forma de botão: é uma etiqueta, e diz onde a
 * fórmula se lê. Fingir um botão que não leva a lado nenhum é a maneira mais
 * barata de perder quem veio conferir. */
.chip-formula {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--e3);
  border-radius: var(--raio-pilula, 999px);
  border: 1px dashed currentColor;
  font-size: var(--t1);
  color: var(--secundario);
}

/* ── OS SEIS ÍCONES ──────────────────────────────────────────────────────────
 * Desenhados à mão em SVG, no HTML, ao lado da frase de cada cartão. Sem
 * biblioteca, sem ficheiro de fora e sem um único glifo de tipo de ícone.
 *
 * A LINGUAGEM É A DA MARCA, e tem três regras: grelha de 24, traço de 1,5, e —
 * a que os torna nossos — CADA ÍCONE DESENHA A MEDIÇÃO DO SEU CARTÃO, nunca uma
 * metáfora. Duas barras desiguais sobre uma linha de base. O mesmo artigo com
 * dois preços a alturas diferentes. Duas colunas com o fosso marcado entre os
 * topos. Uma linha que corta a horizontal e acelera. Dois telemóveis com o
 * enchimento em pontos opostos. Uma fatia fina num círculo. Quem olhar para o
 * ícone e depois para o número vê a mesma coisa duas vezes — e é isso que um
 * ícone tem de fazer numa página de dados.
 *
 * `currentColor` sempre: no cartão branco herda `--azul-moco`, que mede 9,87:1
 * sobre o fundo; no cartão azul herda o creme, 8,27:1. E NUNCA é a única coisa
 * a dizer a categoria — a categoria está escrita ao lado, por extenso. É por
 * isso que os seis vão `aria-hidden`: quem ouve a página não deve ouvir a mesma
 * palavra duas vezes seguidas. */
.montra-icone {
  inline-size: 28px;
  block-size: 28px;
  flex: none;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--azul-moco);
}
.cartao-montra.azul .montra-icone { color: #e8ddc8; }


/* ── 20.5d · A LINHA DOS PONTOS MENSAIS DA CAPA ──────────────────────────────
 * Sem eixo e sem grelha, como toda a geometria desta página — e COM as faltas,
 * que é o contrário do que se vê por aí. O eixo é o MÊS: um mês sem leitura
 * ocupa o seu lugar, a linha parte-se nele e um traço vazado diz que ali devia
 * estar um número. Se o eixo fosse a leitura, as faltas desapareciam por
 * construção e o desenho ficava bonito a mentir. */

.capa-serie { margin: var(--e6) 0 0; padding: 0; }
.serie-ancora {
  display: block;
  inline-size: 100%;
  block-size: clamp(120px, 18vw, 180px);
}
.serie-legenda {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-block-start: var(--e2);
  font-size: var(--t1);
  color: var(--secundario);
  font-variant-numeric: tabular-nums;
}
.serie-legenda > :nth-child(2) { text-align: center; flex: 1 1 auto; }


/* ── 20.5e · A FAIXA DO CÂMBIO ───────────────────────────────────────────────
 * Desceu da capa e não se escondeu: banda própria, aberta, com o enquadramento
 * por cima em corpo grande. A hierarquia desceu e o enquadramento subiu — é a
 * frase que impede a faixa de parecer despromoção.
 *
 * A faixa é creme e não branca. O creme é a superfície de marca desta casa, e o
 * que esta faixa diz é justamente «isto é o que damos todos os dias»: é o
 * material da marca a dizer que a coisa é da casa. A tinta dentro dela é a
 * medida para creme — 13,73:1 — e não a corrente. */

.banda-cambio { padding-block: var(--e7); }
.cambio-enquadramento {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  line-height: 1.35;
  font-weight: 500;
  color: var(--azul-moco);
  max-inline-size: 46ch;
  margin: 0 0 var(--e5);
  text-wrap: balance;
}
/* O botão do tema, no rodapé. Discreto: quem não precisa dele não repara. */
.rodape-tema { margin-block-start: var(--e4); }
.rodape-tema .pilula { font-size: var(--t1); min-block-size: 36px; }

/* ── O BOTÃO DE FONTE E O SEU POPOVER ───────────────────────────────────────
 *
 * A Popover API trata de abrir, fechar com Escape, fechar ao clicar fora e
 * gerir o foco — tudo sem uma linha de JavaScript. O que se estiliza aqui é a
 * superfície e o sítio onde ela aparece.
 *
 * O botão é discreto de propósito: não compete com o número, está ao lado
 * dele. Quem não precisa da origem não repara; quem precisa, encontra-a
 * sempre no mesmo sítio. */
.fonte-caixa { display: inline-flex; }
.fonte-botao {
  min-block-size: 24px;
  padding: 0 var(--e2);
  font: inherit;
  font-size: var(--t1);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--secundario);
  background: transparent;
  border: 1px solid var(--linha);
  border-radius: var(--raio-pilula, 999px);
  cursor: pointer;
  transition: color var(--transicao, 150ms ease-out),
              border-color var(--transicao, 150ms ease-out);
}
.fonte-botao:hover { color: var(--azul-moco); border-color: var(--azul-2); }
.fonte-botao:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: 2px; }

.fonte-painel {
  inline-size: min(360px, calc(100vw - 2 * var(--e4)));
  padding: var(--e4);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  background: var(--superficie);
  color: var(--tinta);
  box-shadow: var(--vidro-sombra, 10px 14px 28px rgba(21, 38, 58, 0.14));
  font-size: var(--t-tabela, var(--t2));
}
.fonte-painel:popover-open { display: block; }
.fonte-painel .proveniencia { margin-block-start: var(--e3); }

/* O painel ancora-se ao botão onde o navegador o souber fazer; onde não
 * souber, fica centrado — que é o comportamento por omissão da Popover API e
 * é perfeitamente utilizável. Nunca fica preso fora do ecrã. */
@supports (anchor-name: --a) {
  .fonte-botao { anchor-name: --fonte-ancora; }
  .fonte-painel {
    position-anchor: --fonte-ancora;
    position-area: block-end span-inline-start;
    position-try-fallbacks: block-start span-inline-start, block-end span-inline-end;
    margin-block-start: var(--e2);
  }
}

/* ── A REVELAÇÃO POR SCROLL, EM CSS PURO ────────────────────────────────────
 *
 * Corre no compositor, fora da linha principal — que é exactamente o recurso
 * escasso no telemóvel de gama média que é o aparelho do nosso mercado. Zero
 * JavaScript, zero observadores, zero custo por elemento.
 *
 * A DUPLA PROTECÇÃO NÃO É OPCIONAL, e a razão é dura: `animation-timeline`
 * ainda não é Baseline — no Firefox estável continua atrás de uma opção. Se o
 * estado base fosse `opacity: 0`, um visitante com um navegador sem suporte
 * veria uma página em branco e nunca saberia porquê.
 *
 * Por isso o estado base é SEMPRE visível, e o `@supports` só acrescenta o
 * movimento a quem o consegue fazer. Quem pediu menos movimento não entra no
 * bloco de todo — e recebe a página inteira, imóvel, que é o que pediu. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .escala-item,
    .catalogo-grupo,
    .cartao-montra,
    .cartao-categoria {
      animation: surgir linear both;
      animation-timeline: view();
      animation-range: entry 8% cover 34%;
    }
    @keyframes surgir {
      from { opacity: 0; transform: translateY(10px); }
      to   { opacity: 1; transform: none; }
    }
  }
}

/* ── A PESQUISA DO PRIMEIRO ECRÃ ────────────────────────────────────────────
 *
 * É a primeira coisa com que se pode mexer nesta página, e por isso é grande:
 * o campo tem 52px de altura e a lista abre por baixo, sobreposta, sem
 * empurrar a manchete. Quem chega vê um número seu em três segundos.
 *
 * A lista é `position: absolute` sobre a capa e não um bloco no fluxo: se
 * empurrasse o conteúdo, a página saltava a cada tecla — e uma página que
 * salta debaixo dos dedos lê-se como avaria. */
.procura-heroi {
  position: relative;
  margin-block: var(--e6) var(--e5);
  max-inline-size: 62ch;
}
.procura-heroi > .etiqueta { display: block; margin-block-end: var(--e2); }
.procura-heroi input {
  inline-size: 100%;
  min-block-size: 52px;
  padding-inline: var(--e4);
  font: inherit;
  font-size: var(--t3);
  color: var(--tinta);
  background: var(--superficie);
  border: 1px solid var(--azul-2);
  border-radius: var(--raio-chrome);
}
.procura-heroi input:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: 2px; }
.procura-heroi-nota { margin: var(--e2) 0 0; font-size: var(--t1); color: var(--secundario); }

.procura-heroi-lista {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% - var(--e5));
  z-index: 20;
  list-style: none;
  margin: var(--e2) 0 0;
  padding: var(--e2);
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  box-shadow: var(--vidro-sombra, 10px 14px 28px rgba(21, 38, 58, 0.14));
  max-block-size: 60vh;
  overflow-y: auto;
}
.procura-item { margin: 0; }
.procura-resultado {
  inline-size: 100%;
  display: grid;
  gap: 2px;
  text-align: start;
  padding: var(--e3);
  border: 0;
  border-radius: var(--raio-dados);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.procura-resultado:hover { background: var(--fundo); }
.procura-resultado:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: -2px; }
.procura-nome { display: grid; gap: 1px; }
.procura-nome > span:first-child { font-size: var(--t-tabela, var(--t2)); color: var(--tinta); }
.procura-qual { font-size: var(--t1); color: var(--secundario); }
.procura-meta { display: flex; flex-wrap: wrap; gap: var(--e1) var(--e3); font-size: var(--t1); color: var(--secundario); }
.procura-vazio, .procura-mais {
  margin: 0;
  padding: var(--e3);
  font-size: var(--t1);
  color: var(--secundario);
}

/* ── A ESCALA DO ACERVO — cinco números com consequência ────────────────────
 *
 * O número manda na hierarquia e a consequência vem logo a seguir, na mesma
 * coluna: quem passa os olhos lê os cinco números; quem para, lê porque é que
 * cada um importa. Um número sozinho é vaidade.
 *
 * `<dl>` e não `<div>`: cada par é literalmente um termo e a sua descrição, e
 * um leitor de ecrã anuncia-os ligados sem precisar de `aria-*`. */
.escala-grelha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: var(--e5);
  margin-block-start: var(--e6);
}
.escala-item { margin: 0; }
.escala-numero {
  margin: 0;
  font-family: var(--fonte-display, inherit);
  font-size: var(--t5, 28px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--azul-moco);
  font-variant-numeric: tabular-nums;
}
.escala-dd { margin: var(--e2) 0 0; display: grid; gap: var(--e1); }
.escala-unidade { font-size: var(--t2); color: var(--tinta); }
.escala-porque { font-size: var(--t1); line-height: 1.5; color: var(--secundario); }

/* ── O QUE SÓ O LEITOR DE ECRÃ VÊ ───────────────────────────────────────────
 *
 * Enquanto um número está a ser contado, o nó visível fica `aria-hidden` e o
 * valor final viaja aqui — quem ouve a página recebe o número de uma vez, em
 * vez de ouvir a contagem inteira dígito a dígito.
 *
 * `clip-path` e não `display:none` nem `visibility:hidden`: essas duas tiram o
 * elemento da árvore de acessibilidade, que é precisamente o contrário do que
 * se quer aqui. */
.so-leitor {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Um número que conta não pode tremer. Os algarismos tabulares dão largura
 * igual a todos os dígitos; sem isso, a linha dança a cada fotograma e o
 * efeito lê-se como avaria em vez de acabamento. */
[data-contar] {
  font-variant-numeric: tabular-nums;
  display: inline-block;
}

/* ── DUAS LINHAS QUE PAGAM MAIS DO QUE TODO O RESTO ─────────────────────────
 *
 * `content-visibility: auto` diz ao navegador para não calcular o desenho do
 * que está fora do ecrã; `contain-intrinsic-size` dá-lhe a altura provável
 * para a barra de deslocamento não saltar. Nas listas longas — as centenas de
 * linhas do catálogo e as leituras de uma ficha — poupa a maior parte do
 * trabalho de layout e pintura.
 *
 * É o melhor rácio custo/benefício de todo o estudo de referências, e importa
 * mais aqui do que na maioria dos sítios: o nosso mercado entra por telemóvel
 * de gama média em Luanda, onde o processador é várias vezes mais lento a
 * fazer exactamente este trabalho. */
.catalogo-grupo, .ficha-leitura, .catalogo-linha {
  content-visibility: auto;
}
.catalogo-linha { contain-intrinsic-size: auto 56px; }
.ficha-leitura { contain-intrinsic-size: auto 40px; }

/* ── A FICHA DE UMA SÉRIE ───────────────────────────────────────────────────
 *
 * O `<dialog>` nativo traz de graça o que uma folha nossa teria de
 * reimplementar mal: fecha com Esc, prende o Tab lá dentro, devolve o foco, e
 * pinta o fundo com `::backdrop`. O que se estiliza aqui é só a superfície.
 *
 * É vidro no fundo e superfície sólida no corpo: o vidro sobrepõe, e o corpo
 * é onde estão os DADOS — e sobre dados o vidro não entra. */
.ficha {
  inline-size: min(720px, calc(100vw - 2 * var(--e4)));
  max-block-size: min(88vh, 900px);
  padding: 0;
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  background: var(--superficie);
  color: var(--tinta);
  box-shadow: var(--vidro-sombra, 10px 14px 28px rgba(21, 38, 58, 0.14));
  overflow: hidden;
}
.ficha::backdrop {
  background: rgba(11, 17, 25, 0.55);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.ficha-topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e4);
  padding: var(--e5) var(--e5) var(--e4);
  border-block-end: 1px solid var(--linha);
  position: sticky;
  inset-block-start: 0;
  background: var(--superficie);
  z-index: 1;
}
.ficha-nome { margin: var(--e1) 0 0; font-size: var(--t4); line-height: 1.25; color: var(--azul-moco); }
.ficha-fechar {
  flex: none;
  inline-size: 44px; block-size: 44px;
  font-size: var(--t3);
  color: var(--secundario);
  background: transparent;
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  cursor: pointer;
}
.ficha-fechar:hover { color: var(--tinta); border-color: var(--secundario); }
.ficha-fechar:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: 2px; }
.ficha-corpo { padding: var(--e5); overflow-y: auto; max-block-size: calc(88vh - 110px); }

.ficha-destaque { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--e2) var(--e4); }
.ficha-numero {
  font-size: var(--t5, 28px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--azul-moco);
  font-variant-numeric: tabular-nums;
}
.ficha-unidade { color: var(--secundario); }
.ficha-quando { font-size: var(--t1); color: var(--secundario); }

/* A linha da série. `stroke` por token para mudar de tema com o resto. */
.ficha-forma {
  inline-size: 100%;
  block-size: 120px;
  margin-block: var(--e4) var(--e2);
  display: block;
}
.ficha-forma path { stroke: var(--azul-2); }
.ficha-forma circle { fill: var(--ambar); }
.ficha-vao { margin: 0; font-size: var(--t1); color: var(--secundario); }

.ficha-bloco { margin-block-start: var(--e5); }
.ficha-bloco .formula {
  font-family: var(--fonte-mono, var(--mono));
  font-size: var(--t2);
  line-height: 1.55;
  color: var(--tinta);
  background: var(--fundo);
  border-radius: var(--raio-dados);
  padding: var(--e3) var(--e4);
  overflow-wrap: anywhere;
}

.ficha-citacao {
  margin-block-start: var(--e5);
  padding: var(--e4);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  background: var(--fundo);
}
.ficha-citacao-texto {
  margin: var(--e2) 0 var(--e3);
  font-size: var(--t2);
  line-height: 1.5;
  overflow-wrap: anywhere;
  user-select: all;
}

.ficha-leituras { list-style: none; margin: var(--e3) 0 0; padding: 0; }
.ficha-leitura {
  display: grid;
  grid-template-columns: minmax(9ch, 1fr) minmax(0, 1fr) auto auto;
  gap: var(--e2) var(--e4);
  align-items: baseline;
  padding-block: var(--e2);
  border-block-end: 1px solid var(--linha);
  font-size: var(--t-tabela, var(--t2));
}
.ficha-leitura:last-child { border-block-end: 0; }
.ficha-data { color: var(--secundario); font-variant-numeric: tabular-nums; }
.ficha-valor { color: var(--tinta); }
@media (max-width: 560px) {
  .ficha-leitura { grid-template-columns: minmax(9ch, auto) 1fr; }
  .ficha-selo, .ficha-prova { grid-column: 1 / -1; }
  .ficha-corpo { padding: var(--e4); }
  .ficha-topo { padding: var(--e4); }
}

/* ── O CATÁLOGO — todas as séries, de todas as fontes ───────────────────────
 *
 * Centenas de linhas numa página que se lê. A densidade é maior do que a do
 * resto da montra e menor do que a do motor: aqui percorre-se à procura de uma
 * série, não se opera. Nenhum relevo nas linhas — o relevo é para o que se
 * toca e para o que contém, e uma linha de lista é para ler.
 *
 * A grelha é de quatro colunas em ecrã largo e empilha-se a uma coluna em
 * telemóvel. Sem tabela: não há cabeçalho que valha quatro colunas cujo
 * conteúdo se explica sozinho, e uma <table> a 375px obrigaria a deslocamento
 * horizontal — que é a única coisa que esta página não pode fazer. */
.catalogo-controlos {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--e4) var(--e5);
  margin-block-start: var(--e6);
}
.catalogo-procura { flex: 1 1 26ch; display: grid; gap: var(--e2); }
.catalogo-procura input {
  min-block-size: 44px;
  padding-inline: var(--e4);
  font-size: var(--t3);
  font-family: inherit;
  color: var(--tinta);
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
}
.catalogo-procura input:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: 2px; }
.catalogo-grupos { display: flex; flex-wrap: wrap; gap: var(--e2); }
.catalogo-grupos .pilula[aria-pressed="true"] {
  background: var(--azul-moco);
  color: var(--superficie);
  border-color: var(--azul-moco);
}
.catalogo-contagem {
  margin-block: var(--e4) 0;
  font-size: var(--t2);
  color: var(--secundario);
}

.catalogo-grupo { margin-block-start: var(--e5); }
/* A seta nativa sai e entra uma nossa, para o triângulo do sistema não
 * discutir com a tipografia da casa. `list-style: none` é o que o Safari
 * exige; `::-webkit-details-marker` é o que as versões antigas exigem. */
.catalogo-grupo > summary { list-style: none; cursor: pointer; }
.catalogo-grupo > summary::-webkit-details-marker { display: none; }
.catalogo-grupo > summary::before {
  content: '';
  inline-size: 0; block-size: 0;
  border-inline-start: 5px solid currentColor;
  border-block: 4px solid transparent;
  margin-inline-end: var(--e2);
  flex: none;
  transition: transform var(--transicao, 150ms ease-out);
}
.catalogo-grupo[open] > summary::before { transform: rotate(90deg); }
.catalogo-grupo > summary:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: 3px; }
.catalogo-grupo-nome {
  min-block-size: 44px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e4);
  margin: 0 0 var(--e3);
  padding-block-end: var(--e2);
  border-block-end: 1px solid var(--linha);
  font-size: var(--t3);
  font-weight: 600;
  color: var(--azul-moco);
}
.catalogo-grupo-conta { font-size: var(--t1); color: var(--secundario); font-weight: 400; flex: none; }

.catalogo-linhas { list-style: none; margin: 0; padding: 0; }
/* A linha é um <button> que ocupa a largura toda: quem navega por teclado
 * chega lá com Tab e abre com Enter. O reset é o que impede que pareça um
 * botão de formulário — não tem fundo, não tem contorno, e alinha à esquerda
 * como o texto que é. */
.catalogo-linha {
  inline-size: 100%;
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--e2) var(--e4);
  align-items: baseline;
  text-align: start;
  padding: var(--e3) var(--e2);
  margin-inline: calc(var(--e2) * -1);
  border: 0;
  border-block-end: 1px solid var(--linha);
  border-radius: var(--raio-dados);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--t-tabela, var(--t2));
  cursor: pointer;
}
/* O relevo é para o que se toca — e ao passar, esta linha é o que se toca.
 * É um realce de superfície, não de cor: nenhuma cor carrega juízo. */
.catalogo-linha:hover { background: var(--fundo); }
.catalogo-linha:hover .catalogo-indicador { color: var(--azul-moco); }
.catalogo-linha:focus-visible { outline: var(--foco, 2px solid var(--ambar)); outline-offset: -2px; }
.catalogo-linhas li:last-child .catalogo-linha { border-block-end: 0; }
.catalogo-nome { display: grid; gap: 2px; min-inline-size: 0; }
.catalogo-indicador { color: var(--tinta); overflow-wrap: anywhere; }
.catalogo-qualificador { font-size: var(--t1); color: var(--secundario); overflow-wrap: anywhere; }
.catalogo-medida { display: grid; gap: 2px; }
.catalogo-pontos { color: var(--tinta); font-variant-numeric: tabular-nums; }
.catalogo-periodo { font-size: var(--t1); color: var(--secundario); }
.catalogo-estado { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--e2); }
.catalogo-parada {
  font-size: var(--t1);
  color: var(--secundario);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.catalogo-unidade { font-size: var(--t1); color: var(--secundario); overflow-wrap: anywhere; }

@media (max-width: 760px) {
  .catalogo-linha { grid-template-columns: 1fr 1fr; }
  .catalogo-nome { grid-column: 1 / -1; }
}
@media (max-width: 420px) {
  .catalogo-linha { grid-template-columns: 1fr; }
}

/* ── A BARRA DO CÂMBIO — fixa em baixo, aberta, sempre ──────────────────────
 *
 * Por ordem do CEO a 20-08-2026: o câmbio desce da capa e passa a barra
 * inferior fixa. Desce sem se esconder — passa a estar à vista em TODAS as
 * secções, em vez de aparecer uma vez a meio da página e sumir ao rolar.
 *
 * É vidro, e é o uso que os tokens declaram para si: «só o que sobrepõe
 * temporariamente — barra fixa, painel aberto, folha lateral». Nunca sobre
 * dados; aqui está por cima da página, não por cima de uma tabela.
 *
 * O `padding-block-end` no body é o que impede a barra de tapar a última linha
 * do rodapé. Sem ele, a barra come conteúdo e ninguém dá por isso até alguém
 * reclamar que falta uma frase. */
.barra-cambio {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: 60;
  background: var(--vidro-2, var(--superficie));
  -webkit-backdrop-filter: var(--vidro-desfoque);
  backdrop-filter: var(--vidro-desfoque);
  border-block-start: 1px solid var(--linha);
  box-shadow: 0 -1px 0 rgba(23, 61, 100, 0.06);
}
.barra-cambio-dentro {
  max-inline-size: var(--largura-max, 1180px);
  margin-inline: auto;
  padding: var(--e3) var(--pad-pagina, var(--e5));
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e2) var(--e5);
  font-size: var(--t-tabela, var(--t2));
}
.barra-cambio-etiqueta {
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario);
  font-weight: 500;
  flex: none;
}
.barra-cambio-valores {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e2) var(--e5);
  flex: 1 1 auto;
  min-inline-size: 0;
}
/* Cada valor é rótulo por cima do número, para o número poder ser o que se lê
 * primeiro. Algarismos tabulares porque são números que se comparam. */
.barra-cambio-valor { display: inline-flex; align-items: baseline; gap: var(--e2); }
.barra-cambio-valor b {
  font-variant-numeric: tabular-nums;
  color: var(--azul-moco);
  font-weight: 600;
}
.barra-cambio-valor span { color: var(--secundario); }
.barra-cambio-mais { flex: none; font-size: var(--t1); color: var(--secundario); }
.barra-cambio-mais:hover { color: var(--ambar); }

/* A barra não pode comer o fim da página. A reserva é MEDIDA em `sense.js`
 * depois de a barra estar desenhada — este valor é só o que vale enquanto ela
 * não chega, para a página não saltar quando a medida entrar. */
body { padding-block-end: 72px; }
@media (max-width: 560px) {
  .barra-cambio-dentro { gap: var(--e1) var(--e3); padding-block: var(--e2); }
  .barra-cambio-etiqueta { flex-basis: 100%; }
  .barra-cambio-mais { display: none; }
}
/* Ao imprimir, uma barra fixa repetir-se-ia em todas as páginas. */
@media print { .barra-cambio { display: none; } body { padding-block-end: 0; } }

.faixa-cambio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: var(--e4) var(--e5);
  align-items: start;
  padding: var(--e5);
  border-radius: var(--raio-chrome);
  /* Superfície de marca, e por isso escrita por extenso: no modo escuro o token
   * `--creme-moco` passa a `#242A33`, que é o creme no papel de ELEVAÇÃO e não
   * no papel de superfície. A faixa quer o creme verdadeiro nos dois modos, com
   * a tinta que foi medida para ele — 13,73:1. */
  background: #e8ddc8;
  --tinta: #14140f;
  --secundario: #454239;
  --azul-moco: #173d64;
  --fraca: #851111;
  color: #14140f;
}
.cambio-valor { min-inline-size: 0; }
.cambio-valor .etiqueta { color: var(--secundario); display: block; margin-block-end: var(--e1); }
.cambio-numero {
  margin: 0;
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--azul-moco);
  overflow-wrap: anywhere;
}
.cambio-serie { grid-column: 1 / -1; }
.cambio-nota {
  margin-block-start: var(--e4);
  font-size: var(--t-apoio);
  color: var(--secundario);
  max-inline-size: 78ch;
}
.rodape-cambio {
  margin-block-start: var(--e5);
  font-size: var(--t-apoio);
  color: var(--secundario);
  font-variant-numeric: tabular-nums;
}


/* ── 20.6 · a prova · seis pílulas, um painel ────────────────────────────── */

/* A primeira linha da prova diz QUAL número está aberto e porquê. Sem ela, o
 * dia em que a conta da capa não estiver no ar a secção troca de assunto em
 * silêncio — e trocar de assunto em silêncio é o que esta página inteira existe
 * para não fazer. */
.prova-qual {
  margin-block-end: var(--e5);
  font-size: var(--t-corpo);
  color: var(--secundario);
  max-inline-size: 72ch;
}

.prova-pilulas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  margin-block-end: var(--e5);
}
.prova-pilulas .pilula { flex: 0 0 auto; }

.prova-painel {
  background: var(--escuro-2, #141E2A);
  border-radius: var(--raio-cartao, 32px);
  padding: var(--e6);
  min-block-size: 260px;
  container-type: inline-size;
}
.prova-painel > h3 {
  font-size: var(--t-apoio);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
  color: var(--secundario);
  margin-block-end: var(--e4);
}
.prova-painel p { max-inline-size: 68ch; }
.prova-painel .formula { font-family: var(--fonte-mono, var(--mono)); font-size: var(--t2); }

.hash-extenso {
  font-family: var(--fonte-mono, var(--mono));
  font-size: var(--t4);
  line-height: 1.6;
  overflow-wrap: anywhere;
  word-break: break-all;
  color: var(--tinta);
  background: rgba(232, 221, 200, 0.08);
  border-radius: var(--raio-dados);
  padding: var(--e4);
}

.linhas-insumo { display: grid; gap: 0; margin-block-start: var(--e3); }
.linha-insumo {
  display: grid;
  grid-template-columns: minmax(10ch, 22ch) 1fr;
  gap: var(--e3);
  padding-block: var(--e3);
  border-block-end: 1px solid var(--linha);
  font-size: var(--t-tabela);
}
.linha-insumo:last-child { border-block-end: 0; }
.linha-insumo dt { color: var(--secundario); }
.linha-insumo dd { margin: 0; overflow-wrap: anywhere; }
@container (max-width: 420px) {
  .linha-insumo { grid-template-columns: 1fr; gap: var(--e1); }
}

/* Os documentos que entraram numa conta. Um número calculado não tem documento
   próprio — tem estes, e cada um abre por si. A lista é a prova da manchete, e
   por isso vive à vista dentro da face, nunca dobrada num «ver mais». */
.entraram { margin-block-start: var(--e5); }
.entraram > .etiqueta { display: block; margin-block-end: var(--e3); }
.lista-entraram { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e3); }
.entrou {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e2) var(--e4);
  padding: var(--e4);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  font-size: var(--t-tabela);
}
.entrou-fonte { flex: 1 1 24ch; color: var(--tinta); }
.entrou-momento, .entrou-lugar { color: var(--secundario); }
.entrou .hash-extenso { flex: 1 1 100%; font-size: var(--t5, var(--t4)); padding: var(--e3); }
.entrou .abrir-documento { flex: none; margin-inline-start: auto; }

/* A faixa do fim da prova: o que se descarrega e o que cada linha leva. */
.faixa-descarga {
  margin-block-start: var(--e6);
  padding: var(--e5);
  border: 1px solid var(--linha);
  border-radius: var(--raio-chrome);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e4);
}
.faixa-descarga p { flex: 1 1 32ch; margin: 0; font-size: var(--t-corpo); }
.faixa-descarga .abrir-documento { flex: none; }


/* ── 20.7 · as quatro categorias ─────────────────────────────────────────── */

/* QUATRO CARTÕES, E NUNCA TRÊS MAIS UM.
 *
 * O `auto-fit` com minmax de 280px foi MEDIDO e não dá o que promete. A página
 * tem `--largura-maxima: 1180px` e a caixa assenta em 1132px; quatro colunas de
 * 280px com três vãos de 24px pedem 1192px. Faltam sessenta pixels que não
 * existem em ecrã nenhum, e por isso o `auto-fit` caía SEMPRE em três colunas —
 * a secção que se chama «Quatro categorias» aparecia três mais um, com o quarto
 * cartão órfão numa segunda fila, em todos os portáteis. Não era um caso de
 * fronteira: era o desenho por omissão, em toda a largura possível.
 *
 * Duas colunas resolvem-no por construção. Quatro cartões em quadrado não
 * deixam órfão em largura nenhuma, e a ~554px cada um a pergunta da categoria —
 * que é a linha que vende — cabe em duas linhas em vez de cinco. */
.grelha-categorias {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e5);
}
@media (min-width: 720px) {
  .grelha-categorias { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.cartao-categoria {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  background: var(--superficie);
  border-radius: var(--raio-cartao, 32px);
  box-shadow: var(--cartao-sombra, 0 1px 2px rgba(11,17,25,0.04),0 16px 32px rgba(11,17,25,0.09),inset 1px 1px 0 rgba(255,255,255,0.9));
  padding: var(--e5);
  min-inline-size: 0;
}
.cartao-categoria h3 {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--azul-moco);
  margin: 0;
}
.cartao-categoria .pergunta {
  font-size: var(--t-corpo);
  line-height: var(--lh-corpo);
  color: var(--tinta);
  margin: 0;
}
/* O denominador é o selo da categoria e vem primeiro. Uma categoria sem
 * leitura aparece na mesma, e é este selo que o diz. */
.selo-cobertura {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  align-self: flex-start;
  padding: var(--e1) var(--e3);
  border-radius: var(--raio-pilula, 999px);
  background: var(--creme-moco);
  color: var(--tinta);
  font-size: var(--t1);
  font-weight: 500;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
/* O nome é `sem-leitura` e não `vazio` de propósito: `.vazio` é o <EstadoVazio>
 * do ponto 12, com trama, relevo e 96px de altura mínima. Um selo com esse nome
 * herdava uma caixa onde devia haver uma pílula. */
.selo-cobertura.sem-leitura { background: transparent; box-shadow: inset 0 0 0 1px var(--linha); color: var(--secundario); }

.modulos { list-style: none; margin: var(--e2) 0 0; padding: 0; display: grid; gap: 0; }
.modulos li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e3);
  padding-block: var(--e2);
  border-block-start: 1px solid var(--linha);
  font-size: var(--t-tabela);
}
.modulos li .nome { min-inline-size: 0; overflow-wrap: anywhere; }
.modulos li .selo { flex: none; }


/* ── 20.8 · o mapa de cobertura ──────────────────────────────────────────────
 * A trama densifica onde há cobertura e alarga onde não há. As três classes
 * são de `/ds/trama.css` e a clareira é o que impede uma linha de atravessar
 * uma letra. */

.mapa-legenda {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--e4);
  margin-block-end: var(--e6);
}
.mapa-legenda > div { border-radius: var(--raio-chrome); padding: var(--e4); }
.mapa-legenda .trama-clareira { background: var(--superficie); }
.mapa-legenda h3 { font-size: var(--t-corpo); margin: 0 0 var(--e1); color: var(--azul-moco); }
.mapa-legenda p { margin: 0; font-size: var(--t-apoio); color: var(--secundario); }
.mapa-legenda .medida-legenda {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t5);
  font-weight: 700;
  color: var(--azul-moco);
  font-variant-numeric: tabular-nums;
  display: block;
}

.mapa-fila { margin-block-end: var(--e5); }
.mapa-fila h3 {
  font-size: var(--t-corpo);
  font-weight: 500;
  margin: 0 0 var(--e1);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2) var(--e3);
  align-items: baseline;
}
.mapa-fila h3 .conta { font-size: var(--t-apoio); color: var(--secundario); font-weight: 400; font-variant-numeric: tabular-nums; }
svg.mapa { display: block; inline-size: 100%; block-size: auto; }

.escala-mapa {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2) var(--e4);
  margin-block-start: var(--e4);
  font-size: var(--t1);
  color: var(--secundario);
}
.escala-mapa span { display: inline-flex; align-items: center; gap: var(--e1); }
.escala-mapa i {
  inline-size: 12px;
  block-size: 12px;
  border-radius: 2px;
  display: inline-block;
  flex: none;
}


/* ── 20.9 · quem assina · direito de resposta ────────────────────────────── */

.grelha-dupla,
.grelha-tripla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--e5);
}
.cartao-assina {
  background: var(--superficie);
  border-radius: var(--raio-cartao, 32px);
  box-shadow: var(--cartao-sombra, 0 1px 2px rgba(11,17,25,0.04),0 16px 32px rgba(11,17,25,0.09),inset 1px 1px 0 rgba(255,255,255,0.9));
  padding: var(--e6);
  display: flex;
  flex-direction: column;
  gap: var(--e3);
}
.cartao-assina h3 {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  color: var(--azul-moco);
  margin: 0;
}
.cartao-assina p { margin: 0; max-inline-size: 52ch; }


/* ── 20.10 · os planos ───────────────────────────────────────────────────────
 * Em ecrã largo é uma tabela: quatro linhas comparáveis coluna a coluna, que é
 * como se compara um preço. Abaixo de 860px a mesma matéria vira cartões — uma
 * tabela de quatro colunas a 360px ou transborda ou parte as palavras. */

.tabela-planos { inline-size: 100%; border-collapse: separate; border-spacing: 0; }
.tabela-planos th, .tabela-planos td {
  text-align: start;
  vertical-align: top;
  padding: var(--e4) var(--e4);
  border-block-end: 1px solid var(--linha);
}
.tabela-planos thead th {
  font-size: var(--t1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--secundario);
  font-weight: 500;
  border-block-end: 1px solid var(--linha);
}
.tabela-planos .nome-plano {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  font-weight: 700;
  color: var(--azul-moco);
  white-space: nowrap;
}
.tabela-planos .preco-plano { font-variant-numeric: tabular-nums; font-weight: 500; white-space: nowrap; }
.tabela-planos .preco-plano .por { display: block; font-weight: 400; font-size: var(--t2); color: var(--secundario); white-space: normal; }
.tabela-planos td ul { margin: 0; padding-inline-start: 1.1em; display: grid; gap: var(--e1); }
.tabela-planos tbody tr:last-child th, .tabela-planos tbody tr:last-child td { border-block-end: 0; }

.nota-proforma {
  margin-block-start: var(--e5);
  padding: var(--e4);
  border-radius: var(--raio-dados);
  background: var(--creme-moco);
  --secundario: var(--secundario-creme);
  color: var(--tinta);
  font-size: var(--t-corpo);
  max-inline-size: 72ch;
}

@media (max-width: 860px) {
  .tabela-planos, .tabela-planos tbody, .tabela-planos tr, .tabela-planos td, .tabela-planos th { display: block; }
  .tabela-planos thead { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .tabela-planos tbody tr {
    background: var(--superficie);
    border-radius: var(--raio-cartao, 32px);
    box-shadow: var(--cartao-sombra, 0 1px 2px rgba(11,17,25,0.04),0 16px 32px rgba(11,17,25,0.09),inset 1px 1px 0 rgba(255,255,255,0.9));
    padding: var(--e5);
    margin-block-end: var(--e4);
  }
  .tabela-planos th, .tabela-planos td { border-block-end: 0; padding: 0 0 var(--e3); }
}


/* ── 20.11 · o método · sete valores ─────────────────────────────────────────
 * `--relevo-in`: o relevo é para o que contém, e um valor contém uma regra. O
 * sétimo é o único que não é restrição na base, e por isso é o único em azul de
 * marca — a diferença diz-se com a superfície e com a palavra, nunca só com a
 * cor. */

.grelha-metodo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--e4);
}
.bloco-valor {
  background: var(--fundo);
  box-shadow: var(--relevo-in);
  border-radius: var(--raio-chrome);
  padding: var(--e5);
  display: flex;
  flex-direction: column;
  gap: var(--e2);
}
/* O algarismo do valor mede-se contra o fundo em que assenta, e o `--azul-2`
 * dava 4,97:1 — o único ponto desta página abaixo do 7:1 que impusemos. O
 * próprio ficheiro de cores já o dizia: «formas e títulos grandes · nunca texto
 * pequeno». Um numeral de 28px é forma e é texto ao mesmo tempo, e quem o lê a
 * meio-dia, na rua, com o ecrã a arder, lê-o com o contraste que tiver. Passa
 * ao azul da marca, que mede 10,9:1 no mesmo fundo. */
.bloco-valor .ordem {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t5);
  font-weight: 700;
  line-height: 1;
  color: var(--cor-ordem, var(--azul-moco));
  font-variant-numeric: tabular-nums;
}
.bloco-valor h3 { font-size: var(--t-corpo); font-weight: 500; margin: 0; color: var(--tinta); }
.bloco-valor p { margin: 0; font-size: var(--t-apoio); color: var(--secundario); }
.bloco-valor.fora-da-base {
  background: var(--azul-moco);
  box-shadow: none;
  --tinta: #ffffff;
  --secundario: #dbe6f0;
  --azul-2: #dbe6f0;
  --cor-ordem: #dbe6f0;
  color: #ffffff;
}
/* No tema escuro o azul de marca é claro, e uma letra branca por cima seria
 * 1,4:1. A banda inverte-se: tinta escura sobre o azul claro.
 *
 * O `#2c3a49` que aqui estava media 6,89:1 sobre o azul claro desta banda — o
 * último ponto da página abaixo do 7:1, e logo no sétimo valor, que é o que
 * fala de dizer o que não se sabe. `#1d2732` mede 8,98:1 e é a mesma família. */
@media (prefers-color-scheme: dark) {
  :root:not([data-modo='claro']) .bloco-valor.fora-da-base { --tinta: #12161c; --secundario: #1d2732; --azul-2: #1d2732; --cor-ordem: #1d2732; color: #12161c; }
}
:root[data-modo='escuro'] .bloco-valor.fora-da-base { --tinta: #12161c; --secundario: #1d2732; --azul-2: #1d2732; --cor-ordem: #1d2732; color: #12161c; }


/* ── 20.12 · o rodapé ────────────────────────────────────────────────────── */

.rodape { padding-block: var(--e9) var(--e7); }
.rodape .marca-reverso {
  display: inline-flex;
  align-items: center;
  gap: var(--e3);
  margin-block-end: var(--e5);
}
/* O lockup do rodapé é REVERSO: o ficheiro da marca é azul e sobre `--escuro`
 * desapareceria dentro do próprio fundo. Aqui a marca é letra, e a letra herda
 * a tinta medida da banda — creme sobre #0B1119, 14,3:1. */
.rodape .marca-reverso .wordmark { display: inline-block; color: var(--secundario); }
.rodape .marca-reverso .wordmark b { color: var(--creme-moco); }
.rodape .lema {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t5);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--creme-moco);
  margin: 0 0 var(--e5);
  max-inline-size: 18ch;
}
.rodape .posicionamento {
  font-family: var(--fonte-display, inherit);
  font-size: var(--t4);
  font-weight: 500;
  line-height: 1.3;
  color: var(--creme-moco);
  margin: 0 0 var(--e5);
  max-inline-size: 34ch;
}

.rodape-linhas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--e5);
  padding-block-start: var(--e5);
  border-block-start: 1px solid var(--linha);
}
.rodape-linhas p { margin: 0; font-size: var(--t-apoio); color: var(--secundario); max-inline-size: 46ch; }
.rodape-linhas a { color: var(--azul-moco); }


/* ── 20.13 · a regra do vazio, no ecrã ───────────────────────────────────────
 * Três estados e mais nenhum. Nunca uma célula muda, nunca um erro cru. */

.por-recolher, .encerrado {
  display: inline-flex;
  align-items: baseline;
  gap: var(--e2);
  font-size: var(--t-apoio);
  color: var(--secundario);
}
.por-recolher::before, .encerrado::before {
  content: '—';
  font-variant-numeric: tabular-nums;
  color: var(--tinta);
  font-weight: 500;
}
.a-carregar {
  min-block-size: 72px;
  border-radius: var(--raio-dados);
  background-color: var(--fundo);
  box-shadow: var(--relevo-in);
  background-image: repeating-linear-gradient(to bottom,
    var(--relevo-escuro) 0, var(--relevo-escuro) 1px,
    var(--relevo-claro) 1px, var(--relevo-claro) 2px,
    transparent 2px, transparent 10px);
  animation: trama-desliza 2.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .a-carregar { animation: none; } }


/* ── 20.14 · a montra em ecrã pequeno ────────────────────────────────────── */

@media (max-width: 640px) {
  .banda { padding-block: var(--e8); }
  .capa { padding-block: var(--e7) calc(var(--e8) + var(--entalhe-altura, 24px)); }
  .cartao-venda, .cartao-montra, .cartao-assina, .prova-painel { padding: var(--e5); }
  .cambio-enquadramento { font-size: var(--t-corpo); }
  .capa-chapeu { font-size: var(--t-corpo); }
}


/* ── 20.15 · a montra em papel ───────────────────────────────────────────────
 * O vidro sai, a barra sai, a aurora sai — e o hash fica, porque é ele que faz
 * o papel conferível. */

@media print {
  .barra, .saltar, .abrir-documento { display: none !important; }
  .banda-escura, .banda-luz {
    background: #ffffff !important;
    color: #000000 !important;
    --tinta: #000000; --secundario: #333333; --azul-moco: #000000; --linha: #999999;
  }
  .aurora, .grao::after { background-image: none !important; }
  .cartao-venda.fria, .cartao-montra.azul, .faixa-cambio {
    background: #ffffff !important;
    --tinta: #000000; --secundario: #333333; --azul-moco: #000000;
    color: #000000 !important;
  }
  .cartao-venda, .cartao-montra, .cartao-categoria, .cartao-assina, .prova-painel {
    box-shadow: none !important;
    border: 1px solid #999999;
    break-inside: avoid;
  }
  .banda { padding-block: 12mm; break-inside: avoid; }
}
