/* =============================================================
   SOPPHUS — casca de navegação
   Reaproveita os tokens de sopphus.css (cores, tipos, espaço,
   raio, alturas --topo-h/--nav-h). NÃO redefinir tokens aqui.

   Celular: barra inferior FIXA com 4 destinos.
   >= 768px: a barra some e vira sidebar à esquerda.
   Painel inicial: GRADE DE CARDS por módulo — decisão do usuário.
============================================================= */

/* ---------- Cor por ÁREA ----------
   O roteador (shell.js/irPara) escreve data-area no <html>; este bloco troca
   DOIS tokens — --cor-area e o tint --cor-area-fundo — e então o título do topo,
   o quadradinho do ícone, o foco, o campo em foco e o item ativo da barra falam
   a mesma cor. Aponta para os MESMOS aliases --aba-* que a barra inferior
   consome: topo e rodapé não podem dessincronizar.

   Contrastes do título 18px/600 sobre o topo branco (mínimo 4,5:1):
   Início 6,46:1 · Precificar 5,41:1 · Financeiro 7,57:1 · Relatórios 8,72:1.
   As duas primeiras SÃO o rosa e o dourado da marca levados a texto. */
/* TRÊS destinos desde 14-09-26. As cores NÃO mudaram de valor — mudaram de
   dono, e cada uma herdou a do destino que absorveu, para quem já usava o app
   não ter de reaprender a paleta:
     dashboard ← Início     (--aba-inicio)
     producao  ← Precificar (--aba-precificar)   o dourado da marca
     caixa     ← Financeiro (--aba-financeiro)
   As chaves antigas continuam listadas porque o roteador reencaminha por hash:
   entre o clique no link velho e a troca do data-area há um quadro em que o
   valor antigo ainda está no <html>, e sem a regra ele piscaria sem cor. */
:root[data-area="dashboard"]  { --cor-area: var(--aba-inicio);     --cor-area-fundo: var(--aba-inicio-fundo); }
:root[data-area="producao"]   { --cor-area: var(--aba-precificar); --cor-area-fundo: var(--aba-precificar-fundo); }
:root[data-area="caixa"]      { --cor-area: var(--aba-financeiro); --cor-area-fundo: var(--aba-financeiro-fundo); }
:root[data-area="inicio"]     { --cor-area: var(--aba-inicio);     --cor-area-fundo: var(--aba-inicio-fundo); }
:root[data-area="precificar"] { --cor-area: var(--aba-precificar); --cor-area-fundo: var(--aba-precificar-fundo); }
:root[data-area="financeiro"] { --cor-area: var(--aba-financeiro); --cor-area-fundo: var(--aba-financeiro-fundo); }
:root[data-area="relatorios"] { --cor-area: var(--aba-relatorios); --cor-area-fundo: var(--aba-relatorios-fundo); }
:root[data-area="cadastros"]  { --cor-area: var(--aba-cadastros);  --cor-area-fundo: var(--aba-cadastros-fundo); }
/* PEDIDOS virou destino de barra em 15-09-26 e por isso ganhou cor própria: a
   quinta família (#0E7490), a mesma que o ícone dele acende na navegação. O
   título do topo e o ícone da barra TÊM de falar a mesma cor — é esse par que
   faz o cabeçalho e a navegação conversarem, e foi para isso que o data-area
   existe. */
:root[data-area="pedidos"]    { --cor-area: var(--aba-cadastros);  --cor-area-fundo: var(--aba-cadastros-fundo); }
/* Conta e Vitrine não são destino de barra: ficam no rosa da marca — o neutro
   do app agora é a cor da casa, não um cinza. */
:root[data-area="conta"]      { --cor-area: var(--rosa-texto); --cor-area-fundo: var(--rosa-fundo); }
:root[data-area="vitrine"]    { --cor-area: var(--rosa-texto); --cor-area-fundo: var(--rosa-fundo); }

/* ---------- Casca ---------- */
.app-shell {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.app-topo {
  position: sticky;
  top: 0;
  z-index: 20;
  /* Translúcido com desfoque: o conteúdo passa POR BAIXO do topo em vez de
     sumir atrás de uma barra opaca — dá profundidade sem custar altura.
     `color-mix` degrada para o cartão sólido em navegador que não a tem. */
  /* Mesma correção da barra inferior: 82% deixava o conteúdo legível através
     do topo enquanto a página rolava. 94% mantém a profundidade sem o vazamento. */
  background: var(--card);
  background: color-mix(in srgb, var(--card) 94%, transparent);
  backdrop-filter: saturate(160%) blur(20px);
  -webkit-backdrop-filter: saturate(160%) blur(20px);
  border-bottom: var(--fio);
  min-height: var(--topo-h);
  /* GRID de três colunas, não flex — 05-08-26, pedido do usuário:
     "logo no meio, tela atual na esquerda".
     `1fr auto 1fr` é o que põe o símbolo no centro ÓPTICO da barra: as duas
     colunas laterais recebem a MESMA largura, então o meio cai no meio da tela
     independentemente de o título ser "Início" ou "Relatórios". Com flexbox o
     símbolo cairia no meio do espaço que sobra, deslocando a cada troca de
     área — que é justamente o que se quer evitar num elemento fixo. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--esp-2);
  padding: 0 var(--esp-4);
}
.app-topo .titulo-area {
  font-size: var(--tam-titulo);
  font-weight: var(--peso-forte);
  letter-spacing: -0.01em;
  line-height: var(--ent-titulo);
  color: var(--cor-area);          /* a cor da aba sobe do rodapé para o topo */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* as ações se agrupam à direita da terceira coluna */
.app-topo-acoes {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--esp-2);
  min-width: 0;
}

/* =============================================================
   SINO DE AVISOS — os alertas saíram da primeira dobra do Início

   Antes eles abriam a tela inicial: com quatro contas vencidas, o saldo do mês
   e os atalhos nasciam abaixo da linha d'água todo dia. E não existiam em
   nenhuma outra tela. Aqui alcançam o app inteiro sem empurrar conteúdo.

   O botão só aparece quando há aviso (`.sino[hidden]` some) — sino
   permanentemente vazio ensina a ignorar o sino.
============================================================= */
.sino { position: relative; }
.sino[hidden] { display: none; }

/* O atalho de EDITAR O CARDÁPIO, nas mesmas ferramentas do topo. Sem selo: não
   é fila, é um caminho — e um `hidden` no HTML precisa de `display: none` aqui
   porque `.btn-topo` declara `display: grid`, que vence o atributo. */
#atalho-cardapio[hidden] { display: none; }

.sino-contador {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  border-radius: var(--raio-pilula);
  background: var(--warning);
  color: var(--card);
  font-size: 11px;          /* exceção: selo numérico, não texto de leitura */
  font-weight: var(--peso-forte);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  /* anel na cor do topo separa o selo do ícone por baixo dele */
  box-shadow: 0 0 0 2px var(--card);
}
/* Tem urgente na lista? o selo vai para o vermelho. A cor NÃO carrega o
   sentido sozinha: o número diz quantos, e cada linha do painel traz ícone
   próprio e o prazo escrito ("venceu há 5 dias"). */
.sino[data-nivel="urgente"] .sino-contador { background: var(--danger); }

/* FIXED, e não absolute. Ancorado ao sino, o painel se alinhava à direita DELE
   — e o sino fica a ~120px da borda (tema e conta vêm depois). Com 343px de
   largura, ele vazava 88px para fora da janela num celular de 375.
   Preso à viewport, ele encosta na margem da tela e cabe sempre.
   O topo é sticky e não cria contexto de posicionamento, então `fixed` aqui
   se ancora à janela como se espera. */
.painel-avisos {
  transform-origin: top right;
  position: fixed;
  top: calc(var(--topo-h) + var(--esp-2) + env(safe-area-inset-top));
  right: var(--esp-4);
  z-index: 45;
  width: min(360px, calc(100vw - var(--esp-4) * 2));
  max-height: min(70dvh, 480px);
  overflow-y: auto;
  padding: var(--esp-4);
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-modal);
  animation: painel-abre var(--dur-curta) var(--curva);
}
.painel-avisos[hidden] { display: none; }
/* O painel nasce sob o sino, no canto superior DIREITO: a origem tem de ser
   esse canto, senão ele parece brotar do meio da tela. */
