/* ==============================================================================
   ARQUIVO: FUNDACAO.CSS
   OBJETIVO: A CAMADA QUE TODA PÁGINA DO SISTEMA CARREGA

   Este arquivo é o único que entra em absolutamente todas as telas — da vitrine
   ao PDV do estande. Por isso ele guarda só o que é verdade em qualquer lugar:
   a paleta da marca, o corpo da página, a tipografia e as regras de toque.

   O QUE NÃO ENTRA AQUI: componente de tela específica (torrada, gaveta de acesso,
   carrossel) mora em componentes_compartilhados.css, carregado apenas por quem
   usa. E nada de `overflow-x: hidden` no corpo: essa trava pertence à vitrine e
   ao checkout, que a pedem, e num ancestral ela é a causa clássica de
   `position: sticky` que para de colar — o que quebraria a área de membros.

   A ORDEM IMPORTA: este arquivo é sempre o PRIMEIRO link da página, para que o
   CSS específico de cada tela continue vencendo quando quiser divergir.
============================================================================== */

/* ==============================================================================
   1. AS VARIÁVEIS DA MARCA (TOKENS DE DESIGN)

   Antes deste bloco, a paleta vivia escrita à mão: o azul-escuro do texto
   aparecia 49 vezes espalhadas por nove arquivos, o verde de conversão 47. Trocar
   um tom da marca era caçar dezenas de ocorrências e torcer para não esquecer
   nenhuma — e foi assim que o fundo cinza acabou existindo em três versões quase
   iguais (#f4f7f6, #f4f4f4, #f4f4f9) que ninguém escolheu de propósito.

   Daqui em diante a cor tem um nome, e o nome diz o PAPEL dela, não o tom: o dia
   em que o verde mudar, quem quer dizer "conversão" continua dizendo conversão.
============================================================================== */

