/* ============================================================================
   MOBILE.CSS — Ipacarai
   ----------------------------------------------------------------------------
   REGRA DE OURO: este arquivo NÃO pode ter efeito acima de 1100px.
   TODA regra aqui dentro está obrigatoriamente dentro de @media (max-width: …).
   Nenhuma regra existente de ipacarai.css / dashboard-v2.css foi editada.

   CARREGAMENTO: <link> no FIM do <body> do views/layouts/app.php, logo depois
   de dashboard-v2.css. Isso é de propósito — carregando por último, este
   arquivo vence o cascade contra os <style> inline das views e contra o
   dashboard-v2.css sem precisar de !important espalhado.

   ⛔ A AURA NÃO SE TOCA. Todas as regras aqui estão escopadas em .content ou
   .topbar. O painel da Aura (.aura-*) fica FORA de .content (é anexado no fim
   do <body>), portanto está automaticamente excluído. Não adicione seletor
   .aura-* neste arquivo.

   BREAKPOINTS OFICIAIS:
     1100px  tablet paisagem / notebook pequeno (drawer da sidebar já ativa)
      900px  tablet retrato
      640px  celular
      400px  celular pequeno
   ============================================================================ */


/* ============================================================================
   1. ROLAGEM HORIZONTAL — barras de aba e tabelas          (≤ 900px)
   ----------------------------------------------------------------------------
   Estes contêineres JÁ têm overflow-x:auto no CSS original e JÁ rolam. O que
   falta é (a) esconder a barra de rolagem nativa, que no Windows aparece como
   um traço cinza grosso e feio, e (b) ligar o momentum scrolling do iOS.
   ========================================================================== */