@keyframes painel-abre {
  from { opacity: 0; transform: translateY(-6px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
.painel-avisos-cab {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  margin-bottom: var(--esp-4);
}
.painel-avisos-cab h2 {
  font-size: var(--tam-titulo);
  font-weight: var(--peso-forte);
  line-height: var(--ent-titulo);
  flex: 1;
}
.painel-avisos-limpar {
  background: none;
  border: 0;
  padding: var(--esp-2);
  margin: calc(-1 * var(--esp-2));
  min-height: var(--alvo-toque);
  color: var(--cor-area);
  font-size: var(--tam-apoio);
  cursor: pointer;
}
/* dentro do painel os alertas não precisam de sombra: o painel já flutua */
.painel-avisos .alerta { box-shadow: none; }

/* ---------- O símbolo da marca ----------
   No celular o topo mostra o SÍMBOLO, não o nome escrito: com título de área,
   botão de tema e atalho de conta na mesma linha, "SOPPHUS" por extenso em
   tracking 0,14em consumia ~110px dos 375 e espremia os três. O nome por
   extenso continua na sidebar (desktop) e na tela de entrada. */
/* O símbolo é a ARTE ORIGINAL do usuário (img/sopphus-icone.png): o "S" rosa com
   as barras douradas, recortado do PNG que ele mandou e com o fundo branco
   trocado por transparência. Não leva raio nem fundo — é o desenho solto, e é
   por ser transparente que ele funciona igual no tema claro e no escuro. */
.marca-simbolo {
  display: block;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}
.marca-simbolo.grande { width: 88px; height: 88px; }

/* O símbolo do topo é um link para o Início — no celular ele é o "botão home"
   que a barra de baixo também oferece; no desktop a sidebar já cumpre o papel
   e ele sai (a marca por extenso está lá). */
.marca-link {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  min-height: var(--alvo-toque);
  /* sem padding lateral: ele está na coluna do MEIO do grid do topo, e qualquer
     padding assimétrico o tiraria do centro exato (media 2px fora do eixo) */
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.marca-nome {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  letter-spacing: 0.14em;   /* exceção documentada: o tracking largo é da marca */
  color: var(--text);
  white-space: nowrap;
}

/* ---------- Botões redondos do topo (tema, conta) ---------- */
.btn-topo {
  display: grid;
  place-items: center;
  width: var(--alvo-toque);
  height: var(--alvo-toque);
  flex-shrink: 0;
  border: var(--fio);
  border-radius: var(--raio-pilula);
  background: var(--card);
  color: var(--text-light);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--dur-curta) var(--curva-cor),
              border-color var(--dur-curta) var(--curva-cor);
}
.btn-topo svg { width: 19px; height: 19px; }
/* Um ícone por tema, trocados pelo CSS: o JS só escreve data-tema no <html> e
   não precisa saber desenhar sol nem lua. */
.btn-topo .icone-lua { display: none; }
:root[data-tema="escuro"] .btn-topo .icone-sol { display: none; }
:root[data-tema="escuro"] .btn-topo .icone-lua { display: block; }

.app-area {
  flex: 1;
  /* A safe-area entra na conta: a barra a soma ao próprio padding, então
     reservar só `--nav-h` deixaria o fim do conteúdo atrás dela no iPhone. */
  padding: var(--esp-4) var(--esp-4)
           calc(var(--nav-h) + env(safe-area-inset-bottom) + var(--esp-5));
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}

/* A troca de área NÃO tem transição, e isso é escolhido. A auditoria de
   05-08-26 já listava "troca de aba sem animação" entre os acertos: é a ação
   mais repetida do app, e o que se usa o dia inteiro tem de responder no mesmo
   quadro. Uma entrada com fade chegou a existir em 05-08-26 e saiu no mesmo
   dia — o dono do produto pediu prioridade para performance.
   Se um dia voltar: só a ENTRADA deve ser animada. Animar a saída também
   dobraria o tempo de cada troca, que é o que torna o recurso cansativo. */

/* ---------- Precificar: o quadro é FULL-BLEED ----------
   A tela de precificação é o index.html carregado num <iframe>, e ele já tem o
   próprio padding e o próprio fundo. Herdando também o padding da .app-area,
   virava caixa dentro de caixa: sobrava um vão nas laterais e um canto
   arredondado de 10px (fora da escala) boiando no meio da tela.
   Aqui a área perde o padding e o quadro ocupa a largura inteira. */
:root[data-area="precificar"] .app-area {
  padding: 0;
  max-width: none;
}
.quadro-precificar {
  display: block;      /* iframe é inline por padrão e ganharia 4px de baseline */
  width: 100%;
  border: 0;
  /* Da base do topo até em cima da barra de navegação. A safe-area entra na
     conta porque a barra já a soma no próprio padding — sem isto o rodapé do
     quadro fica atrás da barra de gestos do iPhone. */
  height: calc(100dvh - var(--topo-h) - var(--nav-h) - env(safe-area-inset-bottom));
}
/* Com a barra de sub-abas acima dele (Produção · Receitas), o quadro precisa
   devolver a altura dela — senão passa da tela e cria uma SEGUNDA barra de
   rolagem, uma dentro da outra, que é a pior sensação possível num celular.

   `--desconto-quadro` é MEDIDO pelo JS (`medirAlturaDasAbas`, em shell.js) logo
   depois de a barra existir, e traz TUDO que fica fora do quadro: cabeçalho,
   respiro da área, barra de abas e o rodapé reservado à navegação de baixo.

   Aqui já houve três números cravados — 64px quando a aba era pílula, 102 e 128
   quando virou botão — e os três ficaram errados no dia seguinte, porque a
   altura depende do padding, do tamanho da fonte E de a aba ter ou não contador.
   Pior: a conta antiga descontava `--nav-h` (64px) enquanto o respiro de baixo
   da área é 88px, então sobrava 40px e a ficha SEMPRE abriu com duas barras de
   rolagem, uma dentro da outra. Medir acerta os dois.
   O fallback só vale para a primeira pintura, antes de a medida existir. */
.quadro-precificar.com-abas {
  height: calc(100dvh - var(--desconto-quadro, 302px));
}

/* =============================================================
   NAVEGAÇÃO INFERIOR — 62px + safe-area, sem sombra (fio basta)
============================================================= */
/* QUATRO destinos desde 15-09-26 (Dashboard · Produção · Financeiro · Pedidos).
   Foram 5 até 13-09-26, caíram para 3 em 14-09-26 e Pedidos voltou à barra a
   pedido do dono — fila de pedido é trabalho do dia, não tela de apoio.
   A conta de espaço continua folgada:
     · 375px / 4 = 93px por item (eram 125 com três, e 75 com cinco)
     · o maior rótulo, "Dashboard", ocupa 68px em 13px de fonte: cabe inteiro
     · num iPhone SE de 320px sobram 80px por item, ainda acima dos 68
   O ellipsis fica como rede, para fonte aumentada no sistema operacional. */
.nav-inferior {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: grid;
  /* CINCO desde 16-09-26, com o Mais (spec inicio-mais-tour, Parte 4). Em 375px
     cada item tem 75px, e o maior rotulo, Dashboard, ocupa 68px. */
  grid-template-columns: repeat(5, 1fr);
  /* SÓLIDA. Sem color-mix, sem backdrop-filter.
     A barra sempre esteve encostada no rodapé — medido: base = altura exata da
     janela, sobra 0px. O que o usuário via era o conteúdo ATRAVÉS dela.
     Tentei 88% e depois 96% de opacidade: mesmo a 4% de transparência, texto
     escuro rolando por baixo continua aparecendo como um fantasma cinza, e o
     `backdrop-filter` não salva — quando ele não é suportado (ou está desligado
     por economia de bateria), sobra a translucidez pura.
     Sobre a barra que o polegar usa e o olho consulta o tempo todo, legibilidade
     ganha de efeito de vidro. O topo mantém o vidro: lá o conteúdo passando por
     baixo é o próprio conteúdo da tela, e não atrapalha a leitura de 5 rótulos. */
  background: var(--card);
  border-top: var(--fio);
  /* Trava a altura no token: se o conteúdo crescer, a fresta volta. */
  min-height: var(--nav-h);
  /* barra de gestos do iPhone: sem isto, o último item fica embaixo dela.
     ATENÇÃO: isto SOMA à altura do token — quem reserva espaço tem de contar
     `--nav-h + env(safe-area-inset-bottom)`, nunca só o token. */
  padding-bottom: env(safe-area-inset-bottom);
}

.nav-item {
  position: relative;
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: var(--esp-2) 2px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--text-light);
  text-decoration: none;
  font-size: var(--tam-apoio);
  line-height: 1.2;
  font-weight: var(--peso-normal);
  -webkit-tap-highlight-color: transparent;
  min-width: 0;
}
/* O rótulo continua em 13px — a escala do sistema, sem exceção.
   Cheguei a reduzi-lo para 11px achando que 5 itens não caberiam, e a MEDIÇÃO
   desmentiu: o maior rótulo ("Financeiro") ocupa 58px em 13px, contra 60px
   úteis já num iPhone SE de 320px, e 71px num 375. Não havia problema a
   resolver, então a exceção saiu.
   O ellipsis fica como rede: cobre fonte aumentada no sistema operacional e
   qualquer destino de nome mais longo que venha depois. */
.nav-inferior .nav-item > span:last-child {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* O ícone mora numa pílula: no item inativo ela é transparente, no ativo ela
   acende com o tint da aba. Trocar a barrinha de 3px por isto foi decisão de
   05-08-26 — a barrinha ficava no limite superior do item, longe do polegar e
   do olho, enquanto a pílula acende exatamente onde o dedo tocou.
   Continuam TRÊS sinais de estado: cor + peso do rótulo + a pílula. */
/* A pílula tintada do item ativo saiu junto com os quadradinhos (05-08-26):
   era o mesmo recurso — bloco de cor atrás do ícone. O estado ativo continua
   com TRÊS sinais, só que outros: cor do ícone + peso do rótulo + o pontinho
   abaixo (ver `.nav-item[aria-current]::after`). */
.nav-item .nav-icone {
  display: grid;
  place-items: center;
  height: 26px;
  /* âncora do selo de contagem (Pedidos). No ícone e não no item inteiro:
     na sidebar o item é uma linha larga, e o selo preso a ela iria parar no
     meio do rótulo. */
  position: relative;
}

/* PEDIDOS A PREPARAR — a contagem no próprio destino.
   Rosa da marca, e não o âmbar do sino ao lado: pedido esperando é TRABALHO,
   não alerta. Some quando a fila zera — selo permanentemente em 0 ensina a
   ignorar o selo, mesma regra que já vale para o sino. */
.nav-contador {
  position: absolute;
  top: -5px;
  left: 13px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  border-radius: var(--raio-pilula);
  background: var(--rosa-texto);
  color: var(--card);
  font-size: 10px;          /* exceção: selo numérico, não texto de leitura */
  font-weight: var(--peso-forte);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  /* o selo não pode herdar a cor da aba nem o peso do rótulo ativo */
  box-shadow: 0 0 0 2px var(--card);
}
.nav-contador:empty { display: none; }
.nav-item svg {
  width: 23px;
  height: 23px;
  flex-shrink: 0;
  stroke-width: 1.5;   /* o traço fino da nova linguagem de ícone */
}

/* Item ativo: cor E peso E pontinho — nunca só cor.
   O pontinho substituiu a pílula tintada: diz a mesma coisa com uma fração da
   tinta, e é o que iOS usa há anos justamente por não competir com o ícone. */
.nav-item[aria-current="page"] {
  color: var(--text);
  font-weight: var(--peso-forte);
}
.nav-item[aria-current="page"]::after {
  content: "";
  position: absolute;
  bottom: 6px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
}
.nav-item:active .nav-icone { opacity: 0.6; }

/* ---------- Cor por aba (memória cromática) ----------
   ESCOPADO em .nav-inferior de propósito: .nav-item e data-destino são
   compartilhados com a sidebar e com o admin — solto, o seletor vazaria.
   A cor identifica a ABA; o ESTADO é peso 600 + pílula acesa (cor nunca é o
   único sinal). O rótulo INATIVO fica neutro --text-light (5,72:1): só o
   ícone carrega a cor — é o que evita a "festa" de quatro cores acesas.
   O anel de :focus-visible NÃO muda: permanece o global de sopphus.css.

   Contrastes do ícone sobre o cartão branco (mínimo de traço é 3:1) e do
   rótulo ativo em 13px (mínimo 4,5:1) — os mesmos quatro números do topo:
   6,46 · 5,41 · 7,57 · 8,72:1. */
.nav-inferior .nav-item[data-destino="dashboard"] {
  --cor-aba: var(--aba-inicio);
  --cor-aba-fundo: var(--aba-inicio-fundo);
}
.nav-inferior .nav-item[data-destino="producao"] {
  --cor-aba: var(--aba-precificar);
  --cor-aba-fundo: var(--aba-precificar-fundo);
}
.nav-inferior .nav-item[data-destino="caixa"] {
  --cor-aba: var(--aba-financeiro);
  --cor-aba-fundo: var(--aba-financeiro-fundo);
}
/* A QUINTA família, que nasceu em 05-08-26 justamente para um quinto destino de
   barra e estava sem uso desde que a barra encolheu. #0E7490 dá 5,36:1 no
   branco e separação mínima 10,3 contra as outras quatro E contra o vermelho de
   erro, medida sob protanopia, deuteranopia e tritanopia — é a cor certa aqui
   pelo mesmo motivo pelo qual foi escolhida. */
.nav-inferior .nav-item[data-destino="pedidos"] {
  --cor-aba: var(--aba-cadastros);
  --cor-aba-fundo: var(--aba-cadastros-fundo);
}
/* inativo: SÓ o ícone leva cor */
.nav-inferior .nav-item svg { color: var(--cor-aba, currentColor); }
/* ativo: rótulo na cor da aba + peso 600 + pílula acesa no tint da aba */
.nav-inferior .nav-item[aria-current="page"] { color: var(--cor-aba, var(--text)); }
/* (a pílula tintada do ativo saiu em 05-08-26 — quem marca o estado agora é o
   pontinho do ::after, mais o peso do rótulo e a cor do ícone) */
.nav-inferior .nav-item[aria-current="page"] svg { color: var(--cor-aba, currentColor); }

/* Sidebar só existe no desktop */
.nav-lateral { display: none; }

/* =============================================================
   INÍCIO — saudação, cartões de resumo 2×2 e grade de módulos
============================================================= */
/* A saudação é o único texto de 28px fora de um número. Ela dá o "alto" da
   página: sem ela, a tela começava em 18px e parecia continuar de outra. */
.saudacao {
  margin-bottom: var(--esp-5);
  display: flex;
  align-items: center;
  gap: var(--esp-3);
}
.saudacao-texto { min-width: 0; flex: 1; }
.saudacao h1,
.saudacao .saudacao-titulo {
  font-size: var(--tam-resposta);
  font-weight: var(--peso-forte);
  line-height: 1.2;
  letter-spacing: var(--track-heroi);
}
.saudacao p {
  color: var(--text-light);
  font-size: var(--tam-apoio);
  margin-top: 2px;
}

/* -------------------------------------------------------------
   CARTÕES DE RESUMO — a grade 2×2 do topo

   Um por pergunta que se responde com UM número. Cada um leva:
   quadradinho tintado com o ícone · selo de tendência · número · rótulo.
   O número vem antes do rótulo na LEITURA (fonte maior, peso forte), mas
   o rótulo fica embaixo — quem varre a tela pega os quatro números de
   uma vez e só desce ao rótulo do que interessou.
------------------------------------------------------------- */
/* VALOR EM DINHEIRO OCUPA A LINHA INTEIRA no celular — 05-08-26.

   A conta não fecha de outro jeito, e vale registrar porque parece detalhe:
   num card 2×2 de 375px sobram 116px úteis. "R$ 3.240,00" em 28px precisa de
   143px na fonte do texto e 174px na mono. Ou seja, **já não cabia antes** da
   mono entrar — vinha quebrando em duas linhas, e o `overflow-wrap: anywhere`
   escondia o problema partindo o valor no meio.

   Reduzir a fonte até caber exigiria 17px: menor que o corpo do texto, o que
   mata a ideia de valor-herói. Então quem cede é a GRADE, não a tipografia.
   Dinheiro na linha inteira (295px úteis), contagens continuam lado a lado —
   e isso é melhor hierarquia de qualquer forma: o saldo importa mais que
   "12 produtos". A partir de 560px cabem os dois por linha e tudo volta ao 2×2. */
.grade-resumo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--esp-2);   /* dentro do agrupamento os cartões ficam PRÓXIMOS: é o
                          que os faz ler como um bloco só, e não como quatro */
  margin-bottom: 0;    /* quem dá o respiro agora é o .agrupamento */
}
.card-resumo[data-largo="sim"] { grid-column: 1 / -1; }
@media (min-width: 560px) {
  .card-resumo[data-largo="sim"] { grid-column: auto; }
}
.card-resumo {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  min-width: 0;
  padding: var(--esp-5);
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  color: inherit;
  text-decoration: none;
  transition: box-shadow var(--dur-curta) var(--curva),
              border-color var(--dur-curta) var(--curva-cor),
              transform var(--dur-curta) var(--curva);
}
a.card-resumo:active { transform: scale(0.97); background: var(--superficie-2); }
.card-resumo-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-2);
}
.card-resumo .valor {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-resposta);
  font-weight: var(--peso-forte);
  line-height: 1.15;
  font-variant-numeric: proportional-nums;
  overflow-wrap: anywhere;
}
/* valor longo (R$ 12.480,00) não pode empurrar a coluna vizinha nem quebrar
   em três linhas: abaixo de 360px o herói cede 4px */
