/* ============================================================================
 * css/inet-mobile.css — adaptação do iNeteduca ao celular.
 *
 * POR QUE EXISTE: as ~186 páginas foram escritas para a mesa da secretaria, mas
 * quem mais usa está em campo — professora na sala, coordenação em visita, equipe
 * do CMAE na unidade. No aparelho o conteúdo estourava a largura, o alvo de toque
 * era de mouse e a ação principal ficava no topo, fora do alcance do polegar.
 *
 * COMO FUNCIONA: retrofit global. Nenhuma página é editada; este arquivo (mais o
 * js/inet-mobile.js) é injetado em todas e corrige por padrão estrutural. Por isso
 * é escrito com seletores de elemento e de utilitário do Tailwind, não de página.
 *
 * PRINCÍPIOS (PRODUCT.md): nada sai da tela · ação principal ao alcance do polegar
 * · toque de 44px · corpo ≥16px · o desktop não muda.
 *
 * ARMADILHAS DO CODEBASE respeitadas aqui:
 *  - toda classe que define `display` tem o par `.classe.hidden{display:none}`,
 *    senão o `.hidden` do Tailwind (usado pelo JS do site inteiro) não esconde;
 *  - `position:sticky` do cabeçalho quebra sob `overflow:hidden` no ancestral —
 *    por isso `overflow-x:clip`, que não cria contexto de rolagem;
 *  - z-index vem da escala semântica do brand.css, nunca valor solto.
 * ==========================================================================*/

/* tokens: o brand.css só carrega em 41 das 186 páginas, então os que este
   arquivo usa precisam existir por conta própria. Onde o brand.css carregar,
   ele já terá definido os mesmos valores e nada muda. */
:root{
  --inet-navy-900:#0A1D4D;
  --inet-navy-800:#102C70;
  --inet-cyan-700:#0FA9C8;
  --inet-line:#E3E8F4;
  --inet-txt:#1B2440;
  --inet-txt-2:#5C688A;
  --inet-surface:#FFFFFF;
  --inet-r-md:14px;
  --inet-ease:cubic-bezier(.32,.72,0,1);
  --inet-z-hdr:50; --inet-z-pop:60; --inet-z-dock:70;
  --inet-z-actionbar:65;          /* abaixo da dock de navegação, acima do conteúdo */
  --inet-tap:44px;                /* alvo mínimo de toque */
}

/* ========================================================== 1. NADA SAI ===
   A regra número um do PRODUCT.md. Rede de segurança global: o que não couber
   rola dentro do próprio container, nunca empurra a página. */
@media (max-width:1024px){
  html,body{ max-width:100%; }
  /* `clip` e não `hidden`: hidden cria contexto de rolagem e mata o
     position:sticky do cabeçalho (armadilha #3 do codebase). */
  body{ overflow-x:clip; }
  @supports not (overflow-x:clip){ body{ overflow-x:hidden; } }

  /* mídia e incorporações nunca passam da largura */
  img,svg,video,canvas,iframe,embed,object{ max-width:100%; height:auto; }

  /* palavra longa (e-mail, URL, nome composto) não empurra o bloco */
  h1,h2,h3,h4,h5,h6,p,li,td,th,dd,dt,label,span,a,strong,em{ overflow-wrap:break-word; }

  /* código e pré-formatado rolam sozinhos */
  pre,code,kbd,samp{ overflow-x:auto; max-width:100%; }

  /* Campo de formulário tem largura mínima própria (size=20 do HTML) e, dentro
     de uma linha flex, se recusa a encolher: em logs.html o `#search` com
     `flex-1` ficava com 237px e jogava a linha até 478px numa tela de 360.
     `min-width:0` é o que devolve o controle ao flex. */
  input,select,textarea{ min-width:0; max-width:100%; }

  /* `min-w-[250px]` e parentes foram escolhidos pensando na mesa da secretaria.
     No aparelho eles são exatamente o que impede o flex de encolher: em
     historico.html a linha de filtro (busca + situação + "mostrar
     transferidos") ia até 698px numa tela de 360. A classe do Tailwind vence
     por especificidade, então aqui precisa de `!important`. */
  [class*="min-w-["]{ min-width:0 !important; }

  /* Painel lateral fixo de 20rem (declaracao-comparecimento-responsavel):
     numa tela de 360px ele cobria a tela inteira e ainda empurrava o conteúdo
     20rem para a direita. No aparelho vira um bloco normal no topo. A
     combinação `fixed` + `h-screen` + `w-80` só aparece em painel de mesa. */
  [class~="w-80"][class~="h-screen"][class~="fixed"]{
    position:static !important; width:100% !important;
    height:auto !important; max-height:60vh; overflow-y:auto;
    border-right:0 !important;
  }
  [class~="ml-80"],[class~="ml-72"],[class~="ml-64"]{ margin-left:0 !important; }
}

/* ===================================================== 2. TIPO E LEITURA ===
   16px em campo de formulário não é estética: abaixo disso o iOS dá zoom
   sozinho ao focar, o layout salta e a pessoa perde o contexto. */
@media (max-width:768px){
  input,select,textarea{ font-size:16px !important; }

  /* texto miúdo demais para ler de pé, em movimento */
  .text-\[10px\],.text-\[11px\]{ font-size:12px; }
  .text-xs{ font-size:.8125rem; }
}

/* ====================================================== 3. TOQUE (44px) ===
   Vale por tipo de ponteiro, não por largura: notebook com tela sensível
   também é toque, e tablet com mouse não é. */
@media (pointer:coarse){
  button,
  [role="button"],
  a.btn, .btn,
  input[type="button"],input[type="submit"],input[type="reset"],
  select{
    min-height:var(--inet-tap);
  }
  /* botão só de ícone precisa de largura também */
  button:not(:has(span)):not(:has(p)){ min-width:var(--inet-tap); }

  /* caixa de marcação do tamanho do dedo */
  input[type="checkbox"],input[type="radio"]{
    min-width:22px; min-height:22px;
  }

  /* linha de lista clicável ganha respiro entre alvos */
  .inet-m-lista > * + *{ margin-top:.5rem; }
}

/* nada de função dependente de hover onde não existe hover */
@media (hover:none){
  .group:hover .group-hover\:opacity-100,
  .hover\:opacity-100:hover{ opacity:1; }
}

/* ========================================================== 4. ESTRUTURA ===
   Coluna única no celular. Só onde a página não declarou breakpoint próprio —
   as classes `sm:` / `md:` / `lg:` do Tailwind têm precedência e são respeitadas. */
@media (max-width:768px){
  /* grid escrito direto no style, sem breakpoint */
  [style*="grid-template-columns"]{ grid-template-columns:1fr !important; }

  /* margens laterais menores: em 375px, 2rem de cada lado come 17% da tela */
  .container,.max-w-7xl,.max-w-6xl,.max-w-5xl{ padding-left:1rem; padding-right:1rem; }

  /* barra de filtros/ações vira empilhada em vez de espremer */
  .inet-m-empilha{ flex-direction:column; align-items:stretch; }
  .inet-m-empilha.hidden{ display:none; }
  .inet-m-empilha > *{ width:100%; }
}