@media (max-width: 900px) {
  .content .apv-tabs,
  .content .config-tabs,
  .content [class$="-tabs"],
  .content [class*="-tabs "] {
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    overscroll-behavior-x: contain;
  }
  .content .apv-tabs::-webkit-scrollbar,
  .content .config-tabs::-webkit-scrollbar,
  .content [class$="-tabs"]::-webkit-scrollbar,
  .content [class*="-tabs "]::-webkit-scrollbar {
    width: 0;
    height: 0;
  }

  /* Tabelas: momentum no iOS. O overflow-x:auto já existe em .table-wrap. */
  .content .table-wrap,
  .content .data-table-wrap,
  .content [class$="-table-wrap"],
  .content [class$="-tbl-shell"],
  .content .adv-table-scroll {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
}


/* ============================================================================
   2. TOPBAR — o sino de notificações estava caindo para fora da tela
   ----------------------------------------------------------------------------
   MEDIDO em produção, viewport de 380px, tela /app/comercial/aprovacoes:

     sidebar-toggle    40px   x=14 → 54
     sync badge        22px   x=64 → 86
     brain-data-btn   128px   x=92 → 220     ← o vilão
     theme-toggle      48px   x=226 → 274
     notif-nav-btn     36px   x=370 → 406    ← 26px FORA da viewport de 380

   O sino é a porta de entrada do fluxo de aprovação (o gestor recebe a
   notificação no celular e precisa tocar nela). Estava inalcançável.

   CORREÇÃO: esconder apenas o RÓTULO do Brain Data, não o botão. Ele cai de
   128px para ~44px e continua 100% funcional como ícone. Nenhuma
   funcionalidade é removida do mobile.

   RESULTADO MEDIDO: topbar scrollWidth 406 → 380 (zero overflow),
   sino termina em x=366, com alvo de 44×44.
   ========================================================================== */
@media (max-width: 640px) {
  /* !important necessário: brain-data-btn.php injeta um <style> próprio no
     <body>, e em empate de especificidade o mais recente venceria. */
  .topbar .brain-data-btn__label { display: none !important; }
  .topbar .brain-data-btn {
    padding: 0 10px !important;
    min-width: 44px;
    justify-content: center;
  }

  .topbar .theme-toggle__label { display: none; }

  .topbar .notif-nav-btn {
    min-width: 44px;
    min-height: 44px;
  }

  .topbar .sidebar-toggle {
    min-width: 44px;
    min-height: 44px;
  }
}


/* ============================================================================
   3. CAMPOS DE FORMULÁRIO — zoom automático do iOS       (≤ 640px)
   ----------------------------------------------------------------------------
   O body é font-size:14px (ipacarai.css:170) e .form__input não declara
   font-size, então herda 14px. O Safari do iPhone dá ZOOM em qualquer campo
   com fonte menor que 16px assim que ele recebe foco — a página salta, o
   usuário perde o contexto e precisa dar pinch para voltar.

   MEDIDO: .apv-search estava com font-size 13px.

   16px é o mínimo exato que impede o zoom. Não é escolha estética.

   POR QUE !important AQUI (e só aqui):
   1) ipacarai.css:3825 tem `.ud-period-toolbar .ud-period-select` = (0,2,0),
      que vence `.content select` = (0,1,1);
   2) várias views cravam font-size em atributo style= inline
      (ex.: views/centralizer/index.php:727 `style="…font-size:12px"`), e
      estilo inline só perde para !important. Só em produtos/show.php há 144
      atributos style=.
   Como isto é correção de bug funcional (a tela salta no iPhone) e não
   preferência estética, o !important é a ferramenta certa. Continua sem risco
   para o desktop: está dentro de @media (max-width: 640px).
   ========================================================================== */
@media (max-width: 640px) {
  .content input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  .content select,
  .content textarea,
  .topbar input[type="search"],
  .topbar input[type="text"] {
    font-size: 16px !important;
  }
}


/* ============================================================================
   4. ALVOS DE TOQUE — mínimo de 44px                      (≤ 640px)
   ----------------------------------------------------------------------------
   O sistema unificado de botões usa height:36px (ipacarai.css:227). O mínimo
   confortável para o polegar é 44px (guia da Apple; o Material usa 48dp).

   MEDIDO em /app/comercial/aprovacoes @380px: .btn-secondary 73×36,
   .apv-tab 125×38, .apv-search 275×36.

   A especificidade de .content .btn--primary (0,2,0) vence a original
   (0,1,0) sem precisar de !important.
   ========================================================================== */
@media (max-width: 640px) {
  .content .btn--primary,
  .content .btn--ghost,
  .content .btn-secondary,
  .content .btn-tech,
  .content .btn-danger,
  .content .btn-small,
  .content .btn-back,
  .content .actionbar__btn {
    min-height: 44px;
    height: auto;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .content input[type="submit"],
  .content button[type="submit"] {
    min-height: 44px;
  }

  /* Abas viram alvo confortável sem mudar a aparência */
  .content .apv-tab,
  .content .config-tabs a,
  .content [class$="-tabs"] > a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}


/* ============================================================================
   5. CABEÇALHO DE PÁGINA — empilhar                       (≤ 640px)
   ----------------------------------------------------------------------------
   .page-header é flex-row com justify-content:space-between, align-items:
   flex-end e gap:24px (ipacarai.css:1441) e NÃO tinha nenhum override mobile.
   Título e ações se espremiam lado a lado. 94 ocorrências nas views.
   ========================================================================== */
@media (max-width: 640px) {
  .content .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 22px;
    padding-bottom: 18px;
  }
  .content .page-header-info { width: 100%; }
  .content .page-actions {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .content .page-subtitle { font-size: 13.5px; line-height: 1.5; }
}

/* Celular pequeno: o título de 26px com line-height 0.95 e letter-spacing
   negativo ainda aperta demais em 360px. */
@media (max-width: 400px) {
  .content .page-title {
    font-size: 23px;
    line-height: 1.05;
    letter-spacing: -0.02em;
  }
}


/* ============================================================================
   6. ÁREA SEGURA (notch / home indicator do iPhone)       (≤ 640px)
   ----------------------------------------------------------------------------
   Depende de viewport-fit=cover no <meta name="viewport"> — adicionado em
   views/layouts/app.php. Sem ele, env(safe-area-inset-*) resolve para 0 e
   estas regras simplesmente não fazem nada (degradam em silêncio).

   Só o Aura standalone tratava isso até agora (dashboard-v2.css:400).
   ========================================================================== */
@media (max-width: 640px) {
  .topbar {
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
  }
  .content {
    padding-left: max(12px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
  }
}


/* ============================================================================
   7. FOLGA NO RODAPÉ — o FAB da Aura cobria o conteúdo   (≤ 640px)
   ----------------------------------------------------------------------------
   O .aura-fab é position:fixed; bottom:26px; right:26px com z-index:9000
   (dashboard-v2.css:286). Em 390px ele fica por cima do último item da lista —
   confirmado visualmente em /app/comercial/aprovacoes. Somando a barra de
   câmbio fixa no rodapé (--ipacarai-fx-h: 40px), o canto inferior direito é
   território ocupado.

   ⛔ A CORREÇÃO É DO LADO DO CONTEÚDO, NÃO DA AURA. A Aura não se toca: não
   movemos, encolhemos nem escondemos o FAB. Damos folga ao conteúdo para que
   ele termine acima da área ocupada.

   Isto é especialmente importante nas telas de aprovação, onde os botões
   aprovar/rejeitar ficam no fim do card — e são a ação mais importante do
   sistema no celular.
   ========================================================================== */
@media (max-width: 640px) {
  .content {
    padding-bottom: calc(96px + env(safe-area-inset-bottom));
  }
}


/* ============================================================================
   8. TELA DE LOGIN                                        (≤ 640px)
   ----------------------------------------------------------------------------
   ATENÇÃO: o login NÃO usa views/layouts/app.php — usa views/layouts/auth.php,
   que é um HTML completamente separado. Ele não tem .content nem .topbar,
   então NENHUMA regra das seções 1 a 7 acima o alcança. Por isso esta seção
   existe, escopada em #login-screen.

   O layout em duas colunas já colapsa sozinho em ≤1100px (ipacarai.css:3147:
   grid-template-columns:1fr e .login-left{display:none}), então a estrutura
   está ok. O problema é o campo:

     .input-wrap input { font-size: 14.5px }   (ipacarai.css:693)

   É a PRIMEIRA coisa que o usuário toca no celular — e o Safari do iPhone dá
   zoom nos dois campos, e-mail e senha, logo na entrada do sistema.
   ========================================================================== */
@media (max-width: 640px) {
  #login-screen .input-wrap input {
    font-size: 16px !important;
  }

  /* Alvos de toque: botão de entrar e o olho de mostrar/ocultar senha */
  #login-screen .btn-primary,
  #login-screen button[type="submit"] {
    min-height: 48px;
  }
  #login-screen .pw-toggle {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Área segura do iPhone */
  #login-screen .login-right {
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
    padding-bottom: max(20px, env(safe-area-inset-bottom));
  }
}