@media (max-width: 359px) {
  .card-resumo .valor { font-size: 24px; }
}
.card-resumo .rotulo {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  line-height: var(--ent-apoio);
  letter-spacing: var(--track-apoio);
}

/* =============================================================
   AGRUPAMENTO — o segundo nível de superfície

   Métricas e atalhos passam a viver DENTRO de uma seção com fundo próprio,
   em vez de flutuarem soltos sobre a página. É isso que faz quatro cartões
   iguais lerem como UM bloco ("os indicadores") em vez de quatro coisas
   disputando atenção.

   O fundo é `--superficie`: um degrau acima da página, um abaixo do cartão.
   A escada inteira — página, agrupamento, cartão, cartão importante — é o que
   dá direção visual sem usar uma cor nova sequer.
============================================================= */
.agrupamento {
  background: var(--superficie);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  padding: var(--esp-4);
  margin-bottom: var(--esp-4);
}
/* dentro do agrupamento os cartões não repetem a sombra: o bloco já os agrupa,
   e sombra em cima de sombra é a redundância que deixou a tela pesada antes */
.agrupamento .card-resumo,
.agrupamento .card-modulo { box-shadow: none; }

/* Título que separa blocos dentro de uma área ("Atalhos"). Dentro de um
   agrupamento ele vira o rótulo do bloco, então cola no topo dele. */
.titulo-secao {
  font-size: var(--tam-apoio);
  font-weight: var(--peso-forte);
  color: var(--text-light);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 var(--esp-3);
}
.agrupamento > .titulo-secao:first-child { margin-top: 0; }

/* TRÊS colunas em toda largura — pedido do usuário em 05-08-26, "3 e 3".
   São 6 atalhos, então a grade fecha em duas fileiras iguais em qualquer tela.
   Antes eram 2 no celular e 4 a partir de 1100px, o que dava 3+3, 3+3 e 4+2:
   o bloco mudava de forma conforme a largura e a última fileira ficava manca.
   O número de colunas passou a ser do CONTEÚDO (são seis), não da tela. */
.grade-modulos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--esp-2);   /* compacto: dentro do agrupamento eles são UM bloco */
}

.card-modulo {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  min-height: 132px;
  /* 12px no celular, EXCEÇÃO ao respiro de 24px que os cartões ganharam em
     05-08-26. O motivo é aritmético, não estético: com 3 colunas o cartão mede
     109px num aparelho de 375, e 24+24 de padding comiam 44% dele — sobravam
     61px úteis, com "Contas a pagar" quebrando em duas linhas e o cartão indo a
     204px de altura (medido). O respiro de 24px foi calibrado para cartão
     largo; aqui ele trabalha contra o próprio texto que deveria soltar.

     É PROPRIEDADE e não valor solto porque o chevron ancora no mesmo respiro:
     escritos separados, um dia mudam separados e o ícone descola do texto. */
  --respiro-card: var(--esp-3);
  padding: var(--respiro-card);
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  color: inherit;
  transition: transform var(--dur-curta) var(--curva),
              box-shadow var(--dur-curta) var(--curva),
              border-color var(--dur-curta) var(--curva-cor);
}
.card-modulo:active { background: var(--superficie-2); transform: scale(0.97); }

/* afordância de navegação: o chevron do markup ancora no canto, no MESMO
   respiro do conteúdo (ver --respiro-card) */
.card-modulo .chevron {
  position: absolute;
  top: var(--respiro-card);
  right: var(--respiro-card);
}

/* O ícone agora mora no quadradinho tintado (.icone-caixa). O bloco abaixo
   sobrevive para markup antigo que ainda passe .icone sem a caixa. */
.card-modulo .icone {
  width: auto;
  height: auto;
  background: none;
  border: 0;
  display: block;
  color: var(--cor-area);
}
.card-modulo .icone svg { width: 20px; height: 20px; }
.card-modulo .nome {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-normal);
  letter-spacing: -0.01em;
}
.card-modulo .resumo {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  margin-top: auto;
  font-variant-numeric: tabular-nums;
}

/* Card "em breve": desabilitado de verdade, sem chevron */
.card-modulo[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.58;
  background: var(--superficie-2);
  box-shadow: none;
}
.card-modulo[aria-disabled="true"]:active { transform: none; background: var(--superficie-2); }

/* "Em breve" COM resumo (Vitrine, 05-08-26). O selo sozinho diz que a área não
   existe ainda, mas não diz o que ela vai ser — e "Vitrine" é nome novo no app,
   ninguém adivinha. Quem empurra o bloco para o rodapé passa a ser o resumo;
   o selo o segue no gap normal, senão as duas margens `auto` disputam a folga
   e abrem um vão entre os dois. */
.card-modulo[aria-disabled="true"] .selo { margin-top: 0; }

.selo {
  align-self: flex-start;
  font-size: var(--tam-apoio);
  font-weight: var(--peso-normal);
  color: var(--text-light);
  background: var(--card);
  border: var(--fio);
  border-radius: var(--raio-pilula);
  padding: 0 var(--esp-2);
  margin-top: auto;
}

/* =============================================================
   Faixa de aviso ("Ambiente local") — discreta, último bloco da
   tela, nunca fixa, nunca acima do conteúdo (ordem é do HTML)
============================================================= */
.faixa-aviso {
  display: flex;
  gap: var(--esp-2);
  align-items: flex-start;
  background: var(--superficie-2);   /* recesso: --bg sumiria a 1,04:1 do cartão */
  border: var(--fio);
  color: var(--text-light);
  border-radius: var(--raio);
  padding: var(--esp-2) var(--esp-4);
  font-size: var(--tam-apoio);
  line-height: 1.5;
  margin-bottom: var(--esp-4);
}
.faixa-aviso svg { flex-shrink: 0; margin-top: 2px; }