/* ======================================================== 5. TABELA ROLA ===
   O JS envolve toda <table> num .inet-m-tbwrap. A tabela mantém o alinhamento
   de colunas (nada de `display:block`, que destrói o layout de tabela) e quem
   rola é o container. */
.inet-m-tbwrap{
  /* `min-width:0` junto com o `max-width:100%`: dentro de um container flex o
     `max-width` sozinho não segura, porque a base do item vem do conteúdo */
  display:block; max-width:100%; min-width:0; overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;         /* não puxa a navegação do navegador */
  scrollbar-width:thin;
}
.inet-m-tbwrap.hidden{ display:none; }

/* dica de que há mais conteúdo à direita — some ao chegar no fim */
@media (max-width:1024px){
  .inet-m-tbwrap{
    background:
      linear-gradient(90deg,var(--inet-surface) 30%,transparent) left / 28px 100% no-repeat,
      linear-gradient(90deg,transparent,var(--inet-surface) 70%) right / 28px 100% no-repeat,
      radial-gradient(farthest-side at 0 50%,rgba(16,44,112,.12),transparent) left / 12px 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%,rgba(16,44,112,.12),transparent) right / 12px 100% no-repeat;
    background-attachment:local,local,scroll,scroll;
  }
}

/* ============================== 5b. O MODAL MANDA NA TELA =================
   ESTE É O BUG QUE FAZIA O "GERAR PDF NÃO FUNCIONAR": o modal é z-[60] e a dock
   de navegação é z-index 70 — a barra ficava POR CIMA do modal, cobrindo os
   botões "Cancelar" e "Gerar PDF". Não era o download que falhava: o dedo
   acertava a dock, não o botão.
   Com um modal aberto, nada de navegação disputa a tela. */
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) .inh-dock,
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) #headerExpandTabs,
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) #theme-switcher,
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) #gabbanaFab,
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) .gabbana-fab,
body:has(.fixed.inset-0:not(.hidden):not(.modal-backdrop):not([id*="oading"]):not([id*="pinner"]):not([class*="pointer-events-none"]):not([class*="z-0"])) [class*="gabbana-launcher"],
body.inet-m-modal-aberto .inh-dock,
body.inet-m-modal-aberto #headerExpandTabs,
body.inet-m-modal-aberto #theme-switcher,
body.inet-m-modal-aberto #gabbanaFab,
body.inet-m-modal-aberto .gabbana-fab,
body.inet-m-modal-aberto [class*="gabbana-launcher"]{
  opacity:0 !important; pointer-events:none !important; visibility:hidden !important;
}
/* NÃO travar a rolagem do body aqui.
   `overflow:hidden` no <body> foi o que deixou a página sem rolar com um dedo
   (com dois, o Safari rola por outro caminho — foi exatamente o sintoma que
   apareceu). Num retrofit que vale para 186 páginas, o risco de a classe ficar
   grudada e travar o sistema inteiro não compensa o conforto de não rolar atrás
   da folha. A folha já contém a própria rolagem via `overscroll-behavior`. */

/* o aviso de processamento nunca cobre botão: sobe para o topo com o modal aberto */
body.inet-m-modal-aberto .inet-m-toast{
  bottom:auto; top:calc(.75rem + env(safe-area-inset-top));
}

/* ===================================================== 6. MODAL COM AR ===
   Armadilha #15 do codebase, e a causa real do "botão de PDF não funciona": o
   modal de opções do relatório é alto, fica centralizado e o topo sai da tela —
   sem rolagem no overlay, não há como chegar aos campos nem ao botão de gerar.

   O padrão do codebase é este, e a centralização mora no FILHO, não no overlay:
     <div class="hidden fixed inset-0 z-[60]">          <- overlay
       <div class="modal-backdrop fixed inset-0"></div> <- fundo
       <div class="flex items-center justify-center min-h-screen p-4">
         <div class="modal-content ...">                <- cartão

   Por isso as regras abaixo miram a estrutura, não uma classe que o JS precise
   acertar. `.hidden` continua vencendo em todas (o site inteiro abre e fecha
   modal por essa classe). */
@media (max-width:768px){
  /* 1. o overlay passa a rolar */
  .fixed.inset-0:not(.modal-backdrop):not(.inh-dock):not([id*="oading"]):not([id*="pinner"]){
    overflow-y:auto; -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
  }
  .fixed.inset-0.hidden{ display:none !important; }

  /* 2. o miolo alinha ao TOPO — centralizar é o que corta a cabeça do modal */
  .fixed.inset-0 > .flex.items-center,
  .fixed.inset-0 > div > .flex.items-center{
    align-items:flex-start !important;
    padding:.6rem !important;
  }
  /* min-h-screen dentro de overlay vira 100% do overlay, não da janela */
  .fixed.inset-0 .min-h-screen{ min-height:100% !important; }

  /* 3. o cartão usa a largura toda e respira menos por dentro:
        p-8 são 64px dos 375px da tela, só de padding lateral */
  .fixed.inset-0 .modal-content,
  .fixed.inset-0 [class*="rounded-3xl"][class*="w-full"]{
    max-width:100% !important;
    padding:1.1rem !important;
    border-radius:1.25rem !important;
    margin-bottom:calc(1rem + env(safe-area-inset-bottom));
  }

  /* 4. grade interna do modal nunca fica lado a lado em 375px */
  .fixed.inset-0 .grid[class*="grid-cols-"]{ grid-template-columns:1fr !important; }
  .fixed.inset-0 .grid{ gap:1rem !important; }

  /* 5. os botões de ação do modal ficam grandes e empilhados */
  .fixed.inset-0 .modal-content button{ min-height:var(--inet-tap); }
}

/* ================================ 6b. MODAL COMO FOLHA DE APLICATIVO ======
   Estrutura de app: título preso no topo, ações presas no rodapé, e só o miolo
   rola entre os dois. É o que faz o "Gerar PDF" estar sempre à mão em vez de a
   500px de rolagem, e o que dá a sensação de aplicativo em vez de página. */
