@charset "UTF-8";
/* ^ primeira linha por exigência da spec: o `content` dos pseudo-elementos da
 * tela de login carrega acento, e o proxy serve a folha sem `charset` no
 * cabeçalho. Sem isto o navegador pode decodificar por heurística. */
/* Identidade visual Mobmne — sobrescrita de variáveis do LibreChat.
 *
 * Servida por `backend/librechat-proxy/nginx.conf`, que injeta um <link> para
 * este arquivo antes de `</head>` na resposta HTML do LibreChat. Nada disto
 * vive dentro de `backend/librechat/` — ADR-20/P15.
 *
 * POR QUE VARIÁVEL E NÃO SELETOR DE COMPONENTE: o LibreChat v0.8.7 tematiza
 * por 167 custom properties em `:root`/`.dark`, e as que interessam são
 * SEMÂNTICAS, não paleta. Verificado na instância rodando:
 *
 *     --surface-submit:        var(--green-700)   <- botão primário
 *     --surface-submit-hover:  var(--green-800)
 *     --status-success:        var(--green-300)
 *     --status-success-border: var(--green-800)
 *     --status-success-strong: var(--green-800)
 *     --status-success-subtle: var(--green-950)
 *
 * Sobrescrever a PALETA `--green-*` inteira seria mais curto e estaria errado:
 * pintaria de teal também os indicadores de sucesso, que devem continuar
 * verdes. Por isso cada alias é tratado pelo seu papel.
 *
 * ⚠️ ESTE PARÁGRAFO ESTAVA ERRADO E CUSTOU UM BUG EM PRODUÇÃO — corrigido em
 * 2026-08-22, marcado (não apagado) em 2026-08-24, porque o texto antigo
 * continuava aqui convidando a próxima sessão a desfazer o conserto:
 *
 *   ~~FORMATO: as variáveis do LibreChat guardam TRIPLA RGB SEM `rgb()`
 *   ("39 153 161"), porque o Tailwind as consome como
 *   `rgb(var(--x) / var(--tw-bg-opacity))`. Escrever `#2799A1` aqui quebra em
 *   silêncio.~~
 *
 * O CONTRÁRIO é que é verdade, e foi MEDIDO na folha servida: das 51
 * ocorrências dessas variáveis no bundle, **51 são uso DIRETO e zero passam
 * por `rgb()`**. A tripla é que era sintaxe inválida — descartada em silêncio,
 * caindo no valor nativo do LibreChat. Foi essa premissa invertida que deixou
 * o botão "Continuar" do login INVISÍVEL (`rgba(0,0,0,0)` medido) e a
 * saudação em texto quase-preto sobre fundo escuro (§40.2 do handoff). As 18
 * variáveis foram convertidas para hex; **hex é a forma correta aqui**, e
 * qualquer reversão para tripla reintroduz o mesmo bug.
 *
 * Cores do kit de marca v1.0 (docs/brand/):
 *     Teal        #2799A1   (cor primária)
 *     Verificação #46B985   (estado de sucesso/verificado)
 */

/* ==========================================================================
 * ESPELHOS MOBMNE — leia antes de consumir qualquer token em `var()`
 * ==========================================================================
 *
 * 🔴 REGRA: nosso CSS e nosso JS NUNCA consomem `--surface-*`, `--text-*` ou
 * `--border-light` do LibreChat direto. Consomem o espelho `--mobmne-*`.
 * Hoje são 24 sítios: 17 em `mobmne-aferir.js`, 6 em `mobmne-brand.js`, 1 aqui.
 *
 * POR QUE (medido em 2026-08-25, ao avaliar o bump v0.8.7 → v0.8.8-rc1): o
 * FORMATO dos tokens do upstream MUDA entre versões — hex (`#047857`) na
 * v0.8.7, tripla RGB (`4 120 87`) na v0.8.8-rc1, consumida como
 * `rgb(var(--x) / <alpha>)`. Nosso código os usa em `var()` direto e dentro de
 * `color-mix()`, e nenhum dos dois tolera tripla: o valor vira sintaxe inválida
 * e é descartado EM SILÊNCIO, caindo para transparente. É exatamente o bug que
 * deixou o botão "Continuar" do login invisível (§40.2) — e o bump o
 * reintroduziria em 24 lugares de uma vez.
 *
 * O espelho quebra o acoplamento: os 24 sítios passam a depender de um valor
 * NOSSO, em formato que NÓS controlamos. Quando o upstream mudar de formato de
 * novo, muda-se esta folha — e nada mais.
 *
 * ⚠️ O SELETOR É A PARTE IMPORTANTE: `:root, html`, **sem `.dark`**. O bloco
 * logo abaixo casa `:root, .dark, html.dark, html` de uma vez; pôr os valores
 * CLAROS lá dentro faria valerem também no tema escuro, e só a ordem de
 * declaração impediria o estrago. Ordem não é contrato — mover um bloco
 * quebraria o tema escuro sem erro nenhum. Separados assim, os claros nunca
 * casam `.dark`, e os escuros (em `html.dark`, adiante) vencem por
 * especificidade, não por sorte.
 *
 * ⚠️ DEFINIDOS NOS DOIS TEMAS, e não é simetria decorativa: as sobrescritas de
 * superfície deste arquivo só existem dentro de `html.dark`. No tema CLARO
 * nossos consumidores liam o valor do upstream direto — então o tema claro
 * quebraria mesmo com a folha escura perfeita. Os valores claros abaixo são os
 * do upstream v0.8.7, medidos na folha servida (`index.CdHFgm6U.css`), não
 * estimados.
 *
 * Ao mudar uma sobrescrita de `--surface-*`/`--text-*` em `html.dark`, mude o
 * espelho correspondente no MESMO commit — senão a marca e o painel da Aferição
 * divergem da interface por baixo.
 * ========================================================================== */