/* ---------- Área de conta ---------- */
.bloco-conta {
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  padding: var(--esp-5);
  margin-bottom: var(--esp-3);
}
.bloco-conta dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--esp-2) var(--esp-4);
  font-size: var(--tam-corpo);
}
.bloco-conta dt { color: var(--text-light); font-size: var(--tam-apoio); }
.bloco-conta dd { text-align: right; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------
   Conta — o bloco deixou de ser "um <dl> e nada mais" (04-09-26)

   Agora ele pode ter selo de situação, frase de apoio e ações. O respiro tem de
   ser do CONTEXTO (o irmão anterior), não do <dl>: um `margin-top` fixo nele
   descolaria o primeiro bloco, onde a lista é o único conteúdo.
------------------------------------------------------------- */
.bloco-conta > * + dl { margin-top: var(--esp-4); }
.bloco-conta > .selo-lote + .conta-motivo { margin-top: var(--esp-2); }

/* Frase que explica o bloco: o "por quê" da situação da assinatura e o aviso dos
   parâmetros de cálculo. Contraste de texto de APOIO (--text-light, 6,79:1) —
   nunca --text-suave, que no sistema é só para elemento gráfico. */
.conta-motivo {
  margin-top: var(--esp-3);
  font-size: var(--tam-apoio);
  line-height: 1.5;
  color: var(--text-light);
}
.conta-motivo strong { font-weight: var(--peso-forte); }
/* Quando o bloco veio SÓ com a explicação (sem permissão, assinatura vencida), a
   frase é o primeiro elemento e não tem de quem se afastar. */
.bloco-conta > .conta-motivo:first-child { margin-top: 0; }

/* Ações do bloco: empilham no celular e dividem a linha quando há largura.
   Os 24px acima são o piso do sistema ("BOTÃO NÃO ENCOSTA EM NADA"), não um
   número escolhido aqui. O gap entre eles é 12 e não 8 de propósito — são ações
   DIFERENTES ("Editar meus dados" x "Trocar senha"), não um par de barra de ação.
   `text-decoration: none` porque "Pagar agora" é um <a> com cara de botão: o
   projeto não tem regra global de link, cada componente declara a sua. */
.acoes-conta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-3);
  margin-top: var(--esp-5);
}
.acoes-conta > * {
  flex: 1 1 auto;
  text-align: center;
  text-decoration: none;
}

/* A coluna de cobranças é cartão próprio, fora do bloco — precisa se separar do
   que vem depois dela. Escopado na área para não virar regra do componente:
   dentro de um cartão, na tela de precificar, essa margem estaria errada. */
.app-area > .coluna-dinheiro { margin-bottom: var(--esp-5); }

/* =============================================================
   >= 768px — a barra inferior SOME e vira sidebar
============================================================= */
@media (min-width: 768px) {
  :root { --nav-h: 0px; }

  .app-shell {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }
  .app-topo { grid-column: 2; }
  /* A sidebar já exibe o símbolo + SOPPHUS: no desktop a marca sai do topo, e
     com ela some a coluna do meio — o grid vira "título | ações". */
  .app-topo { grid-template-columns: 1fr auto; }
  .app-topo .marca-link { display: none; }
  .app-area { grid-column: 2; padding: var(--esp-5) var(--esp-5) var(--esp-6); }

  .nav-inferior { display: none; }

  /* Barra lateral CLARA — mudança de 05-08-26.

     Era preta (#2A1B10), assinatura cromática herdada do ERP da Chocolateria.
     Com a paleta própria ela virou uma parede escura ao lado de uma tela rosada
     clara: duas linguagens na mesma janela. Agora é do mesmo material do resto —
     cartão branco separado do fundo pelo fio — e as cores das abas são as MESMAS
     de baixo, sem precisar da variante clara.

     Ganho colateral: sumiu a duplicação de tokens (--aba-*-clara só existe agora
     para o tema escuro) e o bug do anel de foco invisível some junto, porque o
     anel volta a ser o global de sopphus.css. */
  .nav-lateral {
    display: flex;
    flex-direction: column;
    grid-row: 1 / -1;
    grid-column: 1;
    background: var(--card);
    color: var(--text);
    border-right: var(--fio);
    padding: var(--esp-4) var(--esp-3);
    gap: 2px;
    position: sticky;
    top: 0;
    height: 100dvh;
  }
  .nav-lateral .marca {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
    font-size: var(--tam-corpo);
    font-weight: var(--peso-forte);
    letter-spacing: 0.14em;
    color: var(--text);
    padding: var(--esp-2) var(--esp-3) var(--esp-5);
  }
  .nav-lateral .nav-item {
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--esp-3);
    font-size: var(--tam-corpo);
    min-height: var(--alvo-toque);
    padding: var(--esp-2) var(--esp-3);
    border-radius: var(--raio-medio);
    color: var(--text-light);
  }
  /* na sidebar o ícone não usa a pílula da barra inferior: a linha inteira
     é que acende */
  .nav-lateral .nav-item .nav-icone { width: auto; height: auto; background: none; }
  .nav-lateral .nav-item:active { background: var(--superficie-2); }

  /* Cor por aba: as mesmas quatro do rodapé, sem variante — o fundo aqui é
     branco, igual ao de baixo. O ícone leva a cor; o rótulo do item inativo
     fica neutro. */
  .nav-lateral .nav-item[data-destino="inicio"]     { --cor-aba: var(--aba-inicio);     --cor-aba-fundo: var(--aba-inicio-fundo); }
  .nav-lateral .nav-item[data-destino="precificar"] { --cor-aba: var(--aba-precificar); --cor-aba-fundo: var(--aba-precificar-fundo); }
  .nav-lateral .nav-item[data-destino="financeiro"] { --cor-aba: var(--aba-financeiro); --cor-aba-fundo: var(--aba-financeiro-fundo); }
  .nav-lateral .nav-item[data-destino="relatorios"] { --cor-aba: var(--aba-relatorios); --cor-aba-fundo: var(--aba-relatorios-fundo); }
  .nav-lateral .nav-item[data-destino="cadastros"]  { --cor-aba: var(--aba-cadastros);  --cor-aba-fundo: var(--aba-cadastros-fundo); }
  .nav-lateral .nav-item svg { color: var(--cor-aba, currentColor); }

  /* Ativo: fundo NEUTRO + rótulo e ícone na cor da aba + peso 600.
     O fundo era o tint colorido da aba; virou neutro em 05-08-26, junto com a
     saída dos blocos de cor atrás dos ícones. Aqui o fundo continua existindo
     porque o item é uma LINHA inteira, e realçar a linha ativa é outra coisa
     que pintar um quadrado atrás de um ícone — mas ele não precisa ter cor
     para isso: a cor já está no texto e no traço. */
  .nav-lateral .nav-item[aria-current="page"] {
    background: var(--superficie-2);
    color: var(--cor-aba, var(--text));
    font-weight: var(--peso-forte);
  }
  /* o pontinho é da barra inferior; na sidebar o realce da linha já marca */
  .nav-lateral .nav-item[aria-current="page"]::after { content: none; }

  .grade-resumo { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--esp-4); }
  /* as colunas não mudam mais com a largura (ver .grade-modulos): o que cresce
     aqui é só o respiro entre os cartões, que sobra na tela grande */
  .grade-modulos { gap: var(--esp-4); }
  /* a partir daqui o cartão tem largura de sobra e volta ao respiro da casa —
     uma linha só, porque padding e chevron leem a mesma propriedade */
  .card-modulo { --respiro-card: var(--esp-5); }
}

/* =============================================================
   Tela de entrar (login / cadastro)
============================================================= */
/* =============================================================
   TELA DE ENTRADA — o "alto" colorido e o cartão que sobe

   É a única tela do app com área de cor cheia. Ela existe porque a entrada é o
   primeiro contato: o gradiente da marca recebe, e o cartão sobe por cima dele
   com canto grande, criando a dobra que dá o ar de acolhimento.

   O gradiente usa DUAS CORES QUE JÁ SÃO TOKENS — o vinho #3A1A25 e o rosa lido
   #A8305F. Não é uma terceira paleta: é a marca esticada. Medido ponto a ponto
   contra o texto #FFF1F4, o PIOR trecho do gradiente dá 5,97:1 (mínimo 4,5).
============================================================= */
/* DIVISÃO: faixa de gradiente em cima, corpo CLARO embaixo — 05-08-26.

   Duas versões anteriores morreram no caminho e as duas ensinaram algo:
     1. faixa com canto arredondado + cartão subindo por cima → a faixa boiava e
        lia como imagem cortada, e o cartão com `flex: 1` esticava até o rodapé
        deixando meia tela vazia;
     2. gradiente na tela INTEIRA → resolveu o corte, mas ficou pesado. O claro
        embaixo é justamente o que dá leveza à tela de entrada.

   Esta versão junta o que funcionou de cada uma. O que conserta o "cortado" é a
   faixa ser FULL-BLEED: ela encosta nas três bordas da viewport e só a base é
   curva — não sobra moldura clara em volta dela em largura nenhuma.

   E o contraste que assombrava o tema escuro sumiu por construção: sem cartão
   em cima do gradiente, não existe mais o cruzamento de luminosidade entre os
   dois. Os campos vivem sobre o corpo claro, onde o contraste já era medido. */
.entrar-tela {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  overflow-x: hidden;
}

/* ---------- CAMADA 1: a hero ----------
   30% da altura da viewport, com piso em 232px para o conteúdo não se espremer
   em celular deitado. A curva orgânica é um SVG na base (ver .onda) — não é
   border-radius: raio elíptico dá um arco simétrico e mecânico, e o que se
   quer aqui é uma curva com dois vales, que só um bezier faz. */
.entrar-hero {
  position: relative;
  flex-shrink: 0;
  min-height: max(30dvh, 232px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  /* o padding de baixo reserva o espaço que a onda ocupa */
  padding: calc(var(--esp-6) + env(safe-area-inset-top)) var(--esp-4) var(--esp-6);
  /* DO MAIS CLARO PARA O MENOS CLARO — pedido do usuário em 05-08-26. Antes ia
     de vinho escuro a rosa escuro (#3A1A25 → #A8305F), e o rosa escuro do fim
     não agradou.

     As três cores são da paleta oficial: #FFE3E8 é o off-white rosado, e
     #F7ADB7 / #E58FA8 são os DOIS rosas da arte da marca. Nada inventado.

     Isso obrigou a virar o texto: sobre rosa claro, o off-white dá 1,81:1 e
     reprova sem apelação. O texto agora é o VINHO da marca, que dá 6,59:1 no
     pior ponto do percurso — mais contraste do que a versão anterior tinha.
     Hex cravado, não var(): a faixa é a MARCA e não muda com o tema. */
  background: linear-gradient(160deg, #FFE3E8 0%, #F7ADB7 52%, #E58FA8 100%);
  color: var(--vinho);
}
/* Halo fora de foco: impede o gradiente de ler como retângulo chapado.
   Com a faixa clara, o halo é o DOURADO da marca — sobre rosa, mais rosa não
   apareceria. Decorativo, nunca por baixo de texto. */
.entrar-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 88% -12%, rgba(212, 175, 55, 0.30) 0%, transparent 60%);
  pointer-events: none;
}
.hero-conteudo {
  position: relative;
  z-index: 2;              /* acima do halo E da onda */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--esp-1);
}