:root {
	/* --- Cores de texto --- */
	--cor_de_texto_principal: #2c3e50;
	--cor_de_texto_suave: #7f8c8d;
	--cor_de_texto_sobre_cor: #ffffff;

	/* O cinza do texto de exemplo dentro dos campos. Ele é mais claro do que o
	   `--cor_de_texto_suave` de propósito: exemplo não é conteúdo, e um
	   "fulano@email.com" com o mesmo peso do que o cliente digitou faz o campo
	   parecer preenchido de longe.

	   O TOM É ESCOLHIDO POR CONTRASTE MEDIDO, e não a olho: `#b7b7b7` dá
	   **2,006:1** sobre o branco das superfícies, que é a régua que o Felipe
	   definiu para este projeto. Não é o 4,5:1 da WCAG, e a escolha é deliberada —
	   placeholder aqui é dica, não conteúdo, e nenhum campo depende dele para ser
	   entendido (todos têm rótulo próprio em negrito acima).

	   ANTES DE CLAREAR MAIS, MEÇA. O caminho de `#a0aec0` (2,26:1) para `#c9c9c9`
	   derrubou o contraste para 1,66:1 sem que a diferença fosse óbvia na tela de
	   quem escolheu — e abaixo de 2:1 o texto some para uma parcela grande de
	   gente em telas comuns, sob luz do dia. A conta é a da WCAG:
	   (L_claro + 0,05) / (L_escuro + 0,05), com L linearizado por canal. */
	--cor_de_texto_de_exemplo_de_campo: #b7b7b7;

	/* --- Cores de superfície --- */
	--cor_de_fundo_de_pagina: #f4f7f6;
	--cor_de_superficie: #ffffff;
	--cor_de_superficie_suave: #f8f9fa;

	/* --- Cores de intenção --- */
	--cor_de_conversao: #27ae60;        /* O verde que fecha a venda */
	--cor_de_conversao_escura: #219653; /* O mesmo verde sob o dedo/cursor */
	--cor_de_conversao_clara: #eafaf1;  /* Fundo de realce em verde */
	--cor_de_alerta: #e74c3c;

	/* O fundo de realce em vermelho, par do `--cor_de_conversao_clara` que já
	   existia em verde. Nasceu para a pílula de favoritos apagada: ela precisa
	   dizer "vermelho" sem gritar, do mesmo jeito que o verde claro faz no
	   bloquinho de peso que tem itens no carrinho. */
	--cor_de_alerta_clara: #fdecea;
	--cor_de_atencao: #f39c12;

	/* O fundo de realce em laranja, o QUARTO irmão de `--cor_de_conversao_clara`,
	   `--cor_de_alerta_clara` e `--cor_de_informacao_clara`. Ele já existia de
	   fato: era o `#ffe7be` escrito à mão em `.pilula_de_categoria`, na vitrine,
	   e a marcação de categorias do painel (D5, 2026-08-12) precisou do mesmo tom
	   — o par claro/forte das pílulas é o vocabulário que o cliente já lê na loja,
	   e repetir o literal no painel criaria a segunda cópia de uma cor que ninguém
	   nomeou.

	   ⚠️ É O ÚNICO DOS QUATRO QUE NÃO É UM LAVADO DO TOM FORTE. Os outros três
	   são a cor de intenção a 10% sobre o branco; este é o creme que a vitrine
	   escolheu à mão, e ele é mais saturado do que a conta daria. Trocá-lo pelo
	   resultado da conta mudaria a trilha de pílulas da loja. */
	--cor_de_atencao_clara: #ffe7be;

	/* O QUINTO PAR CLARO/FORTE, E ELE É AMARELO — "FALTA INFORMAÇÃO" (item 8.85-B, 2026-08-25).

	   ⚠️ ELE NASCEU PORQUE `--cor_de_atencao` PRECISOU DIZER DUAS COISAS AO MESMO TEMPO, e não
	   podia. A tela de saídas marca dois estados de nota que exigem gestos diferentes:

	     INCOMPLETA  falta digitar o que foi comprado   → este par, amarelo, borda TRACEJADA
	     DIVERGENTE  os números não fecham entre si     → `--cor_de_atencao`, laranja, borda SÓLIDA

	   Uma cor só para os dois faria a pessoa abrir a nota para descobrir qual dos dois é, em toda
	   linha marcada — e o item 8.85 é explícito: "cor sozinha não diz QUAL dos dois é".

	   ⚠️⚠️ E OS DOIS SÃO VIZINHOS DE PROPÓSITO, o que soa errado até se ver na tela. `#f39c12` é um
	   âmbar quase amarelo, e escolher um amarelo distante dele (um limão, digamos) faria os dois
	   estados parecerem coisas de famílias diferentes — quando eles são a mesma família: "isto
	   precisa da sua atenção". O que os separa é a FORMA DA BORDA, que continua legível para quem
	   não distingue as duas cores. A decisão é dele, de 2026-08-25.

	   📌 O CLARO É UM LAVADO DO FORTE, como o verde, o vermelho e o azul — e ao contrário de
	   `--cor_de_atencao_clara`, que é o creme `#ffe7be` que a vitrine escolheu à mão para as
	   pílulas de categoria e que por isso é mais saturado do que a conta daria. */
	--cor_de_pendencia: #e8c33c;
	--cor_de_pendencia_clara: #fdf6dd;

	--cor_de_informacao: #3498db;

	/* O VIOLETA DA OFERTA (2026-08-13).

	   Ele não é novo: está escrito à mão como `#8e44ad` na pílula de peso
	   promocional da vitrine desde sempre, com um `#9b59b6` de borda ao lado. Virou
	   token porque os selos do cartão (v9_37) passaram a precisar do MESMO violeta —
	   e a régua da casa é que a segunda ocorrência de uma cor é o momento de nomeá-la,
	   não a terceira.

	   ⚠️ ELE SIGNIFICA "AQUI HÁ OFERTA", e é o que o cliente já aprendeu a ler na
	   pista de pesos. Usá-lo para outra coisa gastaria esse aprendizado. */
	--cor_de_oferta: #8e44ad;

	/* O MESMO VIOLETA, COM NOME PRÓPRIO — A LINHA ALTERADA POR TABELA (item 8.22, 2026-08-21).

	   Na grade de lançamentos financeiros, editar um campo comum a uma nota (data,
	   fornecedor, desconto…) numa linha propaga o valor para as linhas-irmãs do
	   mesmo grupo. Aquelas linhas precisam de uma cor própria — diferente do verde
	   de `--cor_de_conversao_clara`, que é "eu editei isto diretamente" —, para que
	   a pessoa veja de relance qual linha ela tocou e quais mudaram por tabela.

	   ⚠️ NÃO REAPROVEITA `--cor_de_oferta` PELO NOME — só pelo tom. O comentário de
	   cima já reserva aquele token para "aqui há oferta" na vitrine, lido por
	   cliente de verdade; este é vocabulário do painel administrativo, que nenhum
	   cliente vê, e merece o próprio nome para não diluir o aprendizado do outro. */
	--cor_de_alteracao_em_cascata: #8e44ad;
	--cor_de_alteracao_em_cascata_clara: #f5eef8;

	/* O fundo de realce em azul, o terceiro irmão de `--cor_de_conversao_clara` e
	   `--cor_de_alerta_clara`. Ele já existia de fato, escrito como
	   `rgba(52, 152, 219, 0.1)` em três lugares do painel administrativo — e um
	   deles usava `0.12` em vez de `0.1`, sem que ninguém tivesse decidido isso: é
	   o que acontece quando a mesma cor é redigitada em vez de nomeada.

	   É OPACO, E NÃO UM `rgba`, de propósito. Um realce translúcido muda de tom
	   conforme o que estiver atrás dele — e estes selos ficam ora sobre a linha
	   branca, ora sobre o cinza do `:hover`, ora sobre o verde da linha alterada.
	   A cor é o resultado de `#3498db` a 10% sobre o branco, achatado. */
	--cor_de_informacao_clara: #ebf5fc;

	/* O MESMO AZUL UM DEGRAU MAIS FORTE — `#3498db` a 20% sobre o branco, contra
	   os 10% do de cima. Ele nasceu em 2026-08-12 para a grade do catálogo poder
	   dizer duas coisas com a mesma cor: a LINHA em edição é o claro, e a CÉLULA
	   que foi alterada dentro dela é este.

	   ⚠️ ELE SÓ FAZ SENTIDO EM CIMA DO OUTRO. Sozinho, é um azul claro qualquer;
	   o que ele informa é a diferença — "dentro desta linha, foi ESTE campo que
	   mudou". Usá-lo isolado num fundo branco desperdiça a única coisa que ele
	   tem a dizer. */
	--cor_de_informacao_clara_realcada: #d6eaf8;

	/* --- Bordas e traços --- */
	--cor_de_borda_suave: #e2e8f0;
	--cor_de_borda_de_campo: #bdc3c7;
	--cor_de_divisor: #ecf0f1;

	/* --- Geometria --- */
	--raio_de_canto_de_cartao: 12px;
	--raio_de_canto_de_campo: 8px;

	/* --- Profundidade --- */
	--sombra_de_cartao: 0 4px 15px rgba(0, 0, 0, 0.05);
	--sombra_de_cartao_elevado: 0 12px 25px rgba(0, 0, 0, 0.1);
	--sombra_de_barra: 0 2px 5px rgba(0, 0, 0, 0.05);

	/* --- Tipografia --- */
	--pilha_de_fontes: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

/* ==============================================================================
   2. A RAIZ DO DOCUMENTO E A TRAVA DE ZOOM ACIDENTAL

   O PROBLEMA: no celular, dois toques rápidos no mesmo ponto são interpretados
   como "aproximar" — e como esta loja é feita de cartões, pílulas e botões [+]
   que o cliente toca em sequência rápida, o zoom disparava sozinho no meio da
   compra e desmontava o layout.

   A SOLUÇÃO, E POR QUE NÃO É NA META VIEWPORT: o caminho antigo era escrever
   `user-scalable=no, maximum-scale=1` na tag viewport. Isso mata o zoom INTEIRO,
   inclusive o de dois dedos — quem enxerga pouco perde a capacidade de ampliar a
   página, o que reprova na WCAG 1.4.4. Fora que o Safari do iOS ignora esse
   pedido desde o iOS 10, então nem funcionaria.

   `touch-action: manipulation` diz outra coisa: "role e aproxime com dois dedos à
   vontade, só não trate toque duplo como zoom". Some o zoom acidental, fica o
   zoom intencional. A propriedade não é herdada, mas o navegador calcula o gesto
   pela cadeia de ancestrais, então declarar na raiz vale para a página toda — e
   quem precisa de mais restrição (a faixa de arraste da gaveta usa
   `touch-action: none`) continua mandando no próprio pedaço, porque o valor mais
   restritivo é o que prevalece na interseção.
============================================================================== */

html {
	touch-action: manipulation;

	/* O celular deitado inflava a fonte por conta própria e estourava as caixas */
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

/* ==============================================================================
   3. O CORPO DA PÁGINA
============================================================================== */

body {
	font-family: var(--pilha_de_fontes);
	background-color: var(--cor_de_fundo_de_pagina);
	color: var(--cor_de_texto_principal);
	margin: 0;
	padding: 0;

	/* Abaixo disso não há telefone: serve de piso para o layout não se espremer */
	min-width: 320px;
}

/* ==============================================================================
   O TEXTO DE EXEMPLO DENTRO DOS CAMPOS

   Até aqui só o campo de busca da vitrine dizia que cor queria; todo o resto do
   sistema ficava com o cinza que o navegador escolhe — mais escuro, e diferente
   entre Chrome, Safari e Firefox. Um "Ex: felipe@gmail.com" quase tão firme
   quanto o texto digitado faz o campo parecer preenchido para quem passa o olho,
   e num checkout isso é o cliente pulando um campo que ainda está vazio.

   POR QUE NA FUNDAÇÃO, e não em cada tela: são catorze campos espalhados por
   checkout, cadastro, acesso, estande e painel administrativo, e todos querem a
   mesma coisa. A regra vale para quem não pedir nada — quem quiser divergir
   declara depois, porque a fundação é sempre o primeiro <link> da página.

   As duas linhas são obrigatórias: `::-webkit-input-placeholder` continua sendo
   o que o Safari do iOS entende, e navegador que não reconhece um seletor
   descarta a regra inteira — por isso elas não podem ser agrupadas por vírgula.
============================================================================== */

input::placeholder,
textarea::placeholder {
	color: var(--cor_de_texto_de_exemplo_de_campo);
	opacity: 1; /* O Firefox aplica 0.54 por conta própria e apagaria o tom */
}

input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
	color: var(--cor_de_texto_de_exemplo_de_campo);
}

/* ==============================================================================
   4. CAMPO DE SENHA COM O OLHINHO

   Vive na fundação, e não na camada de componentes, porque os três formulários de
   senha do sistema estão em telas que não compartilham mais nada entre si: a
   gaveta de acesso da loja, a página isolada /acesso e o /cadastro.

   COMO SE MONTA: a envoltória embrulha o input e o botão. Ela não desenha nada —
   apenas cria o ponto de referência para o botão pousar dentro do campo, e por
   isso funciona por cima de qualquer estilo de input que a página já tenha.

       <div class="envoltoria_de_campo_de_senha">
           <input type="password" id="...">
           <button type="button" class="botao_de_mostrar_senha" ...>
       </div>
============================================================================== */

.envoltoria_de_campo_de_senha {
	position: relative;
	display: block;
	width: 100%;
}

/* O campo precisa abrir espaço à direita, senão a senha digitada passa por baixo
   do olhinho e o cliente perde as últimas letras de vista justamente quando quer
   conferi-las.

   O `[type]` NÃO É DECORATIVO. Sem ele o seletor empata em especificidade com
   `.caixa_de_login input`, do acesso.css, e como a fundação é sempre o primeiro
   arquivo da página, o empate seria resolvido a favor do outro: o `padding: 15px`
   de lá reabsorveria a reserva de espaço e a senha voltaria a correr por baixo do
   olhinho. O atributo `type` está sempre presente num campo de senha — inclusive
   depois de virar `text` — então ele custa nada e desempata a nosso favor. */
.envoltoria_de_campo_de_senha > input[type] {
	width: 100%;
	padding-right: 52px;
	box-sizing: border-box;
}

/* A CENTRALIZAÇÃO NÃO É ENFEITE: ELA É A REDE DE SEGURANÇA.

   Com `top: 0` o botão pousava no alto da envoltória e descia até o fim dela — e
   a envoltória nem sempre tem a altura do campo. Nas páginas isoladas de acesso
   e de cadastro o input traz uma margem inferior própria, que era contada na
   altura da envoltória: 71px de caixa para 51px de campo, e o olhinho ficava
   20px mais baixo do que deveria, encostado na borda de baixo.

   A causa foi corrigida no motor_de_formularios.js, que passa a mudar essa
   margem de lugar. Ancorar pelo meio é o que garante que, se alguma página
   voltar a inflar a envoltória por outro motivo — um padding, uma borda —, o
   olhinho continue no centro do campo em vez de escorregar para uma das pontas. */
.botao_de_mostrar_senha {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	right: 0;
	height: 100%;

	/* 44px é o alvo mínimo confortável para o polegar. Menos que isso vira um
	   botão que só o mouse acerta. */
	width: 48px;

	display: flex;
	align-items: center;
	justify-content: center;

	padding: 0;
	border: none;
	background: transparent;
	cursor: pointer;
	color: var(--cor_de_texto_suave);
	transition: color 0.2s ease;

	/* O campo tem cantos arredondados; o botão encostado na borda precisa
	   acompanhar, senão aparece um quadrado sobrando na quina. */
	border-radius: 0 var(--raio_de_canto_de_campo) var(--raio_de_canto_de_campo) 0;
}

.botao_de_mostrar_senha:hover {
	color: var(--cor_de_texto_principal);
}

/* O foco por teclado precisa aparecer: quem navega por Tab não tem cursor para
   saber onde está. */
.botao_de_mostrar_senha:focus-visible {
	outline: 2px solid var(--cor_de_conversao);
	outline-offset: -2px;
}

.botao_de_mostrar_senha svg {
	width: 22px;
	height: 22px;
	display: block;
	pointer-events: none; /* O clique é sempre do botão, nunca do desenho */
}

/* O desenho é um só: o olho aberto está sempre lá, e o que entra e sai é a barra
   cortando ele. Trocar a barra de visível para invisível é mais barato e mais
   estável do que trocar o ícone inteiro por outro. */
.botao_de_mostrar_senha .traco_de_olho_cortado {
	display: none;
}

.botao_de_mostrar_senha.estado_de_senha_visivel .traco_de_olho_cortado {
	display: block;
}

/* Alguns navegadores (Edge, Safari) desenham um olhinho PRÓPRIO dentro do campo
   de senha. Sem esta regra o cliente vê dois olhos lado a lado, e o do navegador
   não conversa com o nosso — clicar num deles deixa o outro mentindo sobre o
   estado do campo. */
.envoltoria_de_campo_de_senha input::-ms-reveal,
.envoltoria_de_campo_de_senha input::-ms-clear,
.envoltoria_de_campo_de_senha input::-webkit-textfield-decoration-container {
	display: none;
}

/* ==============================================================================
   5. A TORRADA DE AVISOS

   O recado curto que aparece no alto da tela e some sozinho. Subiu para a
   fundação porque estava escrito CINCO vezes no sistema: uma em cada uma das
   páginas /acesso, /cadastro e /oferta, cada qual com a sua cópia do CSS e da
   função que a acende, mais a versão da loja e o balão do estande.

   As três cópias soltas usavam nomes em kebab-case (.estilo-de-notificacao,
   .cor-de-sucesso), fora da convenção snake_case do projeto, e já tinham
   divergido no visual — a mesma mensagem de erro tinha uma aparência na loja e
   outra no login. Agora existe uma torrada só, e mudar o aviso do sistema é
   mudar um arquivo.

   NOTA: o balão do estande continua separado, com animação própria. Ele entra na
   revisão do PDV, que está anotada na lista de tarefas.
============================================================================== */

/* ==========================================================================
   O MOTOR DE TORRADAS (A TORRADEIRA)

   A torrada era UMA, centralizada, e mensagem nova substituía a anterior. Isso
   tinha uma razão boa, que continua valendo: apertar [ + ] no teto do estoque
   cinco vezes produz cinco vezes a mesma frase, e fazê-la sair e voltar a cada
   toque é "bonito uma vez e cansativo na terceira".

   Agora existe uma PILHA, e a regra ficou mais precisa: mensagem repetida
   continua não empilhando — reinicia o relógio e gesticula, como antes —, mas
   mensagem DIFERENTE ganha lugar próprio. No painel administrativo isso importa:
   "produto salvo" e "3 variações gravadas" são duas informações, e a segunda
   engolia a primeira antes de alguém ler.

   A CENTRALIZAÇÃO MUDOU DE DONO, e é a melhoria escondida daqui. Ela vive na
   pilha, e não em cada torrada. Antes, todo passo de todo keyframe precisava
   repetir `translate(-50%, 0)` junto com o gesto, porque `transform` é uma
   propriedade só e declarar apenas `scale()` apagava a centralização — a torrada
   pulava meia largura para a direita no meio da animação. Com o pai centralizando,
   os keyframes falam só do gesto.
   ========================================================================== */
.pilha_de_torradas {
	position: fixed;
	top: 20px;
	left: 50%;
	transform: translateX(-50%);

	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;

	width: max-content;
	max-width: min(92vw, 560px);

	/*
		ACIMA DE TUDO — E DESTA VEZ DE VERDADE.

		O 10010 de outrora ficava ABAIXO do fundo escurecido das janelas (10020) e
		do balão de pesos (10030), então toda torrada disparada com uma janela
		aberta nascia atrás da cortina escura: o aviso existia, estava na tela, e
		era invisível. Isso valia justamente para as mensagens que mais importam —
		as da gaveta de acesso, que só aparecem com a gaveta aberta.

		10050 passa por cima de todas as camadas do sistema e continua ABAIXO da
		cortina de carregamento (99999), que é a única coisa que deve mesmo cobrir
		a torrada: enquanto ela está de pé, a página está trocando debaixo dela.
	*/
	z-index: 10050;

	/* A PILHA NÃO INTERCEPTA CLIQUE, as torradas sim. Sem isto, a faixa
	   invisível do recipiente cobriria o topo da página inteira e engoliria
	   cliques em botões que estão logo abaixo dela. */
	pointer-events: none;
}

.torrada {
	padding: 14px 24px;
	border-radius: 8px;

	color: white;
	font-size: 15px;
	font-weight: bold;
	text-align: center;
	line-height: 1.4;

	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);

	/* Tocar na torrada a dispensa — daí o cursor e o retorno do ponteiro que a
	   pilha desligou. */
	pointer-events: auto;
	cursor: pointer;

	opacity: 0;
	transform: translateY(-14px);
	transition: opacity 0.3s ease, transform 0.3s ease;
}

