/* lensub — identidade visual, por cima do haruo-ds.
 * ============================================================================
 * Carregado DEPOIS de ds/tokens.css e ds/primitives.css, e faz três coisas:
 *
 *  1. Redefine os tokens que são DESTE produto: acento, superfície, forma,
 *     sombra e a fonte de display. O haruo-ds é verde-azulado sobre papel
 *     quente (#0f766e / #faf9f6), a cara do Tamperlens. O lensub é ROXO sobre
 *     papel frio. Como `.btn`, `.field:focus-visible`, `.callout`, `.card` e
 *     `.chip` do DS já leem esses tokens, trocá-los aqui repinta o conjunto
 *     inteiro sem tocar em primitiva nenhuma — é exatamente a razão de o DS
 *     compartilhar TOKEN e não componente.
 *
 *  2. Escreve o wordmark. Tipográfico, sem imagem e sem requisição: `lensub`
 *     na cor do texto com o **"b" no acento**. `lensub` é "lens" + "sub", e é
 *     o "b" — a última letra, a que fecha "sub" — cuja barriga vira a lente no
 *     símbolo; colorir essa letra é a mesma ideia dita em tipografia. A fonte
 *     é ARREDONDADA (`ui-rounded`), não a de display: ver `--font-display`
 *     abaixo. O símbolo (`public/marca/`) leva a
 *     mesma letra desenhada, com a barriga vazada, e é ele que aparece no
 *     favicon, no ícone de PWA e na imagem de compartilhamento: é o que faz
 *     os arquivos parecerem uma marca em vez de vários desenhos. Guia
 *     completo em `docs/MARCA.md`.
 *
 *  3. Compõe as telas: cabeçalho, rodapé, formulário, e as páginas públicas
 *     (landing, planos, e as três legais em prosa). Zero compartilhamento —
 *     terceira regra do DS: 92% do CSS de um produto é daquela tela.
 *
 * CONTRASTE. Todo par de texto sobre superfície foi medido (WCAG 2.1, mesmo
 * cálculo do haruo-ds/scripts/contraste.mjs) e o pior caso é 4.93:1 no claro
 * (tangerina-texto sobre o próprio wash) e 5.06:1 no escuro, contra o mínimo
 * de 4.5:1. Borda de controle passa dos 3:1 da 1.4.11 nas QUATRO superfícies —
 * papel, card, afundado e lilás. Os números NÃO estão só neste comentário:
 * `test/unit/ds.test.ts` refaz a conta sobre estes mesmos valores e vai a
 * vermelho se alguém clarear um cinza "só um pouco". Sistema de cor não falha
 * com erro, falha calado.
 */

:root {
  /* ── acento ──────────────────────────────────────────────────────────
   * Violet-800. Um matiz só, como manda o DS. */
  --color-accent: #5b21b6;
  --color-accent-strong: #4c1d95;
  --color-on-accent: #ffffff;
  --color-accent-wash: rgba(91, 33, 182, 0.06);
  --color-accent-glow: rgba(91, 33, 182, 0.06);

  /* ── lilás: a superfície de destaque ─────────────────────────────────
   * Direção A. O que era `background: var(--color-text)` no bloco de totais
   * — o único elemento da tela que INVERTIA o tema, ficando branco no escuro
   * — vira esta cor. Ela é opaca de propósito e não um `rgba` do acento: um
   * wash translúcido muda de cor conforme o que está atrás, e este bloco
   * aparece sobre papel e sobre card. */
  --color-lilas: #ede6fa;

  /* ── tangerina: um emprego só ────────────────────────────────────────
   * Qualquer coisa laranja nesta interface quer dizer DINHEIRO EM DOBRO ou
   * achado novo. Nem trial, nem erro, nem "subiu de preço" — esses ficam em
   * roxo ou neutro. Uma cor que significa duas coisas não significa nenhuma.
   *
   * São TRÊS tokens porque o laranja bonito não é legível: `#f26b1d` dá
   * 2,80:1 sobre o papel, então ele serve para FUNDO, barra, pupila e número
   * grande em negrito — e texto laranja usa `--color-achado-text`, que é o
   * mesmo laranja escurecido até 5,55:1. `test/unit/ds.test.ts` mede os dois
   * e reprova quem usar o claro como texto. */
  --color-achado: #f26b1d;
  --color-achado-text: #b13a0a;
  --color-achado-wash: #ffe3d0;

  /* Economia confirmada e "conferido". Era usado com fallback
   * (`var(--color-ok, var(--color-accent))`) e nunca declarado — verde por
   * acidente é o mesmo que verde nenhum. */
  --color-ok: #0e7055;

  /* ── superfície ──────────────────────────────────────────────────────
   * O DS acerta em não usar branco puro; o que muda aqui é a TEMPERATURA. O
   * papel do Tamperlens é quente porque o acento dele é verde. Com um acento
   * roxo o mesmo papel fica sujo, então o fundo puxa dois pontos para o
   * violeta — longe de ser roxo, perto o bastante para o conjunto ter uma
   * temperatura só. `raised` continua branco: card precisa subir. */
  --color-bg: #f7f4fc;
  --color-bg-raised: #ffffff;
  --color-bg-inset: #f4f1f8;
  --color-bg-code: #f0edf6;

  --color-border: #e4ddf0;
  --color-border-strong: #d3ccdf;
  /* ≥3:1 nas QUATRO superfícies (3.63 · 3.95 · 3.53 · 3.25 no lilás), que é o
   * que a WCAG 1.4.11 exige do limite de um controle. Escureceu de `#8b8496`
   * quando o lilás entrou: sobre ele o valor antigo dava 2,96:1, e um campo
   * dentro de um bloco de destaque é caso comum. */
  --color-control-edge: #847d90;

  --color-text: #241a3a;
  --color-text-article: #363044;
  --color-text-muted: #5e5670;
  --color-text-faint: #675f74;
  --color-text-code: #2a2338;

  /* ── espaço ──────────────────────────────────────────────────────────
   * O DS pula o 5 (1,2,3,4,6,8,12,16). Esta pele usava `var(--space-5)` em
   * catorze lugares, e um `var()` sem fallback que aponta para token
   * inexistente NÃO cai para o valor anterior: a declaração inteira vira
   * inválida em tempo de valor computado. O resultado medido no navegador em
   * 2026-09-05 era `padding: 0` no bloco de totais do painel (o número
   * transbordando por cima da linha de cima e por baixo da de baixo) e
   * `gap: 0` entre o palpite e o valor real, que saíam grudados como
   * "R$ 300,00R$ 521,38". Um degrau que falta é falha silenciosa, e por isso
   * `test/unit/marca.test.ts` reprova qualquer `var(--…)` sem fallback que
   * não esteja declarado no DS nem aqui. */
  --space-5: 1.25rem;

  /* ── forma ───────────────────────────────────────────────────────────
   * Dois pontos mais redondo que o raio da casa (10px). Não é gosto: este é
   * um produto de consumo que se lê no telefone, e o mockup do dono já tinha
   * decidido em 16px. `--radius-lg` é o card grande da landing. */
  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 18px;

  /* Sombra é ELEVAÇÃO, não decoração: dois passos e nada mais, na tinta do
   * texto e não em preto — preto sobre papel violeta cinza a cor. */
  --shadow-sm: 0 1px 2px rgba(36, 26, 58, 0.06);
  --shadow-md: 0 6px 20px rgba(36, 26, 58, 0.09);
  --color-menu-shadow: rgba(36, 26, 58, 0.14);

  /* ── tipografia ──────────────────────────────────────────────────────
   * Continua a pilha do SISTEMA: zero requisição, zero layout shift, e a
   * mesma letra que o resto do aparelho — o que um app de dinheiro quer
   * parecer é nativo, não impresso. `--font-display` ganha as variantes de
   * DISPLAY que macOS e Windows já têm instaladas (desenhadas para corpo
   * grande, com espaço mais fechado); onde não existirem, cai na mesma
   * pilha e nada quebra.
   *
   * ⚠️ Direção A trocou DISPLAY por ARREDONDADA. `ui-rounded` é uma palavra-
   * chave CSS: nos Apple ela resolve para SF Pro Rounded sem baixar nada, e
   * as contraformas redondas do "e", do "s" e do "u" ecoam o anel da lente.
   * Fora dos Apple ninguém tem a palavra-chave, então a pilha continua caindo
   * para Nunito (se instalada) e daí para a do sistema — nenhuma requisição,
   * nenhum layout shift, nenhum arquivo binário no repo. O subset self-hosted
   * de Nunito que o guia sugere fica de fora até alguém medir que faz falta:
   * são ~25 kB e uma diretiva de CSP a mais para uma letra de manchete. */
  --font-display: ui-rounded, "SF Pro Rounded", "Nunito", "SF Pro Display",
    "Segoe UI Variable Display", var(--font-sans);
  /* Manchete da landing. `clamp` porque de 390 px a 1160 px é a mesma frase,
   * e uma manchete fixa ou estoura no telefone ou some no desktop. */
  --text-hero: clamp(2rem, 5.6vw, 3rem);
}

