/* ════════════════════════════════════════════════════════════════════════
   LAYOUT MOBILE FIX — Reestruturação Global da Responsividade
   Versão: 1.0.0

   Carregado APÓS style.css. Só toca mobile/tablet (≤ 1024px),
   exceto o reset global de min-width:0 e imagens que são seguros
   em qualquer contexto.

   Estrutura deste arquivo:
     §1  Reset global (min-width:0 + box-sizing)
     §2  Mídia nativa (img/svg/video)
     §3  Proteção de overflow no documento
     §4  Tablet + Mobile — estrutura raiz (≤ 1024px)
     §5  Sidebar — range 992–1024px (gap não coberto pelo style.css)
     §6  Grids problemáticos — colunas fixas que causam overflow
     §7  Células de tabela com min-width forçando largura
     §8  FAB safe area — padding-bottom para botões flutuantes draggáveis
     §9  Hero — correções mobile (≤ 768px) com alta especificidade
     §10 Phone (≤ 640px) — ajustes específicos
     §11 Small phone (≤ 480px) — compressão máxima
     §12 Tabelas — anti-esmagamento (≤ 1024px)
     §13 Títulos e header-rows — quebra de linha garantida (≤ 1024px)
     §14 KPI / stat cards — colunas adaptativas em tablet/phone

   PROIBIDO AQUI:
     - overflow:hidden aleatório
     - zoom / scale
     - esconder elementos
     - !important sem necessidade real
     - correções por página
   ════════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════
   §1 RESET GLOBAL — min-width:0

   O default de flex/grid items é min-width:auto, o que faz elementos
   filhos recusarem encolher abaixo do tamanho do seu conteúdo. Este é
   o motor principal dos overflows horizontais em layouts flex e grid.

   min-width:0 não tem efeito fora de contexto flex/grid — é seguro
   aplicar globalmente. box-sizing:border-box já vem do style.css.
   ══════════════════════════════════════════════════════════════════════ */
*,
*::before,
*::after {
    min-width: 0;
}


/* ══════════════════════════════════════════════════════════════════════
   §2 MÍDIA NATIVA

   Imagens, SVGs e vídeos devem sempre respeitar o container pai.
   Sem esta regra, qualquer imagem maior que a tela causa scroll
   horizontal.
   ══════════════════════════════════════════════════════════════════════ */
img,
svg,
video,
canvas,
embed,
object {
    max-width: 100%;
}

img,
video {
    height: auto;
}


/* ══════════════════════════════════════════════════════════════════════
   §3 PROTEÇÃO DE OVERFLOW NO DOCUMENTO

   overflow-x:clip no html é diferente de overflow-x:hidden:
   - clip: não cria scroll container, então position:fixed continua
     funcionando corretamente em relação ao viewport
   - hidden: cria scroll container, quebra position:fixed

   Aplicado globalmente pois é seguro e previne scroll horizontal
   mesmo quando um elemento escapa de algum container.
   ══════════════════════════════════════════════════════════════════════ */
html {
    overflow-x: clip;
}