:root,
html {
  --mobmne-acao: #2799A1;          /* espelha --surface-submit (Teal da marca) */
  --mobmne-superficie: #fff;       /* espelha --surface-primary   — upstream */
  --mobmne-superficie-2: #f7f7f8;  /* espelha --surface-secondary — upstream */
  --mobmne-superficie-3: #ececec;  /* espelha --surface-tertiary  — upstream */
  --mobmne-tinta: #212121;         /* espelha --text-primary      — upstream */
  --mobmne-tinta-2: #424242;       /* espelha --text-secondary    — upstream */
  --mobmne-borda: #e3e3e3;         /* espelha --border-light      — upstream */
}

:root,
.dark,
html.dark,
html {
  /* --- Ação primária: Teal ------------------------------------------------
   * Botão "Continuar" do login, botão de envio do compositor e qualquer
   * superfície de submit. É a troca que muda a percepção da marca com uma
   * linha. */
  --surface-submit: 39 153 161; /* #2799A1 */
  --surface-submit-hover: 31 130 138; /* #1F828A */ /* #1F828A — Teal ~12% mais escuro */

  /* --- Estado de sucesso: Verificação --------------------------------------
   * Deliberadamente NÃO é o Teal. "Verificado" é justamente o vocabulário do
   * produto (roteamento sob veredito, registro do que foi negado) — misturar
   * a cor de sucesso com a cor da marca apagaria essa distinção na tela. */
  --status-success: 70 185 133; /* #46B985 */
  --status-success-strong: 55 148 106; /* #37946A */
  --status-success-border: 55 148 106; /* #37946A */
  --status-success-subtle: 16 46 33; /* #102E21 */ /* fundo tênue, para o tema escuro */

  /* --- TINTA da Aferição (texto sobre superfície tênue da marca) ----------
   * `US-L.3`/`US-L.4`, achado de 2026-08-24 ao conferir o TEMA CLARO.
   *
   * A faixa de sessão e a pílula acesa desenham texto na cor da marca sobre um
   * `color-mix` da própria marca a 10%/14%. Medida a razão de contraste dos
   * quatro casos (fórmula WCAG 2.x, fundo composto de verdade):
   *
   *     tema claro  · faixa  #2799A1 sobre rgb(233,245,246) = 3,06:1  ✗
   *     tema claro  · pílula #2799A1 sobre rgb(225,241,242) = 2,93:1  ✗
   *     tema escuro · faixa  #2799A1 sobre rgb(32,42,42)    = 4,32:1  ✗
   *     tema escuro · pílula #2799A1 sobre rgb(32,47,47)    = 4,08:1  ✗
   *
   * Os quatro ficam abaixo do mínimo de 4,5:1 para texto normal — e a faixa é
   * de 12px. Não é preferência estética: é a mesma CLASSE de defeito que o
   * §40.2 já pegou em campo (texto ilegível por contraste, não por overlay),
   * agora medida antes de chegar ao operador em vez de depois.
   *
   * O QUE NÃO MUDA: `--surface-submit` (#2799A1) continua sendo a cor da
   * marca em preenchimento, borda e botão primário — nada de branding foi
   * tocado. O que se ajusta é só a TINTA DE TEXTO sobre essas superfícies
   * tênues, na mesma matiz, um tom por tema — que é como qualquer design
   * system trata "cor de marca" × "cor de texto sobre a cor de marca".
   *
   *     claro  #196E75 → 5,34:1 (faixa) e 5,12:1 (pílula)  ✓
   *     escuro #3FB3BC → 5,88:1 (faixa) e ~~5,56:1 (pílula)~~  ← ERRADO
   *
   * ⚠️ CORRIGIDO EM 2026-08-26, e a correção vale como método, não só como
   * número: o `5,56:1` da pílula no escuro foi medido contra a superfície da
   * PÁGINA. A pílula fica sobre o COMPOSITOR, que é mais claro — sobre o
   * fundo real o valor era 4,47:1, ou seja REPROVAVA. A tinta escura passou
   * para `#4cc0c9` (5,16:1); ver o bloco `html.dark` no fim deste arquivo.
   * A faixa não foi afetada: ela de fato fica sobre a superfície da página,
   * e os 5,88:1 se confirmaram.
   *
   * 🔴 A LIÇÃO: contraste se mede contra o fundo COMPOSTO do elemento, no
   * lugar onde ele realmente está — não contra o fundo do tema. Os quatro
   * números acima foram escritos como se um valor de tema bastasse, e três
   * estavam certos por coincidência de posicionamento.
   *
   * Reverter é uma linha: apagar as duas declarações e a superfície volta a
   * usar `--surface-submit` no texto. */
  --mobmne-afericao-tinta: #196e75;

  /* Vermelho de erro no claro — 6,60:1 sobre a superfície do cartão
   * (#f7f7f8). O `#e24b4a` que estava embutido no JS dava 3,67:1, ou seja
   * reprovava em AA nos DOIS temas. Vira variável por tema pela mesma razão
   * da tinta: cor de aviso fixa não sobrevive à troca de fundo.
   *
   * Fundo de ação FORTE, só para botão com texto branco: `--mobmne-acao`
   * (#2799A1) com `#fff` dá 3,41:1 e reprova. Este dá 5,95:1, mesma matiz.
   * Não substitui `--mobmne-acao` em outros usos — ali o teal claro é o
   * certo, porque não carrega texto por cima. */
  --mobmne-erro: #a32d2d;
  --mobmne-acao-forte: #196e75;

  /* --- Acento de marca ---------------------------------------------------
   * O default é `--brand-purple: 171 104 255`, usado em detalhes de UI. Vira
   * Teal para não conviver um roxo órfão ao lado da marca. */
  --brand-purple: 39 153 161; /* #2799A1 */

  /* O símbolo, servido pelo proxy. Variável para o par claro/escuro viver num
   * lugar só — os dois usos abaixo herdam a troca de tema de graça.
   *
   * NÃO é o ativo do kit copiado: é derivado dele por
   * `scripts/gerar-simbolo-marca.py`. O kit entrega LADRILHO (fundo próprio),
   * que é o certo para ícone de app e errado dentro da interface — o ladrilho
   * claro é `#F4F8F7`, quase a cor da barra lateral, e some. Além disso o
   * desenho ocupa 66%x42% da tela do ativo, então no mesmo espaço ele aparecia
   * com menos da metade do peso visual dos ícones vizinhos. Relatado em campo
   * pelo operador em 2026-08-19: *"apagado em relação aos outros símbolos"*.
   * O script recorta no desenho e deriva a versão de traço branco. */
  --mobmne-simbolo: url('/mobmne-symbol-light.png');
  --mobmne-assinatura: url('/mobmne-wordmark-light.png');
}