/* Aliases curtos: o haruo-ds define os dois conjuntos, então os dois mudam.
 * Fora do bloco acima de propósito — aqui são derivados, e `var()` basta
 * porque nada nossa lê este arquivo sem motor de cascata. */
:root {
  --accent: var(--color-accent);
  --accent-strong: var(--color-accent-strong);
  --on-accent: var(--color-on-accent);
  --accent-wash: var(--color-accent-wash);
  --accent-glow: var(--color-accent-glow);
  --bg: var(--color-bg);
  --bg-raised: var(--color-bg-raised);
  --bg-inset: var(--color-bg-inset);
  --bg-code: var(--color-bg-code);
  --border: var(--color-border);
  --border-strong: var(--color-border-strong);
  --control-edge: var(--color-control-edge);
  --text: var(--color-text);
  --text-article: var(--color-text-article);
  --text-muted: var(--color-text-muted);
  --text-faint: var(--color-text-faint);
  --text-code: var(--color-text-code);
  --menu-shadow: var(--color-menu-shadow);
}

/* ── tema escuro ─────────────────────────────────────────────────────────
 * Não é o claro invertido. O fundo puxa para o violeta do acento (#15131b,
 * não #000) e o acento clareia para violet-400, porque violet-800 sobre
 * escuro não tem contraste nenhum. Mesmo matiz, papéis trocados.
 *
 * O bloco se repete no `:root[data-theme="dark"]` de propósito: o botão de
 * tema precisa vencer nas duas direções, e nenhuma cor pode ter sua ÚNICA
 * definição dentro de um bloco de tema.
 *
 * ⚠️ O `:root` do segundo seletor NÃO É ENFEITE, e a falta dele custou um tema
 * escuro inteiro. O haruo-ds escreve `:root[data-theme="dark"]`, que tem
 * especificidade 0-2-0; um `[data-theme="dark"]` solto tem 0-1-0 e PERDE por
 * especificidade, não importa qual arquivo venha depois. O resultado era esta
 * pele carregar normalmente, o claro ficar roxo, e o escuro continuar
 * inteiramente no verde-azulado do Tamperlens — medido no navegador, não
 * deduzido. Empatar a especificidade é o que deixa a ordem dos arquivos
 * decidir, que é como isto deveria funcionar. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-accent: #b197fc;
    --color-accent-strong: #c4b5fd;
    --color-on-accent: #17121f;
    --color-accent-wash: rgba(177, 151, 252, 0.1);
    --color-accent-glow: rgba(177, 151, 252, 0.07);

    --color-lilas: #2a2140;
    --color-achado: #ff8a3d;
    --color-achado-text: #ff8a3d;
    --color-achado-wash: #3a2418;
    --color-ok: #5eead4;

    --color-bg: #17121f;
    --color-bg-raised: #221b2e;
    --color-bg-inset: #121019;
    --color-bg-code: #221d2e;

    --color-border: #332a47;
    --color-border-strong: #3f3850;
    --color-control-edge: #756d88;

    --color-text: #f0eafa;
    --color-text-article: #d5d0e0;
    --color-text-muted: #a79fba;
    --color-text-faint: #9992a8;
    --color-text-code: #ddd7ea;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
    --color-menu-shadow: rgba(0, 0, 0, 0.5);
  }
}

:root[data-theme="dark"] {
  --color-accent: #b197fc;
  --color-accent-strong: #c4b5fd;
  --color-on-accent: #17121f;
  --color-accent-wash: rgba(177, 151, 252, 0.1);
  --color-accent-glow: rgba(177, 151, 252, 0.07);

  --color-lilas: #2a2140;
  --color-achado: #ff8a3d;
  --color-achado-text: #ff8a3d;
  --color-achado-wash: #3a2418;
  --color-ok: #5eead4;

  --color-bg: #17121f;
  --color-bg-raised: #221b2e;
  --color-bg-inset: #121019;
  --color-bg-code: #221d2e;

  --color-border: #332a47;
  --color-border-strong: #3f3850;
  --color-control-edge: #756d88;

  --color-text: #f0eafa;
  --color-text-article: #d5d0e0;
  --color-text-muted: #a79fba;
  --color-text-faint: #9992a8;
  --color-text-code: #ddd7ea;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
  --color-menu-shadow: rgba(0, 0, 0, 0.5);
}

/* ── casco ───────────────────────────────────────────────────────────── */

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  line-height: var(--leading-normal);
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}

/* Link de pular, visível só quando recebe foco pelo teclado. Não é enfeite:
 * é a primeira parada de quem navega por Tab e a única forma de escapar do
 * cabeçalho sem passar por ele em toda página. */
.pular {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-accent);
  color: var(--color-on-accent);
  padding: var(--space-3) var(--space-4);
  border-radius: 0 0 var(--radius) 0;
  z-index: 10;
}
.pular:focus {
  left: 0;
}

.topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg-raised);
  /* A faixa atravessa a tela inteira, mas a MARCA fica na mesma coluna do
   * conteúdo. Feito no recuo em vez de num <div> interno: um wrapper aqui
   * trocaria os filhos do flex e empilharia a marca e o menu — e a estrutura
   * do layout é para ser estendida, não redesenhada. */
  padding: var(--space-4) max(var(--space-6), calc((100% - var(--width-page)) / 2));
}

.marca {
  text-decoration: none;
  color: inherit;
}

/* O WORDMARK. Nome na tinta do texto, "b" no destaque — feito de duas
 * declarações e nenhuma requisição. `-0.03em` de espaçamento e 680 de peso é o
 * que separa `lensub` de um <h1> qualquer na mesma pilha de fontes, e o
 * minúsculo é como o dono escreveu o nome. */