/* ══════════════════════════════════════════════════════════════════════
   §4 TABLET + MOBILE — ESTRUTURA RAIZ (≤ 1024px)

   Todas as correções de layout base ficam aqui.
   Desktop (> 1024px) NÃO é afetado.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {

    /* ── 4.1 Raiz ── */
    html,
    body {
        max-width: 100vw;
        overflow-x: clip;
    }

    /* ── 4.2 Wrapper principal ── */
    .wrapper {
        width: 100%;
        max-width: 100%;
        overflow-x: clip;
    }

    /* Neutraliza o sistema de desktop-scale em tablets.
       O CSS original usa @media (min-width: 1024px), que inclui o
       limite exato de 1024px. Se um tablet receber a classe
       system-desktop-scaled, o wrapper ficaria com min-width:1600px.
       Anulamos isso aqui. */
    body.system-desktop-scaled .wrapper {
        width: 100% !important;
        min-width: 0 !important;
        transform: none !important;
    }

    /* ── 4.3 Coluna de conteúdo ── */
    #page-content-wrapper {
        width: 100%;
        max-width: 100%;
        min-width: 0;
        overflow-x: clip;
    }

    #page-content-wrapper > .content,
    #page-content-wrapper > .container-fluid.content,
    #page-content-wrapper > main.content,
    #page-content-wrapper > main {
        width: 100%;
        max-width: 100%;
        min-width: 0;
    }

    /* ── 4.4 Topbar ── */
    #content-header {
        width: 100%;
        max-width: 100%;
        min-width: 0;
        padding-top: env(safe-area-inset-top, 0px);
        box-sizing: border-box;
    }

    html.pwa-standalone #content-header {
        padding-top: 0;
    }

    .navbar {
        max-width: 100%;
        min-width: 0;
    }

    .container-fluid-nav {
        min-width: 0;
        padding-left: max(12px, env(safe-area-inset-left, 0px));
        padding-right: max(12px, env(safe-area-inset-right, 0px));
    }

    /* ── 4.5 Cards — contenção ── */
    .card,
    .card-header,
    .card-body,
    .card-footer {
        max-width: 100%;
        min-width: 0;
    }

    /* ── 4.6 Bootstrap grid ── */
    .row {
        margin-left: 0;
        margin-right: 0;
    }

    .row > [class*="col-"] {
        max-width: 100%;
        min-width: 0;
    }

    /* ── 4.7 Containers ── */
    .container,
    .container-fluid {
        max-width: 100%;
        min-width: 0;
        box-sizing: border-box;
    }

    /* ── 4.8 Tabelas — scroll horizontal ── */
    .table-responsive,
    .sl-table-wrap,
    [class$="-table-wrap"] {
        width: 100%;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }

    /* Sem table-wrap explícito: tabela faz seu próprio scroll */
    .card-body > table:not(.no-mobile-wrap),
    .container-fluid > table:not(.no-mobile-wrap) {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
    }

    /* ── 4.9 Inputs e formulários ── */
    .form-control,
    .form-select,
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
    select,
    textarea {
        max-width: 100%;
        min-width: 0;
        box-sizing: border-box;
    }

    .input-group {
        max-width: 100%;
        min-width: 0;
    }

    /* ── 4.10 Sl-shell, Sl-panel, Sl-hero ── */
    .sl-shell,
    .sl-panel,
    .sl-filter-bar {
        max-width: 100%;
        min-width: 0;
    }

    /* sl-hero: clip horizontal overflow so children cannot bleed past the
       hero boundary. clip (not hidden) preserves position:fixed descendants
       and does NOT create a scroll container. */
    .sl-hero {
        max-width: 100%;
        min-width: 0;
        overflow-x: clip;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §5 SIDEBAR — RANGE 992–1024px (GAP NÃO COBERTO)

   style.css cobre:
     - ≤ 768px → sidebar fixed (linhas 3694-3793)
     - 769px–991.98px → sidebar fixed (linhas 3652-3692)

   GAP: entre 992px e 1024px o sidebar volta para position:relative,
   ficando inline no flex row e potencialmente empurrando conteúdo.
   Este bloco fecha esse gap.
   ══════════════════════════════════════════════════════════════════════ */
@media (min-width: 992px) and (max-width: 1024px) {

    #sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        height: 100%;
        z-index: 1050;
        transform: translateX(calc(var(--sidebar-width) * -1));
        transition: transform 0.28s ease, box-shadow 0.28s ease;
        overflow: hidden;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    }

    /* Keep the internal flex column chain alive so ul.components is bounded
       and scrolls (same fix as the ≤991px ranges in style.css). */
    .sidebar-sticky-shell {
        position: relative;
        top: auto;
        height: 100%;
        min-height: 0;
        max-height: 100%;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    #sidebar .sidebar-menu-mode-panels {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    #sidebar .sidebar-menu-mode-view {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    .wrapper.sidebar-mobile-open #sidebar {
        transform: translateX(0);
        box-shadow: 0 0 24px rgba(0, 0, 0, 0.22);
    }

    #sidebar ul.components {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overflow-x: hidden;
        padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px));
        touch-action: pan-y;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }

    /* Com sidebar fixed, o page-content-wrapper ocupa 100% da largura */
    #page-content-wrapper {
        width: 100%;
        max-width: 100%;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §6 GRIDS PROBLEMÁTICOS — COLUNAS FIXAS QUE CAUSAM OVERFLOW

   Problema: minmax(Xpx, ...) faz a coluna nunca ser menor que X.
   Em telas pequenas, a soma dos mínimos ultrapassa o viewport.

   .standard-filter-grid: 5 cols, min 140px cada → soma min ≈ 700px
   .standard-filter-grid-report: 5 cols com mins 220+150+150+190 ≈ 710px
   ══════════════════════════════════════════════════════════════════════ */