/* ============================================================================
   9. TABELAS VIRAM CARDS                                  (≤ 640px)
   ----------------------------------------------------------------------------
   Decisão D3. Até 900px a tabela continua tabela (colunas secundárias somem,
   rola na horizontal). Abaixo de 640px vira card empilhado.

   A classe .mob-cards e os atributos data-label são carimbados em runtime por
   assets/js/mobile.js — que só executa em ≤640px. Nenhuma view foi editada.

   OBJETIVO DE DESIGN: isto é uma LISTA PARA ESCANEAR, não um formulário.
   A primeira versão gastava 6 linhas altas por registro e cabiam 3 por tela.
   Aqui o card é compacto (rótulo pequeno acima/ao lado, pouco padding) e o
   tbody é uma GRADE que se adapta: em 390px dá 1 coluna, em 560-640px dá 2.
   Assim a largura disponível é usada em vez de virar espaço morto.

   TRUQUE IMPORTANTE — por que o <td> não recebe display:
   as views escondem colunas com regras como
     .pedidos-table tbody td:nth-child(4){display:none}
   Se eu declarasse display:block/grid no td, essas regras seriam anuladas e
   as colunas que a view escondeu de propósito reapareceriam no card.

   Solução: declaro display:flex no <tr>. Pela especificação de CSS, itens de
   flex container são "blockificados" automaticamente (table-cell vira block),
   então não preciso tocar no display do td — e o td com display:none
   simplesmente não vira item de flex, continuando escondido. A intenção de
   cada view é respeitada sem que eu edite nenhuma delas.
   ========================================================================== */