.marca-nome {
  font-family: var(--font-display);
  /* Cresceu um degrau quando o cabeçalho virou lockup: o símbolo tem 33 px de
   * altura (o piso da pupila é 32) e um nome de 22 px ao lado dele ficaria
   * pendurado. `--text-2xl` põe o ascendente perto da metade da altura do
   * símbolo, que é a proporção do lockup em `scripts/marca.mjs`. */
  font-size: var(--text-2xl);
  font-weight: 680;
  letter-spacing: -0.03em;
  color: var(--color-text);
}
/* A letra, não um pseudo-elemento: `::after` servia para acrescentar um ponto
 * que o texto não tinha, e um "b" que JÁ está no nome tem que continuar no
 * texto — senão ele some do que a pessoa copia, do que o leitor de tela lê e
 * do que o buscador indexa. */
.marca-b {
  color: var(--color-accent);
}
/* O LOCKUP do cabeçalho: símbolo + nome. O `gap` é maior que a área de respiro
 * da marca (21% da largura do símbolo = 5 px em 24), e o nome inteiro vira
 * tinta porque o símbolo ao lado JÁ é o "b" acentuado — repetir o roxo faria
 * "b roxo, lensu, b roxo" (MARCA § 2). */
.marca-lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.marca-lockup .marca-b {
  color: inherit;
}
.marca-simbolo {
  flex: none;
}
.marca:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.topo-nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
  flex-wrap: wrap;
}
/* X3 do roast 2: a 375 px estes links mediam 24–33 px de altura, abaixo dos
 * 44 px que o dedo pede. A caixa cresce por `min-height`; o texto continua
 * centrado e o sublinhado continua colado nele porque saiu de `border-bottom`
 * (que desceria junto com a caixa) para `text-decoration`, que acompanha o
 * texto. O desenho fica igual — quem muda é a área que aceita o toque. */
.topo-nav a {
  color: var(--color-text);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.topo-nav a:hover,
.topo-nav a:focus-visible {
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
}
/* A página em que já se está não é um destino. `aria-current="page"` carrega
 * o significado; isto só o mostra. */
.topo-nav a[aria-current="page"] {
  color: var(--color-accent);
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
}
/* O "Entrar"/"Painel" é `.btn.small`: 0,35rem de recuo dá ~34 px. Inline não
 * aceita `min-height`, por isso o `inline-flex`; o recuo lateral fica. */
.topo-nav .btn {
  border-bottom: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  box-sizing: border-box;
}
.topo-email {
  color: var(--color-text-muted);
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pagina {
  flex: 1;
  width: 100%;
  max-width: var(--width-page);
  margin: 0 auto;
  padding: var(--space-8) var(--space-6);
  box-sizing: border-box;
}
/* Formulário de autenticação: uma coluna estreita centrada. Uma senha não fica
 * mais fácil de digitar em 1160px de largura. */
.pagina-estreita {
  max-width: 27rem;
}

.rodape {
  border-top: 1px solid var(--color-border);
  padding: var(--space-6) max(var(--space-6), calc((100% - var(--width-page)) / 2));
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  background: var(--color-bg-raised);
}
.rodape-interno {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: baseline;
  justify-content: space-between;
}
.rodape p {
  margin: 0;
  max-width: var(--width-prose);
}
.rodape nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}
/* Mesmo X3, e aqui era pior: 19 px. O sublinhado do rodapé já é
 * `text-decoration` do navegador, então basta a altura. */
.rodape a {
  color: var(--color-text-muted);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ── conteúdo ────────────────────────────────────────────────────────── */

h1 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-2);
}
h2 {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-2);
}

.sub {
  color: var(--color-text-muted);
  margin: 0 0 var(--space-5);
}
.dica {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  margin: var(--space-2) 0 0;
}
.opcional {
  color: var(--color-text-faint);
  font-weight: 400;
}

.card {
  margin-bottom: var(--space-5);
}
.card:last-child {
  margin-bottom: 0;
}

.form {
  margin: 0;
}
.campo {
  margin-bottom: var(--space-4);
}
.campo .field {
  width: 100%;
  box-sizing: border-box;
}
/* Escopado em `.campo`, e não `.label` solto: a primitiva do DS é do DS, e
 * isto aqui é só como ela se posiciona DENTRO deste formulário. */
.campo .label {
  display: block;
  margin-bottom: var(--space-2);
}

a {
  color: var(--color-accent);
}
a:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.rodape-card {
  margin: var(--space-5) 0 0;
  font-size: var(--text-sm);
}

/* Separador "ou" entre o formulário e o login social. Uma régua com um rótulo
 * no meio, sem markup extra além do <span>. */
.ou {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  color: var(--color-text-faint);
  font-size: var(--text-sm);
}
.ou::before,
.ou::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

.btn-row {
  flex-wrap: wrap;
}
.btn-row form {
  margin: 0;
}

/* O callout do DS já tem variantes; estas só trocam a cor da borda esquerda
 * para que erro e confirmação se distingam sem depender só da cor do texto. */
.aviso-ok {
  border-left: 3px solid var(--color-ok, var(--color-accent));
}
.aviso-erro {
  border-left: 3px solid var(--color-danger, #b42318);
}

.vazio {
  border-style: dashed;
}

/* ── páginas públicas ────────────────────────────────────────────────────
 * Landing, planos e as três legais. Todas saem de `content/*.md` pelo leitor
 * de `src/views/markdown.ts`, então o CSS estiliza TAGS, não classes: o
 * markdown não sabe escrever `class=` e não deveria saber. */

.publico {
  color: var(--color-text-article);
  line-height: var(--leading-relaxed);
}
.publico h1,
.publico h2,
.publico h3 {
  color: var(--color-text);
  font-family: var(--font-display);
  line-height: var(--leading-tight);
  letter-spacing: -0.02em;
  /* Cabeçalho pertence ao que vem DEPOIS dele, não ao que veio antes. */
  margin: var(--space-12) 0 var(--space-4);
}
.publico > :first-child,
.publico > .ilu-dagua + * {
  margin-top: 0;
}
.publico h2 {
  font-size: var(--text-2xl);
}
.publico h3 {
  font-size: var(--text-xl);
}
.publico p,
.publico ul,
.publico ol {
  max-width: var(--width-prose);
  margin: 0 0 var(--space-4);
}
.publico li {
  margin-bottom: var(--space-2);
}
.publico li:last-child {
  margin-bottom: 0;
}
/* Régua de seção: espaço, não linha. O `<hr>` do markdown separa assuntos e o
 * cabeçalho seguinte já diz onde começou o próximo — uma linha por cima disso
 * é a mesma informação duas vezes. */
.publico hr {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--space-12) 0;
  max-width: var(--width-prose);
}
.publico blockquote {
  margin: var(--space-6) 0;
  max-width: var(--width-prose);
  padding: var(--space-4) var(--space-6);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warn, var(--color-accent));
  border-radius: var(--radius-sm);
  background: var(--color-bg-inset);
  color: var(--color-text);
}
.publico blockquote p:last-child {
  margin-bottom: 0;
}

/* A tabela rola DENTRO dela mesma. Uma tabela de quatro colunas não cabe em
 * 390 px, e a alternativa — a página inteira rolando de lado — é o defeito
 * que mais faz um site parecer quebrado no telefone. */
.tabela {
  overflow-x: auto;
  margin: 0 0 var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg-raised);
  box-shadow: var(--shadow-sm);
}
.tabela .table {
  min-width: 32rem;
}
.tabela .table th,
.tabela .table td {
  padding: var(--space-3) var(--space-4);
}
.tabela .table tbody tr:last-child td {
  border-bottom: 0;
}

/* Linha de ação. O leitor de markdown marca assim todo parágrafo que só tem
 * botões. */
.acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-6) 0;
  color: var(--color-text-faint);
}
.acoes .btn {
  text-decoration: none;
  display: inline-block;
}