@media (max-width:768px){
  /* Numa folha de aplicativo quem rola é o MIOLO, nunca o overlay. Deixar o
     overlay rolar empurra a folha inteira para fora da tela e o botão de ação
     vai junto — foi o que o teste flagrou: "Gerar PDF" fora da viewport. */
  .fixed.inset-0:not(.modal-backdrop):not(.inh-dock):has(.modal-content){
    overflow:hidden !important;
  }
  .fixed.inset-0 > .flex.items-center,
  .fixed.inset-0 > div > .flex.items-center{
    padding:0 !important;
    height:100% !important; min-height:0 !important;
    align-items:flex-end !important;
  }
  /* A folha é ancorada na PRÓPRIA viewport, não no alinhamento do wrapper.
     Depender do flex do pai deixava o cartão terminar 60px abaixo da tela
     (medido: 125→872 numa tela de 812) e o botão de ação ia junto. Com
     `position:fixed` no rodapé, a folha começa e termina onde deve, sempre. */
  .fixed.inset-0:not([id*="oading"]):not([id*="pinner"]) .modal-content{
    position:fixed !important;
    left:0 !important; right:0 !important; bottom:0 !important; top:auto !important;
    width:100% !important; max-width:100% !important;
    height:auto !important; max-height:92svh; max-height:92dvh;
    display:flex; flex-direction:column;
    padding:0 !important; margin:0 !important;
    border-radius:1.5rem 1.5rem 0 0 !important;
    overflow:hidden;
    transform:none !important;                 /* o site anima com scale-95: aqui atrapalha */
    opacity:1 !important;
    animation:inet-m-sobe .28s var(--inet-ease) both;
  }
  /* alça de folha, como app: sinaliza que dá para arrastar/fechar */
  .fixed.inset-0 .modal-content::before{
    content:''; flex:0 0 auto; width:2.5rem; height:.25rem; margin:.55rem auto .1rem;
    border-radius:99px; background:var(--inet-line);
  }
  /* Título e ações são marcados pelo JS (`marcarPartesDoModal`), não deduzidos
     por `:first-of-type` / `:last-child`. A dedução por posição transformava o
     `<form>` inteiro do add-pessoas em barra de ações e o desenhava em linha,
     jogando metade do formulário para fora da tela. */
  /* título preso no topo */
  .fixed.inset-0 .modal-content > .inet-m-modal-titulo{
    flex:0 0 auto; position:sticky; top:0; z-index:2;
    margin:0 !important; padding:.75rem 1.1rem !important;
    background:var(--inet-surface);
    border-bottom:1px solid var(--inet-line);
  }
  .fixed.inset-0 .modal-content > .inet-m-modal-titulo h3,
  .fixed.inset-0 .modal-content > .inet-m-modal-titulo h2{
    font-size:1.0625rem !important; line-height:1.3;
  }
  /* miolo rola */
  .fixed.inset-0 .modal-content > *:not(.inet-m-modal-titulo):not(.inet-m-modal-acoes){
    flex:1 1 auto; overflow-y:auto; -webkit-overflow-scrolling:touch;
    padding:.9rem 1.1rem !important; margin:0 !important;
  }
  /* ações presas no rodapé, do tamanho do dedo */
  .fixed.inset-0 .modal-content > .inet-m-modal-acoes{
    flex:0 0 auto; position:sticky; bottom:0; z-index:2;
    display:flex; gap:.6rem; margin:0 !important;
    padding:.75rem 1.1rem calc(.75rem + env(safe-area-inset-bottom)) !important;
    background:var(--inet-surface);
    border-top:1px solid var(--inet-line);
    box-shadow:0 -10px 24px -18px rgba(10,25,70,.5);
  }
  .fixed.inset-0 .modal-content > .inet-m-modal-acoes > button{
    flex:1; min-height:48px; margin:0 !important; font-size:.95rem;
  }
}

/* ==================================== 7b. DENSIDADE DE APLICATIVO ========
   O que fazia a tela parecer "feia" no celular não era erro de layout, era
   escala de desktop: título de 2rem, cartão com 2rem de padding, cada AVD
   ocupando uma tela inteira. Aqui o ritmo é recalibrado para a mão. */
@media (max-width:768px){
  h1{ font-size:1.5rem !important; line-height:1.2; }
  h2{ font-size:1.25rem !important; line-height:1.25; }
  h3{ font-size:1.0625rem !important; line-height:1.3; }
  .text-4xl,.text-3xl{ font-size:1.5rem !important; }
  .text-2xl{ font-size:1.25rem !important; }

  /* cartões respiram menos: 2rem de padding come 1/6 da largura */
  .p-8{ padding:1.1rem !important; }
  .p-6{ padding:.95rem !important; }
  .px-8{ padding-left:1.1rem !important; padding-right:1.1rem !important; }
  .py-8{ padding-top:1.1rem !important; padding-bottom:1.1rem !important; }
  .gap-8{ gap:1rem !important; }
  .gap-6{ gap:.85rem !important; }
  .mb-8{ margin-bottom:1rem !important; }
  .space-y-6 > * + *{ margin-top:.85rem !important; }

  /* cantos menos exagerados na mão */
  .rounded-3xl{ border-radius:1.15rem !important; }

  /* AVDs e afins: blocos empilhados viram linha compacta de 3 */
  .inet-m-trio{ display:grid !important; grid-template-columns:repeat(3,1fr) !important; gap:.5rem !important; }
  .inet-m-trio.hidden{ display:none !important; }
  .inet-m-trio > *{ padding:.7rem .4rem !important; text-align:center; }
  .inet-m-trio .w-12,.inet-m-trio .w-14,.inet-m-trio .w-16{ width:2rem !important; height:2rem !important; margin:0 auto .35rem !important; }
  .inet-m-trio [class*="text-"]{ font-size:.7rem !important; line-height:1.25; }

  /* fileira de pílulas (LAU · DIAG · REL · PAR · HIS…) em grade uniforme,
     em vez de flex-wrap desalinhado em seis linhas */
  .inet-m-grade-pilulas{ display:grid !important; grid-template-columns:repeat(3,minmax(0,1fr)) !important; gap:.4rem !important; }
  .inet-m-grade-pilulas.hidden{ display:none !important; }
  .inet-m-grade-pilulas > *{ width:100% !important; margin:0 !important; min-height:2.5rem; justify-content:center; font-size:.72rem !important; padding:.35rem .3rem !important; }

  /* Legenda de cores: SAI do celular a pedido da rede. São 8 pílulas que
     abriam meia tela antes do conteúdo, para explicar cores que já aparecem
     no anel de status de cada aluno. No computador ela continua igual. */
  .inet-m-legenda{ display:none !important; }
}

/* variante folha-de-baixo, aplicada pelo JS onde o modal é curto e simples */
@media (max-width:768px){
  .inet-m-modal:not([id*="oading"]):not([id*="pinner"]){ align-items:flex-end !important; padding:0 !important; }
  .inet-m-modal.hidden{ display:none !important; }
  .inet-m-modal > .inet-m-modal-card{
    width:100%; max-width:100%;
    max-height:92vh; overflow-y:auto;
    border-radius:1.25rem 1.25rem 0 0;
    padding-bottom:calc(1rem + env(safe-area-inset-bottom));
    animation:inet-m-sobe .26s var(--inet-ease) both;
  }
}
@keyframes inet-m-sobe{ from{ transform:translateY(12px); opacity:.7 } to{ transform:none; opacity:1 } }