@media (max-width: 640px) {

  /* O wrapper não precisa mais rolar na horizontal em modo card */
  .content .table-wrap:has(table.mob-cards),
  .content [class$="-table-wrap"]:has(table.mob-cards),
  .content [class$="-tbl-shell"]:has(table.mob-cards) {
    overflow-x: visible;
    border: 0;
    background: transparent;
    border-radius: 0;
  }

  .content table.mob-cards { display: block; width: 100%; min-width: 0 !important; }
  .content table.mob-cards > thead { display: none; }

  /* A grade: 1 coluna no celular estreito, 2 quando houver espaço.
     minmax com min(100%, …) evita estouro em telas muito estreitas. */
  .content table.mob-cards > tbody {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 228px), 1fr));
    gap: 7px;
    /* stretch (padrao) e proposital: cartoes da MESMA fileira ficam com a
       mesma altura. Com align-items:start cada um assumia a altura do proprio
       conteudo e, como as descricoes tem 1, 2 ou 3 linhas, a fileira saia
       desalinhada — o efeito "tudo torto". */
    align-items: stretch;
  }

  /* Cada linha vira um cartão compacto. display:flex aqui blockifica os td
     sem que eu precise declarar display neles — ver explicação acima. */
  .content table.mob-cards > tbody > tr {
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--line);
    border-radius: 8px;
    margin: 0;
    padding: 5px 0;
    overflow: hidden;
  }

  .content table.mob-cards > tbody > tr > td {
    border-bottom: none !important;
    padding: 1px 10px !important;
    white-space: normal !important;
    font-size: 12px;
    line-height: 1.32;
    text-align: left !important;
    width: auto !important;
    max-width: none !important;
  }

  /* ALINHAMENTO EM DUAS COLUNAS sem declarar display no <td>.
     O rotulo mora numa calha fixa de 68px e o valor comeca sempre em 78px —
     inclusive as linhas que quebram (descricao longa). Isso deixa a coluna de
     valores reta em todos os cartoes.

     Como funciona: padding-left empurra TODAS as linhas para 78px; o
     text-indent negativo traz so a PRIMEIRA linha de volta para 10px, que e
     onde o rotulo (::before) e desenhado. Truque de recuo pendente — nao
     preciso de display:grid no td, entao as colunas escondidas pela view
     continuam escondidas. */
  .content table.mob-cards > tbody > tr > td[data-label] {
    padding-left: 78px !important;
    text-indent: -68px;
  }

  /* OBRIGATORIO junto com o recuo pendente acima: text-indent e herdado.
     Quando o valor da celula e um bloco (pill de status, badge de tag, botao),
     ele cai numa linha propria e herda o -68px, sendo puxado para a esquerda
     POR CIMA do rotulo. Era o "TAG/COZINHA" e "STATUS/ATIVO" grudados.
     Zerar nos filhos resolve sem desalinhar o texto simples. */
  .content table.mob-cards > tbody > tr > td[data-label] > * {
    text-indent: 0;
  }

  /* Rótulo pequeno e discreto, largura curta — o valor é o que importa. */
  .content table.mob-cards > tbody > tr > td[data-label]::before {
    content: attr(data-label);
    display: inline-block;
    width: 68px;
    margin: 0;
    /* OBRIGATORIO: text-indent e herdado, e este ::before e inline-block
       (portanto um container de bloco). Sem zerar aqui, ele herda o
       text-indent:-68px do <td>, empurra o proprio texto para fora da caixa
       e o overflow:hidden apaga o rotulo da tela. */
    text-indent: 0;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 8px;
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    /* --txt-faint (#4a423b) fica escuro demais sobre o fundo do cartao no tema
       escuro; o rotulo praticamente some. --txt-muted mantem a discricao com
       contraste legivel. */
    color: var(--txt-muted);
    vertical-align: baseline;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Primeira célula é o título do cartão: sem rótulo, com destaque. */
  /* Primeira celula e o titulo do cartao: sem rotulo, sem calha, com destaque. */
  .content table.mob-cards > tbody > tr > td:first-child {
    font-size: 13px;
    font-weight: 600;
    padding: 3px 10px 4px !important;
    text-indent: 0;
  }
  .content table.mob-cards > tbody > tr > td:first-child::before {
    content: none;
  }

  /* Ultima celula ancorada no rodape do cartao. Com os cartoes esticados pela
     grade, isso alinha os botoes de acao (ex.: "Catalogo") na mesma altura em
     toda a fileira, em vez de cada um flutuar onde o texto acabou. */
  .content table.mob-cards > tbody > tr > td:last-child {
    margin-top: auto;
    padding-top: 6px !important;
  }

  /* Célula sem conteúdo nenhum não vira linha vazia no cartão */
  .content table.mob-cards > tbody > tr > td.mob-empty { display: none; }

  /* MINIATURA DE PRODUTO ancorada no canto superior direito.
     Marcada por mobile.js quando a celula contem so uma <img> e nenhum texto.
     Sem isto ela ocupa uma linha inteira e empurra todos os campos para
     baixo, deixando uma coluna morta a esquerda — o cartao fica mal
     distribuido. Ancorada no canto, a largura toda sobra para os dados. */
  .content table.mob-cards > tbody > tr { position: relative; }
  .content table.mob-cards > tbody > tr > td.mob-thumb {
    position: absolute;
    top: 6px;
    right: 8px;
    width: 44px;
    height: 44px;
    padding: 0 !important;
    margin: 0 !important;
    text-indent: 0;
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-elevated);
  }
  .content table.mob-cards > tbody > tr > td.mob-thumb::before { content: none; }
  .content table.mob-cards > tbody > tr > td.mob-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
  }
  /* Os campos nao passam por baixo da miniatura */
  .content table.mob-cards > tbody > tr:has(> td.mob-thumb) > td:not(.mob-thumb) {
    padding-right: 58px !important;
  }
  /* Quando a miniatura e a primeira celula, quem manda no titulo e a segunda */
  .content table.mob-cards > tbody > tr > td.mob-thumb + td {
    font-size: 13px;
    font-weight: 600;
  }

  /* Linha de "nenhum registro encontrado" continua simples */
  .content table.mob-cards > tbody > tr > td[colspan] {
    text-align: center !important;
    font-weight: 400;
    font-size: 12.5px;
    padding-left: 10px !important;
    text-indent: 0;
    margin-top: 0;
  }
  .content table.mob-cards > tbody > tr > td[colspan]::before { content: none; }

  /* Cartão de "nenhum registro" ocupa a largura toda da grade */
  .content table.mob-cards > tbody > tr:only-child { grid-column: 1 / -1; }

  /* Rodapé de totais: sem colunas, vira lista simples */
  .content table.mob-cards > tfoot { display: block; margin-top: 8px; }
  .content table.mob-cards > tfoot > tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
    padding: 6px 11px;
    border-top: 1px solid var(--line);
  }
  .content table.mob-cards > tfoot > tr > td {
    border: 0 !important;
    padding: 2px 0 !important;
    font-size: 12px;
  }
  .content table.mob-cards > tfoot > tr > td:empty { display: none; }
}

