/* ============================================================================
   SOMA · soma-page-boot.css  (CSS crítico de boot — anti-flicker)
   ----------------------------------------------------------------------------
   Esconde APENAS as regiões instáveis/auth-sensitive enquanto a sessão/menu
   resolvem. NUNCA esconde a página inteira (sem tela branca). Reserva espaço
   (visibility/skeleton) para não haver layout shift. Carregar no <head>, ANTES
   do JS, e marcar <html class="soma-booting"> estaticamente nas páginas logadas.
   Aditivo e reversível: remover a classe 'soma-booting' = volta ao normal.
   ============================================================================ */

/* ---- regiões auth-sensitive: invisíveis durante o boot (espaço preservado) ---- */
html.soma-booting [data-auth-sensitive],
html.soma-booting .pl-user-name,
html.soma-booting .pl-user-clinic,
html.soma-booting .pl-header-plan-pill-text,
html.soma-booting .pl-sidebar-foot-title,
html.soma-booting .adm-userchip .who,
html.soma-booting .adm-userchip .av{ visibility:hidden !important; }

/* avatar do chip vira skeleton circular (reserva o círculo; sem flash de inicial errada) */
html.soma-booting .pl-user-avatar{
  color:transparent !important;
  background:var(--soma-line,#e4e7ec) !important;
}
html.soma-booting .pl-user-avatar img{ visibility:hidden !important; }

/* reserva de altura do nome/clínica (evita o "pulo" quando o texto chega) */
.pl-user-name{ min-height:1.05em; }
.pl-user-clinic{ min-height:.95em; }

/* ============================================================================
   OFFSET do banner de demonstração — reservado via custom property ANTES do
   paint (soma-page-boot.js lê localStorage['soma_demo_v1']==='on' e adiciona
   html.soma-demo-reserved). Header/sidebar fixos usam a var; assim o banner
   (injetado depois) ocupa o espaço já reservado e NADA "pula" 34px.
   ============================================================================ */
:root{ --soma-demo-offset:0px; }
html.soma-demo-reserved{ --soma-demo-offset:34px; }
@media (max-width:560px){ html.soma-demo-reserved{ --soma-demo-offset:30px; } }

html.soma-demo-reserved .pl-header{ top:var(--soma-demo-offset) !important; }
html.soma-demo-reserved .pl-sidebar{ top:var(--soma-demo-offset) !important; height:calc(100% - var(--soma-demo-offset)) !important; }

/* ---- banner demo: elimina o CLS de 34px no fluxo (o conteúdo "pulava" quando o banner injetava) ----
   #soma-demo-banner é injetado PÓS-paint (defer) e, sendo position:sticky, fica NO FLUXO e empurra
   todo o conteúdo do .pl-app 34px (30px ≤560px) para baixo no instante em que aparece. A classe
   html.soma-demo-reserved já é aplicada PRÉ-paint (soma-page-boot.js lê localStorage['soma_demo_v1']).
   Aqui reservamos o MESMO offset no fluxo do body.pl-app e tornamos o banner FIXED → ele ocupa o espaço
   já reservado sem empurrar (sem duplicar o offset). Resultado: conteúdo nasce na posição final, sem salto.
   Escopo restrito a body.pl-app: NÃO toca admin (.adm-body), páginas de venda nem nada fora do shell logado.
   Só em @media screen — no print o banner segue static (regra do soma-demo-banner.css) e o body não ganha
   padding. Aditivo, gated e reversível (remover soma-demo-reserved volta ao normal). */
@media screen{
  html.soma-demo-reserved body.pl-app{ padding-top:var(--soma-demo-offset); }
  html.soma-demo-reserved body.pl-app > #soma-demo-banner{ position:fixed; }
}

/* ---- skeleton neutro reutilizável (mesma dimensão do conteúdo final) ---- */
.soma-skel{ position:relative; overflow:hidden; background:var(--soma-line,#e9edf2); border-radius:8px; }
.soma-skel::after{
  content:""; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.5), transparent);
  animation:soma-skel-shimmer 1.25s infinite;
}
@keyframes soma-skel-shimmer{ 100%{ transform:translateX(100%); } }
@media (prefers-reduced-motion: reduce){ .soma-skel::after{ animation:none; } }

/* SPA: reserva de altura nos containers que sofrem swap estático→innerHTML, p/ o conteúdo
   não "colapsar e re-inflar" (layout shift) durante a 1ª renderização do JS. Aditivo.
   (configuracoes-app/documents-app já reservam nos seus page-*.css.) */
#crmView{ min-height:60vh; }
main.atendimento-app{ min-height:70vh; }
/* lista de modelos do Estúdio (documentos): só é preenchida após o fetch do orchestrator; sem piso
   ela nasce com 1 linha ("Carregando modelos…") e infla com N itens → pop-in/CLS numa região visível.
   Reserva mínima (alinhada ao min-height:420px de .doc-preview-empty). Mantida na FUNDAÇÃO p/ não
   colidir com page-documents.css (em edição paralela). */
.documents-app .doc-template-list{ min-height:400px; }

/* ============================================================================
   Anti-flicker de ENTRADA (fade/slide). As telas-módulo têm o painel ativo ESTÁTICO
   no HTML com uma animação de entrada (somaPanelIn/estfade/cxfade, opacity 0→1 +
   translateY), que portanto roda no PRIMEIRO paint → o conteúdo principal "aparece
   deslizando" a cada carregamento (o flicker percebido em CRM e Estruturação).
   Gatear por html.soma-booting NÃO resolve: ao remover a classe (markSessionReady)
   a animação RE-DISPARA (muda animation-name de none→nome) e o flash só desloca.
   Solução robusta e sem re-trigger: suprimir essas animações de ENTRADA de vez. São
   decorativas (transição de aba/subseção); o conteúdo passa a aparecer instantâneo na
   altura já reservada. Centralizado na fundação → cobre estrutura/documentos/
   configurações/CRM sem tocar o JS do Codex. Aditivo e reversível. */
.cx-fade,
.est-phase.is-active{ animation:none !important; }
/* (o somaPanelIn das abas — .est-tabpanel/.module-app-panel.is-active — é !important com
   especificidade maior em banner-standard.css; neutralizado lá na fonte, não aqui.) */