/* ── landing ─────────────────────────────────────────────────────────────
 * O `# lensub` do markdown vira a sobrancelha da manchete, e não um título
 * repetindo o wordmark que já está no cabeçalho três centímetros acima. O
 * `##` seguinte é a manchete. Nenhum dos dois muda no arquivo de conteúdo:
 * quem escreve prosa não deveria ter que saber disto. */
/* O `>` saiu quando a manchete ganhou o wrapper `.hero-texto`: seletor de
 * filho direto e wrapper novo é a colisão que apaga um estilo em silêncio. A
 * landing tem UM h1, então `.landing h1` é tão específico quanto era. */
.landing h1 {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.14em;
  /* MINÚSCULO. O nome é `lensub`, escrito assim pelo dono, e uma sobrancelha em
   * caixa alta escreveria "LENSUB" — a única linha da página que contradiz o
   * nome do produto. O espacejamento sozinho já a separa da manchete. */
  color: var(--color-accent);
  margin: 0 0 var(--space-3);
}
.landing h1 + h2 {
  font-size: var(--text-hero);
  letter-spacing: -0.035em;
  line-height: 1.08;
  margin: 0 0 var(--space-6);
  /* 26ch e não 20: dentro da coluna do hero a manchete já tem uma parede, e
   * 20ch a quebrava em cinco linhas em 1280 px. */
  max-width: 26ch;
  text-wrap: balance;
}
/* Os dois parágrafos logo abaixo da manchete são a promessa, não corpo de
 * texto: sobem um degrau de tamanho e param antes da largura de leitura. */
.landing h1 + h2 + p,
.landing h1 + h2 + p + p {
  font-size: var(--text-lg);
  color: var(--color-text-muted);
  max-width: 54ch;
}

/* ── planos ──────────────────────────────────────────────────────────────
 * Quatro cartões, não uma tabela de quatro colunas: no telefone eles viram
 * uma pilha sozinhos, e o preço de cada plano continua colado ao seu nome. */
/* `.publico` na frente NÃO é enfeite: `.publico ul { max-width: var(--width-prose) }`
 * tem especificidade 0-2-0 e vencia o `max-width: none` daqui (0-1-0), então
 * os quatro cartões de plano viviam espremidos em 685 px dentro de uma página
 * de 1160 — dois por linha, com meia tela vazia à direita. */
.publico .planos,
.planos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-4);
  margin: var(--space-6) 0;
  padding: 0;
  list-style: none;
  max-width: none;
}
.plano {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
}
.plano h2 {
  font-size: var(--text-lg);
  margin: 0;
}
.plano .preco {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 680;
  letter-spacing: -0.02em;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.plano .preco small {
  font-size: var(--text-sm);
  font-weight: var(--weight-normal);
  color: var(--color-text-muted);
  letter-spacing: 0;
}
.plano ul {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}
/* Empurra a ação para o rodapé do cartão, para os quatro botões ficarem na
 * mesma linha mesmo com descrições de tamanhos diferentes. */
.plano .btn {
  margin-top: auto;
  text-align: center;
  text-decoration: none;
}
/* O plano em destaque é marcado pela BORDA, e a palavra "recomendado" está
 * escrita dentro dele — cor sozinha nunca carrega significado. */
.plano-destaque {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-md);
}

/* ── F1b: catálogo, formulário de plano e lista ──────────────────────────
 *
 * Composições desta tela, como manda a terceira regra do DS. Nada aqui vira
 * primitiva: quando a segunda tela precisar de um card de serviço, ela copia.
 */

/* Iniciais coloridas no lugar de logo. Sem imagem, sem CDN, sem requisição —
 * e sem cor inline, porque a CSP é `style-src 'self'` e bloquearia
 * `style="--h:262"`.
 *
 * ⚠️ A matiz é CURADA, não sorteada (direção A). Ela vem do hex de marca do
 * serviço em `src/services/cores.ts`, quantizado em 24 passos de 15° — a
 * Netflix é vermelha, o Spotify é verde, e quem não está curado cai no hash de
 * antes. A saturação e a luminosidade são as mesmas em todas as 24, que é o
 * que deixa o contraste ser propriedade do sistema: `test/unit/ds.test.ts`
 * refaz a conta de hsl para RGB nas 24 matizes e nos dois temas, e o intervalo
 * medido é 4,69–10,61:1 no claro e 5,23–6,63:1 no escuro, contra o mínimo de
 * 4,5:1. */
.logo {
  --logo-h: 272;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.125rem;
  height: 2.125rem;
  border-radius: var(--radius-full);
  background: hsl(var(--logo-h) 45% 90%);
  color: hsl(var(--logo-h) 60% 27%);
  font-size: var(--text-xs);
  font-weight: 680;
  letter-spacing: 0.02em;
}
.logo-g {
  width: 2.75rem;
  height: 2.75rem;
  font-size: var(--text-sm);
}
.logo-h0 { --logo-h: 0; }
.logo-h15 { --logo-h: 15; }
.logo-h30 { --logo-h: 30; }
.logo-h45 { --logo-h: 45; }
.logo-h60 { --logo-h: 60; }
.logo-h75 { --logo-h: 75; }
.logo-h90 { --logo-h: 90; }
.logo-h105 { --logo-h: 105; }
.logo-h120 { --logo-h: 120; }
.logo-h135 { --logo-h: 135; }
.logo-h150 { --logo-h: 150; }
.logo-h165 { --logo-h: 165; }
.logo-h180 { --logo-h: 180; }
.logo-h195 { --logo-h: 195; }
.logo-h210 { --logo-h: 210; }
.logo-h225 { --logo-h: 225; }
.logo-h240 { --logo-h: 240; }
.logo-h255 { --logo-h: 255; }
.logo-h270 { --logo-h: 270; }
.logo-h285 { --logo-h: 285; }
.logo-h300 { --logo-h: 300; }
.logo-h315 { --logo-h: 315; }
.logo-h330 { --logo-h: 330; }
.logo-h345 { --logo-h: 345; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo {
    background: hsl(var(--logo-h) 30% 24%);
    color: hsl(var(--logo-h) 65% 76%);
  }
}
:root[data-theme="dark"] .logo {
  background: hsl(var(--logo-h) 30% 24%);
  color: hsl(var(--logo-h) 65% 76%);
}

/* ── catálogo ── */

.busca {
  margin-bottom: var(--space-4);
}
.busca-linha {
  display: flex;
  gap: var(--space-2);
}
.busca-linha .field {
  flex: 1;
  min-width: 0;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}
.chips .chip {
  text-decoration: none;
}
.chip-ativo {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}
.chip-n {
  opacity: 0.65;
  margin-left: 0.35em;
  font-variant-numeric: tabular-nums;
}

/* `auto-fill` e não uma contagem fixa: a mesma grade serve 390px de celular e
 * 1160px de desktop sem media query nenhuma. */
.grade {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: var(--space-3);
}
.svc {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-raised);
  text-decoration: none;
  color: var(--color-text);
  height: 100%;
  box-sizing: border-box;
}
.svc:hover,
.svc:focus-visible {
  border-color: var(--color-accent);
  background: var(--color-accent-wash);
}
.svc-nome {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-align: center;
  line-height: var(--leading-tight);
}
.svc-preco {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}
.rodape-catalogo {
  margin-top: var(--space-4);
}