/* Navegador sem suporte a :has() (Safari < 15.4): o wrapper mantém o
   overflow-x, o que é inofensivo — o card simplesmente não estica além dele. */


/* ============================================================================
   10. GRADES CRAVADAS EM style= INLINE                    (≤ 640px)
   ----------------------------------------------------------------------------
   11 views montam grades no atributo style= do elemento, com colunas fixas.
   O caso mais comum e o formulario de filtros:

     <div style="grid-column: span 12; display:grid;
                 grid-template-columns: repeat(12, 1fr); gap:12px;">

   (views/produtos/index.php:189 e :220 — mais 16 ocorrencias de repeat(12,1fr)
   espalhadas por admin/settings, catalogos, catalogo_digital/manage,
   dashboard, plataforma/config_email, produtos/show, qualidade, sync/index,
   sync/schedule e tag_engine/edit.)

   Em 380px isso da ~25px por coluna: os campos viram caixinhas de "Con" e os
   rotulos aparecem cortados ("FABRICANT", "ARCA/MODEL").

   Estilo inline so perde para !important — dai o uso aqui. Continua sem risco
   para o desktop: esta dentro de @media (max-width: 640px).

   Grades que ja se adaptam sozinhas (auto-fill / auto-fit) ficam de fora: elas
   ja fazem a coisa certa e forcar 1fr so pioraria.
   ========================================================================== */