html.dark {
  --mobmne-simbolo: url('/mobmne-symbol-dark.png');
  --mobmne-assinatura: url('/mobmne-wordmark-dark.png');
}

/* ===========================================================================
 * ASSINATURA DA TELA DE LOGIN — sem o retângulo de fundo
 *
 * O `logo.svg` montado embute um JPEG, e JPEG não tem transparência: sob tema
 * escuro ele desenhava um SELO BRANCO aceso no meio do fundo escuro. Relatado
 * pelo operador em 2026-08-19 — *"não pode ficar com recorte branco"*.
 *
 * Duas coisas o `logo.svg` não resolve sozinho, e as duas somem aqui:
 *   1. Fundo — os PNGs derivados por `scripts/gerar-simbolo-marca.py` têm alfa,
 *      então não há retângulo em tema nenhum.
 *   2. Tema — o `logo.svg` troca claro/escuro por `prefers-color-scheme`, que é
 *      o tema do SISTEMA OPERACIONAL. Com o app em escuro e o Windows em claro
 *      (o caso do operador), ele servia a versão clara. Aqui a troca é por
 *      `html.dark`, o tema que o usuário escolheu de fato — a mesma correção já
 *      aplicada ao símbolo.
 *
 * `content` numa `<img>` substitui a imagem renderizada sem tocar no `src`: se
 * esta regra deixar de valer, a tela volta ao `logo.svg` montado, que é a nossa
 * marca também — degrada para o estado anterior, não para o logo do LibreChat. */
/* ⚠️ SEM barra inicial: o atributo é `assets/logo.svg`, RELATIVO. O seletor
 * casa com o atributo escrito no HTML, não com a URL resolvida — `currentSrc`
 * é `http://…/assets/logo.svg`, e foi olhar para ele que produziu a primeira
 * versão, com `/assets/…`, que não casava com nada. */
img[src*='assets/logo.svg'] {
  content: var(--mobmne-assinatura);
}