/* ============================================== 7. AÇÃO AO ALCANCE DO DEDO ===
   Princípio 3 do PRODUCT.md. O JS move o botão primário da página (salvar,
   emitir, registrar) para esta barra quando a tela é de celular. */
.inet-m-actionbar{ display:none; }
.inet-m-actionbar.hidden{ display:none !important; }
@media (max-width:768px){
  .inet-m-actionbar{
    display:flex; gap:.5rem; align-items:center;
    position:fixed; left:0; right:0;
    bottom:0; z-index:var(--inet-z-actionbar);
    padding:.6rem .9rem calc(.6rem + env(safe-area-inset-bottom));
    background:rgba(255,255,255,.92);
    backdrop-filter:blur(18px) saturate(160%);
    -webkit-backdrop-filter:blur(18px) saturate(160%);
    border-top:1px solid var(--inet-line);
    box-shadow:0 -8px 28px -18px rgba(10,25,70,.5);
  }
  .inet-m-actionbar > *{ flex:1; min-height:var(--inet-tap); }
  /* quando a dock de navegação também existe, uma fica acima da outra */
  body.inet-m-tem-dock .inet-m-actionbar{ bottom:4.6rem; }
  /* o espaço no fim da página é reservado na seção 9g, por espaçador `::after`:
     `padding-bottom` aqui não funcionava nas páginas com `h-full` no body. */
}

/* ===================================================== 8. ÁREAS SEGURAS ===
   Entalhe e barra de gestos do aparelho. */
@media (max-width:1024px){
  .inet-m-safe-b{ padding-bottom:max(.75rem,env(safe-area-inset-bottom)); }
  .inet-m-safe-x{
    padding-left:max(.75rem,env(safe-area-inset-left));
    padding-right:max(.75rem,env(safe-area-inset-right));
  }
}

/* ============================================ 8b. NADA ATRÁS DA DOCK ======
   A dock é position:fixed no rodapé e a página não reservava espaço para ela: o
   último cartão ficava escondido atrás — foi o que apareceu no iPhone, com
   "Educação Infantil" e o cartão roxo cobertos.
   A reserva de espaço mudou de lugar: está na seção 9g, feita por espaçador
   `::after`, porque `padding-bottom` no <body> não cria rolagem nas páginas que
   usam `h-full`. Ver o comentário de lá antes de trazer o padding de volta. */

/* O assistente flutuante disputava o mesmo canto e cobria um item da dock.
   Sobe para cima dela e sai do caminho dos alvos de toque. */
@media (max-width:1024px){
  #gabbanaFab,#gabbana-fab,.gabbana-fab,
  [id*="gabbanaBtn"],[class*="gabbana-launcher"]{
    bottom:calc(6.25rem + env(safe-area-inset-bottom)) !important;
    z-index:calc(var(--inet-z-dock) - 1) !important;
  }
}

/* ======================================= 8c. BARRA DE AÇÕES QUE ROLA ======
   Linha de botões (Backup · Migrar Dados · Alunos Regulares · Novo Aluno) que
   estourava e ficava cortada nas duas pontas, sem indicação de que havia mais.
   Vira uma faixa que rola com encaixe, e o corte deixa de parecer defeito. */
@media (max-width:768px){
  .inet-m-rolagem{
    display:flex; flex-wrap:nowrap;
    overflow-x:auto; overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    /* sem margin negativa: quando o pai não tem o padding correspondente, ela
       joga a barra para fora e a página inteira passa a estourar na horizontal. */
    padding-inline:.15rem;
    scroll-padding-inline:.15rem;
    max-width:100%;
    /* sem `min-width:0` um item de flex nunca encolhe abaixo do próprio
       conteúdo, e a barra continua estourando o pai mesmo com max-width */
    min-width:0;
  }
  .inet-m-rolagem::-webkit-scrollbar{ display:none; }
  .inet-m-rolagem.hidden{ display:none; }
  .inet-m-rolagem > *{ flex:0 0 auto; scroll-snap-align:start; }
}

/* ============================== 8d. CABEÇALHO SEM SOBREPOSIÇÃO ============
   "Escola Arco Íris" passava por cima da pílula do ano quando o cabeçalho
   encolhia. O brand.css zera o max-width do nome no celular; aqui devolvemos
   um limite e deixamos o texto truncar, que é o comportamento correto. */
@media (max-width:768px){
  /* Largura fixa não resolve: o nome começa depois da logo e ainda alcança a
     pílula. O certo é deixar o flex fazer a conta — o bloco da marca encolhe
     até o espaço que sobra, e o nome corta com reticências dentro dele.
     `min-width:0` é o que destrava isso: sem ele, item de flex nunca encolhe
     abaixo do tamanho do próprio conteúdo. */
  .inh-bar{ display:flex; align-items:center; }
  .inh-brand{ flex:1 1 auto; min-width:0; overflow:hidden; }
  .inh-org,.inh-org-txt{ min-width:0; overflow:hidden; }
  .inh-name{
    display:block; max-width:100%;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* a pílula do ano nunca encolhe nem é coberta */
  .inh-pill,#yearSelectorBtn,[id*="yearSelector"]{
    flex:0 0 auto; position:relative; z-index:1;
  }

  /* ---- cabeçalho que não é o `.inh`: a linha do topo estourava a tela ----
     Medido em atv.pr.html a 354px: a `nav` do cabeçalho terminava em 354 mas o
     carimbo do iNeteduca ia de 444 a 595, ou seja, 240px fora da tela, e a
     página inteira rolava de lado. O carimbo é marcado `flex:0 0 auto` no
     brand.css (para não ser espremido no quadrado de 40px do desktop) e no
     aparelho isso vira "não encolho de jeito nenhum".
     Aqui ele passa a poder encolher — a proporção é mantida por `height:auto`,
     que é o que preserva o 5,5:1 exigido pela marca. */
  /* `min-width:0` em tudo que é filho direto do cabeçalho: sem isso um item de
     flex nunca encolhe abaixo do próprio conteúdo e a linha inteira vaza.
     Foi o que estourava duvidas.html, duvidas.tutorial.html e leitor_nfe.html. */
  header,header nav,#mainHeader,#mainHeader nav{ min-width:0; }
  header > *,header > nav > *,#mainHeader > *,#mainHeader > nav > *{ min-width:0; }

  /* `min-width:0` sozinho é veneno para botão redondo: o flex passa a poder
     encolher QUALQUER item, e no atv.pr o `#backBtn` de 40px virou 8px de
     largura enquanto o título era espremido em 46px e descia 324px de altura.
     Controle e marca não encolhem; quem cede espaço é o texto. */
  header button,header a,header img,header svg,header input,
  #mainHeader button,#mainHeader a,#mainHeader img,#mainHeader svg{ flex-shrink:0; }

  /* e a linha do cabeçalho pode quebrar: duas linhas é melhor do que botão
     amassado ou marca desenhada fora da tela */
  header > div,header nav,#mainHeader > div,#mainHeader nav{
    flex-wrap:wrap; row-gap:.4rem;
  }
  /* Quando a página fixa a altura do cabeçalho (`h-16` = 64px), a linha que
     quebrou vaza para fora da caixa e é desenhada por cima do conteúdo. O JS
     mede isso e marca só os cabeçalhos que podem crescer sem tapar nada
     (`ajustarAlturaDoCabecalho`, nunca em `position:fixed`). */
  .inet-m-cab-cresce{ height:auto !important; }
  /* texto de cabeçalho corta com reticências em vez de empurrar a linha
     (o id do sistema em historico.html tinha 203px numa tela de 360px) */
  header h1,header h2,header p,header [id*="ystemId"],
  #mainHeader h1,#mainHeader h2,#mainHeader p,#mainHeader [id*="ystemId"]{
    min-width:0; overflow:hidden; text-overflow:ellipsis;
  }
  /* dentro do cabeçalho, qualquer linha flex pode encolher (fora dele a regra
     seria arriscada: encolheria avatar e ícone de largura fixa) */
  header .flex > *,#mainHeader .flex > *{ min-width:0; }
}