.torrada.estado_visivel {
	opacity: 1;
	transform: translateY(0);
}

/* A SAÍDA SOBE, e não desce: a torrada nasce do topo da tela e volta para lá.
   Sair para baixo a faria atravessar o conteúdo da página no caminho. */
.torrada.estado_de_saida {
	opacity: 0;
	transform: translateY(-14px);
}

/* --- AS CORES DOS QUATRO TIPOS --- */

.torrada_de_sucesso { background-color: var(--cor_de_conversao); }
.torrada_de_erro { background-color: var(--cor_de_alerta); }
.torrada_de_aviso { background-color: var(--cor_de_atencao); }
.torrada_de_informacao { background-color: var(--cor_de_informacao); }

/* ==========================================================================
   OS GESTOS

   Quando a mensagem repetida chega, a torrada não sai para voltar: ela gesticula
   no lugar. O pulso confirma ("sim, de novo, registrado"), o chacoalhão recusa
   ("não, continua sendo não").
   ========================================================================== */
@keyframes pulso_de_torrada {
	0%   { scale: 1; }
	40%  { scale: 1.06; }
	100% { scale: 1; }
}

/* O NOME PERDEU O "DE_TORRADA" EM 2026-08-10, e o motivo é que ele ganhou um
   segundo inquilino: o bloco de engajamento chacoalha do mesmo jeito quando a
   resposta do enigma está errada (item 1.14b). A alternativa era um
   `@keyframes chacoalhao_de_bloco` com os mesmos seis passos e os mesmos nove
   pixels — a duplicação clássica que ninguém percebe, porque as duas cópias
   nascem idênticas e só divergem no dia em que alguém acha nove pixels demais.
   O gesto é da RECUSA, e não do componente que recusa. */
