/* ============================================================================
   nexus-responsivo.css · camada de redimensionamento do Nexus
   ----------------------------------------------------------------------------
   UMA folha para TODAS as telas. Celular, notebook, monitor grande e TV.

   COMO ELA GANHA DAS REGRAS DA TELA
   ---------------------------------
   Cada tela do Nexus carrega o proprio <style> inline no <head>. Esta folha e
   injetada com <link> IMEDIATAMENTE ANTES do </head> — ou seja, DEPOIS daquele
   <style>. Com isso ela vence por ORDEM DE FONTE em especificidade igual, e
   quase nao precisa de !important. Se alguem mover este <link> para cima do
   <style>, a folha para de valer em silencio: o layout volta ao de antes sem
   erro nenhum no console. O lugar dela e o fim do <head>.

   O VOCABULARIO E O DAS TELAS, NAO UM NOVO
   ----------------------------------------
   Os seletores abaixo foram levantados das 66 telas app.*.v1.html que estao no
   ar (contagem em 03/08/2026): .wrap (35) .card (33) .btn (31) .main (26)
   .kpi (26) .kpi-row (25) .hdr (24) .page (20) .rank-table (19) .kpis (17)
   .modal (12) .rank-scroll (10). Nada aqui inventa classe nova — se um seletor
   daqui nao existe em tela nenhuma, ele e peso morto e deve sair.

   AS DUAS FAMILIAS DE GRID — e por que sao seletor de familia, nao lista
   ---------------------------------------------------------------------
   O sistema tem 25+ nomes diferentes de grid multi-coluna (.kpi-row .kpis
   .stats .behave-grid .dl-grid .cols4 .audit-grid .home-kpis .health ...), e
   telas novas inventam mais. Uma lista de nomes envelhece em silencio: a tela
   nova nasce fora dela e ninguem descobre ate abrir no celular. Por isso o
   alvo aqui e `[class*="kpi"]`, `[class*="-grid"]` e afins — o nome novo cai
   na familia sozinho.

   As duas familias pedem coisas OPOSTAS, e confundi-las e o erro fatal:

     KPI (numero curto)     -> 2 colunas no celular. Uma coluna so viraria uma
                               torre de rolagem antes de comecar o conteudo.
     CONTEUDO (bloco de     -> 1 coluna no celular. Em duas nao sobra largura
     leitura, card, tabela)    para o texto e tudo vira palavra por linha.

   ORDEM IMPORTA: o bloco de CONTEUDO vem sempre ANTES do de KPI. Uma classe
   como `kpi-grid` casa nas duas familias; vindo depois, a regra de KPI ganha —
   que e o certo, porque um grid DE kpi deve ser tratado como kpi.

   Poe grid-template-columns em elemento que nao e grid (ex.: o card `.kpi`
   individual, que casa `[class*="kpi"]`). Isso e inofensivo: a propriedade nao
   tem efeito fora de um container grid.

   .main SIGNIFICA DUAS COISAS — e por isso todo seletor e escopado
   ---------------------------------------------------------------
   Na casca (app.v1.html) `.main` e a coluna ao lado do sidebar: flex:1, ocupa a
   altura toda. Nas telas `.main` e o container do conteudo, com max-width e
   margin:0 auto. Sao a MESMA classe com papeis opostos. Mexer em `.main` solto
   quebra um dos dois. Por isso: `.shell .main` para a casca, `.page > .main`
   (e `body > .main`) para as telas. Nunca `.main` sozinho.

   O QUE ESTA FOLHA NAO FAZ
   ------------------------
   Nao entra em documento de PDF. Os templates de _novo/cotacao_nexus/templates/
   sao folha A4 de medida fixa: o PDF sai do layout impresso, e "responsivo" ali
   significa pagina quebrada no documento do cliente. O @media print no fim e
   uma trava caso alguem injete o <link> num template por engano.
   ============================================================================ */