/* ---------- CAMADA 2: as ondas ----------
   Cada onda é preenchida com a cor da seção que vem DEPOIS dela — é assim que
   ela "come" a seção anterior e desenha a curva. O -1px lateral cobre a linha
   de meio pixel que alguns navegadores deixam na emenda.

   É SVG e não border-radius de propósito: raio elíptico produz um arco
   simétrico e mecânico; o que o briefing pede é uma curva ORGÂNICA, com mais
   de um vale — e isso só um bezier faz. `preserveAspectRatio="none"` deixa o
   mesmo path servir de 320 a 1920px sem achatar a altura. */
.onda {
  position: absolute;
  left: -1px;
  width: calc(100% + 2px);
  display: block;
  pointer-events: none;
}
.onda path { fill: var(--bg); }
.onda-hero { bottom: -1px; height: 68px; z-index: 1; }

.entrar-hero .marca-simbolo {
  /* Disco BRANCO SÓLIDO. O translúcido servia sobre o gradiente escuro; sobre o
     rosa claro ele sumiria, e o símbolo — que também é rosa — sumiria junto.
     O branco devolve exatamente o fundo em que a arte foi desenhada. A sombra
     é o que dá o limite, já que o disco só faz 1,36:1 contra a faixa. */
  width: 82px;
  height: 82px;
  padding: 13px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: 0 4px 14px rgba(58, 26, 37, 0.16);
  margin-bottom: var(--esp-3);
}
.entrar-saudacao {
  font-size: var(--tam-resposta);
  font-weight: var(--peso-forte);
  line-height: 1.15;
  letter-spacing: var(--track-heroi);
}
/* O subtítulo se separa do título por TAMANHO e PESO, não por opacidade.
   Medido: em vinho sólido ele dá 6,59:1; a 78% cairia para 4,31 e reprovaria.
   Hierarquia por opacidade é a primeira coisa que quebra quando o fundo clareia. */
.entrar-sub {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-normal);
  color: var(--vinho);
  line-height: 1.4;
}

/* ---------- CAMADA 3: o cartão flutuante ----------
   Sobe sobre a onda (margin-top negativo) — é essa sobreposição que cria a
   profundidade e amarra as duas seções. z-index acima da onda e do halo. */
.entrar-conteudo {
  position: relative;
  z-index: 3;
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 424px;
  margin: -44px auto 0;
  padding: 0 var(--esp-4);
}

/* O cartão É o <form>: agrupar em duas caixas aninhadas só para desenhar uma
   borda seria peso morto no DOM. Padding generoso (32/24) e raio de 28px — a
   escala de espaço do sistema (8/16/24/32) já é a pedida no briefing. */
.entrar-cartao {
  background: var(--card);
  border: var(--fio);
  border-radius: 28px;
  padding: var(--esp-6) var(--esp-5);
  box-shadow: 0 1px 2px rgba(58, 26, 37, 0.05),
              0 12px 32px rgba(58, 26, 37, 0.10),
              0 32px 64px rgba(58, 26, 37, 0.06);
}
/* O respiro de 32/24 vale até no iPhone padrão (375px): medido, o cartão fica
   com 343px e sobram 295 de área útil, folgado para os campos. Só abaixo de
   360px ele cede — e aí é o alvo de toque que manda, não o conforto. */
@media (max-width: 359px) {
  .entrar-cartao { padding: var(--esp-5) var(--esp-4); }
}

/* ---------- Rodapé, fechado pela curva invertida ----------
   Existe para dar peso ao pé da tela: sem ele sobrava um vão claro entre o
   cartão e a borda inferior, que era exatamente a "sensação de vazio".
   `margin-top: auto` cola no fim quando a tela é alta; quando é curta, ele
   simplesmente segue o cartão. */
.entrar-rodape {
  position: relative;
  margin-top: auto;
  padding: calc(var(--esp-6) + 56px) var(--esp-4) calc(var(--esp-5) + env(safe-area-inset-bottom));
  text-align: center;
  background: var(--superficie-2);
}
/* invertida: preenchida com a cor do CORPO, comendo o topo do rodapé */
.onda-rodape { top: -1px; height: 90px; }
.onda-rodape path { fill: var(--bg); }
.rodape-marca {
  position: relative;
  font-size: var(--tam-apoio);
  font-weight: var(--peso-forte);
  letter-spacing: 0.14em;   /* exceção documentada da marca */
  color: var(--text-light);
}
.rodape-tag {
  position: relative;
  font-size: var(--tam-apoio);
  color: var(--text-light);
  margin-top: 2px;
}

/* ---------- Campo com ícone dentro ----------
   O ícone deixa reconhecer a linha antes de ler o rótulo. Ele é DECORATIVO
   (aria-hidden): o <label> continua acima e é ele que nomeia o campo — trocar
   rótulo por placeholder é o anti-padrão clássico, porque o placeholder some
   exatamente quando a pessoa começa a digitar e não pode mais conferir. */
.campo-com-icone { position: relative; display: flex; align-items: center; }
.campo-com-icone .campo-icone {
  position: absolute;
  left: 16px;
  width: 19px;
  height: 19px;
  color: var(--text-light);
  pointer-events: none;
  transition: color var(--dur-curta) var(--curva-cor);
}
.campo-com-icone .input { padding-left: 46px; }
/* o ícone acende na cor da área quando o campo está em foco */
.campo-com-icone .input:focus ~ .campo-icone,
.campo-com-icone:focus-within .campo-icone { color: var(--cor-area); }

/* botão do olho, dentro do campo de senha */
.campo-com-icone .senha-revelar {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: var(--alvo-toque);
  height: var(--alvo-toque);
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--raio-pilula);
  color: var(--text-light);
  cursor: pointer;
}
.campo-com-icone .senha-revelar svg { width: 20px; height: 20px; }
.campo-com-icone .input { padding-right: 52px; }
/* um ícone por estado, trocados pelo CSS a partir do aria-pressed do botão */
.senha-revelar .olho-ocultar { display: none; }
.senha-revelar[aria-pressed="true"] .olho-ver { display: none; }
.senha-revelar[aria-pressed="true"] .olho-ocultar { display: block; }

/* "Esqueci minha senha": à direita, colado no campo de que fala */
.link-esqueci {
  align-self: flex-end;
  margin-top: calc(-1 * var(--esp-2));
  padding: var(--esp-2) 0;
  min-height: var(--alvo-toque);
  background: none;
  border: 0;
  color: var(--cor-area);
  font-size: var(--tam-apoio);
  font-weight: var(--peso-normal);
  cursor: pointer;
}
/* `.abas`/`.aba` saíram em 05-08-26 junto com o formulário de criar conta:
   com um painel só, não havia mais o que alternar. (O painel administrativo
   usa `.adm-abas`/`.adm-aba`, que são outras classes e continuam de pé.)
   Quem dá o título agora é o "Bem-vindo" do topo colorido. */

.campos-empilhados { display: flex; flex-direction: column; gap: var(--esp-4); }
.dica-senha { font-size: var(--tam-apoio); color: var(--text-light); }
/* `.senha-caixa` e `.link-discreto` saíram em 05-08-26: o campo de senha virou
   `.campo-com-icone` (com o botão-olho) e o link virou `.link-esqueci`. Nenhum
   HTML ou JS os referenciava mais — conferido antes de apagar. */

/* =============================================================
   Gráficos e relatórios
   Marcas finas, grade recessiva, texto SVG só em 13px e 16px/600.
============================================================= */

/* ---------- KPI / stat — transição até virar coluna do dinheiro ----------
   Rótulo 13/400 cinza EM CIMA, valor 600 embaixo (nunca o contrário). */
.kpi {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--esp-3);
  margin-bottom: var(--esp-4);
}
.stat {
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  padding: var(--esp-5);
  min-width: 0;
}
.stat-rotulo {
  font-size: var(--tam-apoio);
  font-weight: var(--peso-normal);
  color: var(--text-light);
  margin-bottom: var(--esp-1);
}
.stat-valor {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  font-variant-numeric: proportional-nums;
  overflow-wrap: anywhere;
}
.stat-valor.heroi {
  font-size: var(--tam-resposta);
  line-height: 1.2;
  letter-spacing: 0;
}
.stat-apoio { font-size: var(--tam-apoio); color: var(--text-light); margin-top: var(--esp-1); }

/* ---------- Cartão de gráfico ---------- */
.cartao-grafico {
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  padding: var(--esp-5);
  margin-bottom: var(--esp-3);
}
/* cabeçalho do cartão de gráfico: título à esquerda, segmentado à direita —
   o arranjo do print. Abaixo de 420px o segmentado desce para a linha de baixo
   em vez de espremer o título. */
.cartao-grafico-cab {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--esp-3);
  flex-wrap: wrap;
  margin-bottom: var(--esp-4);
}
.cartao-grafico-cab > div { min-width: 0; }
.cartao-grafico-cab h3 { margin-bottom: 2px; }
.cartao-grafico-cab .sub { margin-bottom: 0; }
/* título como pergunta; termo técnico vai no .sub em 13px */
.cartao-grafico > h3 {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: var(--esp-1);
}
.cartao-grafico > .sub {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  margin-bottom: var(--esp-3);
}
.msg-grafico {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  padding: var(--esp-4) var(--esp-1);
  text-align: center;
}

/* ---------- Legenda (rótulo direto obrigatório) ---------- */
.legenda { display: flex; flex-direction: column; gap: var(--esp-1); margin-top: var(--esp-3); }
.lg-item { display: flex; align-items: center; gap: var(--esp-2); font-size: var(--tam-apoio); }
.lg-cor { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
.lg-cor.tracejada { background-image: repeating-linear-gradient(90deg, transparent 0 2px, rgba(255,255,255,.85) 2px 3px); }
.lg-nome { color: var(--text); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-valor {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero); color: var(--text); font-weight: var(--peso-normal); font-variant-numeric: tabular-nums; }
.lg-pct {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero); color: var(--text-light); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }

