/* ==========================================================================
   mobile.css -- Greyes no celular (PWA). Carregado DEPOIS de style.css e dos
   css de módulo, de propósito: só existe pra ajustes de celular/toque, num
   arquivo próprio (nenhuma outra sessão mexe aqui, então não gera conflito
   no style.css gigante). Diário e medições: docs/mobile-pwa.md.

   REGRA: tudo que muda layout fica dentro de @media (max-width: 860px) (mesmo
   corte do layout mobile do style.css) -- desktop não é tocado. Alvos de
   toque >= 44 px (mín. 40), campos >= 16 px (iOS dá zoom abaixo disso).
   ========================================================================== */

/* ---------- base de toque (só aparelho com toque/ponteiro grosso) ---------- */
@media (max-width: 860px) {
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  /* Sem o atraso/zoom de duplo toque em botões e links. */
  button, a, select, summary, label, [role="button"], .tab-inline, .topcat { touch-action: manipulation; }
  button, a { -webkit-tap-highlight-color: rgba(53, 208, 126, .18); }
  /* iOS dá zoom na página ao focar um campo com fonte < 16 px. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select, textarea { font-size: 16px !important; }
}
/* PWA instalado: puxar a tela pra baixo recarregava a página sem querer (e
   derrubava o vídeo ao vivo). No navegador comum o recarregar continua. */
@media (display-mode: standalone) and (max-width: 860px) {
  html, body { overscroll-behavior-y: none; }
}

/* ---------- área segura (notch / barra de gestos) ----------
   Depende de `viewport-fit=cover` no index.html. Sem notch o env() vale 0. */
@media (max-width: 860px) {
  .topcats {
    padding-top: calc(6px + env(safe-area-inset-top, 0px));
    padding-left: calc(10px + env(safe-area-inset-left, 0px));
    padding-right: calc(10px + env(safe-area-inset-right, 0px));
  }
  main { padding-left: calc(10px + env(safe-area-inset-left, 0px)); padding-right: calc(10px + env(safe-area-inset-right, 0px)); }
  .bottom-nav {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
  .toast-container { top: calc(12px + env(safe-area-inset-top, 0px)); }
}

/* ---------- cabeçalho e navegação ---------- */
@media (max-width: 860px) {
  /* Os 5 ícones da conta (tema, ajuda, avisos, conta, sair) mediam 34x30. */
  .topcat-util { min-width: 40px; min-height: 44px; justify-content: center; align-items: center; padding: 6px 4px; }
  .topcats-account { gap: 2px; }
  /* Tira de categorias rolável: esmaece a borda direita pra mostrar que tem mais. */
  .topcats-menu { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent); padding-right: 22px; }
  .topcat { min-height: 44px; justify-content: center; }
  /* A linha de sub-abas (Início / Regras de Alarme / Central de Alarmes...)
     ficava grudada embaixo do cabeçalho: ~110 px de tela fixos o tempo todo,
     num celular de 812 px. Com a barra inferior para navegar, ela pode rolar
     junto com a página (o grupo Vídeo já era assim desde 28/10). */
  .sidebar { position: static; }
  .tabs > button { min-height: 44px; }
  .bottom-nav button { font-size: 12px; }
  .topcat > span, .topcat-util > span { font-size: 12px; }
  /* Página inteira com altura que acompanha a barra de endereço do celular. */
  .app { min-height: 100dvh; }
}

/* ---------- teclado virtual ----------
   mobile.js mede o teclado (visualViewport) e marca <html class="kb-open">
   com --vvh/--vvt. Sem isso, janelas centralizadas ficam com os botões
   escondidos atrás do teclado (iOS e Android recente não redimensionam a
   página, o teclado só cobre). */
@media (max-width: 860px) {
  html.kb-open .bottom-nav { display: none; }
  html.kb-open .sobreposicao,
  html.kb-open .modal { top: var(--vvt, 0px); bottom: auto; height: var(--vvh, 100%); }
  html.kb-open .sobreposicao { align-items: flex-start; padding-top: 12px; }
  html.kb-open .sobreposicao-caixa { max-height: calc(var(--vvh, 100dvh) - 24px); overflow-y: auto; }
  html.kb-open .modal-body { max-height: var(--vvh, 92dvh); }
}

/* ---------- janelas (modal / sobreposição) ---------- */
@media (max-width: 860px) {
  .modal-body { max-height: 92vh; }
  .sobreposicao-caixa { max-height: calc(100vh - 32px); }
}
@supports (height: 100dvh) {
  @media (max-width: 860px) {
    .modal-body { max-height: 92dvh; }
    .modal.is-expanded .modal-body { height: 100dvh; max-height: 100dvh; }
    .sobreposicao-caixa { max-height: calc(100dvh - 32px); }
    .sobreposicao-galeria { height: calc(100dvh - 32px); }
  }
}
@media (max-width: 860px) {
  /* Margem de 26 px reservada pra scrollbar do desktop: no toque a barra é
     sobreposta, e a margem só estreitava o conteúdo. */
  #modal-content { margin-right: 0; padding-right: 0; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .modal-body { padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
  /* Botões de minimizar / expandir / fechar: 30 px -> alvo de toque decente. */
  .modal-ctls .modal-ctl, .modal-ctls .modal-close { min-width: 40px; min-height: 40px; }
  .sobreposicao-fechar { min-width: 44px; min-height: 44px; font-size: 20px; }
  .sobreposicao { padding: 10px; }
  .sobreposicao-caixa textarea { font-size: 16px; }
  .sobreposicao-caixa .toolbar button { min-height: 46px; flex: 1 1 0; }
}

/* ==========================================================================
   MÓDULO 1 -- Central de Alarmes
   ========================================================================== */
@media (max-width: 860px) {
  /* Barra do topo: linha 1 = Mostrar filtros + Atualizar; linha 2 =
     Criticidade + Selecionar; linha 3 = filtros ativos (uma linha só, rolável).
     Antes: botões de 29 px de altura e os filtros ativos ocupavam 3 linhas. */
  #view-alarm-history .ap-filtros-toggle-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
  #view-alarm-history .apf-toggle-actions { display: contents; }
  #ap-hist-toggle-filtros { order: 1; flex: 1 1 170px; min-width: 170px; min-height: 44px; text-align: left; white-space: nowrap; }
  #ap-hist-refresh { order: 2; flex: 0 0 auto; }
  #ap-hist-crit-report { order: 3; flex: 1 1 calc(50% - 4px); }
  #ap-hist-selecionar { order: 4; flex: 1 1 calc(50% - 4px); }
  #ap-hist-manage-watch, #ap-hist-ia-qualidade { order: 5; flex: 1 1 calc(50% - 4px); }
  #view-alarm-history .apf-toggle-actions button { min-height: 44px; padding: 8px 10px; font-size: 14px; }
  #ap-hist-filtros-resumo { order: 6; display: flex; flex-wrap: nowrap; gap: 6px; align-items: center; font-size: 13px; width: 100%;
    overflow-x: auto; white-space: nowrap; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  #ap-hist-filtros-resumo::-webkit-scrollbar { display: none; }
  #ap-hist-filtros-resumo > * { flex: 0 0 auto; }
  .ap-night-strip { font-size: 13.5px; padding: 8px 12px; }
  /* Os "x" dos filtros ativos eram 33x25. */
  .ap-filtro-ativo { min-height: 40px; padding-left: 12px; font-size: 13px; }
  .ap-filtro-x { min-width: 40px; min-height: 40px; margin: 0 -6px 0 0; font-size: 20px; }
  /* Chips do painel de filtros. */
  .apf .ap-hist-range-tab, .apf .ap-hist-category-tab { min-height: 40px; padding: 8px 12px; font-size: 14px; }
  .ap-area-pill { min-height: 40px; padding: 8px 12px; font-size: 14px; }
  .crit-filter-btn { min-height: 40px; padding: 8px 12px; font-size: 14px; }
  .apf-label { font-size: 12.5px; }
  .apf-field > span { font-size: 13px; }
  .apf-actions button, #ap-hist-filter, #ap-hist-limpar { min-height: 46px; }
  /* Datas e horas: campo nativo (seletor do sistema), com altura de dedo. */
  .apf input[type="date"], .apf input[type="time"] { min-height: 44px; }

  /* "Exibição": Ordenar / Agrupar / Por página / Cards-Lista / Legenda ocupavam 5
     linhas (~190 px) antes do primeiro alarme. Agora grade de 2 colunas. */
  .ap-exibicao-bar { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: end; margin-bottom: 10px; }
  .ap-exibicao-bar .apf-label-inline { display: none; }
  .ap-exibicao-bar .ap-page-size { display: flex; flex-direction: column; gap: 3px; font-size: 12.5px; color: var(--muted); text-align: left; }
  .ap-exibicao-bar .ap-page-size select { width: 100%; min-height: 44px; }
  .ap-exibicao-bar .ap-view-toggle { display: flex; gap: 6px; }
  .ap-exibicao-bar .ap-view-toggle button { flex: 1; min-height: 44px; padding: 8px 6px; }
  .ap-exibicao-bar .ap-hist-legend { grid-column: 1 / -1; }
  .ap-hist-legend summary { min-height: 40px; display: flex; align-items: center; }

  /* Card do alarme: textos mais legíveis e botões de 44 px. */
  .ap-card-top .ap-time { font-size: 13px; }
  .ap-card-meta { font-size: 13px; }
  .ap-chip { font-size: 12px; line-height: 20px; padding: 0 8px; }
  .ap-card-actions { grid-template-columns: 1fr 1fr 44px; }
  .ap-card-actions button { min-height: 44px; }
  .ap-card-actions .ap-card-pin-btn { width: 44px; min-height: 44px; padding: 0; }
  .alarme-alvo { font-size: 12px; }
  .crit-badge { font-size: 12px; }

  /* Modo Lista: miniatura + texto numa linha e, embaixo, as 3 ações com 44 px
     (eram 33x24 espremidas ao lado do texto, que ficava cortado). */
  .ap-hist-row { flex-wrap: wrap; row-gap: 8px; padding: 8px 10px; }
  .ap-hist-row-thumb { width: 84px; height: 48px; }
  .ap-hist-row-main { flex: 1 1 0; min-width: 0; row-gap: 2px; }
  .ap-hist-row-event { font-size: 14.5px; }
  .ap-hist-row-sub { font-size: 13px; flex: 1 1 100%; }
  .ap-hist-row-time { font-size: 13px; }
  .ap-hist-row-actions { flex: 1 1 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }
  .ap-hist-row-actions:empty { display: none; }
  .ap-hist-row-actions button { min-height: 44px; font-size: 16px; padding: 6px; }

  /* Paginação: 4 botões + rótulo empilhados em 5 linhas; agora grade 2x2. */
  #ap-hist-pagination { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  #ap-hist-pagination #ap-hist-page-label { grid-column: 1 / -1; text-align: center; order: -1; }
  #ap-hist-pagination button { min-height: 44px; width: 100%; }

  /* Barra de ações em lote (modo "Selecionar"). */
  .massa-barra { position: sticky; bottom: calc(66px + env(safe-area-inset-bottom, 0px)); }
  .massa-barra button, .massa-barra select { min-height: 44px; }
}

/* ---------- Detalhe do alarme (modal): evidência primeiro ----------
   Em celular as duas colunas empilham, e a foto/vídeo ficava DEPOIS de seis
   linhas de "Detalhes" (medido: foto a ~560 px do topo do modal). Quem
   reconhece um alarme precisa ver a imagem primeiro. `display: contents`
   dissolve as colunas e `order` remonta: cabeçalho, status, ações, ABAS +
   imagem/vídeo, e só então Detalhes. Desktop não é tocado. */
@media (max-width: 860px) {
  .aed { display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding-bottom: 60px; min-width: 0; }
  .aed > *, .aed-col-left > *, .aed-col-right > * { min-width: 0; max-width: 100%; }
  .aed-col-left, .aed-col-right { display: contents; }
  .aed-head { order: 1; margin-bottom: 0; }
  .aed-status-line { order: 2; margin-bottom: 0; }
  .aed-actions-main { order: 3; }
  .aed-actions-sec { order: 4; }
  .aed-col-right > .tabs-inline { order: 5; }
  .aed-col-right > #aed-tab-body { order: 6; margin-top: 0; }
  .aed-col-right > #aed-quick-comment-wrap { order: 7; }
  .aed-fields { order: 8; }
  .aed-footer { order: 9; margin-top: 4px; }
  /* Reconhecer: botão grande, com altura de dedo, status ao lado. */
  .aed-actions-main { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .aed-actions-main > * { min-width: 0; width: 100%; box-sizing: border-box; }
  .aed-actions-main .aed-confirm-btn, .aed-actions-main .aed-status-select { min-height: 52px; }
  .aed-actions-sec { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .aed-actions-sec button { min-height: 44px; }
  .tabs-inline { display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 6px; scrollbar-width: none; }
  .tabs-inline::-webkit-scrollbar { display: none; }
  .tab-inline { min-height: 44px; flex: 0 0 auto; }
  .aed-score-label { font-size: 12px; }
  .aed-score { width: 60px; height: 60px; min-height: 44px; }
  .aed-field { padding: 8px 0; font-size: 14px; }
  .aed-quick-comment { flex-direction: column; align-items: stretch; }
  .aed-quick-comment textarea, .aed-comment-form textarea { width: 100%; box-sizing: border-box; }
  .aed-quick-comment button, .aed-comment-form-actions button { min-height: 46px; }
  .aed-galeria-link { min-height: 44px; }
  /* Setas anterior/próximo: ficavam no meio da altura da tela, por cima do
     texto. Descem pro canto inferior, acima da área segura, com 44 px. */
  .aed-nav-arrow {
    top: auto; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); transform: none;
    width: 44px; height: 44px; font-size: 22px; background: rgba(0, 0, 0, .62);
  }
  .aed-nav-prev { left: 10px; }
  .aed-nav-next { right: 10px; }
  .aed-img-nav { min-width: 44px; min-height: 44px; }
  .aed-img-open { min-width: 40px; min-height: 40px; }
}

/* ==========================================================================
   MÓDULO 2 -- Dashboard e linha do tempo de alertas
   ========================================================================== */
@media (max-width: 860px) {
  /* Barra do topo (Cluster / Atualizar / Editar). */
  #view-dashboard > .toolbar button, #dash-cluster-btn, #dash-refresh { min-height: 44px; }
  #dash-editar { margin-left: 0 !important; }
  .dash-cluster-menu { max-height: 60vh; min-width: min(260px, calc(100vw - 32px)); }
  .dash-cluster-menu label { min-height: 44px; padding: 8px 10px; font-size: 15px; }
  .dash-cluster-menu input { width: 20px; height: 20px; }
  .dash-edit-bar .dash-edit-acoes { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; }
  .dash-edit-bar button { min-height: 44px; }

  /* Início rápido: 7 atalhos em 2 colunas ocupavam ~370 px; 3 colunas compactas. */
  .dash-quickstart-panel .dash-quick-grid:not(.hidden) { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: auto; }
  .dash-quickstart-panel .dash-quick-btn { min-height: 76px; padding: 8px 4px; font-size: 13px; }
  .dash-quickstart-panel .ap-view-toggle { display: flex; gap: 6px; }
  .dash-quickstart-panel .ap-view-toggle button { flex: 1; min-height: 44px; padding: 8px 6px; font-size: 14px; }
  .dash-live-events-list li { min-height: 44px; align-items: center; }

  /* Linha do tempo. A grade rola na horizontal dentro da própria caixa
     (rótulo da usina fixo à esquerda); a coluna da usina estreita pra sobrar
     mais área de eventos à vista, e as bolinhas ganham área de toque maior. */
  .dash-tl-legend { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .dash-tl-key { min-height: 40px; padding: 6px 10px; font-size: 13px; min-width: 0; white-space: normal; line-height: 1.2; text-align: left; }
  .toast-close { min-width: 40px; min-height: 40px; }
  .donut-chart-hole .muted { font-size: 11.5px; }
  .dash-tl { max-height: 62vh; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
  .dash-tl-grid { min-width: 620px; }
  .dash-tl-row { grid-template-columns: 112px 1fr; }
  .dash-tl-label { font-size: 13px; padding: 8px 6px 8px 8px; }
  .dash-tl-track { height: 38px; }
  .dash-tl-axis-t { font-size: 12px; }
  .dash-tl-dot::after { content: ""; position: absolute; inset: -10px; border-radius: 50%; }
  .dash-tl-tip { max-width: calc(100vw - 16px); font-size: 13.5px; }
  #dash-tl-hours, #dash-chart-site, #dash-chart-days, #dash-calor-dias { min-height: 44px; }

  /* Cartões das usinas: 3 linhas + botão por usina (~170 px cada; com 48
     usinas eram ~8000 px de rolagem). Agora nome/cluster em cima e, embaixo,
     números à esquerda e "Ver ao vivo" à direita (~110 px). */
  .dash-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px 12px; }
  .dash-card-top { grid-column: 1 / -1; }
  .dash-card-stats, .dash-card-alarm { grid-column: 1; }
  .dash-card-btn { grid-column: 2; grid-row: 2 / span 2; align-self: center; min-height: 44px; padding: 8px 14px; }
  .dash-card-top strong { font-size: 16px; }

  /* Mapa: um dedo na vertical rola a PÁGINA (antes o mapa prendia o gesto e
     não dava pra passar dele); arrastar de lado e pinça continuam no mapa. */
  #dash-map, #dash-map.leaflet-container { touch-action: pan-y; }
  #dash-map-expand, #dash-map-theme-toggle { min-height: 44px; min-width: 44px; }
  .leaflet-touch .leaflet-bar a { width: 40px; height: 40px; line-height: 40px; }

  /* Gráfico de alarmes por hora: dica de cada barra ao toque. */
  .chart-trend { height: 150px; }
  .chart-trend-bar { min-width: 6px; }
  /* A dica ficava cortada nas barras das pontas (centralizada na barra). */
  .chart-trend-bar:nth-last-child(-n+4) .chart-trend-tip { left: auto; right: 0; transform: none; }
  .chart-trend-bar:nth-child(-n+4) .chart-trend-tip { left: 0; transform: none; }
  .dash-panel-clickable { -webkit-tap-highlight-color: rgba(53, 208, 126, .15); }
}

/* ==========================================================================
   MÓDULO 3 -- Ao Vivo e Gravação (técnico em campo)
   ========================================================================== */
@media (max-width: 860px) {
  /* Abas "Ao Vivo | Gravação": empilhadas (~130 px) com ícone em cima; agora
     lado a lado, 44 px, e a árvore/busca ocupam a linha toda abaixo delas. */
  .tabs[data-group="video"] { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 6px 8px; align-items: stretch; }
  .tabs[data-group="video"] > button[data-view] { flex-direction: row; justify-content: center; align-items: center; gap: 8px; min-height: 44px; font-size: 14px; padding: 8px 10px; }
  .tabs[data-group="video"] > :not(button[data-view]) { grid-column: 1 / -1; min-width: 0; }
  .arvore-toggle { min-height: 48px; }
  .live-tree-search-wrap input, .live-tree-search { min-height: 44px; font-size: 16px; }
  .lt-area, .lt-nvr, .lt-cam { min-height: 44px; }
  .lt-row-edit, .lt-row-add, .lt-row-fav { min-width: 40px; min-height: 40px; opacity: .75; }

  /* Barra do Ao Vivo/Gravação em 2 linhas (eram 5, ~360 px antes da grade):
     seletores crescem, botões viram quadrados de 44 px. */
  #view-live > .toolbar, #view-recordings > .toolbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
  #view-live > .toolbar > .toolbar-group, #view-recordings > .toolbar > .toolbar-group,
  #view-live > .toolbar .dropdown, #view-recordings > .toolbar .dropdown { display: contents; }
  #view-live > .toolbar > .sep, #view-recordings > .toolbar > .sep { display: none; }
  #view-live > .toolbar button, #view-recordings > .toolbar button { flex: 0 0 auto; min-width: 44px; min-height: 44px; padding: 8px 10px; }
  #view-live > .toolbar select, #view-recordings > .toolbar select { flex: 1 1 110px; min-width: 96px; min-height: 44px; }
  #live-page, #rec-page { flex: 0 0 auto; font-size: 13px; }
  #saved-view-select, #rec-saved-view-select { flex: 1 1 100px; min-width: 100px; }
  #view-live .toolbar [style*="margin-left:auto"] { margin-left: 0 !important; }

  /* Menus e filtros abrem como folha embaixo (já era assim): alvos 44 px. */
  .filter-menu label, .rec-more-menu label { min-height: 44px; }
  /* As regras da barra de ferramentas acima (flex: 1 1 110px nos select) também
     alcançavam os controles DENTRO dos menus (que ficam dentro da toolbar) e
     esticavam campos para 110-140 px de altura (coluna). Zera dentro dos menus. */
  #view-live > .toolbar .dropdown-menu :is(button, select, input),
  #view-recordings > .toolbar .dropdown-menu :is(button, select, input) { flex: none; min-width: 0; }
  #view-live > .toolbar .dropdown-menu select, #view-recordings > .toolbar .dropdown-menu select,
  #view-live > .toolbar .dropdown-menu input:not([type="checkbox"]), #view-recordings > .toolbar .dropdown-menu input:not([type="checkbox"]) { width: 100%; }
  .rec-more-menu .rec-range { align-items: stretch; justify-content: flex-start; }
  .filter-menu label.live-online-toggle, .filter-menu label.filter-check { flex-direction: row; align-items: center; text-align: left; }
  .filter-menu .filter-check, .live-online-toggle { min-height: 44px; display: flex; align-items: center; gap: 10px; }
  .filter-menu input[type="checkbox"], .live-online-toggle input[type="checkbox"] { width: 22px; height: 22px; }
  /* O "Mais" da Gravação é pop-up centralizado com translate(-50%,-50%) no
     style.css, mas a regra de folha (.dropdown-menu, mais abaixo) troca
     left/top e a transformação continua: saía 163 px fora da tela. Vira folha
     embaixo, como os outros menus. */
  .rec-more-menu { transform: none; left: 12px; right: 12px; top: auto; width: auto; max-height: calc(100dvh - 90px); overflow-y: auto; overscroll-behavior: contain; }
  .rec-more-head button { min-width: 44px; min-height: 44px; }
  .rec-more-section button { min-height: 44px; }
  .rec-range input { min-height: 44px; }

  /* Células da grade: no toque não existe :hover, então o botão de remover
     da visualização, a câmera (foto) e o selecionar ficam visíveis. */
  .cell-close-btn { opacity: .9; min-width: 40px; min-height: 40px; }
  .cell-rec-btn, .cell-target-btn { min-width: 40px; min-height: 40px; }
  .cell .label { font-size: 14px; }
  .cell-ptz-pad button { touch-action: none; }

  /* Linha do tempo da Gravação: faixa de 44 px e sem rolagem da página por
     cima (o arrasto escolhe período; ver mobile.js). */
  .cell button[data-reconnect] { min-height: 44px; padding: 8px 16px; }
  .rec-timeline.rec-tl-inline { height: 44px; min-height: 44px; }
  .tl-selectable { touch-action: none; }
  .rec-timeline.rec-tl-inline .tl-hour-label { font-size: 11px; }
  /* Ampliar uma câmera (foco): o vídeo fica grudado embaixo do cabeçalho
     enquanto se rola pelos controles de PTZ, presets e patrulha -- dava pra
     mexer a câmera sem ver a imagem. */
  .em-foco .foco-video { position: sticky; top: var(--hdr-h, 62px); z-index: 30; background: var(--bg); padding-bottom: 6px; }
  .em-foco .foco-barra button { min-height: 44px; }
  .foco-lateral button, .foco-lateral select { min-height: 44px; }
  .foco-lateral input[type="range"] { min-height: 44px; }
  .ptz-pad button { touch-action: none; -webkit-touch-callout: none; user-select: none; }
}
@media (hover: none) and (max-width: 860px) {
  .cell:hover .cell-ptz-overlay { opacity: 0; pointer-events: none; }
}

/* ==========================================================================
   MÓDULO 4 -- Histórico de alarmes (Central: relatório, seleção em massa)
   ========================================================================== */
@media (max-width: 860px) {
  /* Relatório de criticidade: abas de período 44 px. */
  .crit-rel-periodo .ap-hist-category-tab, .ap-hist-category-tab { min-height: 44px; }
  .crit-heat-cell { min-height: 48px; }
  .crit-rel-tabela td, .crit-rel-tabela th { padding: 8px 6px; }

  /* Edição em massa: a barra grudada ocupava ~274 px (34% da tela) quebrada
     em 4 linhas por cima da lista. Vira UMA linha de rolagem lateral: a
     contagem fica fixa à esquerda, a ação principal (Reconhecer) vem
     primeiro e "Todos/Limpar/Sair" ao final. */
  .massa-barra { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; padding: 8px 10px; gap: 8px; }
  .massa-barra::-webkit-scrollbar { display: none; }
  .massa-barra > * { flex: 0 0 auto; white-space: nowrap; order: 5; }
  .massa-barra .massa-qtd { order: 0; position: sticky; left: -10px; z-index: 2; min-width: 0; padding: 0 10px 0 10px;
    margin-left: -10px; background: var(--panel); display: flex; align-items: center; min-height: 44px; box-shadow: 8px 0 8px -4px var(--panel); }
  .massa-barra [data-massa-acao="ack"] { order: 1; }
  .massa-barra [data-massa-acao="verifying"] { order: 2; }
  .massa-barra [data-massa-acao="false_alarm"] { order: 3; }
  .massa-barra [data-massa-acao="comment"] { order: 4; }
  .massa-barra [data-massa-acao="pin"] { order: 5; }
  .massa-barra [data-massa-acao="pin_all"] { order: 6; }
  .massa-barra [data-massa-acao="unpin"] { order: 7; }
  .massa-barra [data-massa="todos"] { order: 8; }
  .massa-barra [data-massa="limpar"] { order: 9; }
  .massa-barra .massa-sair { order: 10; margin-left: 0; }
  .massa-barra .massa-sep { display: none; }

  /* Selo de criticidade (abre o detalhe da pontuação): 20 px de altura -> área de toque ~44 px. */
  [data-crit-alarm] { position: relative; }
  [data-crit-alarm]::after { content: ""; position: absolute; inset: -12px -6px; }
  .ap-watch-item button { min-height: 44px; }
}

/* ==========================================================================
   MÓDULO 5 -- Equipamentos (Sites/Usinas, NVRs, Câmeras, Cornetas, Tags, Áreas)
   Tabelas viram cartões (classe .m-cards e data-label são postas por mobile.js;
   o HTML original das tabelas não muda).
   ========================================================================== */
@media (max-width: 860px) {
  /* Cabeçalho do painel (título + PDF/Excel/Novo): quebra linha em vez de vazar. */
  .view > .panel > h3 { flex-wrap: wrap; gap: 8px; }
  .view > .panel > h3 > span { flex-wrap: wrap; }
  .view > .panel > h3 button, .view .toolbar button, .tabs-inline button { min-height: 44px; }
  .view .toolbar { flex-wrap: wrap; gap: 8px; }
  .view .toolbar select, .view .toolbar input { min-height: 44px; flex: 1 1 140px; min-width: 0; }
  .tabs-inline { display: flex; flex-wrap: wrap; gap: 6px; }

  /* A coluna de ações grudada (sticky) tinha 404 px nos NVRs e cobria a tela
     inteira: o nome do NVR nem aparecia. */
  .col-sticky-actions { position: static; box-shadow: none; background: transparent; }

  table.data-table.m-cards { display: block; min-width: 0 !important; width: 100%; border: 0; }
  .table-scroll table.data-table.m-cards { min-width: 0; }
  table.data-table.m-cards tbody { display: block; }
  /* Cabeçalho vira barra "Ordenar por" com chips (o clique de ordenação continua no <th>). */
  table.data-table.m-cards thead { display: block; margin: 8px 0 10px; }
  table.data-table.m-cards thead tr { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
  table.data-table.m-cards thead tr::before { content: "Ordenar por"; font-size: 13px; color: var(--muted); margin-right: 2px; }
  table.data-table.m-cards thead th { display: none; }
  table.data-table.m-cards thead th.sortable-th { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; padding: 0 14px;
    border: 1px solid var(--border); border-radius: 999px; background: var(--panel2); text-transform: none; letter-spacing: 0; font-size: 14px; }
  table.data-table.m-cards tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px 14px;
    padding: 12px; margin: 0 0 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel2); }
  table.data-table.m-cards tbody tr:hover { background: var(--panel2); }
  table.data-table.m-cards td { display: block; padding: 0; border: 0; min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
  table.data-table.m-cards td[data-label]::before { content: attr(data-label); display: block; font-size: 12px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .4px; margin-bottom: 1px; }
  table.data-table.m-cards td.m-titulo { grid-column: 1 / -1; order: -2; font-size: 17px; font-weight: 600; }
  table.data-table.m-cards td.m-titulo::before { display: none; }
  table.data-table.m-cards td.m-imagem, table.data-table.m-cards td.m-acoes, table.data-table.m-cards td[colspan] { grid-column: 1 / -1; }
  table.data-table.m-cards td.m-acoes { order: 99; display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin-top: 2px; }
  table.data-table.m-cards td.m-acoes::before { display: none; }
  table.data-table.m-cards td.m-acoes button { min-height: 44px; width: 100%; white-space: normal; }
  table.data-table.m-cards td button { min-height: 44px; }
  .cam-mgmt-thumb button { min-height: 44px; }

  /* Áreas, Cornetas, Tags e formulários em janela: botões 44 px, linhas de
     seleção de site 44 px (os rótulos têm font-size 13px inline). */
  #view-clusters button, #view-tags button, #view-outputs button, #modal-content button { min-height: 44px; }
  .nff-help { min-width: 40px; }
  #view-clusters details summary { min-height: 44px; align-items: center; }
  #view-clusters details label { min-height: 44px; font-size: 15px !important; }
  #view-clusters details input[type="checkbox"] { width: 22px; height: 22px; }
}

/* ==========================================================================
   MÓDULO 6 -- Regras de alarme, Relatórios, Mapas
   ========================================================================== */
@media (max-width: 860px) {
  /* Cartão de totais (Regras de Evento / Total / Ativas / Desativadas) tinha
     394 px de largura fixa por conteúdo e empurrava a página (rolagem lateral). */
  .alarmrule-total-card { display: flex; width: 100%; box-sizing: border-box; gap: 12px; padding: 12px 14px; flex-wrap: wrap; }
  .alarmrule-total-card .art-title { padding-right: 12px; }
  .alarmrule-total-card .art-metrics { flex: 1 1 200px; gap: 8px; justify-content: space-around; min-width: 0; }
  .alarmrule-total-card .art-metric { min-width: 0; flex: 1 1 0; }

  /* Lista de regras: setinha que abre o detalhe (24 px), selo do tipo de evento
     (filtra a lista, 22 px), "+ Nova regra" do grupo e "Limpar filtros". */
  .evrule-toggle { min-width: 44px; min-height: 44px; font-size: 16px; }
  .evrule-type-badge { min-height: 40px; display: inline-flex; align-items: center; }
  .evrule-group-add, #alarmrule-filter-clear, .evrule-li button.ghost { min-height: 44px; }
  .evrule-site-group-summary { min-height: 52px; }
  #view-alarm-rules .evrule-select-cb { width: 24px; height: 24px; }

  /* Filtros em 2 colunas (7 campos empilhados ocupavam ~800 px antes da lista). */
  #view-alarm-rules .filter-bar-fields { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
  #view-alarm-rules .filter-bar-fields > label { min-width: 0; font-size: 14px; }
  #view-alarm-rules .filter-bar-fields > .filter-bar-search { grid-column: 1 / -1; }
  #view-alarm-rules .filter-bar-fields select { width: 100%; min-width: 0; text-overflow: ellipsis; }

  /* Janela "Editar Regra de Evento": a linha de cada ação (select 340 px + ⓘ + 🗑)
     passava 82 px da janela; dias da semana e interruptores de 23-37 px. */
  .evrule-action-card-head { min-width: 0; gap: 4px; }
  .evrule-action-card-head select.evrule-action-type { flex: 1 1 0; width: auto; min-width: 0; }
  .evrule-action-card-head .info-btn, .evrule-action-card-head .evrule-action-remove { flex: 0 0 auto; min-width: 44px; min-height: 44px; }
  #modal-content .info-btn { min-width: 40px; min-height: 44px; }
  .evrule-day-label { min-height: 44px; display: inline-flex; align-items: center; }
  .evrule-enabled-top { min-height: 44px; display: flex; align-items: center; gap: 10px; }
}

@media (max-width: 860px) {
  /* Relatórios: totais em 2 colunas e cartões de relatório compactos (ícone ao
     lado do título, descrição em até 2 linhas): 16 cartões de ~135 px (~2000 px)
     viram ~85 px cada. */
  #view-reports .dashboard-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .rep-cards-grid .rep-card { display: grid; grid-template-columns: 36px minmax(0, 1fr); column-gap: 12px; row-gap: 2px; align-items: center;
    text-align: left; min-height: 72px; padding: 12px 14px; }
  .rep-cards-grid .rep-card .rep-card-icon { grid-row: 1 / span 2; font-size: 26px; text-align: center; }
  .rep-cards-grid .rep-card .rep-card-desc { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 14px; }
}

/* ==========================================================================
   MÓDULO 7 -- Administração (usável, sem redesenho): nada estoura a tela,
   tabelas rolam dentro do próprio quadro, alvos de toque e fontes mínimas.
   Telas: Usuários, Papéis, Sistema, Log de Auditoria, API e webhooks,
   Centrais, Vínculos do Telegram, Configuração em lote, Preferências.
   ========================================================================== */
@media (max-width: 860px) {
  /* Tabelas largas rolam de lado dentro do quadro, com sombra nas bordas que
     indica que há mais conteúdo (técnica de "scroll shadows"; só aparece
     quando há o que rolar). */
  .table-scroll { -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
    background:
      linear-gradient(to right, var(--panel, #1c2326) 30%, rgba(0,0,0,0)) 0 0 / 28px 100% no-repeat local,
      linear-gradient(to left, var(--panel, #1c2326) 30%, rgba(0,0,0,0)) 100% 0 / 28px 100% no-repeat local,
      linear-gradient(to right, rgba(0,0,0,.45), rgba(0,0,0,0)) 0 0 / 14px 100% no-repeat scroll,
      linear-gradient(to left, rgba(0,0,0,.45), rgba(0,0,0,0)) 100% 0 / 14px 100% no-repeat scroll; }
  .data-table th.sortable-th, .data-table th { padding-top: 13px; padding-bottom: 13px; }

  :is(#view-users, #view-roles, #view-system, #view-audit-log, #view-api-publica, #view-centrais,
      #view-telegram-links, #view-fleet-bulk, #view-notification-prefs) :is(button, .ghost, summary) { min-height: 44px; }
  :is(#view-users, #view-roles, #view-system, #view-audit-log, #view-api-publica, #view-centrais,
      #view-telegram-links, #view-fleet-bulk, #view-notification-prefs) :is(input:not([type="checkbox"]):not([type="radio"]):not([type="color"]), select, textarea) {
    min-height: 44px; font-size: 16px !important; }
  :is(#view-users, #view-roles, #view-system, #view-audit-log, #view-api-publica, #view-centrais,
      #view-telegram-links, #view-fleet-bulk, #view-notification-prefs) label:has(> input[type="checkbox"], > input[type="radio"]) {
    min-height: 44px; display: flex; align-items: center; gap: 10px; }
  :is(#view-users, #view-roles, #view-system, #view-audit-log, #view-api-publica, #view-centrais,
      #view-telegram-links, #view-fleet-bulk, #view-notification-prefs) input[type="checkbox"] { width: 22px; height: 22px; }
  #view-notification-prefs .np-toggle { min-height: 44px; display: flex; align-items: center; gap: 10px; }
  #view-system input[type="color"] { min-width: 44px; min-height: 44px; }
}

/* ==========================================================================
   MÓDULO 8 -- PWA: aviso de sem conexão, convite para instalar
   ========================================================================== */
.m-offline { position: fixed; inset: 0; z-index: 10000; display: flex; align-items: center; justify-content: center;
  background: rgba(10, 15, 17, .92); padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }
.m-offline-box { width: 100%; max-width: 380px; text-align: center; background: var(--panel, #1c2326); color: var(--text, #e8eef0);
  border: 1px solid var(--border, #2c373b); border-radius: 14px; padding: 22px 20px; }
.m-offline-box strong { display: block; font-size: 18px; margin-bottom: 8px; }
.m-offline-box p { margin: 0 0 16px; color: var(--muted, #a9b6ba); }
.m-offline-box button { min-height: 48px; padding: 0 24px; font-size: 16px; }
.m-instalar-banner { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 8px 8px 8px 14px;
  background: var(--panel, #1c2326); border: 1px solid var(--accent, #2ecc71); border-radius: 12px; }
.m-instalar-banner .m-inst-txt { flex: 1 1 auto; min-width: 0; font-size: 14px; line-height: 1.35; }
.m-instalar-banner button { min-height: 44px; min-width: 44px; flex: 0 0 auto; }
.m-inst-passos { padding-left: 22px; line-height: 1.55; }
.m-inst-passos li { margin-bottom: 8px; }
#help-menu #help-install { min-height: 44px; }
/* só no celular/tablet: no desktop o menu de ajuda segue exatamente como era */
@media (min-width: 861px) { #help-menu #help-install, .m-instalar-banner { display: none !important; } }

/* ==========================================================================
   Menu só embaixo (29/10, pedido do dono): sem a barra do topo no celular;
   "Mais" da barra de baixo abre a folha com o resto (mobile.js).
   ========================================================================== */
@media (max-width: 860px) {
  .topcats { display: none !important; }
  .app { padding-top: env(safe-area-inset-top, 0px); }
  .view, #grid { scroll-margin-top: 8px; }
  /* painel de avisos (movido pro <body> no celular): folha acima da barra */
  body > #notif-panel {
    position: fixed; top: auto; left: 8px; right: 8px; width: auto; z-index: 46;
    bottom: calc(66px + env(safe-area-inset-bottom, 0px)); max-height: 70vh;
  }
}
.m-mais { position: fixed; inset: 0; z-index: 44; background: rgba(0, 0, 0, .45); }
.m-mais-folha {
  position: absolute; left: 8px; right: 8px; bottom: calc(66px + env(safe-area-inset-bottom, 0px));
  max-height: calc(100dvh - 90px - env(safe-area-inset-top, 0px)); overflow-y: auto;
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .45); padding: 6px;
}
.m-mais-quem { padding: 10px 12px 4px; font-weight: 600; color: var(--text); }
.m-mais-titulo { padding: 10px 12px 4px; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.m-mais-item {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px; padding: 0 12px;
  background: transparent; border: 0; border-radius: 10px; color: var(--text); font-size: 15px; text-align: left;
}
.m-mais-item:active, .m-mais-item.active { background: var(--panel2); }
.m-mais-item.active { color: var(--accent); font-weight: 600; }
.m-mais-ico { width: 22px; display: inline-flex; justify-content: center; font-size: 18px; line-height: 1; }
.m-mais-ico svg { width: 20px; height: 20px; }
.m-mais-sair { color: var(--red); }
@media (min-width: 861px) { .m-mais, #bottom-nav-mais { display: none !important; } }

/* Câmera em tela cheia no celular (29/10, pedido do dono): barra de tempo,
   ajuda e fechar escondidos; tocar na imagem mostra/esconde (app.js,
   `bindImageZoom` -> .controles-visiveis). Pinça com dois dedos dá zoom:
   o navegador não pode tratar o gesto como zoom da página. */
@media (hover: none) {
  .zoomable-video.is-fullscreen:not(.controles-visiveis) .zoom-timeline,
  .zoomable-video.is-fullscreen:not(.controles-visiveis) .zoom-help,
  .zoomable-video.is-fullscreen:not(.controles-visiveis) .zoom-close { display: none !important; }
  .zoomable-video .zoom-hit, .cell { touch-action: pan-x pan-y; }
}

/* ==========================================================================
   Sub-abas embaixo (29/10, pedido do dono): faixa fixa acima da barra de
   baixo (#m-subabas, mobile.js). Os botões originais do lateral somem; o
   lateral só fica no grupo Vídeo (árvore de câmeras). --sub-h = altura da
   faixa, somada a tudo que fica preso acima da barra de baixo.
   ========================================================================== */
.m-subabas { display: none; }
@media (max-width: 860px) {
  :root { --sub-h: 0px; }
  html.tem-subabas { --sub-h: 48px; }
  #sidebar .tabs > button[data-view] { display: none !important; }
  .sidebar:not(:has(.tabs[data-group="video"]:not([hidden]))) { display: none !important; }
  .tabs[data-group="video"] { padding-top: 2px; }
  html.tem-subabas .m-subabas:not([hidden]) {
    display: flex; position: fixed; left: 0; right: 0; z-index: 45;
    bottom: calc(58px + env(safe-area-inset-bottom, 0px)); height: var(--sub-h);
    gap: 6px; align-items: center; padding: 0 calc(8px + env(safe-area-inset-right, 0px)) 0 calc(8px + env(safe-area-inset-left, 0px));
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
    background: var(--panel); border-top: 1px solid var(--border);
  }
  .m-subabas::-webkit-scrollbar { display: none; }
  .m-subabas > button {
    flex: 1 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 36px; padding: 0 12px; white-space: nowrap; font-size: 13px;
    background: var(--panel2); color: var(--muted); border: 1px solid var(--border); border-radius: 999px;
  }
  .m-subabas > button svg { width: 15px; height: 15px; flex-shrink: 0; }
  .m-subabas > button.active { background: var(--accent-dim); color: var(--accent); border-color: var(--accent); font-weight: 600; }
  html.kb-open .m-subabas { display: none !important; }
  /* o que fica preso acima da barra de baixo sobe junto */
  .app { padding-bottom: calc(58px + var(--sub-h) + env(safe-area-inset-bottom, 0px)); }
  .ap-bulk-bar, .massa-barra { bottom: calc(66px + var(--sub-h) + env(safe-area-inset-bottom, 0px)); }
  .modal-taskbar { bottom: calc(68px + var(--sub-h) + env(safe-area-inset-bottom, 0px)); }
  .dropdown-menu { bottom: calc(70px + var(--sub-h) + env(safe-area-inset-bottom, 0px)); }
  body > #notif-panel, .m-mais-folha { bottom: calc(66px + var(--sub-h) + env(safe-area-inset-bottom, 0px)); }
}