/* ── Escada de tamanhos (referencia dos breakpoints usados abaixo) ───────────
     <= 640px   celular retrato
     <= 900px   celular paisagem · tablet retrato
     <= 1280px  tablet paisagem · notebook pequeno
     1281-1919  notebook e monitor comum  ← linha de base, NAO se mexe
     >= 1920px  monitor grande
     >= 2560px  TV / 4K
   A faixa 1281-1919 e deliberadamente vazia: e onde o sistema ja e usado todo
   dia e ja esta certo. Toda regra daqui e para FORA dessa faixa.
   ------------------------------------------------------------------------- */

/* ── 1. Base · vale em qualquer tamanho ──────────────────────────────────── */

/* A altura da tela do celular MENTE. 100vh no Safari/Chrome mobile conta a
   barra de endereco que some ao rolar, entao a casca fica ~60-100px mais alta
   que o visivel e o rodape nasce embaixo da barra. 100dvh e a altura de fato.
   Fica em @supports porque navegador velho sem dvh deve continuar com o vh. */
@supports (height: 100dvh) {
  .shell { height: 100dvh; }
  .sb    { height: 100dvh; }
  .page  { min-height: 100dvh; }
}

/* Nada pode empurrar a pagina para os lados. Um card de largura fixa, uma
   tabela ou um <pre> longo cria scroll horizontal no documento inteiro e o
   celular passa a "balancar" — some com o menu e o usuario acha que travou.
   A tabela continua rolando na horizontal, mas DENTRO da caixa dela (item 4). */
html, body { max-width: 100%; overflow-x: hidden; }

/* Palavra sem espaco (URL, CNPJ, e-mail, hash) nao quebra sozinha e estoura o
   card. Aqui o alvo e so onde o texto e do usuario/servidor, nao a UI inteira. */
.card, .panel, .modal, .empty, .vazio, .foot-note, .info { overflow-wrap: anywhere; }

/* Dedo nao e mouse. 44px e o minimo tocavel da Apple HIG / Material. Vale so
   onde o ponteiro e GROSSO (pointer:coarse) — no desktop os botoes continuam
   com a altura desenhada, senao a densidade das telas de operacao morre. */
@media (pointer: coarse) {
  .btn, .btn-primary, .btn-ghost, .btn-clear,
  .sb .item, .toolbar .seg button, .tab, .aba {
    min-height: 44px;
  }
  /* Campo com fonte < 16px faz o iOS dar ZOOM sozinho ao focar, e a tela nunca
     mais volta ao lugar. E o bug de formulario mais comum em celular. */
  input, select, textarea { font-size: 16px; }
}

/* Rolagem com inercia dentro das areas que rolam (iOS). */
.rank-scroll, .tbl-scroll, .sb .menu, .modal { -webkit-overflow-scrolling: touch; }