/* ---------- Barras horizontais ---------- */
.barras { display: flex; flex-direction: column; gap: var(--esp-2); }
.barra-linha {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "nome valor" "trilho trilho";
  gap: var(--esp-1) var(--esp-2);
  align-items: center;
}
.barra-nome {
  grid-area: nome;
  font-size: var(--tam-apoio);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.barra-valor {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  grid-area: valor;
  font-size: var(--tam-apoio);
  font-weight: var(--peso-forte);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.barra-trilho {
  grid-area: trilho;
  height: 8px;
  background: var(--bg);
  border-radius: 4px;
  overflow: hidden;
}
/* sem transição de width: animar largura causa reflow (regra do sistema) */
.barra-fill { height: 100%; border-radius: 4px; }

/* ---------- Medidor de meta (bloco próprio, nunca dentro do extrato) ---------- */
/* A META estava sumindo (apontado pelo usuário): tinha o mesmo tratamento de
   qualquer cartão, num lugar onde ela é o segundo assunto mais importante da
   tela. Ganhou presença por TAMANHO, não por cor — a porcentagem subiu para
   18px e o trilho de 6 para 10px. */
.medidor {
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  box-shadow: var(--sombra-cartao);
  padding: var(--esp-5);
  margin-bottom: var(--esp-4);
}
.medidor-topo { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--esp-3); }
.medidor-rotulo { font-size: var(--tam-corpo); color: var(--text); }
.medidor-pct {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero); font-size: var(--tam-titulo); font-weight: var(--peso-forte); font-variant-numeric: proportional-nums; }
.medidor-trilho { height: 10px; background: var(--superficie-2); border: 0; border-radius: var(--raio-pilula); overflow: hidden; }
.medidor-fill { height: 100%; border-radius: 3px; }
.medidor-base {
  display: flex; justify-content: space-between;
  font-size: var(--tam-apoio); margin-top: var(--esp-2); font-variant-numeric: tabular-nums;
}
.medidor-base .de { color: var(--text-light); }
.medidor-msg { font-size: var(--tam-apoio); color: var(--text-light); margin-top: var(--esp-1); }
.medidor-msg.bom { color: var(--success); font-weight: var(--peso-forte); }

/* ---------- DRE — a coluna do dinheiro canônica (13/16, total 2px) ---------- */
.tabela-wrap { overflow-x: auto; }
table.dre { width: 100%; border-collapse: collapse; font-size: var(--tam-corpo); }
table.dre th {
  text-align: left;
  font-weight: var(--peso-normal);
  font-size: var(--tam-apoio);
  color: var(--text-light);
  padding: 0 var(--esp-2) var(--esp-2);
  border-bottom: var(--fio);
}
table.dre td { padding: var(--esp-3) var(--esp-2); border-bottom: var(--fio); }
table.dre td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.dre td.pct { color: var(--text-light); font-size: var(--tam-apoio); width: 78px; }
table.dre tr.saida td:first-child { padding-left: var(--esp-5); color: var(--text-light); }
table.dre tr.destaque td { font-weight: var(--peso-forte); background: var(--bg); }
/* linha de resultado = linha de total: fio 2px terminal */
table.dre tr.resultado td {
  font-weight: var(--peso-forte);
  border-bottom: 0;
  border-top: var(--fio-total);
}

/* ---------- Faixa de projeção (dado estimado, não realizado) ---------- */
.faixa-projecao {
  display: flex; gap: var(--esp-2); align-items: flex-start;
  background: var(--bg);
  border: var(--fio);
  color: var(--text-light);
  border-radius: var(--raio);
  padding: var(--esp-2) var(--esp-4);
  font-size: var(--tam-apoio);
  line-height: 1.5;
  margin-bottom: var(--esp-3);
}

/* ---------- Período ---------- */
/* Mesmo tratamento das abas: trilho único, selecionado em superfície de cartão
   com o rótulo na cor da ÁREA. O fundo cheio no rosa com texto branco daria
   2,38:1 — o antigo `background: var(--primary); color: var(--card)` só passava
   porque --primary era marrom escuro. */
.filtro-periodo {
  display: inline-flex; gap: 2px; margin-bottom: var(--esp-4);
  padding: 3px;
  background: var(--superficie-2);
  border-radius: var(--raio-pilula);
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.filtro-periodo::-webkit-scrollbar { display: none; }
.filtro-periodo button {
  flex-shrink: 0;
  min-height: 38px;
  padding: 0 var(--esp-4);
  background: none;
  border: 0;
  border-radius: var(--raio-pilula);
  font-size: var(--tam-apoio);
  color: var(--text-light);
  cursor: pointer;
  white-space: nowrap;
  /* `background-color` e não o shorthand — ver a nota do `.cartao` em
     sopphus.css (04-09-26): transicionar o shorthand deixa o fundo preso no
     valor do tema anterior quando o token muda. */
  transition: background-color var(--dur-curta) var(--curva-cor),
              color var(--dur-curta) var(--curva-cor);
}
.filtro-periodo button[aria-pressed="true"] {
  background: var(--card);
  color: var(--cor-area);
  font-weight: var(--peso-forte);
  box-shadow: var(--sombra-cartao);
}

@media (min-width: 768px) {
  .kpi { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--esp-3); }
  .colunas-relatorio { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--esp-3); align-items: start; }
  .barra-linha {
    grid-template-columns: 150px minmax(0, 1fr) auto;
    grid-template-areas: "nome trilho valor";
  }
  .legenda { flex-direction: row; flex-wrap: wrap; gap: var(--esp-4); }
  .lg-item { flex: 0 1 auto; }
  .lg-nome { flex: 0 1 auto; }
}

/* Atalho de conta no cabeçalho (fora da barra: 4 destinos, nunca 5) */
.btn-conta {
  display: grid; place-items: center;
  width: var(--alvo-toque); height: var(--alvo-toque); flex-shrink: 0;
  border: var(--fio); border-radius: var(--raio-pilula);
  background: var(--card);
  color: var(--text-light); text-decoration: none; cursor: pointer;
  transition: color var(--dur-curta) var(--curva-cor),
              border-color var(--dur-curta) var(--curva-cor);
}
.btn-conta svg { width: 20px; height: 20px; }

/* Resultado negativo na DRE: cor + palavra. Cor sozinha não carrega sentido. */
table.dre tr.prejuizo td { color: var(--danger); }
.tag-prejuizo {
  font-size: var(--tam-apoio);
  font-weight: var(--peso-normal);
  color: var(--danger);
  border: 1px solid currentColor;
  border-radius: var(--raio-pilula);
  padding: 0 var(--esp-2);
  margin-left: var(--esp-2);
  vertical-align: 1px;
}
/* Resultado positivo: espelho exato do .tag-prejuizo — a PALAVRA "lucro" em
   --success (7,13:1 sobre branco) com borda currentColor. Cor + palavra, nunca
   cor sozinha. */
.tag-lucro {
  font-size: var(--tam-apoio);
  font-weight: var(--peso-normal);
  color: var(--success);
  border: 1px solid currentColor;
  border-radius: var(--raio-pilula);
  padding: 0 var(--esp-2);
  margin-left: var(--esp-2);
  vertical-align: 1px;
}

/* =============================================================
   ABAS INTERNAS — 14-09-26
   A barra inferior passou de cinco destinos para três, e o que saiu dela virou
   aba DENTRO do destino (Produção: Produtos·Receitas·Estoque; Caixa:
   Resumo·Lançamentos·Relatórios).

   Não é uma segunda barra de navegação: é a fileira de destinos DENTRO da área,
   e a aba escolhida vive na URL (#/producao/receitas) para o F5 e o "voltar"
   caírem onde a pessoa estava.

   COR POR ABA, e não a cor da área. Era --cor-area (uma cor para as três) até
   15-09-26; agora cada aba veste a família do que ela abre — dourado em
   Produtos, rosa em Receitas, azul em Estoque — as mesmas quatro famílias já
   medidas no sopphus.css, sem cor nova entrando por aqui.
============================================================= */
/* -------------------------------------------------------------
   O DESENHO mudou duas vezes em 15-09-26, a pedido do dono. Eram pílulas de
   texto; viraram botões grandes; e agora vestem o estilo que ele mandou de
   referência — quadrado de cantos muito arredondados ("squircle") com um ANEL
   EM DEGRADÊ em volta e um halo suave da mesma cor.

   COMO O ANEL É FEITO, sem imagem e sem SVG.
   O `::before` cobre o botão inteiro e é pintado com o degradê; a máscara
   recorta o MIOLO dele (`content-box` menos a caixa inteira), e o que sobra é
   só a moldura. É a técnica padrão de borda em degradê, e é a única que
   acompanha `border-radius` sem deformar o canto.

   SE A MÁSCARA FALHAR num navegador antigo, o degradê aparece como fundo
   chapado atrás do conteúdo (o texto e o ícone vivem acima, em `z-index: 2`).
   Fica diferente do desenhado, mas continua um botão legível — degradação, não
   tela quebrada.

   GRADE, e não rolagem horizontal. Com três destinos por área, esconder o
   terceiro atrás de um deslize é esconder um terço do app; em grade os três
   cabem em 375px e cada um vira um alvo de 96px de altura, muito acima dos 44
   mínimos. `grid-auto-flow: column` mantém isso verdadeiro para qualquer
   quantidade de abas, sem número de colunas cravado.
------------------------------------------------------------- */
.sub-abas {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--esp-3);
  padding: var(--esp-2) 0 var(--esp-4);
  margin-bottom: var(--esp-2);
}

/* Cada aba traz a SUA família de cor, e a chave é a própria aba (`data-cor`),
   então a paleta vive aqui e não espalhada no JS.

   Nenhuma cor é nova: `--aba-tinta` é a cor de área já medida e `--aba-brilho`
   é a versão de MARCA da mesma família, que é o segundo ponto do degradê. O
   par é o que dá o anel de duas tintas da referência — dourado escuro para
   dourado da arte, vinho para rosa da arte, azul para azul claro. */
.sub-aba {
  --aba-tinta: var(--cor-area);
  --aba-brilho: var(--cor-area);
  --aba-tint: var(--cor-area-fundo);
}
/* A primeira aba de Produção. Era `produtos` (o cadastro) e virou `producao`
   (o registro do que saiu da panela) em 15-09-26; o dourado ficou, porque é a
   cor da área e é ela que a pessoa já associa ao primeiro botão da fileira.
   A chave `produtos` continua aqui: o cadastro virou segmento do Estoque, e se
   um dia voltar a ser aba ele volta vestido igual. */
.sub-aba[data-cor="producao"]    { --aba-tinta: var(--dourado-texto);  --aba-brilho: var(--dourado);               --aba-tint: var(--dourado-fundo); }
.sub-aba[data-cor="produtos"]    { --aba-tinta: var(--dourado-texto);  --aba-brilho: var(--dourado);               --aba-tint: var(--dourado-fundo); }
.sub-aba[data-cor="receitas"]    { --aba-tinta: var(--rosa-texto);     --aba-brilho: var(--rosa);                  --aba-tint: var(--rosa-fundo); }
.sub-aba[data-cor="estoque"]     { --aba-tinta: var(--aba-relatorios); --aba-brilho: var(--aba-relatorios-clara);  --aba-tint: var(--aba-relatorios-fundo); }
.sub-aba[data-cor="resumo"]      { --aba-tinta: var(--aba-financeiro); --aba-brilho: var(--aba-financeiro-clara);  --aba-tint: var(--aba-financeiro-fundo); }
.sub-aba[data-cor="lancamentos"] { --aba-tinta: var(--rosa-texto);     --aba-brilho: var(--rosa);                  --aba-tint: var(--rosa-fundo); }
.sub-aba[data-cor="relatorios"]  { --aba-tinta: var(--aba-relatorios); --aba-brilho: var(--aba-relatorios-clara);  --aba-tint: var(--aba-relatorios-fundo); }