.svc-topo {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.sub-tight {
  margin-bottom: 0;
  font-size: var(--text-sm);
}

/* ── escolha de plano ── */

.tiers {
  border: 0;
  padding: 0;
  margin: 0 0 var(--space-5);
}
.tier-lista {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.tier {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg-raised);
}
/* A borda marca o plano escolhido; o radio marcado continua sendo a fonte da
 * verdade para quem usa leitor de tela. */
.tier-ativo {
  border-color: var(--color-accent);
  background: var(--color-accent-wash);
}
.tier-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.tier-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.tier-nome {
  font-weight: var(--weight-medium);
}
.tier-inclui {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  line-height: var(--leading-tight);
}
.tier-preco {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium);
  white-space: nowrap;
  text-decoration: none;
  border-bottom: 1px dotted currentColor;
}

/* ── "quanto você paga" ── */

.valor-linha {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.valor-moeda {
  color: var(--color-text-muted);
}
.valor-input {
  flex: 1;
  min-width: 0;
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
}
/* O selo diz de onde veio o número que está no campo. Ele some assim que o
 * usuário digita outro — não some sozinho, mas some no próximo carregamento,
 * e o texto de ajuda abaixo carrega o resto do recado. */
.selo {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--color-accent);
  background: var(--color-accent-wash);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  white-space: nowrap;
}
.campo-moeda {
  margin-top: var(--space-2);
  max-width: 8rem;
}