/* standard-filter-grid-report: começa a quebrar abaixo de 1280px */
@media (max-width: 1280px) {
    .standard-filter-grid-report {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 991.98px) {
    .standard-filter-grid-report {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .standard-filter-grid-report {
        grid-template-columns: 1fr;
    }
}

/* standard-filter-grid: coberto parcialmente em style.css,
   reforço para garantia em todos os breakpoints */
@media (max-width: 991.98px) {
    .standard-filter-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .standard-filter-grid {
        grid-template-columns: 1fr;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §7 CÉLULAS DE TABELA COM min-width PROBLEMÁTICO

   Estas células têm min-width definido para garantir legibilidade no
   desktop. São válidas quando a tabela está dentro de um scroll
   container. Mas em telas pequenas precisam ser reduzidas para que
   o scroll não seja excessivo e o layout não quebre.

   Seletores problemáticos encontrados:
     .ops-main-cell { min-width: 320px } — linha 3505
     .ops-timeline  { min-width: 170px } — linha 3560
     .ops-owner     { min-width: 180px } — linha 3625
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 991.98px) {
    .ops-main-cell {
        min-width: 220px;
    }

    .ops-timeline {
        min-width: 130px;
    }

    .ops-owner {
        min-width: 140px;
    }
}

@media (max-width: 640px) {
    .ops-main-cell {
        min-width: 160px;
    }

    .ops-timeline {
        min-width: 100px;
    }

    .ops-owner {
        min-width: 110px;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §8 FAB SAFE AREA — PADDING-BOTTOM PARA BOTÕES FLUTUANTES

   Os botões flutuantes (bug-report-fab, app-footer-fab) são draggáveis
   e DEVEM permanecer. O conteúdo precisa de espaço seguro na base
   para não ficar escondido atrás deles.

   Arquitetura atual dos FABs:
     - bug-report-fab: position:fixed, bottom variável via CSS var
     - app-footer-fab: mostrado no footer (sticky bottom em mobile)
     - A footer fica sticky no bottom em mobile < 768px

   120px é suficiente para cobrir footer sticky + fab fixo.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 991.98px) {

    .content,
    .container-fluid.content {
        padding-bottom: 120px;
    }

    /* Em modo scroll-lock (≥ 768px), o scroll acontece em .content —
       o padding-bottom garante que o último item seja visível */
    body.app-scroll-lock #page-content-wrapper > .content,
    body.app-scroll-lock #page-content-wrapper > .container-fluid.content,
    body.app-scroll-lock #page-content-wrapper > main {
        padding-bottom: 120px;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §9 HERO — Correção mobile (≤ 768px)

   Problema: sheets de componente (slim-list.css, finance-shell.css,
   operational-shell.css) são carregados no <body> DEPOIS deste arquivo
   → mesma especificidade, carregamento posterior = eles VENCEM.

   Solução: prefixo #page-content-wrapper (especificidade 1-1-0) garante
   que estas regras sobrescrevam qualquer sheet de componente (0-1-0 ou
   0-2-0).

   Problemas confirmados:
     A) finance-hero-title { flex-direction:column } em ≤600px
        (finance-shell.css:212) — empilha ícone sozinho acima do título
     B) sl-hero com align-items:flex-start em 641–768px (gap entre
        slim-list.css ≤1023px e style.css ≤640px)
     C) justify-content:space-between herdado da base em modo coluna
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {

    /* ── A) finance-hero-title: manter ícone + título na mesma linha ──
       finance-shell.css ≤600px faz flex-direction:column, causando o
       ícone (42×42px) aparecer sozinho na primeira linha e o texto
       abaixo. Especificidade 1-1-0 vence 0-1-0 do finance-shell. */
    #page-content-wrapper .finance-hero-title {
        flex-direction: row;
        align-items: center;
        gap: 10px;
    }

    /* ── B+C) sl-hero: align-items:stretch + justify-content:flex-start
       no range 641–768px.
       slim-list.css ≤1023px define align-items:flex-start (0-1-0).
       style.css só muda para stretch em ≤640px (0-2-0).
       Aqui cobrimos o gap 641–768px com especificidade 1-1-0. */
    #page-content-wrapper .sl-hero {
        align-items: stretch;
        justify-content: flex-start;
    }

    /* Garantia: todos os filhos diretos do hero preenchem a largura
       total em modo coluna. slim-list.css já faz isso via width:100%
       em ≤1023px, mas esta regra é a net de segurança para variantes
       customizadas que não tenham o width explícito. */
    #page-content-wrapper .sl-hero-left,
    #page-content-wrapper .sl-hero-metrics,
    #page-content-wrapper .sl-actions {
        width: 100%;
        min-width: 0;
    }

    /* sl-hero-left: ícone + título sempre em linha horizontal */
    #page-content-wrapper .sl-hero-left {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 10px;
    }

    /* ── Operational heroes ([class$="-hero"]) ──
       operational-shell.css ≤991.98px já cobre align-items:stretch,
       mas o justify-content:space-between da base pode deixar espaço
       visual indesejado entre os filhos em modo coluna. */
    #page-content-wrapper [class$="-hero"]:not(.sl-hero):not(.finance-hero):not(.no-mobile-wrap) {
        justify-content: flex-start;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §10 PHONE (≤ 640px)

   Ajustes específicos para smartphones.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {

    /* ── 10.1 Topbar ── */
    .container-fluid-nav {
        padding-left: max(10px, env(safe-area-inset-left, 0px));
        padding-right: max(10px, env(safe-area-inset-right, 0px));
        gap: 8px;
    }

    /* ── 10.2 Conteúdo ── */
    .content,
    .container-fluid.content {
        padding: var(--page-padding-mobile, 15px);
        padding-bottom: 120px;
    }

    /* ── 10.3 Cards ── */
    .card-body {
        padding: 14px;
    }

    /* ── 10.4 Botões — wrapping garantido ── */
    .btn:not(.no-mobile-wrap) {
        max-width: 100%;
    }

    /* Grupos de botões sempre em linha com wrap */
    .btn-group:not(.no-mobile-wrap) {
        flex-wrap: wrap;
    }

    /* ── 10.5 Modais ── */
    .modal-dialog:not(.modal-fullscreen):not(.no-mobile-wrap) {
        margin: 0.4rem;
        max-width: calc(100vw - 0.8rem);
    }

    .modal-body {
        max-width: 100%;
        overflow-wrap: anywhere;
        word-break: break-word;
    }

    /* ── 10.6 Tabs ── */
    .tabs,
    .nav-tabs {
        overflow-x: auto;
        flex-wrap: nowrap;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    .tabs::-webkit-scrollbar,
    .nav-tabs::-webkit-scrollbar {
        display: none;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §11 SMALL PHONE (≤ 480px)

   Compressão máxima para telas muito pequenas.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 480px) {

    :root {
        --page-padding-mobile: 12px;
    }

    .content,
    .container-fluid.content {
        padding: 12px;
        padding-bottom: 120px;
    }

    .container-fluid-nav {
        padding-left: max(8px, env(safe-area-inset-left, 0px));
        padding-right: max(8px, env(safe-area-inset-right, 0px));
    }

    .card-body {
        padding: 12px;
    }

    .sl-hero {
        padding: 10px 12px;
        gap: 8px;
    }

    /* KPI grids: 1 coluna em telas muito pequenas */
    [class$="-kpis"]:not(.no-mobile-wrap),
    .tickets-kpis,
    .of-kpis,
    .fab-kpi-row,
    .lo-kpis,
    .pj-kpis,
    .delivery-kpis {
        grid-template-columns: 1fr !important;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §11 FLOATING FABs (chat + bug-report) — MOBILE / TABLET

   Em mobile/tablet (≤ 991.98px) os botões flutuantes ficam:
     - menores (40×40)
     - FIXOS à direita (NÃO arrastáveis em vw<992 — drag desabilitado em footer.php)
     - próximos ao rodapé (canto inferior direito), empilhados:
       chat em cima, bug-report logo abaixo
     - usando svh/dvh para corrigir Safari/Edge (barra de endereço
       dinâmica e cálculo de viewport quebrado em iOS/old Edge)
   Como agora os FABs não ocupam o canto inferior, o padding-bottom
   reservado para eles em mobile pode ser reduzido.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 991.98px) {

    /* Container do chat (DRAWER 2026-07-30): no mobile a mesma ABINHA lateral do
       desktop — presa na borda direita, meio da tela (abaixo do finEdge). O FAB
       redondo flutuante do canto morreu. Só vale com o drawer FECHADO: aberto,
       o footer.php cuida (coluna de balões no desktop / escondido no mobile). */
    body:not([data-komori-dock-open="1"]) .kimori-chat-root,
    body:not([data-komori-dock-open="1"]) .komori-dock-root {
        right: 0 !important;
        left: auto !important;
        top: 50% !important;
        bottom: auto !important;
        transform: translateY(calc(-50% + 90px)) !important;
        gap: 6px !important;
        /* z-index herda o 9990 do base (o 1083 antigo jogava a abinha atrás de overlays) */
    }

    /* Launcher: abinha retangular colada na borda (igual desktop recolhido) */
    /* (2026-07-30) Launcher: ZERO override no mobile — a abinha usa exatamente o
       mesmo CSS do desktop (footer.php, estado recolhido). Os blocos antigos daqui
       (FAB redondo, ícone 24px, label escondida) criavam a "bolota" diferente que
       o dono rejeitou — mesma UI nas duas plataformas, fim da diferença. */

    /* Bug-report FAB: acima do rodapé sticky (.app-footer) — com folga suficiente
       pra não sobrepor/colar nele (report #2628: 20px de folga colidia com o
       rodapé e deixava o botão colado na borda inferior, difícil de tocar). */
    .bug-report-fab {
        right: 12px !important;
        left: auto !important;
        top: auto !important;
        bottom: 72px !important;
        bottom: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
        width: 40px !important;
        height: 40px !important;
        box-shadow: 0 6px 14px rgba(255, 122, 0, 0.34);
        -webkit-transform: translateZ(0); /* força layer no Safari */
        transform: translateZ(0);
    }

    .bug-report-fab i {
        font-size: 0.95rem;
    }

    /* Painel do chat (DRAWER, 2026-07-30): no mobile ocupa a tela inteira,
       respeitando o banner fixo do topo e o footer via as vars --komori-drawer-*
       (setadas pelo syncEdges do footer.php). O bloco antigo forçava
       bottom:140px/top:auto (popup) e ESPREMIA o drawer num "sheet" no meio. */
    .kimori-chat-panel,
    .komori-dock-panel {
        position: fixed !important;
        right: 0 !important;
        left: 0 !important;
        top: var(--komori-drawer-top, 0px) !important;
        bottom: var(--komori-drawer-bottom, 0px) !important;
        width: auto !important;
        max-width: none !important;
        max-height: none !important;
        height: auto !important;
        border-radius: 0;
    }

    /* Janelas individuais de conversa (kimori-chat-window) também
       devem caber na tela quando abertas em mobile. */
    .kimori-chat-window {
        right: 6px !important;
        left: 6px !important;
        bottom: 140px !important;
        bottom: calc(124px + env(safe-area-inset-bottom, 0px)) !important;
        top: auto !important;
        width: auto !important;
        max-width: none !important;
        max-height: calc(100vh - 160px) !important;
        max-height: calc(100svh - 160px) !important;
        max-height: calc(100dvh - 160px) !important;
    }

    /* Como agora os FABs ocupam o canto inferior, mantém folga
       para não esconder conteúdo atrás deles. */
    .content,
    .container-fluid.content,
    body.app-scroll-lock #page-content-wrapper > .content,
    body.app-scroll-lock #page-content-wrapper > .container-fluid.content,
    body.app-scroll-lock #page-content-wrapper > main {
        padding-bottom: 96px;
    }
}

/* Telas muito pequenas (≤ 480px): mantém o mesmo posicionamento,
   apenas garante folga mínima da borda direita. */
@media (max-width: 480px) {
    .kimori-chat-root,
    .komori-dock-root,
    .bug-report-fab {
        right: 8px !important;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §12 TABELAS — ANTI-ESMAGAMENTO ("tabela enrugada") (≤ 1024px)

   Problema: tabelas com width:100% dentro de containers estreitos
   esmagam as colunas — cada célula quebra a cada 1-2 palavras e a
   tabela fica "enrugada"/ilegível.

   Solução: dentro de um scroll container (que §4.8 já garante), a
   tabela usa a largura NATURAL do conteúdo (width:max-content) com
   piso de 100% — colunas respiram e o overflow vira scroll horizontal
   suave, em vez de esmagamento.

   - th nowrap: cabeçalho define a largura mínima legível da coluna
     (resolve cabeçalhos quebrando letra por letra).
   - td max-width: colunas de texto longo (observações/notas) quebram
     em ~70vw em vez de esticar a tabela por quilômetros.
   - table-layout:fixed é excluído (depende de width:100%).
   - Opt-out: .no-mobile-wrap na tabela ou no wrapper.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {

    .table-responsive > table:not(.no-mobile-wrap),
    .sl-table-wrap > table:not(.no-mobile-wrap),
    [class$="-table-wrap"] > table:not(.no-mobile-wrap) {
        width: max-content;
        min-width: 100%;
        max-width: none;
    }

    /* Cabeçalhos nunca quebram letra por letra */
    .table-responsive table:not(.no-mobile-wrap) thead th,
    .sl-table-wrap table:not(.no-mobile-wrap) thead th,
    [class$="-table-wrap"] table:not(.no-mobile-wrap) thead th {
        white-space: nowrap;
    }

    /* Células de dados: largura natural, com teto para texto corrido */
    .table-responsive table:not(.no-mobile-wrap) tbody td,
    .sl-table-wrap table:not(.no-mobile-wrap) tbody td,
    [class$="-table-wrap"] table:not(.no-mobile-wrap) tbody td {
        max-width: min(420px, 70vw);
        overflow-wrap: break-word;
    }

    /* Tabelas com table-layout:fixed dependem de width:100% — restaura */
    .table-responsive > table[style*="table-layout"],
    .table-responsive > .table-fixed,
    .sl-table-wrap > table[style*="table-layout"] {
        width: 100%;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §13 TÍTULOS E HEADER-ROWS — QUEBRA DE LINHA GARANTIDA (≤ 1024px)

   Problema: títulos de página/card e linhas de header
   (.d-flex.justify-content-between) não quebram linha — o texto
   estoura ou é cortado por ellipsis, e botões à direita esmagam o
   título ("header não dando parágrafos").

   - Headings quebram normalmente (inclusive strings longas em
     japonês sem espaços, via overflow-wrap).
   - Linhas flex de header passam a permitir wrap: só tem efeito
     quando o conteúdo realmente não cabe (zero impacto quando cabe).
   - Especificidade 1-1-0 (#page-content-wrapper) para vencer sheets
     de componente carregados depois no <body>.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {

    #page-content-wrapper h1,
    #page-content-wrapper h2,
    #page-content-wrapper h3,
    #page-content-wrapper h4,
    #page-content-wrapper h5,
    #page-content-wrapper h6,
    #page-content-wrapper .card-title,
    #page-content-wrapper .card-header {
        white-space: normal;
        overflow-wrap: break-word;
        min-width: 0;
        max-width: 100%;
    }
}

@media (max-width: 768px) {

    /* Header de card com flex (título + ações): permite quebrar em
       duas linhas quando não cabe, em vez de esmagar o título. */
    #page-content-wrapper .card-header.d-flex:not(.flex-nowrap):not(.no-mobile-wrap) {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    /* Linhas "título à esquerda / ações à direita" — padrão mais
       comum do sistema (d-flex justify-content-between). Wrap só
       acontece se o conteúdo não couber. */
    #page-content-wrapper .d-flex.justify-content-between:not(.flex-nowrap):not(.no-mobile-wrap) {
        flex-wrap: wrap;
        row-gap: 6px;
    }
}


/* ══════════════════════════════════════════════════════════════════════
   §14 KPI / STAT CARDS — COLUNAS ADAPTATIVAS ("cards comidos")

   Problema: strips de KPI/estatística com colunas fixas
   (repeat(4..7, 1fr)) ou minmax(>=180px) esmagam/estouram os cards
   em tablet e phone — números cortados, labels ilegíveis.

   Tablet (≤ 991.98px): 2 colunas confortáveis.
   Small phone (≤ 480px): 1 coluna (§11 já cobre parte; aqui unifica).
   Especificidade 1-0-1-0 via #page-content-wrapper para vencer os
   <style> inline das páginas.
   Opt-out: .no-mobile-wrap.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 991.98px) {

    #page-content-wrapper [class$="-kpis"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-row"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-strip"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-grid"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-stat-grid"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-stats-grid"]:not(.no-mobile-wrap) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Cards de KPI nunca são cortados: conteúdo encolhe e quebra */
    #page-content-wrapper [class*="-kpi"] ,
    #page-content-wrapper [class*="-stat-card"] {
        min-width: 0;
        max-width: 100%;
        overflow-wrap: break-word;
    }
}

@media (max-width: 480px) {

    #page-content-wrapper [class$="-kpis"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-row"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-strip"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-kpi-grid"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-stat-grid"]:not(.no-mobile-wrap),
    #page-content-wrapper [class$="-stats-grid"]:not(.no-mobile-wrap) {
        grid-template-columns: 1fr;
    }
}