/* No escuro o dourado lido JÁ É o dourado da arte, então os dois pontos do
   degradê cairiam na mesma cor e o anel ficaria chapado. O segundo ponto sobe
   para um dourado claro — derivado do próprio token, sem hex novo no arquivo. */
:root[data-tema="escuro"] .sub-aba[data-cor="produtos"] {
  --aba-brilho: color-mix(in oklab, var(--dourado) 55%, #FFFFFF);
}

.sub-aba {
  position: relative;
  /* o anel é filho posicionado; `isolation` prende o empilhamento ao botão e
     impede que ele escape por cima do cartão vizinho */
  isolation: isolate;
  min-height: 96px;
  padding: var(--esp-4) var(--esp-2) var(--esp-3);
  display: flex;
  flex-direction: column;
  align-items: center;
  /* `flex-start` e NÃO `center`: nem toda aba tem contador (Receitas não tem),
     e centrado o rótulo dela descia em relação aos vizinhos. Alinhando pelo
     topo, os três ícones e os três rótulos ficam na mesma linha. */
  justify-content: flex-start;
  gap: var(--esp-2);
  /* o "squircle" da referência: canto muito aberto, sem virar pílula */
  border-radius: 28px;
  background: var(--card);
  color: var(--text-light);
  text-decoration: none;
  /* MAIOR E MAIS FORTE, a pedido do dono (15-09-26): era --tam-apoio (13) em
     peso 400. Estes botões são o miolo da navegação da área — eles têm de pesar
     mais que uma legenda. 600 é o --peso-forte do sistema; 500 é vetado (a
     Segoe estática do Win10 não o tem e desce para 400). */
  font: inherit;
  font-size: 15px;
  font-weight: var(--peso-forte);
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--dur-media) var(--curva-cor),
              color var(--dur-media) var(--curva-cor),
              box-shadow var(--dur-media) var(--curva-cor),
              transform var(--dur-curta) var(--curva);
}

/* O ANEL EM DEGRADÊ. Ver o cabeçalho para a técnica da máscara. */
.sub-aba::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 3px;                       /* espessura do anel */
  background: linear-gradient(145deg, var(--aba-tinta), var(--aba-brilho));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  /* no repouso o anel existe mas não grita; aceso ele vai a 1 */
  opacity: 0.4;
  transition: opacity var(--dur-media) var(--curva-cor);
  pointer-events: none;
}

/* Conteúdo ACIMA do anel: se a máscara falhar e o degradê virar fundo chapado,
   o texto continua por cima e legível. */
.sub-aba-icone,
.sub-aba-texto,
.sub-aba .contador-aba { position: relative; z-index: 2; }

/* O ícone solto sobre o botão, como na referência — sem quadradinho em volta.
   Traço fino e caixa grande é o que dá o ar de ícone desenhado a linha. */
.sub-aba-icone {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: var(--aba-tinta);
  flex-shrink: 0;
  transition: color var(--dur-media) var(--curva-cor);
}
.sub-aba-icone svg { width: 26px; height: 26px; stroke-width: 1.7; }

/* O rótulo pode ter duas palavras ("Lançamentos") em 375px. Quebrar é melhor
   que reticências: o nome do destino tem de ser lido inteiro. */
.sub-aba-texto { line-height: 1.2; }

.sub-aba .contador-aba {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: 12px;
  line-height: 1;
  padding: 3px 9px;
  border-radius: var(--raio-pilula);
  background: var(--aba-tint);
  color: var(--aba-tinta);
  font-weight: var(--peso-forte);
}

/* QUATRO sinais no aceso — miolo tintado, anel inteiro, halo e a cor no texto.
   Cor sozinha nunca marca estado neste app, e aqui menos ainda: as três abas
   já são coloridas no repouso. */
.sub-aba[aria-current="page"] {
  background: var(--aba-tint);
  color: var(--aba-tinta);
  box-shadow: 0 10px 26px -12px var(--aba-tinta);
}
.sub-aba[aria-current="page"]::before { opacity: 1; }
.sub-aba[aria-current="page"] .contador-aba { background: var(--card); }

.sub-aba:focus-visible { outline: 2px solid var(--aba-tinta); outline-offset: 3px; }

/* Só quem tem mouse ganha o hover. No dedo, `:hover` gruda depois do toque e o
   botão fica "aceso" numa aba que a pessoa nem abriu. */
@media (hover: hover) and (pointer: fine) {
  .sub-aba:hover { transform: translateY(-2px); }
  .sub-aba:hover::before { opacity: 0.8; }
  .sub-aba[aria-current="page"]:hover::before { opacity: 1; }
}
.sub-aba:active { transform: translateY(0) scale(0.97); }

/* -------------------------------------------------------------
   A TROCA DE ABA, animada.

   O app repinta a área inteira a cada navegação, então a aba nova nasce já
   acesa e uma `transition` não teria de onde sair — quem anima elemento recém
   criado é `animation`, não `transition`. Daí as duas abaixo.

   `data-trocou` é posto pelo JS SÓ quando a aba mudou de verdade. Sem ele, o
   segmentado do Estoque (que reaproveita a mesma barra) e todo salvamento de
   lista fariam a animação repetir sem motivo — e animação que toca à toa vira
   ruído em duas telas de uso.
------------------------------------------------------------- */
@keyframes aba-acende {
  from { opacity: 0.35; transform: scale(0.9); }
  to   { opacity: 1;    transform: scale(1); }
}
@keyframes aba-halo {
  from { opacity: 0.2; }
  to   { opacity: 1; }
}
/* O conteúdo da aba entra junto, subindo de leve: é o que faz a troca parecer
   UMA coisa acontecendo, e não a tela piscando e outra aparecendo. */
@keyframes aba-corpo-entra {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.sub-abas[data-trocou="sim"] .sub-aba[aria-current="page"] {
  animation: aba-acende var(--dur-longa) var(--curva) both;
}
.sub-abas[data-trocou="sim"] .sub-aba[aria-current="page"]::before {
  animation: aba-halo var(--dur-longa) var(--curva-cor) both;
}
/* Tudo que vem DEPOIS da barra dentro da área — o painel da aba. O seletor de
   irmão é o que dispensa marcar cada painel no JS. */
.sub-abas[data-trocou="sim"] ~ * {
  animation: aba-corpo-entra var(--dur-media) var(--curva) both;
}

@media (prefers-reduced-motion: reduce) {
  .sub-aba { transition: none; }
  .sub-aba:hover, .sub-aba:active { transform: none; }
  .sub-abas[data-trocou="sim"] .sub-aba[aria-current="page"],
  .sub-abas[data-trocou="sim"] .sub-aba[aria-current="page"]::before,
  .sub-abas[data-trocou="sim"] ~ * { animation: none; }
}

/* =============================================================
   ASSISTENTE — base de conhecimento (14-09-26)

   >>> NÃO É INTELIGÊNCIA ARTIFICIAL, e a tela diz isso. <<<
   O dono pediu "assistente por i.a (que não é ia, é só a base de conhecimento
   do código para o cliente ter suporte)". Nada aqui chama modelo nenhum: são
   respostas escritas à mão em js/ajuda.js, filtradas por busca no navegador.
   Chamar de IA o que é um FAQ seria mentir na tela de suporte — justamente onde
   a confiança do assinante é o produto.
============================================================= */
.kb-busca { margin-bottom: var(--esp-3); }

.kb-lista { display: flex; flex-direction: column; gap: var(--esp-2); }

.kb-item {
  border: var(--fio);
  border-radius: var(--raio-medio);
  background: var(--card);
  overflow: hidden;
}
.kb-item[open] { border-color: var(--border-forte); }

.kb-item > summary {
  list-style: none;
  cursor: pointer;
  padding: var(--esp-3) var(--esp-4);
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  color: var(--text);
  -webkit-tap-highlight-color: transparent;
}
.kb-item > summary::-webkit-details-marker { display: none; }
.kb-item > summary::after {
  content: "›";
  margin-left: auto;
  color: var(--text-suave);
  /* o chevron gira; a seta some quando não anima (prefers-reduced-motion),
     e o [open] continua legível pelo próprio conteúdo aberto */
  transform: rotate(90deg);
  transition: transform 0.15s ease;
}
.kb-item[open] > summary::after { transform: rotate(-90deg); }

.kb-resposta {
  padding: 0 var(--esp-4) var(--esp-4);
  color: var(--text-light);
  font-size: var(--tam-apoio);
  line-height: var(--ent-apoio);
}
.kb-resposta p { margin: 0 0 var(--esp-2); }
.kb-resposta p:last-child { margin-bottom: 0; }
.kb-resposta strong { color: var(--text); }
.kb-resposta a { color: var(--cor-area); }

.kb-tema {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-suave);
  margin: var(--esp-4) 0 var(--esp-2);
}

/* =============================================================
   RANKING — "os doces que mais vendem" (14-09-26)
   Lista ordenada com a posição à esquerda e a barra proporcional ao primeiro
   colocado. A barra é leitura RELATIVA (quem lidera e por quanto); o número
   ao lado é o valor absoluto — a barra sozinha nunca carrega o dado.
============================================================= */
.ranking { display: flex; flex-direction: column; gap: var(--esp-3); }

.ranking-item {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: center;
  gap: var(--esp-3);
}
.ranking-pos {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-apoio);
  color: var(--text-suave);
  text-align: right;
}
.ranking-nome {
  font-size: var(--tam-corpo);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ranking-valor {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-apoio);
  color: var(--text-light);
  white-space: nowrap;
}
.ranking-barra {
  grid-column: 2 / -1;
  height: 6px;
  border-radius: var(--raio-pilula);
  background: var(--superficie-2);
  overflow: hidden;
  margin-top: -6px;
}
.ranking-barra > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--cor-area);
}

/* ---------- Endereço da vitrine (Dashboard) ----------
   O link é o que o dono COPIA e MANDA — precisa ser lido inteiro, não
   truncado com reticências. `break-all` porque a URL não tem espaços onde
   quebrar, e sem ele a linha empurra o cartão para fora da tela: o corpo da
   página nunca rola na horizontal neste app. */
.vitrine-rotulo {
  margin: var(--esp-3) 0 var(--esp-1);
  font-size: var(--tam-apoio);
  color: var(--text-light);
}
.vitrine-link {
  display: block;
  margin-bottom: var(--esp-3);
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-apoio);
  color: var(--cor-area);
  overflow-wrap: anywhere;
  word-break: break-all;
}