@keyframes chacoalhao_de_recusa {
	0%, 100% { translate: 0 0; }
	15%      { translate: -9px 0; }
	30%      { translate: 9px 0; }
	45%      { translate: -7px 0; }
	60%      { translate: 7px 0; }
	80%      { translate: -3px 0; }
}

/* `scale` e `translate` COMO PROPRIEDADES INDEPENDENTES, e não dentro de
   `transform`. É o que permite o gesto acontecer sem apagar o `translateY` da
   entrada, que vive no `transform` da própria torrada — as três convivem em vez
   de uma sobrescrever a outra. */
.torrada.gesto_de_pulso {
	animation: pulso_de_torrada 0.32s ease-out;
}

.torrada.gesto_de_chacoalhao {
	animation: chacoalhao_de_recusa 0.45s ease-in-out;
}

/*
	Quem pediu menos movimento ao sistema operacional continua recebendo a
	mensagem — o texto e a cor chegam igual. O que some é só a dança.
*/
@media (prefers-reduced-motion: reduce) {
	.torrada,
	.torrada.gesto_de_pulso,
	.torrada.gesto_de_chacoalhao {
		animation: none;
		transition: opacity 0.2s ease;
		transform: none;
	}
}

/* ==========================================================================
   AS CLASSES DE COR ANTIGAS

   Os 44 chamadores herdados passam nomes como `cor_de_fundo_de_sucesso`, e o
   motor de torradas os traduz para os tipos novos antes de desenhar. Estas
   regras continuam aqui porque outras telas as usam fora da torrada — o alerta
   de topo do cadastro, por exemplo.
   ========================================================================== */