/* em tela estreita (Android de 360px e menores) a folga lateral do cabeçalho é
   justamente o que faz o botão de perfil sair alguns pixels da tela */
@media (max-width:400px){
  header > div,header > nav,#mainHeader > div,#mainHeader > nav{
    padding-left:.7rem !important; padding-right:.7rem !important;
  }
  header .inet-logo-horizontal,
  #mainHeader .inet-logo-horizontal,
  #ineteducaHeaderLogo{
    flex:0 1 auto !important;
    max-width:30vw !important;
    width:auto; height:auto !important;
  }
}

/* =============================================== 9. AVISO DE PROCESSAMENTO ===
   "Funciona ou avisa" (princípio 5). Usado pelo JS quando o PDF está sendo
   gerado — em rede ruim isso leva segundos e o silêncio parece defeito. */
.inet-m-toast{
  display:none; position:fixed; z-index:var(--inet-z-pop);
  left:50%; transform:translateX(-50%);
  bottom:calc(1.25rem + env(safe-area-inset-bottom));
  max-width:min(92vw,26rem);
  padding:.7rem 1rem; border-radius:var(--inet-r-md);
  background:var(--inet-navy-900); color:#fff;
  font-size:.875rem; font-weight:600; line-height:1.35;
  box-shadow:0 20px 44px -20px rgba(4,11,35,.8);
}
.inet-m-toast.is-on{ display:block; animation:inet-m-toast-in .22s var(--inet-ease) both; }
.inet-m-toast.hidden{ display:none !important; }
@keyframes inet-m-toast-in{ from{ transform:translate(-50%,10px); opacity:0 } to{ transform:translate(-50%,0); opacity:1 } }

/* ================================ 9b. O QUE FAZ PARECER APLICATIVO ========
   Não é enfeite: são os detalhes que o navegador faz por padrão e que
   denunciam "isto é um site". Cada um aqui tem um motivo.                 */
@media (max-width:1024px){
  /* 1. O retângulo cinza que o iOS pisca em cada toque é a marca registrada
        de site. Sai — e no lugar entra um retorno que nós controlamos. */
  *{ -webkit-tap-highlight-color:transparent; }

  /* 2. Retorno imediato ao toque. App responde ao dedo; site espera o clique. */
  button:active,[role="button"]:active,a.btn:active,.btn:active,
  .inh-tab:active,.inet-m-cartao:active{
    transform:scale(.975);
    transition:transform .06s ease-out;
  }

  /* 3. Texto de interface não se seleciona por acidente ao rolar/segurar.
        O CONTEÚDO continua selecionável — nome, CID e laudo a pessoa precisa
        conseguir copiar. */
  button,.inh-tab,.inh-dock,nav,th,label,
  .inet-m-actionbar,.inet-m-tbwrap[role="region"] > table > thead{
    -webkit-user-select:none; user-select:none;
  }

  /* 4. Sem o "elástico" da página inteira ao chegar no fim — em app o fim é
        o fim. Dentro de tabela e folha, a rolagem também não vaza. */
  html{ overscroll-behavior-y:none; }

  /* 5. O iOS aumenta fonte sozinho em landscape e quebra o layout. */
  html{ -webkit-text-size-adjust:100%; text-size-adjust:100%; }

  /* 6. Rolagem com inércia, como app nativo. */
  body,.inet-m-tbwrap,.modal-content > *{ -webkit-overflow-scrolling:touch; }

  /* 7. Título de seção acompanha a rolagem, para não perder o contexto de qual
        etapa se está lendo numa lista longa de turmas. */
  .inet-m-secao-titulo{
    position:sticky; top:0; z-index:2;
    padding:.55rem .9rem !important; margin:0 0 .6rem !important;
    background:rgba(238,241,248,.92);
    backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
    border-bottom:1px solid var(--inet-line);
    font-size:.95rem !important;
  }
  .inet-m-secao-titulo.hidden{ display:none !important; }

  /* 8. Cartão de app: leve, com toque de superfície, sem sombra de brochura. */
  .inet-m-cartao{
    border-radius:1rem !important;
    box-shadow:0 1px 2px rgba(16,44,112,.06) !important;
    border:1px solid var(--inet-line) !important;
  }
  .inet-m-cartao.hidden{ display:none !important; }

  /* 9. Rolagem para âncora não passa por baixo do cabeçalho fixo. */
  html{ scroll-padding-top:4.5rem; }

  /* 10. Foco visível para quem navega por teclado/leitor — acessibilidade não
         é opcional (PRODUCT.md) e o :active acima não substitui isto. */
  :focus-visible{ outline:2px solid var(--inet-cyan-700); outline-offset:2px; }
}

/* ================== 9d. CARTÃO DE TURMA COMPACTO (só celular) ============
   O cartão ocupava quase uma tela inteira por turma: cabeçalho colorido alto,
   nome em 1.25rem, contadores grandes e um estado vazio com ícone enorme. Numa
   escola com 13 turmas isso é muita rolagem para pouca informação. */