@media (max-width: 640px) {
  /* minmax(0,1fr) e NAO 1fr: "1fr" equivale a minmax(auto,1fr), e esse auto
     usa o min-content do filho como piso. Se o filho tem conteudo largo, a
     trilha cresce alem do container e vaza. Medido em
     /app/operacoes/limites-permitidos a 320px: trilha de 413px num container
     de 310px, mesmo ja estando em coluna unica. */
  .content [style*="grid-template-columns"]:not([style*="auto-fill"]):not([style*="auto-fit"]) {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  /* Campo que ocupava "span 3" numa grade de 12 passa a ocupar a linha toda */
  .content .filters [style*="grid-column"],
  .content [style*="grid-column: span"],
  .content [style*="grid-column:span"] {
    grid-column: auto !important;
  }
}


/* ============================================================================
   11. COMPONENTES QUE QUEBRAM NO CELULAR                  (≤ 640px)
   ----------------------------------------------------------------------------
   Esta secao nao foi escrita "no olho": rodei um detector em 21 telas do
   sistema em 390px, procurando containers flex/grid cujos filhos vazam ou cuja
   coluna irma colapsa para largura zero. O que esta aqui e a lista fechada que
   ele devolveu.

   A CAUSA E QUASE SEMPRE A MESMA: item de flex/grid tem min-width:auto por
   padrao, entao ele se recusa a encolher abaixo do proprio conteudo. Numa
   linha estreita, ou ele vaza para fora do container, ou empurra o irmao
   flexivel ate zero — que foi o caso dos nomes de cliente do feed do painel,
   cortados a largura ZERO enquanto valor e horario vazavam ate 147px.
   ========================================================================== */
@media (max-width: 640px) {

  /* --- Rede de seguranca generica -----------------------------------------
     min-width:0 so tem efeito em item de flex/grid (em bloco normal o padrao
     ja e 0). Aplicar nos portadores de texto mais comuns desarma a causa raiz
     na maioria dos casos, sem mexer em quem depende de min-width proprio. */
  .content [class*="__who"],
  .content [class*="__name"],
  .content [class*="-name"],
  .content [class*="__title"],
  .content [class*="-title"],
  .content [class*="__label"],
  .content [class*="__info"] {
    min-width: 0;
  }

  /* Barras de acao, cabecalhos de painel e paginacao passam a quebrar linha
     em vez de empurrar o ultimo filho para fora da tela. */
  .content [class*="pagination"],
  .content [class*="__actions"],
  .content [class*="-actions"],
  .content [class*="__head"],
  .content .panel-head,
  .content [class*="__toolbar"],
  .content [class*="-toolbar"] {
    flex-wrap: wrap;
  }

  /* .panel-head e primitiva compartilhada (756 usos de .panel no sistema) e o
     grupo de acoes dela costuma ser um <div> SEM CLASSE — nenhum seletor por
     nome de classe alcanca. Medido em /app/operacoes/sincronizacao a 320px:
     div de 302px dentro de um cabecalho de 284px, com min-width:auto.
     Atacar pelo filho direto resolve em todas as telas de uma vez. */
  .content .panel-head { row-gap: 8px; }
  /* Descendente, nao filho direto: o grupo de acoes e um <div> sem classe
     DENTRO de outro <div> sem classe (medido em /app/operacoes/sincronizacao
     a 320px: div interno de 302px num cabecalho de 284px, com os toggles
     "Cancelar / Ativo"). Nenhum seletor por classe alcanca isso.
     Seguro de aplicar amplo: min-width so tem efeito em item de flex/grid e
     flex-wrap so tem efeito em container flex — em bloco comum, nada muda. */
  .content .panel-head div,
  .content .panel-head > * {
    min-width: 0;
    flex-wrap: wrap;
  }

  /* --- Painel unificado: feed ao vivo de pedidos/orcamentos ---------------
     Original: grid-template-columns: 88px minmax(0,1fr) auto auto
     (dashboard-v2.css:789). Em 380px as duas colunas "auto" (valor e horario)
     consomem a largura toda e a coluna do nome colapsa para 0 — o cliente
     fica invisivel, que e justamente a informacao que importa.
     Aqui vira 2x2: selo + horario em cima, nome + valor embaixo. */
  .content .ud-break-feed__row {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 10px;
    padding: 10px 12px;
  }
  .content .ud-break-feed__row > .ud-break-feed__badge {
    grid-row: 1; grid-column: 1; justify-self: start;
  }
  .content .ud-break-feed__row > .ud-break-feed__when {
    grid-row: 1; grid-column: 2; justify-self: end;
  }
  .content .ud-break-feed__row > .ud-break-feed__who {
    grid-row: 2; grid-column: 1; min-width: 0;
  }
  .content .ud-break-feed__row > .ud-break-feed__amt {
    grid-row: 2; grid-column: 2; justify-self: end; align-self: center;
  }
  .content .ud-break-feed__who strong {
    white-space: normal;
    overflow-wrap: anywhere;
    overflow: visible;
  }

  /* --- Painel unificado: os dois feeds lado a lado -----------------------
     CAUSA RAIZ do feed esmagado. .ud-break-feeds (dashboard-v2.css:710) e
     declarado com TRES !important:
        display:flex !important;
        flex-direction:row !important;
        flex-wrap:nowrap !important;
     Sem nenhum breakpoint. Resultado: em 390px os dois feeds continuam lado
     a lado com ~157px cada, e tudo dentro deles fica esmagado — nome de
     cliente, valor e horario disputando 157px.

     Empilhar e a unica saida, e so !important vence !important. */
  .content .ud-break-feeds {
    flex-direction: column !important;
    flex-wrap: wrap !important;
    min-height: 0;
    gap: 12px;
  }
  .content .ud-break-feed { min-width: 0; }
  .content .ud-break-feed__head { flex-wrap: wrap; gap: 6px; }
  .content .ud-break-feed__head h3 { min-width: 0; }
  .content .ud-break-feed__all { margin-left: 0; }

  /* --- Painel unificado: ranking de vendedores ----------------------------
     Medido em 390px: a linha tem 322px e os filhos somam mais que isso —
     posicao 26 + avatar 34 + [info] + barra 64 + valor 105 + tendencia 46.
     Sobra ZERO para .ud-rank-info, entao o nome do vendedor desaparece.
     A barra de progresso e decorativa e o valor ja diz a mesma coisa em
     numero; escondendo a barra no celular, o nome volta a caber. */
  .content .ud-rank-item { min-width: 0; flex-wrap: wrap; }
  .content .ud-rank-item > * { min-width: 0; }
  .content .ud-rank-bar-wrap { display: none; }
  .content .ud-rank-info {
    flex: 1 1 auto;
    min-width: 0;
  }
  .content .ud-rank-name {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* --- Painel unificado: clientes em risco --------------------------------
     .ud-risk-name e um container FLEX com white-space:nowrap. text-overflow
     nao funciona em container flex — o texto simplesmente vaza (medido:
     159px de caixa para 230px de conteudo). Deixar quebrar linha resolve. */
  .content .ud-risk-name {
    flex-wrap: wrap;
    white-space: normal;
    min-width: 0;
    overflow: visible;
  }
  .content .ud-risk-name > * { min-width: 0; }

  /* --- Cambio: cartoes de cotacao ---------------------------------------- */
  .content .cambio-fx-card,
  .content .cambio-usd-anchor {
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
  }
  .content .cambio-fx-card > *,
  .content .cambio-usd-anchor > * { min-width: 0; }

  /* --- Aniversarios: grade da semana ------------------------------------- */
  .content .aniv-week { grid-template-columns: 1fr; }

  /* --- Ofertas: segmentado ----------------------------------------------- */
  .content .ofl-seg {
    flex-wrap: wrap;
    gap: 6px;
  }

  /* --- Cabecalho de pagina com subtitulo longo --------------------------- */
  .content .page-header,
  .content .page-subtitle { min-width: 0; }
  .content .page-subtitle { overflow-wrap: anywhere; }
}


/* ============================================================================
   12. CELULAR ESTREITO — 320px e abaixo                   (≤ 420px)
   ----------------------------------------------------------------------------
   Detectado rodando o auditor a 320px (viewport util de 310px). Grades de
   cartao declaradas com minmax(280px, 1fr) nao cabem: 280px + o padding do
   painel passa de 310px, e o cartao vaza.

   O sistema tem 4 grades com minmax(280px), 3 com 260px e outras acima de
   200px. Em 320px nenhuma delas comporta duas colunas — uma coluna e sempre
   a resposta certa nessa largura.

   Aparelhos nessa faixa: iPhone SE 1a geracao, Galaxy Fold fechado, e
   qualquer celular com zoom de acessibilidade ligado.
   ========================================================================== */
@media (max-width: 420px) {
  .content .prod-grid,
  .content [class$="-grid"],
  .content [class*="__grid"],
  .content .ud-mini-stats {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* Regua de horarios do mapa (00:00 · 06:00 · 12:00 · 18:00 · AGORA):
     e flex com justify-content:space-between e nao cabe em 310px. */
  .content .ud-map-ticks {
    flex-wrap: wrap;
    gap: 2px 8px;
    justify-content: flex-start;
    font-size: 9px;
  }
}


/* ============================================================================
   13. CAMPOS E GRADES QUE SE RECUSAM A ENCOLHER           (≤ 640px)
   ----------------------------------------------------------------------------
   Mesma familia de causa das secoes 11 e 12 — min-width:auto — em dois lugares
   que os seletores anteriores nao alcancavam.

   1) <select> dentro de barra de filtros: com min-width:auto, o campo e
      dimensionado pela opcao de texto mais longo. Medido em
      /app/comercial/repescagem a 390px: select de 435px numa barra de 356px.
      O flex-wrap ja existia na barra e nao adiantava — o problema nao era
      quebra de linha, era um filho indivisivel largo demais.

   2) Grades declaradas com "1fr" que ja estao em coluna unica mas continuam
      vazando, porque 1fr = minmax(auto,1fr) e o piso auto e o min-content do
      filho. Medido em /app/operacoes/limites-permitidos a 320px: .lp-split
      com trilha de 413px num container de 310px.
   ========================================================================== */
@media (max-width: 640px) {
  .content select,
  .content input,
  .content textarea {
    max-width: 100%;
  }
  .content [class*="filter"] select,
  .content [class*="filter"] input,
  .content .filters select,
  .content .filters input {
    min-width: 0;
  }

  .content [class$="-split"],
  .content [class*="__split"],
  .content .lp-split {
    grid-template-columns: minmax(0, 1fr);
  }
}


/* ============================================================================
   14. REDE DE SEGURANCA — tabela que nao virou card       (≤ 640px)
   ----------------------------------------------------------------------------
   mobile.js so converte em card a tabela que passa em todas as travas: precisa
   de <thead>, 4+ colunas, sem colspan no cabecalho e com <td> batendo com <th>.
   Tabela que nao passa fica como tabela — e se ela tambem nao estiver dentro
   de um .table-wrap (que ja tem overflow-x:auto), ela empurra o layout.

   Medido em /app/operacoes/limites-permitidos a 390px: .lp-table com 414px
   solta no painel, sem wrapper, esticando o container de 310px.

   Aqui ela passa a rolar sozinha na horizontal. Nao e tao bom quanto virar
   card, mas garante que NENHUMA tabela do sistema quebre a pagina, inclusive
   as que eu nao visitei.
   ========================================================================== */
@media (max-width: 640px) {
  .content table:not(.mob-cards) {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .content table:not(.mob-cards)::-webkit-scrollbar {
    height: 0;
  }
}