.cor_de_fundo_de_sucesso { background-color: #28a745; }
.cor_de_fundo_de_alerta { background-color: var(--cor_de_atencao); }
.cor_de_fundo_de_carregamento { background-color: var(--cor_de_informacao); }
.cor_de_fundo_de_prova_social { background-color: var(--cor_de_alerta); }


/* O VERMELHO DE ERRO, QUE NÃO É O LARANJA DE ATENÇÃO.

   As páginas soltas chamavam de "alerta" o vermelho de erro; a loja chama de
   "alerta" o laranja de atenção. Unificar pelo nome teria pintado de laranja
   todo erro de login e de cadastro do sistema. São dois papéis diferentes e
   agora têm dois nomes diferentes: atenção avisa, erro interrompe. */
.cor_de_fundo_de_erro { background-color: var(--cor_de_alerta); }


/* ==============================================================================
   O LOGOTIPO DA MARCA

   Vive na fundação porque aparece em telas que não compartilham mais nada entre
   si: o cabeçalho da loja, a página de acesso, o cadastro, a área de membros e o
   recibo. Cada uma tem o seu CSS; o desenho da marca não pode depender de qual
   delas foi carregada.

   A ALTURA MANDA, A LARGURA OBEDECE. O arquivo é um SVG e não perde nitidez em
   tamanho nenhum, então basta dizer quanto ele deve ocupar na vertical — que é a
   medida escassa numa faixa de cabeçalho. `width: auto` deixa a proporção
   intacta; travar as duas dimensões é como se achata um logotipo sem perceber.

   O `<h1>` CONTINUA SENDO UM `<h1>`, com o nome da loja dentro do `alt` da
   imagem. Trocar o texto por uma figura sem esse cuidado apagaria da página o
   único lugar onde o nome do negócio aparece como texto — para o leitor de tela
   e para o buscador, a loja passaria a não ter nome.
============================================================================== */
.logotipo_de_marca {
	display: block;
	height: 58px;
	width: auto;
	margin: 0 auto;
}


/* ==============================================================================
   6. O ESTADO DE OCULTAÇÃO

   Mostrar e esconder era feito pelo JavaScript escrevendo `elemento.style.display`
   direto — 59 pontos espalhados por três motores — enquanto o estado inicial vinha
   de um `style="display: none"` escrito no HTML. A aparência morava em dois
   lugares e nenhum deles era o CSS: para saber por que um bloco não aparecia era
   preciso ler o JavaScript, e mudar a forma de exibir um elemento significava
   caçar todas as atribuições dele.

   Agora quem esconde é esta classe, e o display natural de cada elemento fica
   onde sempre deveria ter ficado: no CSS da tela dele, ou no padrão do próprio
   HTML.

   POR QUE ESTA REGRA TEM `!important`, num projeto que evita isso: ela precisa
   vencer o display que alguns elementos declaram legitimamente para si. O leitor
   de QR do estande, por exemplo, é `display: flex` no próprio atributo de estilo,
   porque é assim que ele centraliza o conteúdo — e uma classe de ocultação que
   perdesse para isso simplesmente não esconderia nada. Esconder é uma decisão de
   estado, e estado tem de vencer aparência.
============================================================================== */

.estado_oculto {
	display: none !important;
}


/* ==============================================================================
   7. A TRILHA DE BLOQUINHOS DE CÓDIGO

   UM QUADRADINHO POR DÍGITO, e não um campo único. A diferença não é enfeite: o
   campo único não diz quantos números o código tem, aceita um a mais sem avisar,
   e obriga a conferir contando caractere por caractere. Seis caixas dizem o
   tamanho antes da primeira tecla, mostram de longe quanto falta, e transformam
   a conferência contra o e-mail numa comparação de posições.

   POR QUE NA FUNDAÇÃO, e não na camada de componentes: até 2026-08-17 esta trilha
   só existia na gaveta de acesso, e morava no `componentes_compartilhados.css`
   junto com ela. As telas próprias de `/acesso/codigo` e `/acesso/trocar-senha`
   passaram a mostrar a mesma trilha — e elas não carregam aquele arquivo, que traz
   junto a janela flutuante, o carrossel de itens salvos e a cortina de
   recarregamento pós-login, nenhum dos quais aparece ali.

   É a mesma razão que trouxe para cá o campo de senha com olhinho e a torrada:
   componente pequeno, pedido por telas que não compartilham mais nada entre si.
   Criar um terceiro arquivo de CSS para ele custaria um `<link>` a mais em toda
   página que hoje se basta — sem bundler, unificar não apaga cópia, cria pedido.

   ⚠️ OS NOMES NÃO DIZEM "RECUPERAÇÃO", e isso é decisão: a mesma trilha serve ao
   código de seis números da recuperação e ao de quatro do OTP de entrada. Quem
   desenha o comportamento — digitar avança, apagar retrocede, colar se espalha,
   setas andam — é o `bloquinhos_de_codigo.js`, que também não sabe de qual fluxo
   veio a trilha que recebeu.

   O PREFIXO NÃO ESTÁ NA LINHA DOS DÍGITOS, e é texto de apoio à esquerda. Como
   selo colado ao campo ele parecia a primeira casa a preencher — e não é: ele
   não se digita, só se confere.

   O PONTO ENTRE O TERCEIRO E O QUARTO é um pedaço de texto, não uma borda nem um
   pseudo-elemento. Quebrar seis dígitos em dois grupos de três é o que permite
   ler o código de uma vez em vez de soletrá-lo, e o separador precisa ser
   simples o bastante para nunca virar um alvo de toque por engano.
   ============================================================================== */

.bloco_de_codigo_com_prefixo {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	margin-top: 4px;
}

.texto_de_prefixo_de_codigo {
	font-size: 20px;
	font-weight: 700;
	letter-spacing: 2px;
	color: var(--cor_de_texto_suave);
	white-space: nowrap;

	/* Não é campo: não recebe cursor, seleção nem toque. */
	user-select: none;
	pointer-events: none;
}

.trilha_de_bloquinhos_de_codigo {
	display: flex;
	align-items: center;
	gap: 6px;
}

.separador_de_bloquinhos_de_codigo {
	font-size: 22px;
	font-weight: 700;
	color: var(--cor_de_texto_suave);
	padding: 0 2px;
	user-select: none;
	pointer-events: none;
}

/* A borda quase branca: ela desenha a caixa sem competir com o número que vai
   dentro dela. O contorno só ganha peso quando o dedo chega — é o foco que
   precisa gritar, não o repouso. */
.bloquinho_de_codigo {
	width: 42px;
	height: 52px;
	padding: 0;

	font-size: 22px;
	font-weight: 700;
	text-align: center;

	border: 1px solid #f0f1f3;
	border-radius: 8px;
	outline: none;
	background-color: var(--cor_de_superficie);
	color: var(--cor_de_texto_principal);
	box-sizing: border-box;

	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.bloquinho_de_codigo:focus {
	border-color: var(--cor_de_conversao);
	box-shadow: 0 0 0 3px rgba(39, 174, 96, 0.15);
}

/* Preenchido, o quadradinho ganha um contorno um pouco mais firme: é o que
   permite ver, de relance, até onde se chegou. */
.bloquinho_de_codigo.estado_de_bloquinho_preenchido {
	border-color: var(--cor_de_borda_suave);
}

/* As setinhas que alguns navegadores desenham em campos numéricos não têm o que
   fazer aqui: elas só oferecem a chance de somar um ao dígito por engano. */
.bloquinho_de_codigo::-webkit-outer-spin-button,
.bloquinho_de_codigo::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.bloquinho_de_codigo[type="number"] {
	-moz-appearance: textfield;
	appearance: textfield;
}

/* Em telas estreitas os seis quadradinhos, o prefixo e o ponto não cabem lado a
   lado. O prefixo desce para uma linha própria — ele é referência, não parte da
   digitação — e as caixas encolhem o suficiente para caberem inteiras. */
@media (max-width: 420px) {
	.bloco_de_codigo_com_prefixo {
		flex-direction: column;
		gap: 6px;
	}

	.bloquinho_de_codigo {
		width: 38px;
		height: 48px;
		font-size: 20px;
	}
}


/* ==============================================================================
   8. A ALTURA QUE MUDA SEM TRANCO

   A classe que o `altura_fluida.js` acende enquanto interpola os dois números. Ela
   veio do `componentes_compartilhados.css` em 2026-08-17, pela mesma razão que
   trouxe a trilha de bloquinhos para cá: a página `/acesso` passou a trocar de
   passo dentro da própria caixa, com o mesmo gesto da gaveta, e não carrega aquele
   arquivo.

   O `overflow: hidden` é `!important` porque o recipiente pode ter overflow próprio
   declarado com mais especificidade — e durante a interpolação o conteúdo precisa
   ser recortado, senão ele transborda da altura travada em vez de acompanhá-la.

   ⚠️ E O TEMPO É PARTE DO CONTRATO, não decoração: 0,42s com esta curva é como a
   lista do carrinho, a gaveta de acesso e a tela de acesso se movem. Mudar aqui
   muda as três de uma vez, que é exatamente o que se quer.
   ============================================================================== */

.recipiente_de_lista_em_transicao_de_altura {
	transition: height 0.42s cubic-bezier(0.22, 0.8, 0.28, 1);
	overflow: hidden !important;
}

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