/* ===========================================================================
 * SLOGAN E DESCRITOR NA TELA DE LOGIN (2026-09-09)
 *
 * Texto de marca aprovado em `docs/brand/slogan.md` (rodada 8). A tela de
 * login é o único lugar do produto onde o slogan aparece como texto: na tela
 * de conversa a marca é o símbolo (barra lateral + saudação) e o rodapé
 * credita a organização — repetir o slogan lá seria a quarta marca na mesma
 * tela, e o cabeçalho de 52px já disputa espaço com o seletor de modelo.
 *
 * POR QUE CSS E NÃO SCRIPT: é texto estático, sem estado e sem interação.
 * Pseudo-elemento falha VISIVELMENTE (o texto some) e não tem laço de
 * mutação para errar — o degrau mais baixo da escada do `ADR-20` que resolve.
 *
 * ÂNCORA: o contêiner da assinatura, `AuthLayout.tsx`: `<div class="mt-6 h-10
 * w-full bg-cover"><img src="assets/logo.svg"></div>`. Casado por `:has()` no
 * `src` do `<img>` — caminho de asset, contrato do upstream, a mesma âncora
 * que a regra logo acima já usa — e não pela classe utilitária. `mt-6`/`h-10`
 * entram só para desempatar de qualquer outro contêiner que venha a ter a
 * imagem. Registrada em `scripts/check-ancoras-injetadas.py`.
 *
 * POSICIONAMENTO: o contêiner tem 40px de altura fixa e o formulário fica
 * centralizado verticalmente no `<main>` abaixo — entre os dois há espaço
 * vazio em qualquer viewport de desktop. Os dois pseudo-elementos ficam
 * ABSOLUTOS abaixo do contêiner, então não empurram o layout: se o upstream
 * mudar a altura ou a ordem, o texto no máximo sobrepõe, nunca desloca.
 * `pointer-events: none` para não roubar clique de nada por baixo.
 *
 * ⚠️ `::before` e `::after` do MESMO elemento porque um pseudo-elemento só
 * carrega um estilo, e o slogan (peso 600, tinta) e o descritor (tinta-2,
 * menor) precisam de dois. `::before` em posição absoluta não entra no fluxo,
 * então não aparece ACIMA da imagem — que é o que aconteceria se fosse
 * estático.
 *
 * No celular (< 640px) o descritor sai: com o teclado aberto o formulário
 * sobe e o texto de duas linhas invadiria o cartão. O slogan fica. */
/* ⚠️ REVISADO NO MESMO DIA, a pedido do operador: *"desequilibrado… destaque
 * correto para o slogan"*. A primeira versão pôs slogan (15px) e descritor
 * (13px) colados no logo de 40px, no topo da página, e deixou o "Bem-vindo de
 * volta" (30px, negrito) dominar a tela, com um vazio entre os dois blocos.
 * Estava errado nas duas: a hierarquia (a saudação gritava mais que a marca)
 * e a composição (marca no topo, formulário no meio, nada os unia).
 *
 * O que muda, e por quê:
 *   1. O logo cresce (40 → 48px) e o slogan vira a LINHA PRINCIPAL da tela
 *      (22px, peso 600). O descritor fica discreto (14px, tinta-2).
 *   2. A saudação "Bem-vindo de volta" é rebaixada (18px, peso 500, tinta-2):
 *      continua dizendo o que a tela é, sem competir com o slogan.
 *   3. Marca e formulário viram UMA composição, centralizada: o `<main>` deixa
 *      de centralizar o cartão sozinho (`align-items: flex-start`) e o topo da
 *      marca ganha uma margem calculada para o conjunto (~560px) ficar no
 *      meio do viewport — `max(24px, calc(50vh - 290px))`. Em tela curta cai
 *      para 24px e a página rola, em vez de sobrepor.
 *
 * ÂNCORAS NOVAS (registradas no gate): `main.flex-grow` e `h1.text-3xl`, as
 * duas em `AuthLayout.tsx`. Se sumirem, o sintoma é visível: o cartão volta a
 * centralizar sozinho e a saudação volta a 30px. */
div.mt-6.h-10:has(> img[src*='assets/logo.svg']) {
  position: relative;
  height: 48px;
  margin-top: max(24px, calc(50vh - 300px));
}

/* IDIOMA (2026-09-09, pergunta do operador: *"vai de acordo com o padrão de
 * língua do browser, certo?"*). Passou a ir. O LibreChat escreve o idioma
 * ativo em `<html lang>` (`client/src/locales/i18n.ts`, `documentElement.lang
 * = locale`; a preferência manual em Ajustes faz o mesmo), então `:lang()`
 * resolve sem script: `html:lang(pt)` casa pt-BR e pt-PT; qualquer outro
 * idioma recebe o par em inglês de `docs/brand/slogan.md`, que é o fallback
 * internacional do produto. O texto base é o inglês; o português sobrescreve. */
div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::after {
  content: 'Free the AI. Stay in control.';
  position: absolute;
  top: calc(100% + 22px);
  left: 0;
  right: 0;
  text-align: center;
  font-size: 22px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--mobmne-tinta);
  pointer-events: none;
}

div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::before {
  content: 'Multiple models, a single window. Governance with verified results.';
  position: absolute;
  top: calc(100% + 56px);
  left: 50%;
  transform: translateX(-50%);
  /* Mesma largura do cartão do formulário (`sm:max-w-md` = 28rem): o bloco de
   * marca e o formulário passam a ter a mesma coluna. Em duas linhas
   * equilibradas (`text-wrap: balance`), nunca numa linha mais larga que o
   * logo. Revisão do operador: *"não gostei da frase final e nem do
   * alinhamento. não está profissional"*. */
  width: min(28rem, calc(100vw - 48px));
  text-align: center;
  text-wrap: balance;
  font-size: 14px;
  line-height: 1.5;
  color: var(--mobmne-tinta-2);
  pointer-events: none;
}

html:lang(pt) div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::after {
  content: 'Liberte a IA. Mantenha o controle.';
}