@media (max-width:768px){
  /* faixa colorida do topo */
  .inet-m-cartao > [class*="bg-gradient-to-r"]{ padding:.6rem .75rem !important; }
  .inet-m-cartao > [class*="bg-gradient-to-r"] h3{
    font-size:1rem !important; line-height:1.2 !important;
  }
  /* pílula dos contadores */
  .inet-m-cartao > [class*="bg-gradient-to-r"] .rounded-full{
    padding:.15rem .55rem !important; font-size:.72rem !important; gap:.45rem !important;
  }
  .inet-m-cartao > [class*="bg-gradient-to-r"] .rounded-full i{ font-size:.8rem !important; }

  /* linha PROF / turno */
  .inet-m-cartao [class*="PROF"],
  .inet-m-cartao > div:nth-child(2){ padding-top:.55rem !important; padding-bottom:.55rem !important; }

  /* estado vazio: o ícone de caixa ocupava meia tela para dizer "nenhum aluno" */
  .inet-m-cartao svg,
  .inet-m-cartao [class*="text-5xl"],.inet-m-cartao [class*="text-6xl"]{ font-size:1.5rem !important; }
  .inet-m-cartao [class*="py-10"],.inet-m-cartao [class*="py-12"],
  .inet-m-cartao [class*="py-16"]{ padding-top:1rem !important; padding-bottom:1rem !important; }
}

/* ====== 9e. NOME DA ESCOLA FORA DO NAVY + MARCAS CENTRADAS (só celular) ===
   Entre as duas marcas e o seletor de ano não sobra largura no aparelho: o nome
   da escola era espremido até virar uma letra por linha ("C / M"). A pedido da
   rede, no celular ele sai do navy e vira uma faixa logo abaixo — e o cabeçalho
   fica só com o carimbo do município e o do iNeteduca, centralizados.
   No computador o cabeçalho continua exatamente como está hoje. */
@media (max-width:768px){
  /* O nome sai do cabeçalho (o JS já o recriou embaixo). `#headerTitle` fica
     três níveis abaixo de #mainHeader (header > nav > div > h1), então seletor
     de filho direto não alcança — precisa ser descendente. */
  body.inet-m-nome-fora .inh .inh-name,
  body.inet-m-nome-fora .inh .inh-org-txt,
  body.inet-m-nome-fora #headerTitle,
  body.inet-m-nome-fora #mainHeader h1,
  body.inet-m-nome-fora #mainHeader h2{ display:none !important; }

  /* as duas marcas ocupam o centro; o seletor de ano fica encostado à direita */
  body.inet-m-nome-fora .inh-bar{
    justify-content:center !important;
    gap:.6rem !important; padding:.5rem .7rem !important;
    position:relative;
  }
  body.inet-m-nome-fora .inh-brand{
    flex:0 1 auto !important;
    justify-content:center !important;
    margin-inline:auto;
  }
  /* NADA DE `position:absolute` AQUI. A ideia original era tirar o seletor de
     ano do fluxo para as marcas ficarem no centro, e ela estava errada por dois
     motivos, os dois fotografados no iPhone em 08/08/2026:

     (a) `.inh-pill` NÃO é a pílula do ano — o `padronizarAcoes` do brand.js põe
         essa classe em TODO botão do cabeçalho. No formacao-dashboard isso dava
         cinco botões (início, solicitações, tema, perfil, notificações) todos
         em `right:.7rem`, empilhados um em cima do outro, virando uma pasta de
         círculos translúcidos no canto;
     (b) a mesma classe está nas abas da barra inferior do school-dashboard, e
         tirá-las do fluxo fazia a barra colapsar para 10px, com as abas
         desenhadas de 779px a 819px numa tela de 812px.

     A versão correta não tira ninguém do fluxo: a marca cresce e ocupa o meio,
     os botões ficam numa linha à direita. Quando não cabem, a linha desce —
     cabeçalho um pouco mais alto é muito melhor do que botão em cima de botão. */
  body.inet-m-nome-fora #mainHeader .inh-pill,
  body.inet-m-nome-fora .inh-bar .inh-pill,
  body.inet-m-nome-fora #mainHeader [id*="yearSelector"],
  body.inet-m-nome-fora .inh-bar [id*="yearSelector"],
  #headerExpandTabs .inh-pill,
  .inh-dock .inh-pill{
    position:relative !important; top:auto !important; right:auto !important;
    transform:none !important; flex:0 0 auto;
  }
  body.inet-m-nome-fora .inh-brand{ padding-right:0; }

  /* Com os botões de volta ao fluxo, a linha de ações do cabeçalho precisa
     poder quebrar. No admin-dashboard ela ia de 87px a 610px numa tela de
     385px — o "Migrar Dados" sozinho ocupa 275px. Quebrar em duas linhas deixa
     o cabeçalho mais alto e é o preço certo a pagar: melhor um cabeçalho de
     duas linhas do que botão desenhado fora da tela. */
  .inh-bar{ flex-wrap:wrap; row-gap:.4rem; }
  .inh-actions{
    flex-wrap:wrap; justify-content:flex-end;
    gap:.4rem; min-width:0; max-width:100%;
  }
  .inh-actions > *{ flex:0 0 auto; max-width:100%; }

  /* ---- barra do calendário (FullCalendar): agendas do CMAE, AEE, psico ----
     A barra do FullCalendar é `flex-wrap:nowrap`. Numa tela de 385px o título
     era espremido em 65px — "8 de agosto de 2026" saía com uma palavra por
     linha, 100px de altura — e o grupo Mês/Semana/Dia terminava em 390px, com
     o "Dia" cortado pela borda. Deixar quebrar resolve os dois. */
  .fc .fc-toolbar,.fc-header-toolbar{
    flex-wrap:wrap !important; justify-content:center !important; gap:.5rem;
  }
  .fc .fc-toolbar-chunk{ display:flex; align-items:center; gap:.35rem; flex:0 0 auto; }
  .fc .fc-toolbar-title{ font-size:1.05rem !important; white-space:nowrap; }
  .fc .fc-button{ padding:.35rem .6rem !important; font-size:.8rem !important; }

  /* a faixa do nome, logo abaixo do navy */
  .inet-m-escola-faixa{
    display:block;
    padding:.5rem .9rem calc(.5rem + 2px);
    background:var(--inet-surface);
    border-bottom:1px solid var(--inet-line);
    color:var(--inet-navy-800);
    font-size:.9rem; font-weight:800; line-height:1.25;
    text-align:center; letter-spacing:-.01em;
    text-wrap:balance;
  }
  .inet-m-escola-faixa.hidden{ display:none !important; }
}
/* no computador a faixa não existe */
@media (min-width:769px){ .inet-m-escola-faixa{ display:none !important; } }

/* ============ 9c. LADRILHOS DE AÇÃO EM alunos.html (só celular) ==========
   A pedido: no aparelho, a fileira de ações vira grade de 2 colunas com ícone
   em cima e rótulo embaixo, no mesmo desenho dos atalhos do admin-dashboard,
   com METADE da altura deles. Antes era uma faixa horizontal que ficava cortada
   nas duas pontas e escondia metade das ações.

   Mira os IDs, que só existem em alunos.html — nenhuma outra página é tocada.
   NADA disto vale acima de 768px: no computador a barra continua exatamente
   como está hoje. */