/* ── 2. Celular retrato · <= 640px ───────────────────────────────────────── */
@media (max-width: 640px) {

  /* Container: a margem lateral de 28px come 56px de uma tela de 390px — 14%
     da largura util so em respiro. 14px de cada lado devolve isso ao conteudo. */
  .page > .main, body > .main, .wrap {
    padding-left: 14px;
    padding-right: 14px;
    max-width: 100%;
  }
  .page > .main, body > .main { padding-top: 16px; padding-bottom: 40px; }

  /* Cabecalho da tela empilha: icone+titulo em cima, acoes embaixo. */
  .hdr {
    padding: 14px 16px;
    flex-wrap: wrap;
    gap: 10px;
  }
  .hdr h1 { font-size: 16px; }
  .hdr .icon, .header-icon { width: 38px; height: 38px; font-size: 18px; flex-shrink: 0; }

  /* O bloco de titulo nasce com min-width:auto, ou seja, nunca fica menor que a
     MAIOR palavra indivisivel do subtitulo (costuma ter um <code> com nome de
     arquivo). Como ele nao encolhe, o flex-wrap acima o joga inteiro para a
     linha de baixo — e o icone fica sozinho numa linha, com o titulo embaixo.
     min-width:0 devolve a ele o direito de encolher e quebrar o texto POR
     DENTRO, que e o que se espera de um cabecalho.

     A base do flex tem de ser 0, nao auto — e a parte que nao e obvia. Com
     flex-wrap, o navegador primeiro DISTRIBUI os itens pelo tamanho-base e so
     depois encolhe o que sobrou na linha. Com base auto (= largura do conteudo)
     o bloco ja nasce maior que o espaco livre e e mandado para a linha de
     baixo antes de qualquer encolhimento — foi medido: min-width:0 sozinho nao
     resolveu nada. Com base 0 ele cabe na linha do icone e depois cresce. */
  .hdr > div:not(.icon):not(.header-icon) { min-width: 0; flex: 1 1 0; }

  /* Grid de CONTEUDO: uma coluna. Sao blocos de leitura, nao numero curto —
     em duas colunas nao sobra largura para o texto. VEM ANTES do bloco de KPI
     de proposito (ver "AS DUAS FAMILIAS" no topo). */
  [class*="-grid"], [class*="grid-"], .mgrid, .emoji-panel, .steps,
  .mission, .cover-meta, .provider {
    grid-template-columns: 1fr;
  }

  /* KPIs: DUAS colunas. Uma so viraria torre de rolagem antes do conteudo;
     duas cabem e continuam legiveis, porque KPI e numero curto. */
  [class*="kpi"], [class*="stats"], [class*="cards"], [class*="cols"],
  [class*="metric"], [class*="tiles"], .health, .num-row {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  .kpi { padding: 12px 13px; }
  .kpi .val { font-size: 21px; }
  .kpi .lbl { font-size: 9.5px; }

  /* Barra de filtros: a busca ocupa a linha inteira; os selects dividem o resto.
     O min-width:260px da busca, no desktop, aqui forcaria overflow. */
  .toolbar { padding: 10px 12px; gap: 8px; }
  .toolbar .search-wrap { flex: 1 1 100%; min-width: 0; }
  .toolbar select, .toolbar .seg { flex: 1 1 auto; }

  .card, .panel, .section { padding: 14px; border-radius: 10px; }
  .section-head { flex-wrap: wrap; gap: 8px; }
}

/* ── 3. Celular paisagem e tablet retrato · 641-900px ────────────────────── */
@media (min-width: 641px) and (max-width: 900px) {
  /* Conteudo em duas: aqui ja ha largura para duas colunas de texto. */
  [class*="-grid"], [class*="grid-"], .mgrid, .emoji-panel, .steps,
  .mission, .cover-meta, .provider {
    grid-template-columns: repeat(2, 1fr);
  }
  /* Tres colunas de KPI: num tablet de 834px da 256px por card. Cabe folgado,
     e evita o pulo de 5 direto para 2. */
  [class*="kpi"], [class*="stats"], [class*="cards"], [class*="cols"],
  [class*="metric"], [class*="tiles"], .health, .num-row {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 900px) {
  .page > .main, body > .main, .wrap { max-width: 100%; }

  /* POPUP · o desenho e sempre o mesmo: um `.modal-bg` fixed inset:0 em flex
     centrado, com o `.modal` dentro. No desktop o modal tem largura fixa
     (320, 520, 560px) ou max-width de 460 a 820px — no celular isso ou estoura
     a tela ou fica boiando.

     A largura e 100% do wrapper, NAO calc(100vw - Npx). Uma versao anterior
     usava calc(100vw - 24px): em 6 dos 7 wrappers, que ja tem padding de 18-20px,
     o modal ficaria mais largo que a caixa que o contem e vazaria para fora da
     tela. Deixar a folga por conta do padding do wrapper acerta os dois casos —
     e para o wrapper que NAO tem padding, a regra abaixo da um. */
  .modal-bg, .overlay, .modal-ov, .modal-mask, .modal-bd { padding: 12px; }

  .modal, .sheet {
    width: 100%;
    max-width: 100%;
    max-height: 88dvh;
    overflow-y: auto;
    border-radius: 14px;
  }
  /* NAO se mexe no max-height do corpo do modal. Varios modais sao
     `overflow:hidden` + flex column com o corpo rolando por dentro; tirar o
     teto do corpo faria o conteudo crescer atras do overflow:hidden do pai e
     sumir — sem barra de rolagem que o alcance. O `overflow-y:auto` acima ja
     garante que nada fique inalcancavel, inclusive no modal que nao tem teto. */
}

/* ── 4. Tabela larga · em qualquer tamanho apertado ──────────────────────── */
/* As tabelas do Nexus tem min-width entre 900 e 1100px dentro de uma caixa com
   overflow-x:auto. Isso ja "funciona": rola de lado. O problema e que no
   celular NAO SE VE que rola — o corte cai numa borda branca identica ao fim
   do card, e a leitura para na 3a coluna achando que acabou.
   A sombra da direita e a dica: ela some quando a rolagem chega ao fim. */
@media (max-width: 1280px) {
  .rank-scroll, .tbl-scroll {
    overflow-x: auto;
    background:
      linear-gradient(to right, var(--surface, #fff) 30%, rgba(255,255,255,0)),
      linear-gradient(to right, rgba(255,255,255,0), var(--surface, #fff) 70%) 100% 0,
      radial-gradient(farthest-side at 0 50%, rgba(3,20,48,.16), rgba(0,0,0,0)),
      radial-gradient(farthest-side at 100% 50%, rgba(3,20,48,.16), rgba(0,0,0,0)) 100% 0;
    background-repeat: no-repeat;
    background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
  }
  /* Barra de rolagem sempre visivel: no Mac/iOS ela e invisivel em repouso, e
     e justamente ali que o usuario precisa saber que ha mais coluna. */
  .rank-scroll::-webkit-scrollbar, .tbl-scroll::-webkit-scrollbar { height: 8px; }
  .rank-scroll::-webkit-scrollbar-thumb, .tbl-scroll::-webkit-scrollbar-thumb {
    background: rgba(3,20,48,.22); border-radius: 8px;
  }
}
@media (max-width: 640px) {
  /* Aperta o respiro da celula para caber mais coluna por rolagem. A tabela
     NAO vira card aqui: card generico exigiria saber qual coluna e o titulo de
     cada uma das 19 tabelas, e chutar isso troca "rola de lado" por "informacao
     errada em negrito". Quando uma tela especifica pedir card, faz-se nela. */
  .rank-table thead th { padding: 10px 10px; font-size: 9.5px; }
  .rank-table tbody td { padding: 10px 10px; font-size: 12px; }
}

/* ── 5. Notebook pequeno · 901-1280px ────────────────────────────────────── */
/* Aqui NAO se mexe em coluna de grid, de proposito. Uma versao anterior desta
   folha forcava 3 colunas nesta faixa; seria uma REGRESSAO justamente no
   aparelho onde o sistema e usado o dia inteiro — em 1280px cabem 4 e 5 KPIs
   com folga, e as telas ja nascem assim. Mexer aqui e piorar o que funciona.
   Sobra so o respiro lateral, que a 901px ainda e generoso demais. */
@media (min-width: 901px) and (max-width: 1280px) {
  .page > .main, body > .main, .wrap { padding-left: 20px; padding-right: 20px; }
}

/* ── 6. Monitor grande · >= 1920px ───────────────────────────────────────── */
/* Aqui o problema e o oposto: max-width entre 920 e 1400px deixa a tela cheia
   de vazio dos dois lados enquanto a tabela rola de lado no meio. Solta o teto
   proporcionalmente — mas com limite, porque linha de texto de 2400px de largura
   e ilegivel (o olho perde a proxima linha ao voltar). */
@media (min-width: 1920px) {
  .page > .main, body > .main, .wrap { max-width: 1720px; }
  [class*="kpi"], [class*="stats"], [class*="cards"] { gap: 18px; }
}

/* ── 7. TV / 4K · >= 2560px ──────────────────────────────────────────────── */
/* TV se le a 3 metros, nao a 50cm. Entao NAO e "mais conteudo na tela" — e o
   MESMO conteudo, maior. Duas notas de implementacao:

   1. Aumentar font-size da raiz nao resolve: o Nexus escreve tamanho em px, e
      px ignora a raiz. O que escala px e o `zoom`.
   2. O zoom vai no CONTAINER (.wrap / .main), nunca no body. No body ele
      multiplicaria tambem o 100vh da .page/.shell e criaria rolagem eterna —
      a tela ficaria 25% mais alta que a propria tela.

   A classe `nx-tv-off` no <html> desliga tudo isto (a casca marca o iframe
   filho para o zoom nao ser aplicado DUAS vezes — ver nexus-responsivo.js). */
@media (min-width: 2560px) {
  html:not(.nx-tv-off) .page > .main,
  html:not(.nx-tv-off) body > .main,
  html:not(.nx-tv-off) .wrap {
    zoom: 1.25;
    max-width: 1600px;   /* 1600 x 1.25 = 2000px reais na tela */
  }
  /* O sidebar da casca acompanha, senao vira um fio ao lado do conteudo grande. */
  html:not(.nx-tv-off) .sb { width: 316px; min-width: 316px; }
  html:not(.nx-tv-off) .sb .item { font-size: 14px; padding: 10px 18px; }
  html:not(.nx-tv-off) .sb .item i { font-size: 17px; width: 20px; }
  html:not(.nx-tv-off) .topbar { height: 66px; }
}
@media (min-width: 3800px) {
  html:not(.nx-tv-off) .page > .main,
  html:not(.nx-tv-off) body > .main,
  html:not(.nx-tv-off) .wrap { zoom: 1.6; }
}

/* ── 8. Casca (app.v1.html) · sidebar vira gaveta ────────────────────────── */
/* O sidebar tem 252px fixos. Num celular de 390px isso e 65% da largura: sobra
   138px para o sistema inteiro. Abaixo de 900px ele sai do fluxo e vira gaveta
   sobreposta, aberta pelo botao que o JS injeta na topbar.
   Sem esta parte, nada do resto importa: nao da nem para CHEGAR numa tela. */
.nx-burger { display: none; }              /* so aparece quando vira gaveta */
.nx-scrim  { display: none; }

@media (max-width: 900px) {
  .shell { position: relative; }

  .sb {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    z-index: 1000;
    width: 272px; min-width: 272px;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: 0 0 40px rgba(3,20,48,.4);
  }
  .sb.nx-aberto { transform: translateX(0); }

  /* Veu: escurece o conteudo e fecha a gaveta no toque fora. */
  .nx-scrim {
    display: block;
    position: fixed; inset: 0;
    z-index: 999;
    background: rgba(3,20,48,.5);
    opacity: 0; pointer-events: none;
    transition: opacity .22s ease;
  }
  .nx-scrim.nx-aberto { opacity: 1; pointer-events: auto; }

  .nx-burger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    margin-right: 6px;
    border: 0; border-radius: 9px;
    background: transparent;
    color: var(--text, #031430);
    font-size: 22px; cursor: pointer;
    flex-shrink: 0;
  }
  .nx-burger:hover { background: rgba(13,171,225,.10); }

  .shell .main { width: 100%; min-width: 0; }
  .topbar { padding: 0 12px; gap: 8px; }
  .topbar .title { font-size: 12px; }
}

/* TECLADO — a gaveta fechada nao pode receber Tab nem ser lida por leitor de
   tela. Isso e feito com `inert` no JS, e nao com um `visibility:hidden` aqui,
   porque `inert` tira do Tab E da arvore de acessibilidade de uma vez, enquanto
   `visibility:hidden` some com o elemento para todo mundo, inclusive para a
   pintura — e a gaveta precisa continuar pintavel para deslizar. */

/* Quem pediu menos animacao no sistema nao ganha gaveta deslizante. */
@media (prefers-reduced-motion: reduce) {
  .sb, .nx-scrim { transition: none; }
}

/* ── 9. Trava de impressao ───────────────────────────────────────────────── */
/* Se este <link> for injetado por engano num template de PDF, o documento do
   cliente sai com a medida do template, nao com a desta folha. A folha A4 tem
   ~794px de largura em CSS: sem esta trava ela cairia no @media <=900px e o
   PDF sairia com a tabela cortada e o modal em tela cheia. */
@media print {
  html, body { overflow-x: visible; max-width: none; }
  .page > .main, body > .main, .wrap {
    max-width: none; zoom: 1; padding: 0;
  }
  .sb, .nx-scrim, .nx-burger { display: none !important; }
  .rank-scroll, .tbl-scroll { overflow: visible; background: none; }
}