html:lang(pt) div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::before {
  /* Revisão do operador em três tempos, 2026-09-09: "rastro" nunca foi
   * aprovado ("não aprovamos isso de rastro"); "única" sai ("não colocaria
   * como a única janela"); registro do conselho ("múltiplos",
   * "rastreabilidade"), sem o "de cada resposta". */
  /* Rodada 9 — texto do operador, com um polimento de gramática ("e", "com"). */
  content: 'Múltiplos modelos, uma única janela. Governança com resultados aferidos.';
}

/* O formulário deixa de flutuar no meio do espaço restante e passa a vir logo
 * abaixo do bloco de marca — 104px reservam slogan + descritor (até duas
 * linhas) sem sobreposição. */
main.flex.flex-grow.items-center.justify-center:has(h1) {
  align-items: flex-start;
  padding-top: 124px; /* slogan + descritor em duas linhas */
}

/* A saudação rebaixada: informa, não anuncia. */
main.flex-grow h1.text-3xl.font-semibold {
  font-size: 18px;
  line-height: 1.3;
  font-weight: 500;
  color: var(--mobmne-tinta-2);
  margin-bottom: 20px;
}

@media (max-width: 639px) {
  /* ⚠️ A primeira versão ESCONDIA o descritor no celular (para o teclado não
   * empurrar o texto sobre o formulário). O operador quer a frase em todas as
   * telas — *"a frase com descrição só aparece na visão desktop"*. Fica, menor
   * (13px, até três linhas em 375px), e o espaço reservado cresce junto. */
  div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::after {
    /* 22px encosta nas bordas em 375px; 20px respira. */
    font-size: 20px;
  }
  div.mt-6.h-10:has(> img[src*='assets/logo.svg'])::before {
    font-size: 13px;
    line-height: 1.4;
    top: calc(100% + 54px);
  }
  div.mt-6.h-10:has(> img[src*='assets/logo.svg']) {
    margin-top: max(24px, calc(50vh - 330px));
  }
  main.flex.flex-grow.items-center.justify-center:has(h1) {
    padding-top: 132px;
  }
}

/* ===========================================================================
 * "powered by ValoraIT" NO RODAPÉ DA TELA DE LOGIN (2026-09-09)
 *
 * A tela de conversa já credita a organização via `CUSTOM_FOOTER` (compose) —
 * ver o bloco RODAPÉ mais abaixo. A tela de login usa OUTRO componente de
 * rodapé (`Auth/Footer.tsx`), que só desenha os links de privacidade e termos
 * quando existem no `librechat.yaml`; sem eles, renderiza um `<div
 * role="contentinfo">` VAZIO. Pedido do operador: o crédito discreto em
 * todas as telas, não só na de conversa.
 *
 * ÂNCORA: `[role='contentinfo']:empty` — o papel ARIA (mesma âncora do bloco
 * de rodapé abaixo) mais o estado vazio. `:empty` é o que impede a regra de
 * casar o rodapé da conversa, que nunca está vazio (tem o `CUSTOM_FOOTER`).
 * Se um dia os links de privacidade/termos forem configurados, o rodapé de
 * login deixa de estar vazio e este crédito some — nesse dia, o caminho é pôr
 * o crédito no mesmo mecanismo (config), não emendar aqui.
 *
 * Um pseudo-elemento, um estilo: sem o corte Valora/IT em duas cores que o
 * rodapé da conversa faz via Markdown. Na tela de login a assinatura
 * completa está a 40px de distância, e o crédito é só o crédito. */
[role='contentinfo']:empty::after {
  content: 'powered by ValoraIT';
  font-size: 12px;
  color: var(--mobmne-tinta-2);
  opacity: 0.8;
  pointer-events: none;
}

/* ===========================================================================
 * SLOGAN NO CABEÇALHO DA TELA DE CONVERSA — DESLIGADO, decisão pendente do
 * operador (2026-09-09: "talvez manter slogan no topo das telas").
 *
 * Recomendação registrada: NÃO ligar. O cabeçalho tem 52px e já carrega o
 * seletor de modelo à esquerda e os botões (tema, Aferição) à direita; a
 * barra lateral já tem o símbolo, a saudação também, e o rodapé credita a
 * organização. Slogan aqui seria a quarta marca na mesma tela, e num produto
 * cujo argumento é "uma só janela, sem ruído", a interface tem de praticar o
 * que o slogan diz. No celular o cabeçalho troca de arranjo e o texto nem
 * caberia.
 *
 * Se o operador decidir ligar mesmo assim, é descomentar o bloco abaixo —
 * âncora `div.absolute.top-0[class*="h-[52px]"]`, a mesma que
 * `mobmne-brand.js` usa para o seletor de tema (já registrada no gate). Texto
 * centralizado, absoluto, sem evento de ponteiro, só acima de 1024px. */
/* LIGADO em 2026-09-09 a pedido do operador ("pode ligar o slogan no cabeçalho
 * pra eu ver") — em avaliação. Para desligar, envolver o bloco em comentário
 * de novo. Idioma pelo mesmo `<html lang>` da tela de login. */
@media (min-width: 1024px) {
  div.absolute.top-0[class*='h-[52px]']::after {
    content: 'Free the AI. Stay in control.';
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font-size: 12px;
    letter-spacing: 0.01em;
    color: var(--mobmne-tinta-2);
    pointer-events: none;
    white-space: nowrap;
  }
  html:lang(pt) div.absolute.top-0[class*='h-[52px]']::after {
    content: 'Liberte a IA. Mantenha o controle.';
  }
}