@media (max-width:768px){
  /* o container de cada fileira vira grade */
  #addAlunoBtnContainer:not(.ga-nova),
  div:has(> #openPdfGeralBtn):not(.ga-direita),
  #superAdminTools:not(.ga-nova){
    display:grid !important;
    grid-template-columns:1fr 1fr !important;
    gap:.45rem !important;
    width:100% !important;
    border:0 !important; padding:0 !important; margin:0 !important;
    align-items:stretch !important;
  }
  /* o grupo de superadmin ocupa a linha inteira e distribui os seus dentro */
  #superAdminTools:not(.ga-nova){ grid-column:1 / -1 !important; }
  #superAdminTools:not(.ga-nova) > .relative{ display:block; }

  /* cada ação vira um ladrilho compacto — SEMPRE dentro de um dos três
     containers de alunos.html. Mirar só o id era errado: `#migrateDataBtn`
     também existe no cabeçalho do admin-dashboard, e lá esta regra reimpunha
     `display:flex !important`, vencendo o `display:none` da própria página e
     mantendo na tela justamente o botão que atrapalha no celular. */
  :is(#addAlunoBtnContainer:not(.ga-nova),#superAdminTools:not(.ga-nova),div:has(> #openPdfGeralBtn):not(.ga-direita))
  :is(#backupMenuBtn,#migrateDataBtn,#regularesNavBtn,#addAlunoBtn,
      #openPdfGeralBtn,#openPdfDiagnosticoBtn,#openEntrevistasBtn){
    display:flex !important;
    flex-direction:column !important;
    align-items:center !important;
    justify-content:center !important;
    gap:.2rem !important;
    width:100% !important;
    min-height:54px !important;          /* ~metade do ladrilho do admin, e ainda tocável */
    padding:.45rem .3rem !important;
    border-radius:.85rem !important;
    font-size:.7rem !important;
    line-height:1.15 !important;
    text-align:center !important;
    white-space:normal !important;
    box-shadow:0 1px 2px rgba(16,44,112,.06) !important;
  }
  /* o ícone sobe e ganha corpo, como no ladrilho do painel */
  :is(#addAlunoBtnContainer:not(.ga-nova),#superAdminTools:not(.ga-nova),div:has(> #openPdfGeralBtn):not(.ga-direita))
  :is(#backupMenuBtn,#migrateDataBtn,#regularesNavBtn,#addAlunoBtn,
      #openPdfGeralBtn,#openPdfDiagnosticoBtn,#openEntrevistasBtn) > i{
    font-size:1.05rem !important; line-height:1 !important; margin:0 !important;
  }
  /* o menu do backup abre ancorado no ladrilho, sem sair da tela */
  #backupDropdown{ right:auto !important; left:0 !important; width:min(15rem,86vw) !important; }

  /* o aviso de pendências fecha a grade ocupando a linha toda */
  #pendenciasAvisoContainer{ grid-column:1 / -1; margin:0 !important; width:100%; }
  #pendenciasAvisoContainer > span{ width:100%; justify-content:center; }

  /* ---- barra NOVA da alunos.html (reestruturada em 17/08/2026) ----
     Ela já nasce responsiva: as pílulas quebram sozinhas. Aqui só o respiro
     e a busca ocupando a linha inteira, que é a ação do dia a dia. */
  .ga-topo{ gap:.55rem !important; }
  .ga-topo .ga-busca{ flex:1 1 100% !important; order:3; }
  .ga-topo #addAlunoBtnContainer.ga-nova{ order:4; width:100%; }
  .ga-topo #addAlunoBtnContainer.ga-nova .inb-p{ width:100%; justify-content:center; }
  .ga-linha2{ gap:.4rem !important; }
  .ga-direita{ width:100%; }
  .ga-direita #pendenciasAvisoContainer{ width:auto; }
  .ga-direita #pendenciasAvisoContainer .inb-p{ width:100%; justify-content:center; }
}

/* ============= 9g. O RODAPÉ DO APLICATIVO: UMA BARRA SÓ, E NADA EMBAIXO ===
   Três defeitos medidos em 07/08/2026 numa varredura das 105 páginas a 360px,
   todos no mesmo canto da tela.

   1. `padding-bottom` no <body> NÃO reserva espaço quando a página usa `h-full`
      (40 páginas usam). Com `height:100%` e `box-sizing:border-box` o padding
      entra DENTRO da altura fixa: não vira rolagem, e o último elemento continua
      embaixo da barra. Medido: em diagnostico.html o `#btnSubmitForm` real ia de
      690 a 778 com a barra começando em 732 — 46px do botão de enviar cobertos,
      e a página já estava no fim (não havia como rolar mais). O espaçador
      `::after` é imune a isso porque é conteúdo, não caixa.
   2. `#headerExpandTabs` (a barra criada pelo header-menu.js, e inline no
      school-dashboard) é a dock real de 28 páginas, mas todas as regras de dock
      deste arquivo miravam só `.inh-dock` — que existe em UMA página. Daí
      nenhuma proteção valia onde ela era necessária.
   3. `#theme-switcher` é `bottom-5/6 right-5/6` e dividia o canto com a barra:
      48x38px de sobreposição em cima da última aba, em 11 páginas. O dedo
      acertava o botão de tema quando queria a aba. */
@media (max-width:1024px){
  :root{ --inet-dock-h:4.6rem; --inet-actionbar-h:5.75rem; }

  /* (0) `h-full` no <body> (40 páginas) é o que trava tudo o que vem abaixo.
     Com `height:100%` mais o `overflow-x:clip` da seção 1, o eixo vertical
     deixa de ser `visible` e o <body> vira o próprio container de rolagem, com
     812px de altura fixa. Medido no school-dashboard a 360px: a página tinha
     1679px de conteúdo e só 886px eram alcançáveis. Soltar a altura (mantendo
     o piso de tela cheia) devolve a rolagem normal e faz o espaçador de baixo
     valer. Só onde existe barra inferior, que é onde a diferença aparece. */
  body.inet-m-tem-dock,
  body.inet-m-tem-actionbar,
  body:has(#headerExpandTabs),
  body:has(.inh-dock){
    height:auto !important;
    min-height:100%;
  }

  /* (1) espaço no fim da página — conteúdo, não padding */
  body.inet-m-tem-dock::after,
  body.inet-m-tem-actionbar::after,
  body:has(#headerExpandTabs)::after,
  body:has(.inh-dock)::after{
    content:''; display:block; width:100%; flex:0 0 auto;
    height:calc(var(--inet-dock-h) + env(safe-area-inset-bottom));
  }
  body.inet-m-tem-actionbar::after{
    height:calc(var(--inet-actionbar-h) + env(safe-area-inset-bottom));
  }
  /* as duas juntas somam — esta regra fica por último de propósito */
  body.inet-m-tem-dock.inet-m-tem-actionbar::after,
  body.inet-m-tem-actionbar:has(#headerExpandTabs)::after,
  body.inet-m-tem-actionbar:has(.inh-dock)::after{
    height:calc(var(--inet-dock-h) + var(--inet-actionbar-h) + env(safe-area-inset-bottom));
  }

  /* (2) a barra inferior encosta no rodapé e respeita o entalhe */
  #headerExpandTabs{
    bottom:calc(.45rem + env(safe-area-inset-bottom)) !important;
    z-index:var(--inet-z-dock) !important;
  }
  /* alvo de toque de 44px e rótulo legível: estavam em 38px de altura e 8,48px
     de fonte, abaixo do mínimo do PRODUCT.md */
  #headerExpandTabs .exp-tab{
    min-height:var(--inet-tap) !important;
    justify-content:center !important;
  }
  #headerExpandTabs .exp-tab .exp-tab-label{
    font-size:.625rem !important; line-height:1.15 !important;
  }

  /* (3) o alternador de tema sobe para cima da barra */
  body:has(#headerExpandTabs) #theme-switcher,
  body:has(.inh-dock) #theme-switcher,
  body.inet-m-tem-dock #theme-switcher{
    bottom:calc(var(--inet-dock-h) + .8rem + env(safe-area-inset-bottom)) !important;
    right:.75rem !important;
    z-index:calc(var(--inet-z-dock) - 2) !important;
  }

  /* a barra de ação do retrofit fica ACIMA da navegação, nunca por cima dela */
  body.inet-m-tem-dock .inet-m-actionbar,
  body:has(#headerExpandTabs) .inet-m-actionbar,
  body:has(.inh-dock) .inet-m-actionbar{
    bottom:calc(var(--inet-dock-h) + env(safe-area-inset-bottom));
  }
}

/* ============== 9i. BARRA DE FORMATAÇÃO DO QUILL (chat de solicitações) ===
   Fotografado no iPhone: os botões de negrito, itálico, lista etc. saíam
   gigantes, ocupando duas fileiras e um terço da tela.

   A causa é a SOMA de duas regras, nenhuma delas errada sozinha:
   o Quill declara `.ql-toolbar button svg{ height:100% }`, e a regra de alvo de
   toque desta folha dá 44px de altura ao botão. Resultado: o ícone, que deveria
   ter 18px, virou 38px de altura por 34px de largura — medido.

   O alvo de toque continua em 44px, que é o mínimo do PRODUCT.md; quem volta ao
   tamanho certo é o ícone dentro dele. */
@media (max-width:1024px){
  .ql-toolbar button,.ql-toolbar .ql-picker-label{
    display:inline-flex !important;
    align-items:center !important; justify-content:center !important;
    width:40px !important; min-width:40px !important;
    height:40px !important; min-height:40px !important;
    padding:0 !important;
  }
  .ql-toolbar button svg,.ql-toolbar .ql-picker-label svg{
    width:20px !important; height:20px !important;
    float:none !important; max-width:none !important;
  }
  /* a barra inteira numa fileira só, rolando se não couber */
  .ql-toolbar.ql-snow{
    display:flex !important; flex-wrap:nowrap !important;
    overflow-x:auto; overscroll-behavior-x:contain;
    gap:.1rem; padding:.25rem .35rem !important;
    scrollbar-width:none;
  }
  .ql-toolbar.ql-snow::-webkit-scrollbar{ display:none; }
  .ql-toolbar.ql-snow .ql-formats{
    display:flex !important; flex:0 0 auto; margin-right:.35rem !important;
  }
}

/* ================= 9h. MOVIMENTO: ESQUELETO, ENTRADA E PROGRESSO =========
   Em rede de escola o conteúdo demora, e o que a pessoa vê é tela parada. Estes
   três recursos não deixam a espera mais curta, deixam ela LEGÍVEL: dá para
   saber que algo está vindo, de onde, e quando chegou.
   Tudo abaixo respeita `prefers-reduced-motion` no fim da seção — para quem tem
   sensibilidade vestibular, animação não é enfeite, é sintoma. */
/* (1) barra de progresso no topo, enquanto a página carrega ou há overlay.
   O estado base fica FORA da media query de propósito: se a pessoa girar o
   aparelho ou o retrofit mudar de faixa, o nó não pode virar um div solto no
   fluxo da página. Ele é criado só no celular, mas fica invisível sempre que
   não estiver ligado. */
.inet-m-progresso{
  position:fixed; top:0; left:0; right:0; height:3px;
  z-index:71;
  background:rgba(15,169,200,.16);
  opacity:0; transition:opacity .2s ease;
  pointer-events:none; overflow:hidden;
}
@media (max-width:1024px){
  .inet-m-progresso{ z-index:calc(var(--inet-z-dock) + 1); }
  .inet-m-progresso.is-on{ opacity:1; }
  .inet-m-progresso::after{
    content:''; position:absolute; top:0; bottom:0; left:0; width:38%;
    background:linear-gradient(90deg,transparent,var(--inet-cyan-700),transparent);
    animation:inet-m-desliza 1.1s linear infinite;
  }
  @keyframes inet-m-desliza{
    from{ transform:translateX(-100%) } to{ transform:translateX(360%) }
  }

  /* (2) entrada do conteúdo: sobe e aparece, em onda. O escalonamento é por
     posição na tela, com teto — esperar 139 atrasos seria pior que não animar. */
  .inet-m-entra{ animation:inet-m-surge .34s var(--inet-ease) both; }
  @keyframes inet-m-surge{
    from{ opacity:0; transform:translateY(10px) } to{ opacity:1; transform:none }
  }

  /* (3) esqueleto de imagem: o lugar dela já existe e pisca enquanto ela vem,
     em vez de o layout pular quando a foto chega */
  img.inet-m-img-carrega{
    background-image:linear-gradient(100deg,var(--inet-line) 30%,#F4F7FD 50%,var(--inet-line) 70%);
    background-size:220% 100%;
    animation:inet-m-brilha 1.25s linear infinite;
    border-radius:.5rem;
  }
  @keyframes inet-m-brilha{
    from{ background-position:220% 0 } to{ background-position:-220% 0 }
  }
}
@media (prefers-reduced-motion:reduce){
  .inet-m-entra{ animation:none !important; }
  .inet-m-progresso::after{ animation:none !important; width:100%; }
  img.inet-m-img-carrega{ animation:none !important; }
}

/* ==================================================== 10. IMPRESSÃO/PDF ===
   O que é navegação não vai para o papel. */
@media print{
  .inet-m-actionbar,.inet-m-toast,.inh-dock,#headerExpandTabs,#theme-switcher{ display:none !important; }
  .inet-m-tbwrap{ overflow:visible !important; background:none !important; }
}

/* ================================================ 11. MOVIMENTO REDUZIDO ===
   Não é opcional (PRODUCT.md, acessibilidade). */
@media (prefers-reduced-motion:reduce){
  .inet-m-modal > .inet-m-modal-card,
  .inet-m-toast.is-on{ animation:none !important; }
  .inet-m-tbwrap{ scroll-behavior:auto; }
}