.campo-check {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
.check {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
}

/* ── totais ── */

/* LILÁS, não o bloco preto. O `background: var(--color-text)` de antes era o
 * ÚNICO elemento da tela que invertia com o tema — preto no claro, branco no
 * escuro — e era o maior bloco da primeira dobra. Em lilás ele continua sendo
 * a superfície de destaque e passa a concordar com o resto da página. */
.totais {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--color-lilas);
  color: var(--color-text);
  margin-bottom: var(--space-5);
}
.total-bloco {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}
.total-direita {
  align-items: flex-end;
  flex: 0;
}
.total-rotulo {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.7;
}
.total-grande {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.total-medio {
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.total-extra {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--text-sm);
  opacity: 0.8;
}

/* A régua do palpite: uma LINHA de contexto embaixo do total, não um segundo
 * total. Antes eram dois números do mesmo tamanho lado a lado, e um deles era
 * um chute — dar ao chute o mesmo peso tipográfico do número real é dizer que
 * os dois valem igual. */
.total-regua {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.total-regua strong {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* ── o achado ───────────────────────────────────────────────────────────
 *
 * O cartão que abre o painel e o onboarding: "você paga isto duas vezes".
 * É o ÚNICO lugar da interface onde a tangerina aparece, e a regra que a
 * mantém legível está nos tokens — fundo em `--color-achado`, texto em
 * `--color-achado-text`, nunca o contrário.
 *
 * Um SEGUNDO achado na mesma tela leva `.achado-2` e vira roxo: dois laranjas
 * competindo é o mesmo que nenhum. */
.achado {
  background: var(--color-achado-wash);
  border: 1px solid var(--color-achado);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.achado-rotulo {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-achado-text);
}
.achado-num {
  margin: 2px 0 0;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 800;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--color-achado-text);
  line-height: 1.1;
}
.achado-unidade {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--color-text-muted);
  margin-left: var(--space-2);
}
.achado-texto {
  margin: var(--space-2) 0 0;
}
.achado-2 {
  background: var(--color-accent-wash);
  border-color: var(--color-accent);
}
.achado-2 .achado-rotulo,
.achado-2 .achado-num {
  color: var(--color-accent);
}

/* ── redundância e lista ── */

.lista-red,
.lista-ass {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lista-red > li + li {
  margin-top: var(--space-4);
}
.red-titulo {
  margin: 0;
  font-weight: var(--weight-medium);
}
.redundancias {
  border-left: 3px solid var(--color-warn);
}

.lista-ass > li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.ass-texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 10rem;
}
.ass-nome {
  font-weight: var(--weight-medium);
}
.ass-detalhe {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.ass-valor {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.ass-acoes {
  display: flex;
  gap: var(--space-2);
}
.ass-acoes form {
  margin: 0;
}

.resumo {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  font-variant-numeric: tabular-nums;
}
.convite {
  border-style: dashed;
  margin-top: var(--space-6);
}
.nota .dica {
  margin-top: 0;
}

/* ── F1c: plano do usuário, avisos e painel ──────────────────────────────
 *
 * Composições destas telas. O cartão de plano já existe (`.plano`, das páginas
 * públicas); aqui só entram a marca do plano vigente, o lugar do botão morto
 * quando não há ação, e o contêiner de rolagem das tabelas do /admin. */

/* O plano vigente é marcado pela BORDA e pela palavra "seu plano" dentro dele,
 * como o destaque: cor sozinha nunca carrega significado. */
.plano-atual {
  border-color: var(--color-ok, var(--color-accent));
}
/* Ocupa o mesmo lugar do botão para os quatro cartões terminarem alinhados,
 * sem fingir ser clicável. */
.plano-marca {
  margin-top: auto;
  margin-bottom: 0;
  text-align: center;
  color: var(--color-text-muted);
  cursor: default;
}
.plano .btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Tabela larga não empurra a página: rola dentro da própria caixa. */
.rolagem {
  overflow-x: auto;
  max-width: 100%;
}

/* ── F2b: extrato, sugestões e painel ─────────────────────────────────────
 *
 * Composições, como o resto deste arquivo: nenhuma primitiva do DS é
 * redeclarada. Duas decisões de forma valem comentário porque não são óbvias:
 *
 *  1. As barras de categoria são LARGURAS EM CLASSE (`.barra-0` … `.barra-100`,
 *     de 5 em 5), e não `style="width:37%"`. A CSP desta app é
 *     `style-src 'self'` — estilo inline é BLOQUEADO pelo navegador, não
 *     "desencorajado". Vinte e uma classes é o preço de uma barra sem
 *     JavaScript e sem `unsafe-inline`, e o número exato fica ao lado da barra
 *     em texto: a barra é decoração (`aria-hidden`), o número é o dado.
 *  2. O card de candidato do extrato usa rádio e não botão. Um formulário só,
 *     um envio só, nenhum estado no servidor — ver src/views/extrato.ts.
 */

/* ── candidatos do extrato ── */

.lista-cand {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
}
.cand {
  padding: var(--space-4);
  margin-bottom: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-raised);
}
.cand-ja-lista {
  background: var(--color-bg-inset);
  opacity: 0.85;
}
.cand-topo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.cand-desc {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  word-break: break-word;
}
.cand-valor {
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cand-ritmo,
.cand-ja {
  margin: var(--space-1) 0 var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.cand-acoes {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  align-items: center;
  border: 0;
  margin: 0;
  padding: 0;
}
.cand-acoes legend {
  float: left;
  width: 100%;
  padding: 0;
  margin-bottom: var(--space-1);
}

/* ── barras de categoria ── */

.barras {
  list-style: none;
  margin: 0;
  padding: 0;
}
.barra-linha {
  display: grid;
  grid-template-columns: minmax(6rem, 1fr) minmax(0, 3fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}
.barra-rotulo {
  font-size: var(--text-sm);
}
.barra-trilho {
  height: 0.6rem;
  border-radius: 999px;
  background: var(--color-bg-inset);
  overflow: hidden;
}
.barra-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--color-accent);
}
.barra-valor {
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  white-space: nowrap;
}
.barra-0   { width: 0; }
.barra-5   { width: 5%; }
.barra-10  { width: 10%; }
.barra-15  { width: 15%; }
.barra-20  { width: 20%; }
.barra-25  { width: 25%; }
.barra-30  { width: 30%; }
.barra-35  { width: 35%; }
.barra-40  { width: 40%; }
.barra-45  { width: 45%; }
.barra-50  { width: 50%; }
.barra-55  { width: 55%; }
.barra-60  { width: 60%; }
.barra-65  { width: 65%; }
.barra-70  { width: 70%; }
.barra-75  { width: 75%; }
.barra-80  { width: 80%; }
.barra-85  { width: 85%; }
.barra-90  { width: 90%; }
.barra-95  { width: 95%; }
.barra-100 { width: 100%; }

/* ── próximas cobranças ── */

.prox {
  list-style: none;
  margin: 0;
  padding: 0;
}
.prox > li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.prox > li:last-child {
  border-bottom: 0;
}
.prox-texto {
  flex: 1;
  min-width: 9rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.prox-quando {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* ── sugestões ── */

.lista-sug {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lista-sug > li {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.lista-sug > li:last-child {
  border-bottom: 0;
}
.sug-topo {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.sug-titulo {
  margin: 0;
  font-weight: var(--weight-medium);
}
.sug-valor {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}
.sug-detalhe {
  margin: var(--space-2) 0 var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-article);
}
.sug-acoes {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}
.sug-acoes form {
  margin: 0;
}
.sug-anti {
  border-left: 3px solid var(--color-border-strong);
}

/* Alternativas gratuitas / open source / mais baratas (migração 024).
 *
 * Uma lista dentro do cartão, e não prosa: o tipo e o esforço são chips do DS
 * porque a pessoa escaneia por eles ("tem algo de esforço baixo aqui?"), e o
 * que se PERDE fica em bloco logo abaixo do nome — uma alternativa cujo custo
 * some na dobra é propaganda, não sugestão. */
.sug-alts {
  list-style: none;
  margin: var(--space-2) 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.sug-alts > li {
  padding-left: var(--space-3);
  border-left: 2px solid var(--color-border);
}
.sug-alts .sug-detalhe,
.sug-alts .dica,
.sug-referral .dica {
  display: block;
  margin: var(--space-1) 0 0;
}
.sug-referral {
  margin: var(--space-2) 0;
  font-size: var(--text-sm);
}

/* ── barra de cliente (workspace do PJ, F4) ──────────────────────────────
 *
 * Uma faixa abaixo do cabeçalho, e só existe para quem tem workspace: conta
 * pessoal nunca a vê. Os "chips" são <button> de um <form> POST, porque trocar
 * de cliente muda estado e o produto não carrega JavaScript — `name`/`value`
 * em botão de submit é o jeito do HTML puro de dizer qual deles foi apertado.
 * Herda `.chip` do DS; só o que um <button> perde por padrão é reposto. */
.ws-barra {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg-inset);
}
.ws-barra button.chip {
  font-family: inherit;
  cursor: pointer;
}
.ws-barra button.chip:hover {
  border-color: var(--color-accent);
}
.ws-rotulo {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.ws-gerir {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Uma linha por cliente na página de workspaces: nome, CNPJ, contagem e as
 * duas ações. Grade e não tabela — no celular ela vira pilha sozinha. */
.ws-lista {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: grid;
  gap: var(--space-3);
}
.ws-item {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg-raised);
}
.ws-item .ws-nome {
  font-weight: var(--weight-semibold);
}
.ws-item .ws-meta {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.ws-item .ws-acoes {
  margin-left: auto;
  display: flex;
  gap: var(--space-2);
}

/* Rótulo só para leitor de tela. Cada campo do renomear tem um <label>; ele
 * não cabe na linha, mas um input sem nome acessível é um input que ninguém
 * navegando por teclado consegue identificar. Não é enfeite, é o mínimo. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Formulário que mora dentro de uma linha de lista: campos e botão lado a
 * lado, quebrando para baixo no celular. */
.form-inline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  width: 100%;
}
.form-inline input {
  flex: 1 1 12ch;
  min-width: 0;
}
/* ── F3 ────────────────────────────────────────────────────────────────── */

/* Os cinco passos do iPhone. Numerada de verdade (é uma ordem, não uma lista
 * de opções), com respiro entre o passo e o detalhe. */
.passos {
  margin: var(--space-4, 1rem) 0 0;
  padding-left: 1.4rem;
}
.passos li {
  margin-bottom: var(--space-3, 0.75rem);
}
.passos li:last-child {
  margin-bottom: 0;
}

/* Candidato a confirmar — áudio, recibo e (na F2b) extrato. Uma linha por
 * rascunho, com a caixa de marcar à esquerda e o valor à direita. */
.candidatos {
  list-style: none;
  margin: var(--space-4, 1rem) 0 0;
  padding: 0;
}
.candidato {
  display: flex;
  gap: var(--space-3, 0.75rem);
  align-items: baseline;
  padding: var(--space-3, 0.75rem) 0;
  border-top: 1px solid var(--color-border);
}
.candidato:first-child {
  border-top: 0;
}
.candidato-nome {
  flex: 1 1 auto;
  min-width: 0;
}
.candidato-valor {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* De onde veio o rascunho, e é informação de confiança, não enfeite: um
 * candidato de LLM erra de um jeito que um de regex não erra. */
.candidato-origem {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm, 0.875rem);
}

/* Código de vínculo do Telegram e endereço de recibo: os dois são para copiar
 * ou digitar em outro aplicativo, então quebram em qualquer largura e ganham
 * fonte monoespaçada — endereço com sufixo aleatório lido em fonte de texto é
 * um erro de digitação esperando acontecer. */
.codigo {
  display: inline-block;
  font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--font-size-sm, 0.875rem);
  /* `--color-surface-sunken` e `--color-surface` são nomes do DS de OUTRA
   * casa: nenhum dos dois existe aqui, então a declaração inteira era
   * inválida e o código ficava sem fundo. O nome certo é `--color-bg-inset`. */
  background: var(--color-bg-inset);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 4px);
  padding: 0.35rem 0.6rem;
  word-break: break-all;
  user-select: all;
}

/* ── ilustrações ─────────────────────────────────────────────────────────
 * Os desenhos de `src/views/ilustracoes.ts` são SVG INLINE, e é por isso que
 * eles seguem o tema: cada forma é um elemento da página, pintada por estas
 * classes, com os mesmos tokens do resto da tela. Um `<img src="…svg">` seria
 * um documento à parte — não herda `currentColor`, não enxerga custom
 * property, e a única saída seria um `<style>` dentro do arquivo, que é o que
 * `style-src 'self'` proíbe aqui.
 *
 * O vocabulário é um só: traço de 2, cantos arredondados, e UM elemento em
 * acento por desenho — quase sempre o anel da lente, que é a barriga do "d"
 * do símbolo virada dispositivo de ilustração. */
.ilu {
  display: block;
  width: 100%;
  height: auto;
}
.ilu-fundo {
  fill: var(--color-bg-raised);
}
.ilu-painel {
  fill: var(--color-bg-inset);
}
.ilu-linha {
  fill: none;
  stroke: var(--color-border-strong);
  stroke-width: 2;
  stroke-linejoin: round;
}
.ilu-cap {
  stroke-linecap: round;
}
.ilu-fluxo {
  fill: none;
  stroke: var(--color-border-strong);
  stroke-width: 2;
  stroke-dasharray: 5 6;
  stroke-linecap: round;
}
.ilu-tinta {
  fill: var(--color-text-muted);
}
/* Segundo plano do desenho. Opacidade e não uma cor nova: o cinza mais claro
 * que passaria no contraste de TEXTO é escuro demais para uma forma de apoio,
 * e forma de apoio não é texto. */
.ilu-fraco {
  opacity: 0.4;
}
.ilu-acento {
  fill: var(--color-accent);
}
.ilu-acento-linha {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 2.5;
  stroke-linejoin: round;
}
.ilu-acento-fundo {
  fill: var(--color-accent-wash);
}
.ilu-icone {
  width: 3rem;
  height: 3rem;
  flex: none;
}
.ilu-simbolo {
  color: var(--color-accent);
  display: block;
}

/* ── hero ────────────────────────────────────────────────────────────────
 * Duas colunas a partir de 62rem, empilhado abaixo — e o TEXTO vem primeiro
 * na marcação, então no telefone a manchete continua sendo a primeira coisa
 * lida, sem `order` nenhum. */
.hero {
  display: grid;
  gap: var(--space-8);
  align-items: center;
  margin-bottom: var(--space-12);
}
@media (min-width: 62rem) {
  .hero {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: var(--space-12);
  }
}
.hero-texto > :first-child {
  margin-top: 0;
}
.hero-arte {
  max-width: 34rem;
  margin: 0 auto;
  width: 100%;
}

/* ── as três trilhas e os quatro recursos ────────────────────────────────
 * Índice visual, não repetição da prosa: a prosa logo abaixo explica cada um
 * com as palavras do dono, e isto só diz quais são e em que ordem. */
/* Mesma armadilha de especificidade dos `.planos`: sem o `.publico` na frente
 * as duas grades ficavam presas na largura de prosa. */
.publico .trilha,
.publico .recursos,
.trilha,
.recursos {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-8);
  max-width: none;
}
.trilha > li,
.recursos > li {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg-raised);
  margin: 0;
}
.trilha h3,
.recursos h3 {
  font-family: var(--font-display);
  font-size: var(--text-base);
  margin: 0 0 var(--space-1);
  color: var(--color-text);
}
.trilha p,
.recursos p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  max-width: none;
}

/* ── telas de verdade ────────────────────────────────────────────────────
 * A moldura é CSS e a imagem é a captura crua, então trocar a captura não
 * pede refazer moldura nenhuma. `<picture>` com `prefers-color-scheme` porque
 * este produto não tem botão de tema: o sistema é o único interruptor, e
 * assim o navegador baixa UMA das duas imagens em vez das duas. */
.telas {
  display: grid;
  gap: var(--space-6);
  align-items: end;
  margin: 0 0 var(--space-8);
}
@media (min-width: 52rem) {
  .telas {
    grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr);
  }
}
.telas figcaption {
  grid-column: 1 / -1;
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin: 0;
}
.moldura {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-bg-raised);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  min-width: 0;
}
/* A barra do navegador: três pontos e nada mais. Um endereço falso desenhado
 * aqui seria a única frase da página que o produto não pode cumprir. */
.moldura-barra {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg-inset);
}
.moldura-barra span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-border-strong);
}
.moldura img {
  display: block;
  width: 100%;
  height: auto;
}
.moldura-fone {
  border-radius: 26px;
  border-width: 8px;
  border-color: var(--color-text);
  max-width: 15rem;
  margin: 0 auto;
  background: var(--color-text);
}
.moldura-fone img {
  border-radius: 18px;
}