/* ===========================================================================
 * SÍMBOLO NA BARRA LATERAL
 *
 * Pedido do operador em 2026-08-19 depois de constatar que a marca só existia
 * na tela de LOGIN — a tela de conversa, que é a que ele usa, não tinha sinal
 * nenhum de Mobmne. A versão anterior deste trabalho registrou "não existe
 * slot de marca ali" e parou; era verdade enquanto não havia injeção de CSS.
 * Com este proxy de pé, deixou de ser.
 *
 * ÂNCORA, e por que esta: `data-testid` é contrato de teste do upstream, mais
 * estável que classe utilitária. A classe entra só para desempatar do `<aside
 * class="... w-56 shrink-0 flex-col ... bg-surface-primary-alt">` (outro painel,
 * usa `shrink-0`, não `flex-shrink-0`).
 *
 * VERIFICADO NO BUNDLE SERVIDO, não presumido do submodule — a imagem que roda
 * é v0.8.8-rc1 e o submodule está em v0.8.7 (US-K.1). Em
 * `assets/index.n3kZ-bvQ.js` a string de classe da trilha é literalmente
 * `flex h-full flex-shrink-0 flex-col gap-2 border-r border-border-light
 * bg-surface-primary-alt px-2 py-2`, e `open-sidebar-button`/
 * `close-sidebar-button` estão presentes. Se um bump futuro mudar isso, o
 * sintoma é o símbolo sumir — visível, não silencioso.
 *
 * `::before` vira o primeiro item do flex-column, ou seja acima do botão de
 * recolher: o topo da barra, que é onde o símbolo foi pedido. */