/* =============================================================
   ESTOQUE (016) — saldo por insumo
============================================================= */
/* Segmentado Insumos | Embalagens. É FILTRO da mesma lista, não navegação,
   por isso são <button> e não <a>: não mexem no hash e não poluem o histórico
   do navegador, senão o "voltar" do celular pararia de voltar de verdade. */
.segmentado {
  display: flex;
  gap: 2px;
  padding: 3px;
  margin-bottom: var(--esp-3);
  background: var(--superficie-2);
  border-radius: var(--raio-pilula);
}
.seg {
  flex: 1;
  min-height: 40px;
  border: 0;
  border-radius: var(--raio-pilula);
  background: none;
  color: var(--text-light);
  font: inherit;
  font-size: var(--tam-apoio);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.seg[aria-current="page"] {
  background: var(--card);
  color: var(--text);
  font-weight: var(--peso-forte);
  box-shadow: var(--sombra-cartao);
}

.lista-estoque { display: flex; flex-direction: column; gap: var(--esp-3); }

.item-estoque {
  border: var(--fio);
  border-radius: var(--raio-medio);
  background: var(--card);
  overflow: hidden;
}
/* Sem controle é estado de repouso, não de alerta: a superfície recua em vez
   de chamar atenção. Quem não usa estoque vê uma lista calma, que era a
   promessa do opt in. */
.item-estoque.sem-controle { background: var(--superficie); }

/* O cabeçalho é o botão que abre a edição do insumo. Ele já vem com o padding
   de .item; aqui só se tira a borda, que agora é do contêiner. */
.item-estoque-cab { border: 0; border-radius: 0; background: none; width: 100%; }

.estoque-saldo {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--esp-2);
  padding: 0 var(--esp-4) var(--esp-2);
}
.estoque-numero {
  font-family: var(--fonte-numero);
  letter-spacing: var(--track-numero);
  font-size: var(--tam-corpo);
  color: var(--text);
}

/* O saldo negativo é explicado por escrito, não só pelo sinal de menos. Quem
   olha o número sozinho não sabe o que fazer com ele. */
.estoque-aviso {
  margin: 0;
  padding: 0 var(--esp-4) var(--esp-2);
  font-size: var(--tam-apoio);
  line-height: var(--ent-apoio);
  color: var(--danger);
}

.estoque-acoes {
  display: flex;
  gap: var(--esp-2);
  padding: 0 var(--esp-4) var(--esp-4);
}
.estoque-acoes .btn { flex: 1; }

/* =============================================================
   PLANEJAR · datas boas de venda e o checklist de cada uma
   Spec inicio-mais-tour, Parte 2.

   Tudo aqui reaproveita os tokens do sistema. O que carrega sentido e sempre
   a PALAVRA ("Atrasada", "Feriado", o risco na etapa feita junto com a caixa
   marcada), e a cor so reforca.
============================================================= */
.planejar-barra { align-items: center; }
.planejar-barra .ajuda { margin: 0; }
/* A barra-acao da casa inverte a linha a partir de 620px, pensada para busca e
   botao. Aqui o par e explicacao e botao, e a explicacao vem primeiro na leitura
   nas duas larguras. */
@media (min-width: 620px) {
  .planejar-barra { flex-direction: row; }
  .planejar-barra .ajuda { flex: 1; }
}
.planejar-lista { display: flex; flex-direction: column; gap: var(--esp-3); }

.oportunidade,
.planejamento {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  color: inherit;
  text-decoration: none;
}
.oportunidade-topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--esp-3);
}
.oportunidade-cabeca { min-width: 0; }
.oportunidade-nome {
  margin: 0;
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  color: var(--text);
  overflow-wrap: anywhere;
}
.oportunidade-quando {
  margin: 2px 0 0;
  font-size: var(--tam-apoio);
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.rotulo-apoio {
  margin: var(--esp-1) 0 0;
  font-size: var(--tam-apoio);
  color: var(--text-light);
}
.oportunidade-sugestao,
.planejamento-proxima {
  margin: 0;
  font-size: var(--tam-corpo);
  color: var(--text);
}
.planejamento-prazo {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  white-space: nowrap;
}
.oportunidade .btn { margin-top: var(--esp-2); }

.planejar-progresso { margin-bottom: var(--esp-3); }
.planejar-progresso .barra-fill { background: var(--aba-inicio); }

/* Voltar de um checklist para a lista. 44px de alvo, como todo toque do app. */
.link-voltar {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  min-height: 44px;
  margin-bottom: var(--esp-2);
  color: var(--text-light);
  font-size: var(--tam-apoio);
  text-decoration: none;
}
.link-voltar:hover { color: var(--text); }

.checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
}
.checklist-item {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  background: var(--card);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  padding: var(--esp-2) var(--esp-3);
}
/* A linha inteira e o alvo da caixa, com 48px de altura minima. Caixa de 22px
   sozinha seria alvo pequeno demais para o polegar. */
.checklist-marca {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--esp-3);
  min-height: 48px;
  padding: var(--esp-1) 0;
  cursor: pointer;
}
.checklist-marca input {
  width: 22px;
  height: 22px;
  margin: 2px 0 0;
  flex-shrink: 0;
  accent-color: var(--aba-inicio);
  cursor: pointer;
}
.checklist-texto { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.checklist-titulo { font-size: var(--tam-corpo); color: var(--text); overflow-wrap: anywhere; }
.checklist-prazo {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.checklist-item.feita .checklist-titulo {
  color: var(--text-light);
  text-decoration: line-through;
}
.checklist-abrir { flex-shrink: 0; min-height: 44px; }

/* =============================================================
   DASHBOARD · lembretes do dia, link secundario e acoes do cardapio
   Spec inicio-mais-tour, Parte 3.
============================================================= */
/* Link de apoio embaixo de um cartao, como "Ver todas as datas". Texto e nao
   botao, porque a acao principal do bloco ja e o botao dentro do cartao. */
.link-secundario {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: var(--esp-2);
  color: var(--text-light);
  font-size: var(--tam-apoio);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.link-secundario:hover { color: var(--text); }

.lembretes {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--esp-3);
}
@media (min-width: 620px) {
  .lembretes { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}
.lembrete {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  min-height: 72px;
  color: inherit;
  text-decoration: none;
}
.lembrete-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.lembrete-titulo {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  color: var(--text);
}
.lembrete-sub { font-size: var(--tam-apoio); color: var(--text-light); }
/* Com insumo pedindo atencao a FRASE ja diz quantos e por que. A borda so
   reforca, nunca e o unico sinal. */
.lembrete.atencao { border-color: var(--warning); }

.vitrine-acoes {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  margin-top: var(--esp-3);
}
@media (min-width: 620px) {
  .vitrine-acoes { flex-direction: row; }
  .vitrine-acoes .btn { flex: 1; }
}

/* =============================================================
   MAIS · o quinto item da barra e a folha que ele abre
   Spec inicio-mais-tour, Parte 4.
============================================================= */
/* E botao, nao link. O .nav-item ja zera fundo e borda, e aqui so a altura de
   linha, que o navegador nao herda em botao. */
.nav-mais { line-height: inherit; }
/* A quinta familia de cor da barra. Nenhum outro item de baixo usa, e a aba
   Estoque, que tambem usa, mora em outro contexto. */
.nav-inferior .nav-item[data-destino="mais"] {
  --cor-aba: var(--aba-relatorios);
  --cor-aba-fundo: var(--aba-relatorios-fundo);
}

/* Acima da barra de baixo (40) e abaixo do modal (50). Um modal aberto a partir
   de uma tela do Mais tem de cobrir a folha, nunca o contrario. */
.folha-fundo {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.folha-fundo[hidden] { display: none; }
.folha {
  width: 100%;
  max-width: 560px;
  max-height: 85vh;
  max-height: 85dvh;
  overflow-y: auto;
  background: var(--card);
  border-radius: var(--raio-folha) var(--raio-folha) 0 0;
  padding: var(--esp-4) var(--esp-4) calc(var(--esp-4) + env(safe-area-inset-bottom));
  box-shadow: var(--sombra-elevada);
}
@media (min-width: 768px) {
  .folha-fundo { align-items: center; padding: var(--esp-4); }
  .folha { border-radius: var(--raio-folha); }
}
.folha-cabeca {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
  margin-bottom: var(--esp-3);
}
.folha-titulo { margin: 0; font-size: var(--tam-titulo); color: var(--text); }
.folha-lista { display: flex; flex-direction: column; gap: var(--esp-2); }
.folha-item {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  min-height: 64px;
  padding: var(--esp-2) var(--esp-3);
  border: var(--fio-cartao);
  border-radius: var(--raio);
  background: var(--card);
  color: inherit;
  text-decoration: none;
}
.folha-item:active { background: var(--superficie-2); }
/* Rever o tour e BOTAO, porque abre o tour e nao muda de tela. Sem isto ele sai
   centralizado, com a fonte do navegador e sem ocupar a linha. */
button.folha-item {
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.folha-item-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.folha-item-titulo { font-size: var(--tam-corpo); font-weight: var(--peso-forte); color: var(--text); }
.folha-item-sub { font-size: var(--tam-apoio); color: var(--text-light); }

/* Atalhos do Mais para dentro da Conta. O topo e fixo, e sem esta margem o
   titulo da secao pararia escondido embaixo dele. */
#conta-assinatura,
#conta-ajustes { scroll-margin-top: 88px; }

/* ---------- Meus clientes ---------- */
.clientes-lista { display: flex; flex-direction: column; gap: var(--esp-3); }
.cartao.cliente { padding: 0; }
.cliente-cabeca {
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  min-height: 64px;
  padding: var(--esp-3) var(--esp-4);
  cursor: pointer;
  list-style: none;
}
.cliente-cabeca::-webkit-details-marker { display: none; }
.cliente[open] .cliente-cabeca .chevron { transform: rotate(90deg); }
.cliente-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cliente-nome {
  font-size: var(--tam-corpo);
  font-weight: var(--peso-forte);
  color: var(--text);
  overflow-wrap: anywhere;
}
.cliente-sub {
  font-size: var(--tam-apoio);
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.cliente-corpo {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  padding: 0 var(--esp-4) var(--esp-4);
}
.cliente-pedidos { list-style: none; margin: 0; padding: 0; }
.cliente-pedidos li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-1) var(--esp-2);
  padding: var(--esp-2) 0;
  border-top: var(--fio);
  font-size: var(--tam-apoio);
  font-variant-numeric: tabular-nums;
}
.cliente-pedido-num { font-weight: var(--peso-forte); color: var(--text); }
.cliente-pedido-data { color: var(--text-light); }
.cliente-pedido-total { margin-left: auto; color: var(--text); }