/* O símbolo abre o /sobre. É a única página que o mostra em tamanho de
 * verdade: é a página sobre quem está por trás do produto, e é onde a marca
 * ganha ser vista inteira em vez de a 20 px no cabeçalho. */
.sobre-marca {
  margin: 0 0 var(--space-6);
}

/* ── "ver como": a faixa de impersonação, e a barra dentro de tabela ─────
 *
 * A faixa é `position: sticky` e não `fixed`: fixed sobrepõe o conteúdo em
 * tela curta e esconde justamente o que se foi ver. Cor de aviso e não de
 * acento — ela existe para ser notada e para não ser confundida com a conta
 * da própria pessoa. Fica ANTES do <header>, então empurra a página inteira
 * para baixo em vez de cobrir o cabeçalho.
 */
.faixa-vercomo {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--color-warn, #7a4b00);
  color: var(--color-warn-text, #fff);
  font-size: var(--font-size-sm, 0.875rem);
}
.faixa-vercomo form {
  margin: 0;
}

/* A barra do /admin/insights vive numa célula de tabela, e `.barra-trilho` é
 * um <span>: sem `display:block` a altura não se aplica e a barra some. */
.celula-barra {
  width: 8rem;
  min-width: 5rem;
}
.celula-barra .barra-trilho {
  display: block;
}
/* Os botões de ação de /admin/usuarios: cada um é um <form method="post">
 * (CSRF), então sem isto eles empilhariam um por linha. */
.acoes-conta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.acoes-conta form {
  margin: 0;
}

/* /admin/emails: a prévia da peça e a versão texto dela.
 *
 * A prévia é um <iframe> apontado para /admin/emails/<tipo>.html porque a CSP
 * desta página é `style-src 'self'` e um e-mail é feito de `style=` inline por
 * definição: colar o HTML aqui dentro faria o navegador descartar exatamente o
 * que se quer conferir. O documento filho serve a peça com a CSP dele. */
.email-previa {
  width: 100%;
  height: 720px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: #ffffff;
}
.email-texto {
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.5;
}

/* ── /comecar: o onboarding de 90 segundos ───────────────────────────────
 *
 * Cinco telas, zero JavaScript, e por causa disso três decisões de markup que
 * o CSS aqui existe para sustentar:
 *
 *  · a grade inteira é UM formulário, então os chips de categoria e a busca
 *    são `<button type="submit">` e não links — filtrar reenvia as caixas já
 *    marcadas em vez de perdê-las;
 *  · o estado "marcado" vem de `:has(:checked)`, que é seletor nativo: sem
 *    ele seria uma classe calculada no servidor a cada render, ou script;
 *  · o "Continuar com N" gruda no rodapé no telefone, porque numa lista de
 *    179 cartões o botão de avançar fica a vinte e cinco linhas de distância.
 */

.passo {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Um <button> perde a fonte e o cursor por padrão; o resto vem do `.chip` do
 * DS, que não é forkado aqui. Mesmo remendo do `.ws-barra`. */
.chip-botao {
  font-family: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}
.chip-botao:hover,
.chip-botao:focus-visible {
  border-color: var(--color-accent);
}

.chips-palpite {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.chips-palpite .chip-botao {
  font-size: var(--text-sm);
  padding: var(--space-2) var(--space-4);
}

/* Rádio dentro de um chip: a bolinha continua lá (é ela que o leitor de tela
 * e o teclado usam), e o chip inteiro vira a área de toque. */
.chip-radio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}
.chip-radio:has(:checked) {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}

.form-grade {
  display: block;
}
.form-grade .busca-linha {
  margin-bottom: var(--space-4);
}

.grade-marcar {
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
}
.svc-marcar {
  cursor: pointer;
  position: relative;
}
.svc-marcar:has(:checked) {
  border-color: var(--color-accent);
  background: var(--color-accent-wash);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}
.svc-marcar input[type="checkbox"] {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  margin: 0;
  accent-color: var(--color-accent);
}

/* No telefone o botão de avançar não pode estar no fim de 179 cartões. */
.barra-continuar {
  position: sticky;
  bottom: 0;
  margin: 0;
  padding: var(--space-3) 0;
  background: var(--color-bg);
  border-top: 1px solid var(--color-border);
}

/* A3 do ROAST-2: as fichas do que já foi marcado, na mesma barra fixa do
 * botão. Numa lista de 943 serviços, buscar é o único caminho viável, e sem
 * isto a busca parecia apagar a seleção. Envolve para caber no telefone. */
.marcados {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
}
.marcados-vazio {
  color: var(--color-text-muted);
}
/* M5: o teto do plano Grátis, contado na 6ª marca em vez de no passo 5. */
.marcados-aviso {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-warn-text, var(--color-text-muted));
}

/* A confirmação: um bloco por serviço, plano em pílulas e o valor já
 * preenchido com o preço de tabela. Sete campos por item viraram um. */
.conf-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg-raised);
  padding: var(--space-4);
  margin: 0 0 var(--space-3);
}
.conf-nome {
  font-weight: var(--weight-semibold);
  padding: 0 var(--space-2);
}
.conf-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.campo-valor {
  margin-bottom: 0;
}