div.flex-shrink-0.flex-col.bg-surface-primary-alt:has(
    [data-testid='open-sidebar-button'],
    [data-testid='close-sidebar-button']
  )::before {
  content: '';
  display: block;
  flex: none;
  align-self: center;
  /* Proporção do desenho recortado é 1.60:1 — caixa quadrada desperdiçaria
   * altura e deixaria o símbolo menor do que precisa ser. A trilha tem 52px
   * com `px-2`, ou seja ~36px úteis: 32 de largura ocupa bem sem encostar. */
  width: 32px;
  height: 20px;
  margin: 6px 0 8px;
  background-image: var(--mobmne-simbolo);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

/* ===========================================================================
 * SÍMBOLO NA SAUDAÇÃO DA TELA DE CONVERSA
 *
 * O defeito que o operador viu e reportou com print: ao lado de "mobmne —" a
 * tela desenhava o símbolo da OPENAI. Não é engano de configuração — o
 * LibreChat põe ali o ícone do provedor que serve o modelo (`ConvoIcon`,
 * Chat/Landing.tsx:177), e o modelo ativo era `gpt-5.6`. Correto como
 * informação, e péssimo como marca: ao lado do nome do produto lê-se como se o
 * símbolo do ChatGPT FOSSE o nosso.
 *
 * ESCOPO DELIBERADAMENTE ESTREITO — só a saudação. O ícone do seletor de
 * modelo continua sendo o do provedor, de propósito: ele responde "quem está
 * servindo esta resposta", que é justamente a pergunta que um produto de
 * governança não deve esconder. Trocar os dois teria sido mais fácil e teria
 * apagado informação de procedência para pintar marca por cima.
 *
 * ÂNCORA: `relative size-10 justify-center` ocorre UMA vez no bundle servido
 * (`size-10` aparece 3 vezes no total, as outras em contexto diferente).
 * `visibility` e não `display` para o ícone do provedor: preserva a caixa de
 * 40px que o layout reserva, então nada ao redor se desloca. */
div.relative.size-10.justify-center {
  background-image: var(--mobmne-simbolo);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

div.relative.size-10.justify-center > * {
  visibility: hidden;
}

/* ===========================================================================
 * RODAPÉ — "powered by Valora[IT]", com o IT em Verificação
 *
 * O rodapé credita a ORGANIZAÇÃO (`CUSTOM_FOOTER` no compose), não o produto:
 * com o símbolo já na barra lateral e na saudação, repetir "mobmne" aqui seria
 * a terceira ocorrência da mesma marca na mesma tela.
 *
 * COMO O CORTE ACONTECE: o LibreChat renderiza `CUSTOM_FOOTER` como Markdown
 * (`Chat/Footer.tsx`), então `**Valora**_IT_` chega ao DOM como
 * `<strong>Valora</strong><em>IT</em>` — dois nós, e é isso que permite pintar
 * só o segundo. Parse conferido com o `mdast-util-from-markdown` do próprio
 * container, contra as três grafias candidatas, antes de escolher.
 *
 * `<em>` e não `<code>` (a crase daria o mesmo corte) porque `code` já vem com
 * fundo, borda e fonte monoespaçada do LibreChat — mais estilo para desfazer,
 * e mais chance de um bump do upstream mexer nele.
 *
 * ÂNCORA: `role="contentinfo"` — papel ARIA, não classe utilitária. Presente
 * no bundle servido (2 ocorrências, ambas rodapé). É a âncora mais estável
 * disponível aqui: mudar o papel de acessibilidade de um rodapé é mudança de
 * semântica, não de estilo, e não acontece num bump de rotina. */
/* ===========================================================================
 * TEMA ESCURO — tons quentes, barra lateral mais fechada que o centro
 *
 * O QUE ESTAVA ERRADO, medido na folha servida: o LibreChat faz o INVERSO do
 * pedido. `--surface-primary-alt` (barra lateral) = `--gray-850` = `23 23 23`,
 * e `--surface-primary` (centro) = `--gray-900` = `13 13 13`. Ou seja a barra
 * era MAIS CLARA que o centro, e o centro era quase preto puro.
 *
 * Tons daqui em diante são os do design system do Claude — cinza levemente
 * QUENTE (o verde/vermelho sobem um pouco acima do azul), não cinza neutro.
 * É o que dá a sensação de papel escuro em vez de tela desligada.
 *
 * ALIASES SEMÂNTICOS, não a paleta `--gray-*` — mesma disciplina da troca de
 * cor de acento. Sobrescrever `--gray-900` seria mais curto e repintaria todo
 * lugar que usa aquele cinza por outro motivo.
 *
 * ⚠️ FORMATO — ESTE PARÁGRAFO ESTAVA ERRADO, e é a MESMA premissa invertida que o
 * cabeçalho deste arquivo (linhas 22-38) já corrigiu em 22/08. Ele sobreviveu aqui,
 * 230 linhas abaixo, dizendo o contrário — e quem lesse só este bloco desfaria o
 * conserto com confiança. Achado em 2026-08-25; marcado, não apagado:
 *
 *   ~~FORMATO: tripla RGB sem `rgb()`, porque o Tailwind consome como
 *   `rgb(var(--x) / <alpha>)`. Hex aqui invalida a regra em silêncio.~~
 *
 * O CONTRÁRIO é que vale, e a prova está três linhas abaixo: os valores deste
 * próprio bloco são hex (`#1F1E1D`) e funcionam. Medido na folha servida — das 51
 * ocorrências dessas variáveis no bundle, 51 são uso DIRETO e zero passam por
 * `rgb()`. A tripla é que é sintaxe inválida, descartada em silêncio.
 *
 * **Hex é a forma correta aqui.** Reverter para tripla reintroduz o bug que deixou
 * o botão "Continuar" do login invisível (§40.2 do handoff).
 *
 * A lição que sai deste achado: correção marcada no cabeçalho NÃO alcança uma cópia
 * da mesma afirmação no corpo do arquivo. Ao corrigir uma premissa, procurar todas
 * as repetições dela — foi por esta fresta que o mesmo erro chegou à terceira
 * chance de morder. */
html.dark {
  /* Espelhos Mobmne no tema escuro — explicação completa no bloco do topo.
   * Acompanham as sobrescritas logo abaixo: mudou uma, muda o espelho no mesmo
   * commit. `--mobmne-acao` não se repete aqui porque o Teal da marca é idêntico
   * nos dois temas. */
  --mobmne-superficie: #1F1E1D;    /* = --surface-primary   abaixo */
  --mobmne-superficie-2: #262624;  /* = --surface-secondary abaixo */
  --mobmne-superficie-3: #302F2D;  /* = --surface-tertiary  abaixo */
  --mobmne-tinta: #F0EFEC;         /* = --text-primary      abaixo */
  --mobmne-tinta-2: #C3C2B7;       /* = --text-secondary    abaixo */
  --mobmne-borda: #2C2C2A;         /* = --border-light      abaixo */

  /* Centro da conversa — o mais claro dos dois, como pedido. */
  --surface-primary: 31 30 29; /* #1F1E1D */
  /* Barra lateral — mais fechada que o centro. */
  --surface-primary-alt: 20 20 19; /* #141413 */
  --surface-primary-contrast: 20 20 19; /* #141413 */

  /* Cartões, campos e menus flutuam um degrau acima do centro. */
  --surface-secondary: 38 38 36; /* #262624 */
  --surface-tertiary: 48 47 45; /* #302F2D */
  --surface-active: 58 57 54; /* #3A3936 */

  /* O cabeçalho é um gradiente de `presentation` até transparente. Igualado ao
   * centro de propósito: com valor próprio ele desenha uma faixa mais clara no
   * topo, que é justamente o que o gradiente existe para evitar. */
  --presentation: 31 30 29; /* #1F1E1D */

  /* Divisas: fio de cabelo e borda de contraste. */
  --border-light: 44 44 42; /* #2C2C2A */
  --border-medium: 56 56 53; /* #383835 */

  /* Tinta. Não é branco puro — branco puro sobre fundo quente vibra. */
  --text-primary: 240 239 236; /* #F0EFEC */
  --text-secondary: 195 194 183; /* #C3C2B7 */

  /* Tinta da Aferição no escuro — ver o bloco de racional lá em cima, junto
   * da versão clara. Aqui o ajuste é para CIMA (o fundo é escuro), mesma
   * matiz teal.
   *
   * ⚠️ CORRIGIDO EM 2026-08-26 — o valor anterior era `#3fb3bc`, e os
   * "5,56:1 na pílula" que estavam escritos aqui foram medidos contra o FUNDO
   * ERRADO. A conta usou a superfície da PÁGINA (`--mobmne-superficie`,
   * #1F1E1D); a pílula fica sobre o COMPOSITOR (`--surface-chat`, #2F2F2F).
   * Refeito sobre o fundo real (#2e3e3f, já com a lavagem teal de 14%):
   *   #3fb3bc → 4,47:1  ❌ reprova em AA para texto pequeno (mínimo 4,5)
   *   #4cc0c9 → 5,16:1  ✅
   * Achado por verificação instrumentada na instância viva, medindo cor
   * computada em vez de conferir a olho.
   *
   * 🔴 A ESCOLHA DE `#4cc0c9` E NÃO DE `#40b4bd` É O PONTO. `#40b4bd` dá
   * 4,52:1 e passaria — por 0,02. Foi exatamente essa margem de fio de
   * navalha que produziu o defeito: qualquer mudança futura no fundo do
   * compositor derruba de novo, em silêncio. Margem é o conserto. */
  --mobmne-afericao-tinta: #4cc0c9;

  /* Vermelho de erro no escuro — 6,81:1 sobre a superfície do cartão
   * (#262624). O `#e24b4a` que estava embutido no JS dava 3,85:1. */
  --mobmne-erro: #f09595;
}

/* ===========================================================================
 * SELO/RETÂNGULO VISÍVEL ATRÁS DA ÁREA DE CONVERSA — achado ao vivo em
 * 2026-08-20 (US-L.3/L.4, verificação visual): o wrapper que preenche a tela
 * inteira (`Presentation.tsx`, `bg-presentation`) e o `--surface-primary` do
 * resto da UI já usam o MESMO valor (`31 30 29`) — não é descompasso entre
 * eles. O descompasso é com a página por trás de tudo: `html`/`body` nunca
 * ganharam cor própria nesta folha, então herdam o preto/branco padrão do
 * navegador, mais escuro que os `31 30 29` do conteúdo. Onde o wrapper não
 * cobre 100% da viewport (bordas, resize, gutter de scroll), esse fundo
 * default aparece como um retângulo com aresta viva. `html`/`body` cobrindo
 * a viewport inteira com a MESMA cor elimina a aresta na origem, em vez de
 * caçar todo componente intermediário que porventura não define bg próprio. */
html {
  background: var(--mobmne-superficie);
}

/* ===========================================================================
 * TEXTO "COBERTO" NA SAUDAÇÃO E NO RODAPÉ — achado ao vivo em 2026-08-22
 * (operador reportou "overlay cobrindo a tela toda"; era contraste, não uma
 * camada por cima). Causa raiz: a saudação ("Em que vamos trabalhar...") e o
 * `CUSTOM_FOOTER` passam pelo plugin Tailwind Typography (`.prose`), que tem
 * seu PRÓPRIO conjunto de variáveis de cor (`--tw-prose-headings` etc.),
 * independente de `--text-primary`. Sem a classe `.prose-invert` aplicada
 * pelo componente, o texto cai no padrão CLARO do plugin
 * (`--tw-prose-headings: #111827`, quase preto) mesmo com `html.dark` ativo —
 * verificado na folha servida (`served.css`), a variável e o valor batem
 * exatamente com o que renderizava. Corrigir as variáveis `--tw-prose-*`
 * direto, dentro de `html.dark`, funciona com OU sem `.prose-invert` no
 * componente — não depende de o upstream lembrar de aplicar a classe certa.
 *
 * CORREÇÃO 2026-08-22, mesma sessão: a primeira versão deste bloco escrevia
 * `html.dark { --tw-prose-*: ... }` — no ANCESTRAL. Não funcionava: a classe
 * `.prose` define essas variáveis DIRETO no próprio elemento, e uma
 * declaração no elemento sempre vence valor herdado do ancestral, não
 * importa a especificidade de quem declarou no ancestral. Precisa mirar o
 * elemento que carrega `.prose` (ou `.prose-invert`) direto, com
 * especificidade igual ou maior que a regra original do plugin. */
html.dark .prose,
html.dark .prose-invert {
  --tw-prose-body: #c3c2b7;
  --tw-prose-headings: #f0efec;
  --tw-prose-lead: #c3c2b7;
  --tw-prose-links: #f0efec;
  --tw-prose-bold: #f0efec;
  --tw-prose-counters: #c3c2b7;
  --tw-prose-bullets: #c3c2b7;
  --tw-prose-hr: #2c2c2a;
  --tw-prose-quotes: #f0efec;
  --tw-prose-quote-borders: #2c2c2a;
  --tw-prose-captions: #c3c2b7;
  --tw-prose-code: #f0efec;
  --tw-prose-th-borders: #383835;
  --tw-prose-td-borders: #2c2c2a;
}

[role='contentinfo'] em {
  /* Verificação #46B985 — a mesma cor do estado de sucesso, e o segundo
   * membro do par da marca. Não é o Teal: Teal é ação primária, e o rodapé
   * não é acionável. */
  color: rgb(70 185 133);
  font-style: normal;
  font-weight: 500;
}