/* ── os spots de dentro do app e o mascote ───────────────────────────────
 *
 * A tangerina entra no vocabulário de ilustração pela mesma porta estreita
 * que entra no resto: só o desenho de "pago duas vezes" a usa. O resto
 * continua no roxo. */
.ilu-achado {
  fill: var(--color-achado-text);
}
.ilu-achado-linha {
  fill: none;
  stroke: var(--color-achado-text);
  stroke-width: 2.5;
  stroke-linejoin: round;
}
.ilu-achado-fundo {
  fill: var(--color-achado-wash);
}

/* O mascote. Herda a cor do texto do bloco em que estiver, e é isso que o
 * mantém sendo o logo em vez de um personagem: num vazio ele é cinza, num
 * cartão de achado ele é da cor do achado. */
.ilu-lente {
  color: var(--color-accent);
  width: auto;
  margin: 0 auto var(--space-3);
}

/* Um estado vazio com desenho: o desenho, o título, a frase, os botões. */
.vazio-ilu {
  display: block;
  width: 4.5rem;
  height: auto;
  margin: 0 auto var(--space-3);
  color: var(--color-accent);
}

/* ── a lente que olha, e as cenas de seção ───────────────────────────────
 *
 * `lenteQueOlha()` desenha o anel com PUPILA dentro de uma ilustração — o
 * dispositivo da v2 da marca. Não é o logo (não tem a haste do "b"), e é por
 * isso que ele pode entrar num desenho sem ferir o MARCA § 6.
 *
 * O disco de vidro é da cor do PAPEL e não transparente: sem ele as linhas de
 * fluxo atravessam a lente e ela deixa de ler como vidro. Ele muda com o tema
 * de graça, porque é `--color-bg`. */
.ilu-vidro {
  fill: var(--color-bg);
}
.ilu-anel {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 5;
}
.ilu-achado-anel {
  fill: none;
  stroke: var(--color-achado);
  stroke-width: 5;
}
/* A pupila em tangerina: o ÚNICO emprego da cor (MARCA § 3), e aqui ela é um
 * disco grande, nunca texto — `--color-achado` dá 2,80:1 e reprovaria. */
.ilu-pupila-achado {
  fill: var(--color-achado);
}

/* Uma cena é o desenho de meia seção. `max-width` para que ela não vire um
 * pôster em 1160 px, e `margin: auto` para centrar quando a seção empilha no
 * telefone. */
.ilu-cena {
  max-width: 26rem;
  margin: 0 auto;
}

/* ── o ritmo da landing: seções com arte, alternando o lado ──────────────
 *
 * O texto vem sempre primeiro na marcação; quem troca o lado é o `order`, e
 * só a partir de 62rem. No telefone é uma coluna, prosa antes do desenho, sem
 * `order` nenhum — que é a ordem que um leitor de tela também quer. */
.bloco {
  margin: 0 0 var(--space-12);
}
.bloco > :first-child,
.bloco-texto > :first-child {
  margin-top: 0;
}
.bloco-arte {
  display: grid;
  /* `minmax(0, 1fr)` e não `1fr`: o mínimo automático de um item de grade é o
   * min-content dele, e a `.trilha` lá dentro pede 15rem por coluna — o que
   * estourava a coluna em 375 px e devolvia rolagem horizontal no telefone. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
}
.bloco-texto,
.bloco-cena {
  min-width: 0;
}
@media (min-width: 62rem) {
  .bloco-dir {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: var(--space-12);
  }
  /* Com a arte à esquerda as LARGURAS trocam junto. `order: -1` sozinho move o
   * desenho para a primeira célula, que é a larga — e a prosa ia para a
   * estreita, com o desenho boiando num vão do tamanho de uma tela. */
  .bloco-esq {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: var(--space-12);
  }
  .bloco-esq .bloco-cena {
    order: -1;
  }
  /* A seção "o que o lensub faz" tem duas listas longas e é três vezes mais
   * alta que o desenho. Grudado, ele acompanha a leitura em vez de ficar
   * centrado num vão vazio — e é `sticky` e não script, então não custa nada
   * e degrada para estático em quem não suporta. */
  .bloco-cena .ilu-cena {
    position: sticky;
    top: var(--space-8);
  }
}
/* A faixa de superfície. LILÁS e não roxo: roxo de fundo em faixa larga é o
 * banco roxo, e o MARCA § 3 fecha essa porta. Cantos e recuo em vez de sangria
 * até a borda — sangria pede `100vw`, e `100vw` conta a barra de rolagem e
 * devolve rolagem horizontal no Windows. */
.bloco-lilas {
  background: var(--color-lilas);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-6);
}
@media (min-width: 62rem) {
  .bloco-lilas {
    padding: var(--space-8);
  }
}

/* As listas longas da landing viram duas colunas: "o que o lensub faz" tem
 * seis itens e "o que ele nunca faz" tem cinco, e empilhados eram a parede de
 * texto que o dono viu. `inside` porque o marcador de um item da segunda
 * coluna, posto fora, cairia em cima da primeira. */
@media (min-width: 46rem) {
  .landing .bloco-texto > ul:not(.trilha):not(.recursos),
  .landing .bloco > ul:not(.trilha):not(.recursos) {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--space-2) var(--space-6);
    max-width: none;
    padding-left: 0;
    list-style-position: inside;
  }
}

/* A marca no fecho da landing. É o segundo lugar da página onde a pupila
 * aparece em tamanho legível — o primeiro é o cabeçalho. */
.comecar-marca {
  margin: 0 0 var(--space-6);
}
.comecar-marca .ilu-simbolo {
  width: 88px;
  height: auto;
}

/* ── a marca d'água das páginas de prosa ─────────────────────────────────
 *
 * `/sobre`, `/faq` e `/planos` eram texto do topo ao rodapé. Isto põe o
 * símbolo grande e quase apagado no canto: presença de marca, não enfeite.
 *
 * `isolation: isolate` é o que faz `z-index: -1` funcionar aqui — sem ela o
 * desenho iria parar ATRÁS do fundo da página e sumiria em silêncio. E ele
 * encosta na borda direita do conteúdo em vez de ultrapassá-la, porque um
 * ornamento que estoura a caixa devolve rolagem horizontal no telefone. */
.publico {
  position: relative;
  isolation: isolate;
}
.ilu-dagua {
  position: absolute;
  z-index: -1;
  top: -0.5rem;
  right: 0;
  width: 13rem;
  height: auto;
  max-width: 45%;
  color: var(--color-accent);
  opacity: 0.07;
  pointer-events: none;
}
/* No escuro o roxo é mais claro e some antes: sobe dois pontos. Os dois
 * seletores da casa, e o `:root` em ambos — ver o aviso da § de tema. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ilu-dagua {
    opacity: 0.1;
  }
}
:root[data-theme="dark"] .ilu-dagua {
  opacity: 0.1;
}
