/* ════════════════════════════════════════════════════════════════════
   InfraMINA · Módulos novos (melhorias aprovadas em 27/09/2026)

   O motor de cadastro (js/modulos/nucleo/cadastro.js) e as telas que nascem
   dele: Equipes e as que vierem nas ondas seguintes. Nenhuma linguagem nova:
   é o mundo "Permissão de Trabalho" de DESIGN.md — régua no lugar de caixa,
   rótulo em condensada versal, valor em monoespaçada, raio zero — aplicado a
   telas que ainda não existiam.

   Carregado depois de contratos-remotas.css, com o mesmo escopo `.app`
   (0,2,0), para empatar com as regras de console e a ordem desempatar.

   COR. Só os dois motivos de sempre: classe de risco (status-pill, aviso de
   impedimento) e o carimbo, que aqui não aparece. Selecionado é régua, não
   cor.
   ════════════════════════════════════════════════════════════════════ */

@media screen, print {
  /* ── Formulário do motor de cadastro ── */
  .app .cadastro-form {
    display: grid;
    gap: var(--sp-4);
    padding: var(--sp-4);
    border: var(--rule-hair) solid var(--console-line);
    border-top: var(--rule-heavy) solid var(--console-line-strong);
    background: var(--console-panel);
    min-width: 0;
  }
  .app .cadastro-form h3 {
    margin: 0;
    color: var(--console-text);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-section);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .cadastro-grade,
  .app .minimos-grade,
  .app .revezamento-topo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--sp-3) var(--sp-4);
    align-items: start;
    min-width: 0;
  }
  .app .cadastro-inteira {
    grid-column: 1 / -1;
  }
  /* Quadro padrão por função (15/10/2026): uma coluna por equipe. */
  .app .quadro-padrao-grade {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--sp-4);
    align-items: start;
    min-width: 0;
  }
  .app .quadro-padrao-equipe {
    display: grid;
    gap: var(--sp-2);
    min-width: 0;
    margin: 0;
    padding: var(--sp-3);
    border: var(--rule-hair) solid var(--border);
  }
  .app .quadro-padrao-equipe legend {
    padding: 0 var(--sp-1);
    font-weight: 700;
  }
  .app .quadro-padrao-equipe legend span {
    color: var(--console-muted);
    font-size: var(--t-sm);
    font-weight: 400;
  }
  .app .cadastro-nota {
    margin: var(--sp-1) 0 0;
    max-width: var(--measure);
    color: var(--console-muted);
    font-size: var(--t-sm);
    line-height: var(--lh-body);
  }
  .app .cadastro-nota.is-error,
  .app .cadastro-erros {
    color: var(--risk-blocked-void);
  }
  .app .cadastro-erros {
    margin: 0;
    padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-6);
    border-top: var(--rule-heavy) solid var(--risk-blocked-edge);
    background: var(--console-panel-2);
    font-size: var(--t-sm);
    line-height: var(--lh-body);
  }
  .app .cadastro-form [aria-invalid='true'] {
    border-color: var(--risk-blocked-edge);
  }
  .app .cadastro-acoes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
  }
  .app .cadastro-acoes .btn {
    min-height: 44px;
  }
  .app .cadastro-check {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: 44px;
    color: var(--console-text);
    font-size: var(--t-body);
  }
  .app .cadastro-check input {
    width: 20px;
    height: 20px;
  }
  .app .cadastro-vazio {
    margin: var(--sp-3) 0;
  }

  /* ── Equipes ── */
  .app .equipes-module {
    display: grid;
    gap: var(--sp-4);
    min-width: 0;
  }
  .app .equipes-module .rotas-conteudo {
    display: grid;
    gap: var(--sp-4);
    min-width: 0;
  }
  .app .equipes-module .action-cell {
    white-space: nowrap;
  }
  .app .equipes-module .action-cell > * + * {
    margin-inline-start: var(--sp-2);
  }
  .app .equipes-module .card h3 {
    margin: var(--sp-4) 0 var(--sp-2);
    color: var(--console-text);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .revezamento-grade select {
    min-width: 64px;
    min-height: 40px;
  }
  .app .revezamento-grade th[scope='row'] {
    font-family: var(--font-value);
    font-variant-numeric: tabular-nums;
  }

  /* ── Relatório diário: lista nominal e avisos do fechamento ── */
  .app .daily-nominal {
    margin-top: var(--sp-3);
    border-top: var(--rule-hair) solid var(--border);
    padding-top: var(--sp-2);
  }
  .app .daily-nominal > summary {
    cursor: pointer;
    min-height: 44px;
    display: flex;
    align-items: center;
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    font-size: var(--t-label);
  }
  .app .daily-nominal-aviso {
    margin: 0 0 var(--sp-2);
    max-width: var(--measure);
    color: var(--muted);
    font-size: var(--t-sm);
    line-height: var(--lh-body);
  }
  .app .daily-nominal-lista {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    gap: var(--sp-1) var(--sp-4);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .app .daily-nominal-lista li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-2);
  }
  .app .daily-nominal-lista label {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: 40px;
  }
  .app .daily-nominal-lista input {
    width: 20px;
    height: 20px;
  }
  .app .daily-nominal-lista small {
    color: var(--muted);
  }
  .app .daily-alertas {
    padding: var(--sp-3) var(--sp-4);
    border-top: var(--rule-heavy) solid var(--risk-attention-edge);
    background: var(--risk-attention-wash);
    color: var(--ink);
  }
  .app .daily-alertas ul {
    margin: var(--sp-1) 0 0;
    padding-left: var(--sp-5);
    line-height: var(--lh-body);
  }

  /* ── Relatório diário: quem faltou e quem veio a mais ── */
  .app .daily-extras-table {
    min-width: 0;
    width: 100%;
  }
  .app .daily-extras {
    margin: var(--sp-3) 0 0;
    padding: var(--sp-2) 0 0;
    border: 0;
    border-top: var(--rule-hair) solid var(--border);
  }
  .app .daily-extras > h3 {
    margin: 0 0 var(--sp-2);
    padding: 0;
    color: var(--muted);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .daily-faltas-lista {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
    gap: var(--sp-1) var(--sp-4);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .app .daily-faltas-lista li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-2);
    padding: var(--sp-1) var(--sp-2);
    border-radius: var(--radius);
  }
  .app .daily-falta-programada {
    color: var(--muted);
  }
  .app .daily-falta-detalhe {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
  }
  .app .daily-falta-ate {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
  }

  /* ── Quem faltou (09/10/2026) ──
     A equipe não aparece montada: cada bloco mostra só as faltas, numa
     faixa de atenção (classe de risco, o único motivo de cor aqui), e um
     botão para adicionar. Sem falta, o bloco fica em branco. */
  .app .daily-block > .daily-faltas-lista {
    margin-top: var(--sp-3);
  }
  .app .daily-faltas-lista li.daily-falta {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
    border: var(--rule-hair) solid var(--border);
    background: var(--risk-attention-wash);
  }
  .app .daily-falta-quem {
    display: grid;
    gap: 2px;
    min-width: 0;
  }
  .app .daily-falta-quem strong {
    overflow-wrap: anywhere;
  }
  .app .daily-falta-quem small {
    color: var(--muted);
    font-size: var(--t-sm);
  }
  .app .daily-falta-detalhe {
    justify-content: flex-end;
  }
  .app .daily-falta-motivo-fixo {
    font-size: var(--t-sm);
  }
  .app .daily-falta-contagem {
    margin-left: var(--sp-2);
    color: var(--risk-attention);
    font-family: var(--font-value);
    font-size: var(--t-sm);
    font-weight: 700;
  }
  @media (max-width: 520px) {
    .app .daily-faltas-lista li.daily-falta {
      grid-template-columns: 1fr;
    }
    .app .daily-falta-detalhe {
      justify-content: flex-start;
    }
  }

  /* ── Janela "Adicionar falta": função, quantidade e motivo ── */
  .falta-corpo {
    display: grid;
    gap: var(--sp-3);
  }
  .falta-motivo-linha {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: var(--sp-3);
  }

  /* ── Materiais de consumo do turno (13/10/2026) ──
     Tabela no relatório, janela de retirada e resumo em Suprimentos. A
     classe (mecânico/elétrico) é cabeçalho de grupo, não cor. */
  /* As larguras genéricas de .daily-table (210px na 2ª coluna, 180px na 5ª)
     são do contingente; aqui a 2ª é a quantidade e a 5ª, o local. */
  .app .consumo-tabela {
    min-width: 720px;
  }
  .app .consumo-tabela td {
    vertical-align: top;
  }
  .app .consumo-tabela td:nth-child(n) {
    min-width: 0;
  }
  .app .consumo-tabela th:first-child {
    width: 30%;
  }
  .app .consumo-tabela .num {
    white-space: nowrap;
  }
  /* Nos equipamentos, a 2ª coluna é "Abastecido" (um seletor de 118 px): os
     210 px genéricos de .daily-table empurravam a lixeira para fora a 1366 px. */
  .app .daily-equipment-table td:nth-child(2) {
    min-width: 0;
  }
  /* Equipamentos do relatório no celular (13/10/2026): cada equipamento vira
  um cartão, com o nome no alto e os quatro campos rotulados embaixo. Antes
  quatro dos cinco campos ficavam atrás de rolagem lateral em toda linha. */
  @media (max-width: 720px) {
    .app .table-wrap:has(> .daily-equipment-table) {
      overflow: visible;
    }
    .app .table-wrap:has(> .daily-equipment-table)::after {
      display: none !important;
    }
    .app .daily-equipment-table,
    .app .daily-equipment-table tbody {
      display: block;
      width: 100%;
      min-width: 0;
    }
    .app .daily-equipment-table thead {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .app .daily-equipment-table tr {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--sp-2) var(--sp-3);
      padding: var(--sp-3) var(--org-x, 20px);
      border-bottom: var(--rule-hair) solid var(--border);
    }
    /* No cartão, a margem de 20 px é da linha: a célula das pontas zera o
       recuo que organizacao.css dá à tabela de borda a borda. */
    .app .view :is(.card, .daily-block) > .table-wrap .daily-equipment-table :is(td:first-child, td:last-child) {
      padding-inline: 0;
    }
    /* .table-wrap no seletor: a coluna fixa do celular (sticky, com sombra e
       170 px de largura mínima) vinha de `.app .table-wrap td:first-child`. */
    .app .table-wrap .daily-equipment-table td {
      position: static;
      display: block;
      width: auto;
      min-width: 0;
      max-width: none;
      padding: 0;
      border: 0;
      background: none;
      box-shadow: none;
    }
    .app .daily-equipment-table td[data-label='Equipamento'] {
      grid-column: 1;
      align-self: center;
    }
    .app .daily-equipment-table td:last-child {
      grid-column: 2;
      grid-row: 1;
      justify-self: end;
    }
    .app .daily-equipment-table td:is([data-label='Localização'], [data-label='Observações']) {
      grid-column: 1 / -1;
    }
    .app .daily-equipment-table td:not([data-label='Equipamento'])[data-label]::before {
      content: attr(data-label);
      display: block;
      margin-bottom: var(--sp-1);
      color: var(--muted);
      font-family: var(--font-label);
      font-size: var(--t-label);
      font-weight: 700;
      letter-spacing: var(--track-label);
      text-transform: uppercase;
    }
    /* min-width 0: o seletor Sim/Não tem 108 px de mínimo na tabela larga. */
    .app .table-wrap .daily-equipment-table .cell-in {
      width: 100%;
      min-width: 0;
      max-width: none;
    }
    .app .table-wrap .daily-equipment-table td[data-label='Equipamento'] :is(strong, *) {
      margin: 0;
      padding: 0;
    }
  }
  /* Abaixo de 340 px (celular com zoom de 200%), as duas metades não cabem
     "Operando": um campo por linha. */
  @media (max-width: 340px) {
    .app .table-wrap .daily-equipment-table td:is([data-label='Abastecido'], [data-label='Status']) {
      grid-column: 1 / -1;
    }
  }
  /* No celular, cada retirada vira um cartão: material e quantidade no
     alto, e quem pegou, a atividade e o local embaixo, com o rótulo. */
  @media (max-width: 720px) {
    .app .consumo-wrap {
      overflow: visible;
    }
    .app .consumo-wrap::after {
      display: none !important;
    }
    .app .consumo-tabela,
    .app .consumo-tabela tbody {
      display: block;
      width: 100%;
      min-width: 0;
    }
    .app .consumo-tabela thead {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .app .consumo-tabela tr {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      gap: 2px var(--sp-3);
      padding: var(--sp-3);
      border-bottom: var(--rule-hair) solid var(--border);
    }
    .app .consumo-tabela tr.consumo-grupo {
      display: block;
      padding: 0;
    }
    .app .consumo-tabela tr.consumo-grupo th {
      display: block;
      width: auto;
    }
    .app .consumo-tabela td:nth-child(n) {
      display: block;
      padding: 0;
      border: 0;
      box-shadow: none;
    }
    .app .consumo-tabela td.num {
      grid-column: 2;
      grid-row: 1;
      font-weight: 700;
      text-align: right;
    }
    .app .consumo-tabela td[data-label='Quem pegou'],
    .app .consumo-tabela td[data-label='Atividade'],
    .app .consumo-tabela td[data-label='Onde'] {
      grid-column: 1 / -1;
      font-size: var(--t-sm);
    }
    .app .consumo-tabela td[data-label='Quem pegou']::before,
    .app .consumo-tabela td[data-label='Atividade']::before,
    .app .consumo-tabela td[data-label='Onde']::before {
      content: attr(data-label) ': ';
      color: var(--muted);
      font-weight: 600;
    }
    .app .consumo-tabela td[data-label='Atividade'] .consumo-detalhe {
      display: inline;
      margin-left: var(--sp-1);
    }
    .app .consumo-tabela td.consumo-acoes {
      grid-column: 1 / -1;
      margin-top: var(--sp-2);
      text-align: left;
    }
    .app .consumo-tabela td.daily-photo-empty {
      grid-column: 1 / -1;
    }
  }
  .app .consumo-tabela tr.consumo-grupo th {
    padding: var(--sp-2) var(--sp-3);
    background: var(--surface-2);
    color: var(--muted);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-align: left;
    text-transform: uppercase;
  }
  .app .consumo-tabela tr.consumo-grupo th span {
    margin-left: var(--sp-2);
    font-family: var(--font-value);
  }
  .app .consumo-detalhe {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: var(--t-sm);
  }
  .app .consumo-fora {
    display: inline-block;
    margin-left: var(--sp-1);
    padding: 0 var(--sp-1);
    border: var(--rule-hair) solid var(--risk-attention);
    color: var(--risk-attention);
    font-size: var(--t-label);
    font-weight: 600;
    white-space: nowrap;
  }
  .app .consumo-acoes {
    white-space: nowrap;
    text-align: right;
  }
  .app .consumo-acoes .btn + .btn {
    margin-left: var(--sp-1);
  }

  /* Janela "Registrar retirada do box". */
  .consumo-corpo {
    display: grid;
    gap: var(--sp-3);
  }
  .consumo-linha {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(7rem, 9rem);
    gap: var(--sp-3);
  }
  .consumo-linha--local {
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  }
  .consumo-rotulo {
    margin: 0 0 var(--sp-1);
    color: var(--muted);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .consumo-sugestoes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
  }
  .consumo-sugestao {
    min-height: 44px;
    text-align: left;
    white-space: normal;
  }
  @media (max-width: 520px) {
    .consumo-linha {
      grid-template-columns: 1fr;
    }
  }

  /* Consumo dos turnos: mês e planilha lado a lado no cabeçalho. */
  .app .consumo-cabeca-acoes {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--sp-2) var(--sp-3);
  }
  .app .consumo-cabeca-acoes .form-group {
    margin: 0;
  }

  /* Suprimentos › Combustível: preço do litro editável na tabela do mês. */
  .app #view-combustivel .table-wrap {
    margin-top: var(--sp-4);
  }
  .app .combustivel-preco {
    width: min(9rem, 100%);
  }
  .app .combustivel-preco-origem {
    display: block;
    margin-top: var(--sp-1);
    color: var(--muted);
    font-size: var(--t-label);
  }

  /* Resumo em Suprimentos › Consumo dos turnos. */
  /* Régua de atenção no topo, nunca na lateral (DESIGN.md, "Forma"). */
  .app .consumo-resumo-aviso {
    margin: var(--sp-3) 0 0;
    padding: var(--sp-2) var(--sp-3);
    border: var(--rule-hair) solid var(--border);
    border-top: var(--rule-body) solid var(--risk-attention-edge);
    background: var(--warning-soft);
    font-size: var(--t-sm);
  }
  .app .consumo-resumo-bloco {
    margin-top: var(--sp-5);
    min-width: 0;
  }
  .app .consumo-resumo-bloco h3 {
    margin: 0 0 var(--sp-2);
    font-size: var(--t-body);
  }
  .app .consumo-resumo-grade {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
    gap: 0 var(--sp-5);
  }

  /* ── Correias: foto na inspeção, pendências e ficha ── */
  .app .inspecao-fotos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
  }
  .app .inspecao-foto-link {
    font-family: var(--font-value);
    font-size: var(--t-sm);
    text-underline-offset: 3px;
  }
  .app .pendencias-filtro {
    max-width: 320px;
  }
  .app .rotas-conteudo > .card,
  .app .rotas-conteudo > .cadastro-form {
    margin-top: var(--sp-4);
  }
  .app .rotas-conteudo .action-cell {
    white-space: nowrap;
  }
  .app .rotas-conteudo .action-cell > * + * {
    margin-inline-start: var(--sp-2);
  }
  .app .rotas-conteudo td small {
    color: var(--console-muted);
  }

  /* ── Suprimentos: saldo calculado e movimentos ── */
  .app .stock-saldo strong {
    display: block;
    font-family: var(--font-value);
    font-variant-numeric: tabular-nums;
  }
  .app .stock-mov {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1);
    margin-top: var(--sp-1);
  }
  .app #view-stock .cadastro-form,
  .app #view-stock .estoque-extrato,
  .app #view-materials .estoque-projeto {
    margin: var(--sp-4) 0;
  }
  .app .estoque-projeto .cadastro-acoes {
    justify-content: flex-end;
  }
  .app .estoque-vinculo {
    min-width: 240px;
  }

  /* ── Relatório diário: passagem de turno e conferência da terceirizada ── */
  .app .daily-passagem-lista {
    display: grid;
    grid-template-columns: minmax(140px, max-content) 1fr;
    gap: var(--sp-1) var(--sp-4);
    margin: var(--sp-2) 0;
  }
  .app .daily-passagem-lista dt {
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    font-size: var(--t-label);
  }
  .app .daily-passagem-lista dd {
    margin: 0;
    white-space: pre-wrap;
  }
  .app .daily-passagem-ciente {
    margin: var(--sp-2) 0 0;
    font-family: var(--font-value);
    font-size: var(--t-sm);
  }
  .app .daily-passagem-campos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: var(--sp-3);
  }
  .app .daily-passagem-campos label {
    display: grid;
    gap: var(--sp-1);
  }
  .app .daily-tc > summary {
    cursor: pointer;
    min-height: 44px;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
  }
  .app .daily-tc-lista {
    display: grid;
    gap: var(--sp-3);
    margin: var(--sp-3) 0 0;
    padding: 0;
    list-style: none;
  }
  .app .daily-tc-lista > li {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--sp-2) var(--sp-4);
    padding-top: var(--sp-3);
    border-top: var(--rule-hair) solid var(--border);
  }
  .app .daily-tc-lista > li > div:first-child {
    display: grid;
    gap: var(--sp-1);
  }
  .app .daily-tc-lista small {
    color: var(--muted);
  }
  .app .daily-tc-lista .cadastro-acoes,
  .app .daily-tc-devolver {
    grid-column: 1 / -1;
  }
  .app .daily-tc-devolver {
    display: grid;
    gap: var(--sp-2);
    max-width: 560px;
  }
  @media (max-width: 560px) {
    .app .daily-passagem-lista,
    .app .daily-tc-lista > li {
      grid-template-columns: 1fr;
    }
  }

  /* ── Câmaras de refúgio e subestações ── */
  .app .ativo-ficha {
    display: grid;
    gap: var(--sp-3);
  }
  .app .ativo-ficha h3 {
    margin: var(--sp-3) 0 0;
    color: var(--console-text);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .ativo-dados {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
    gap: var(--sp-2) var(--sp-4);
    margin: 0;
  }
  .app .ativo-dados dt {
    color: var(--console-muted);
    font-size: var(--t-sm);
  }
  .app .ativo-dados dd {
    margin: 0 0 var(--sp-1);
    font-family: var(--font-value);
    font-variant-numeric: tabular-nums;
  }
  .app .ativo-alimenta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1);
    margin: 0;
  }
  .app .ativo-lista {
    display: grid;
    gap: var(--sp-2);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .app .ativo-lista > li {
    display: grid;
    grid-template-columns: minmax(200px, 2fr) minmax(140px, 1fr) minmax(140px, 1fr) minmax(160px, 2fr);
    gap: var(--sp-2);
    align-items: center;
    padding-bottom: var(--sp-2);
    border-bottom: var(--rule-hair) solid var(--console-line);
  }
  .app .ativo-lista select,
  .app .ativo-lista input {
    min-height: 44px;
  }
  .app .prontuario-doc {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-2);
    margin-bottom: var(--sp-1);
  }
  .app .ensaio-serie {
    margin: 0 0 var(--sp-4);
    display: grid;
    gap: var(--sp-2);
  }
  .app .ensaio-grafico {
    width: 100%;
    max-width: 480px;
    height: auto;
  }
  .app .ensaio-grafico .eg-linha {
    fill: none;
    stroke: var(--console-text);
    stroke-width: 2;
    stroke-linejoin: round;
  }
  .app .ensaio-grafico .eg-base {
    stroke: var(--console-line);
    stroke-width: 1;
  }
  .app .ensaio-grafico .eg-limite {
    stroke: var(--console-muted);
    stroke-width: 1;
    stroke-dasharray: 4 4;
  }
  .app .ensaio-grafico .eg-ponto {
    fill: var(--console-text);
    stroke: var(--console-panel);
    stroke-width: 2;
  }
  .app .ensaio-grafico .eg-ponto.fora {
    fill: var(--risk-blocked-edge);
  }
  .app .ensaio-grafico text {
    fill: var(--console-muted);
    font-family: var(--font-value);
    font-size: 10px;
  }
  .app .ensaio-grafico .eg-valor {
    fill: var(--console-text);
  }
  @media (max-width: 720px) {
    .app .ativo-lista > li {
      grid-template-columns: 1fr;
    }
  }

  /* ── Remotas: cadastro editável e alterações de intertravamento ── */
  .app .remotas-cadastro {
    margin: var(--sp-4) 0;
    display: grid;
    gap: var(--sp-3);
  }
  .app .remotas-estados {
    margin: 0;
    font-size: var(--t-sm);
  }
  .app .remotas-estados strong {
    font-family: var(--font-value);
    font-variant-numeric: tabular-nums;
  }
  .app .remota-cartao.em-edicao {
    border-top: var(--rule-heavy) solid var(--console-line-strong);
  }
  .app .remota-cartao.em-edicao .cell-in {
    min-width: 88px;
  }
  .app .remota-alteracoes {
    display: grid;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
  }
}

@media print {
  .app .daily-passagem-recebida,
  .app .daily-passagem,
  .app .daily-tc {
    display: none !important;
  }
}

@media print {
  .app .daily-nominal,
  .app .daily-alertas {
    display: none !important;
  }
}

@media screen, print {
  /* ── Financeiro: orçamento do CAPEX e medições ── */
  .app .capex-orcamento,
  .app .contrato-medicoes {
    margin-top: var(--sp-4);
    display: grid;
    gap: var(--sp-3);
  }
  .app .capex-orcamento h3,
  .app .contrato-medicoes h3 {
    margin: var(--sp-2) 0 0;
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .orcamento-projeto,
  .app .medicao-qtd {
    max-width: 140px;
    font-family: var(--font-value);
    font-variant-numeric: tabular-nums;
  }
  .app .contrato-medicoes .action-cell {
    white-space: nowrap;
  }
  .app .contrato-medicoes .action-cell > * + * {
    margin-inline-start: var(--sp-1);
  }
}

@media screen, print {
  /* ── Início: o que pede atenção ── */
  .app .painel-atencao {
    grid-column: 1 / -1;
  }
  .app .painel-grupos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
    gap: var(--sp-4);
  }
  .app .painel-grupo h3 {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin: 0 0 var(--sp-2);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .painel-grupo ul {
    display: grid;
    gap: var(--sp-1);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .app .painel-item {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    width: 100%;
    min-height: 44px;
    padding: var(--sp-2) 0;
    border: 0;
    border-bottom: var(--rule-hair) solid var(--border);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
  }
  .app .painel-item:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
  }
  /* Largura igual para "Vencido" e "Atenção": com a largura do próprio texto,
     a descrição ao lado começava 2 px mais à direita numa linha que na outra. */
  .app .painel-item .status-pill {
    flex: none;
    justify-content: center;
    min-width: 5rem;
  }
  .app .painel-mais {
    margin: var(--sp-1) 0 0;
    color: var(--muted);
    font-size: var(--t-sm);
  }
}

@media screen, print {
  /* ── Navegação: submódulos em abas no topo do conteúdo ──
     O mesmo componente de abas de Correias (.rotas-abas): régua no lugar de
     caixa, e a aba aberta sem cor, só com a régua cheia (DESIGN.md, "O sinal
     de selecionado"). Fica colada ao topo da área rolável para as seções
     vizinhas continuarem à vista numa tela comprida. */
  .app .module-tabs {
    position: sticky;
    top: 0;
    z-index: 3;
    margin: 0 0 var(--sp-4);
    background: var(--void-2);
  }
  .app .module-tabs[hidden] {
    display: none;
  }
  /* No celular a barra superior é que gruda, e a página inteira rola: as
     abas ficariam por baixo dela. Ali elas rolam com o conteúdo. */
  @media (max-width: 768px) {
    .app .module-tabs {
      position: static;
    }
  }
}

@media screen, print {
  /* Toda linha de abas (a de submódulo e as internas) rola só na horizontal: a régua da aba aberta desce 1px
     sobre a do contêiner, e sem isto o navegador oferecia rolagem vertical. */
  .app .rotas-abas,
  .app .module-tabs {
    overflow-y: hidden;
  }

  /* Os cartões dos módulos novos: o cabeçalho já tem o recuo do cartão, e o
     conteúdo abaixo dele acompanha, em vez de encostar na borda. O aviso
     "pede atenção" continua de ponta a ponta, como faixa. */
  .app :is(.painel-atencao, .ativo-ficha, .contrato-medicoes, .capex-orcamento, .estoque-projeto, .estoque-extrato, .remotas-cadastro, .treinamento-ficha) > :not(.card-head):not(.daily-alertas),
  .app :is(.equipes-module, .rotas-conteudo) > .card > :not(.card-head):not(.daily-alertas),
  .app .rotas-conteudo > .card > :not(.card-head):not(.daily-alertas) {
    margin-inline: var(--sp-5);
  }
  .app :is(.painel-atencao, .ativo-ficha, .contrato-medicoes, .capex-orcamento, .estoque-projeto, .estoque-extrato, .remotas-cadastro, .treinamento-ficha),
  .app :is(.equipes-module, .rotas-conteudo) > .card {
    padding-bottom: var(--sp-5);
  }
  .app .ativo-dados > div {
    display: grid;
    gap: var(--sp-1);
    align-content: start;
  }
  .app .ativo-dados dd {
    margin: 0;
  }
  @media (max-width: 560px) {
    .app :is(.painel-atencao, .ativo-ficha, .contrato-medicoes, .capex-orcamento, .estoque-projeto, .estoque-extrato, .remotas-cadastro, .treinamento-ficha) > :not(.card-head):not(.daily-alertas),
    .app :is(.equipes-module, .rotas-conteudo) > .card > :not(.card-head):not(.daily-alertas) {
      margin-inline: var(--sp-3);
    }
  }
}

@media screen, print {
  /* ── Acabamento da revisão visual (28/09/2026) ──
     Cada regra corrige um defeito medido nas telas a 1920 px, a 420 px e com
     o zoom afastado. O comentário diz o que estava errado. */

  /* Barra de busca com botão: o .form-group traz margem embaixo, e o botão,
     alinhado ao fim da linha, descia 14px abaixo do campo. E o botão tem a
     largura do que diz, e não a da coluna inteira. */
  .app .contratos-barra > .form-group {
    margin-bottom: 0;
  }
  .app .contratos-barra > .btn {
    justify-self: start;
  }
  /* A busca é o campo que mais precisa de espaço: com seis itens na linha, ela
     ficava com 214px e cortava o próprio texto de exemplo. */
  @media (min-width: 900px) {
    .app .contratos-barra > .form-group:first-child:has(> input) {
      grid-column: span 2;
    }
  }

  /* Etiqueta de situação dentro de tabela. A tabela é painel escuro, mas
     herdava as tintas de risco do papel: "Atenção" saía amarelo sobre bege,
     a 1,3:1. Aqui ela recebe as tintas do escuro, como o resto do painel. */
  .app .table-wrap,
  .terceirizada-page .table-wrap {
    --success: var(--risk-clear-void);
    --success-soft: rgba(76, 194, 127, 0.16);
    --warning: var(--risk-attention-void);
    --warning-soft: rgba(231, 177, 74, 0.16);
    --danger: var(--risk-blocked-void);
    --danger-soft: rgba(240, 100, 90, 0.16);
    /* O campo de risco aqui é CLARO: a letra sobre ele vira preta. Sem isto
       o botão "Excluir" ficava branco sobre o vermelho claro, 2,75:1
       (auditoria de 13/10/2026). */
    --on-success: var(--void);
    --on-danger: var(--void);
    --on-warning: var(--void);
  }

  /* Linha "nenhum registro" de tabela: a célula virava grade e ocupava só a
     primeira coluna, apesar do colspan. */
  .app td.empty,
  .terceirizada-page td.empty {
    display: table-cell;
  }

  /* Conteúdo logo abaixo do cabeçalho do cartão encostava na régua dele
     (o rótulo "Eixo", "O dia 1 do ciclo é", os mínimos por equipe). */
  .app :is(.painel-atencao, .ativo-ficha, .contrato-medicoes, .capex-orcamento, .estoque-projeto, .estoque-extrato, .remotas-cadastro, .treinamento-ficha) > .card-head + :not(.daily-alertas),
  .app :is(.equipes-module, .rotas-conteudo) > .card > .card-head + :not(.daily-alertas) {
    margin-top: var(--sp-4);
  }

  /* CAPEX e Mensal: a busca, o resumo e a nota de rodapé do cartão
     encostavam na borda esquerda, fora do recuo do cabeçalho. */
  .app .card > :is(.capex-filters, .materials-overview, .material-adjust-note) {
    margin-inline: var(--sp-5);
  }
  .app .card > .material-adjust-note:last-child {
    margin-bottom: var(--sp-4);
  }

  /* Início: sem nada vencido, o cartão mostrava uma faixa vazia abaixo do
     cabeçalho. E o título de grupo com contador era mais alto que o sem
     contador, e os grupos de uma mesma linha não se alinhavam. */
  .app .painel-grupos:empty {
    display: none;
  }
  .app .painel-atencao:not(:has(.painel-grupo)) {
    padding-bottom: 0;
  }
  .app .painel-atencao:not(:has(.painel-grupo)) > .card-head {
    border-bottom: 0;
  }
  .app .painel-grupo h3 {
    min-height: 1.5rem;
  }

  /* A tira de cotações começa na mesma margem do título e do conteúdo. */
  .app .market-ticker {
    padding-inline: var(--ui-page-gutter);
  }

}

@media screen, print {
  /* Malha: a busca aceita tag, código SAP e subestação, e com a coluna de
     190px o texto de exemplo saía cortado. Ela ganha duas colunas, e a linha
     inteira no celular. */
  .app .malha-filtros > .form-group:first-child {
    grid-column: span 2;
  }
  @media (max-width: 600px) {
    .app .malha-filtros > .form-group:first-child {
      grid-column: 1 / -1;
    }
  }
}

@media screen, print {
  /* Dentro dos cartões dos módulos novos, cada bloco (campos, tabela, botões,
     aviso vazio) vinha colado no anterior: "Salvar revezamento" encostava na
     tabela, e o aviso do calendário, no botão. */
  .app :is(.painel-atencao, .ativo-ficha, .contrato-medicoes, .capex-orcamento, .estoque-projeto, .estoque-extrato, .remotas-cadastro, .treinamento-ficha) > :not(.card-head) + :not(.card-head),
  .app :is(.equipes-module, .rotas-conteudo) > .card > :not(.card-head) + :not(.card-head) {
    margin-top: var(--sp-4);
  }
  /* O número do dia do revezamento ficava no pé da célula. */
  .app .revezamento-grade th[scope='row'] {
    vertical-align: middle;
  }
}

@media screen, print {
  /* A faixa de totais de Contratos e Remotas é a mesma peça que o bloco de
     identificação das outras telas (.stats), mas o número saía em 15px contra
     28,8px do resto do sistema, e a célula com metade do recuo. Mesma escala. */
  .app :is(.contratos-resumo-item, .remotas-resumo-item) {
    padding: 1.15rem 1.25rem;
  }
  .app :is(.contratos-resumo-item, .remotas-resumo-item) > strong {
    /* 1,5rem, e não 1,8: "R$ 143.530.932,83" tem 17 caracteres e, com a
       coluna mínima de 16rem abaixo, cabe sem invadir a vizinha. */
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.3;
  }
}

@media screen, print {
  /* Histórico: os dois cartões ficam lado a lado numa grade, e a margem de
     `.card + .card` (feita para empilhar) empurrava o segundo 16px para baixo.
     Em grade quem separa é o gap. */
  .app .historico-colunas > .card {
    margin-top: 0;
  }
}

@media screen, print {
  /* Mapa: na coluna de 300px, título, descrição e dois botões disputavam a
     mesma linha; a descrição quebrava em três linhas e os botões saíam
     empilhados com larguras diferentes. O título vai em cima e os botões
     numa linha própria, repartida ao meio. */
  .app .map-library-head {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-3);
  }
  .app .map-library-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2);
  }
  .app .map-library-actions .btn {
    justify-content: center;
  }

  /* Pré-visita é formulário: com a área de trabalho em largura total, os
     campos passariam de mil pixels. Guarda a mesma largura do relatório
     diário e começa na margem das abas. */
  .app #view-technical-visit > * {
    max-width: 1220px;
  }
}

@media screen, print {
  /* Mensal: o seletor do mês ocupava a linha inteira e empurrava "Imprimir /
     PDF" para baixo, mais estreito e mais baixo que ele. Os dois ficam lado a
     lado, na mesma altura. */
  .app #view-monthly .capex-actions {
    flex-wrap: nowrap;
    align-items: stretch;
  }
  .app #monthlyMonth {
    width: auto;
    min-width: 10rem;
  }
  .app #btnMonthlyPrint {
    min-height: var(--ui-control-height);
  }
}

@media screen, print {
  /* A tela de entrada do sistema fica fora do .app, e os botões dela saíam
     com o espaçamento de letra do rótulo (0,09em), enquanto os mesmos botões
     na terceirizada e dentro do sistema usam 0,025em. */
  .auth-gate .btn {
    letter-spacing: 0.025em;
  }
}

@media screen, print {
  /* Relatório diário: a lista "Quem desceu" ficava na borda do quadro da
     equipe, fora do recuo de 16px do resto do conteúdo dele. */
  .app .daily-block > .daily-nominal {
    margin-inline: 1rem;
  }
  /* "Contingente NPE" e "Equipes e quantitativos" são nome e descrição da
     mesma seção, e saíam um em cada ponta da linha. Ficam juntos, à esquerda. */
  .app .daily-section-title {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
  }
}

@media screen and (min-width: 769px) and (max-width: 1100px) {
  /* Materiais adicionais: em tela intermediária (ou com zoom de 200%), os três
     campos numéricos ficavam com 84px úteis e cortavam o próprio nome. O nome
     do material vai para a linha de cima, e os números ganham a largura. */
  .app .custom-material-form {
    grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  }
  .app .custom-material-form #customMatDesc {
    grid-column: 1 / -1;
  }
}

@media print {
  /* Toda tela que se imprime vira papel. Só a folha do relatório diário (e as
     de Correias e Contratos, com regra própria) tinham virada para a
     impressão; o fechamento Mensal saía com as cores do painel escuro, e numa
     impressora comum, que descarta o fundo, o texto claro sumia no papel
     branco. Aqui as tintas do painel viram as da folha, uma vez só, e todo
     bloco que as usa acompanha. */
  .app {
    --console-bg: var(--p-paper);
    --console-panel: var(--p-paper);
    --console-panel-2: var(--p-wash);
    --console-line: var(--p-hair);
    --console-line-strong: var(--p-rule);
    --console-text: var(--p-ink);
    --console-muted: var(--p-ink-2);
    --success: var(--risk-clear);
    --warning: var(--risk-attention);
    --danger: var(--risk-blocked);
    --risk-clear-void: var(--risk-clear);
    --risk-attention-void: var(--risk-attention);
    --risk-blocked-void: var(--risk-blocked);
  }
  .app .card,
  .app .stat-card,
  .app .table-wrap,
  .app .empty,
  .app .empty-state {
    box-shadow: none !important;
    break-inside: avoid;
  }
  /* Tabela larga não rola no papel: quebra a linha dentro da célula em vez
     de cortar a coluna da direita. */
  .app .table-wrap {
    overflow: visible !important;
  }
  .app .table-wrap table {
    width: 100% !important;
    min-width: 0 !important;
  }
  .app .table-wrap :is(th, td) {
    white-space: normal !important;
  }
  .app .module-tabs,
  .app .table-scroll-hint {
    display: none !important;
  }
}

@media screen, print {
  .app :is(.contratos-resumo, .remotas-resumo) {
    grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  }
}

@media print {
  /* Na folha, a faixa de totais saía cinza: o fundo da célula fica
     transparente na impressão e o vão de 1px (que é a régua) aparecia por
     inteiro. A célula volta a ser papel. */
  .app :is(.contratos-resumo-item, .remotas-resumo-item) {
    background: var(--p-paper) !important;
  }
  /* Hachura na impressora de mina vira mancha. */
  .app :is(.contrato-comparacao, .contrato-coluna) {
    background: none !important;
  }
  /* Texto de exemplo dentro do campo parece valor preenchido no papel. */
  .app ::placeholder {
    color: transparent !important;
  }
}

@media print {
  /* Na folha A4 a coluna é mais estreita que na tela: o valor do contrato
     encostava na régua da coluna vizinha. */
  .app :is(.contratos-resumo-item, .remotas-resumo-item) > strong {
    font-size: 1.2rem;
  }
}

@media screen, print {
  /* Janelas: o título é a mesma peça do título de cartão (Archivo condensada,
     13,76px), mas perdia a versal e o espaçamento de letra, e o subtítulo
     saía menor. Mesma voz nos dois. */
  :is(.app, .terceirizada-page) .modal-head h2 {
    text-transform: uppercase;
    letter-spacing: var(--track-label);
  }
  :is(.app, .terceirizada-page) .modal-head p {
    font-size: var(--t-sm);
  }
  /* Rótulo com botão ao lado (os desvios da atividade): o rótulo ficava numa
     div a mais e perdia o estilo dos outros rótulos do formulário. */
  .form-group-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-2);
    margin-bottom: 0.35rem;
  }
  .form-group-head > label {
    margin: 0;
    color: var(--muted);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-micro);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
}

/* ── Alvos de toque no celular (DESIGN.md: abaixo de 560px, 44px) ──────
   A varredura de 07/10/2026 achou os que tinham ficado de fora da régua:
   ações do cartão da biblioteca (36px de altura), botão do menu e botões só
   de ícone (38 a 40px de largura), ferramentas do mapa e do diagrama, abas
   de grupo do mapa e a célula de revezamento. */
@media screen and (max-width: 560px) {
  .app :is(.library-card-actions .btn, .dg-modo, .map-group-tab, .revezamento-celula) {
    min-height: 44px;
  }
  .app :is(.menu-toggle, .daily-equipment-remove, .map-tool, .map-color-control input, .dg-grupo .btn-sm, .dg-localizar .btn) {
    min-width: 44px;
  }
}

/* ── Selo de sincronização na barra de cima (14/10/2026) ──
   Até 768 px a lateral fica recolhida, e com ela o selo do rodapé: o Fiscal
   salvava o relatório sem ver se ele tinha chegado ao servidor. A cópia mora
   na barra, à direita do título; no computador ela some. */
@media screen {
  .app .topbar-sync {
    display: none;
  }
}
@media screen and (max-width: 768px) {
  /* Título e selo centrados na altura do botão de menu (antes, presos no
     alto), e a barra de ferramentas vazia sem ocupar linha e vão. */
  .app .topbar {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
  }
  .app .topbar > .toolbar:empty {
    display: none;
  }
  .app .topbar-sync {
    display: inline-flex;
    justify-self: end;
    white-space: nowrap;
  }
}
/* Celular com zoom de 200%: o selo desce para uma linha própria, para não
   espremer o título. */
@media screen and (max-width: 340px) {
  .app .topbar-sync {
    grid-column: 1 / -1;
    justify-self: start;
  }
}

/* ── Cartão de atividade (14/10/2026) ──
   Apontar, Editar e Excluir ficavam em absoluto no canto do cartão e tomavam
   metade da largura: o título quebrava em até cinco linhas, "Apontar" caía
   para 10,4 px e os botões não chegavam a 44 px no toque. Agora eles são a
   última fileira do cartão, separada por régua; o título usa a largura toda. */
@media screen {
  .app .act-card {
    padding-top: var(--sp-3);
  }
  .app .act-title,
  .app .act-card.fiscal-mode .act-title {
    padding-right: 0;
    min-height: 0;
  }
  .app .act-card-actions {
    position: static;
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
    padding-top: var(--sp-3);
    border-top: var(--rule-hair) solid var(--border);
  }
  .app .act-card-actions .btn {
    width: 36px;
    min-width: 36px;
    height: 36px;
    min-height: 36px;
    padding: 0;
  }
  .app .act-card-actions .btn.btn-fiscal-entry {
    flex: 1 1 auto;
    width: auto;
    padding: 0 var(--sp-3);
    font-size: var(--t-micro);
  }
}
@media screen and (max-width: 768px), screen and (pointer: coarse) {
  .app .act-card-actions .btn {
    width: 44px;
    min-width: 44px;
    height: 44px;
    min-height: 44px;
  }
  .app .act-switch {
    min-height: 44px;
  }
}

/* ── Três indicadores ao lado do gráfico (14/10/2026) ──
   Estimado, Realizado e Desvios numa grade automática de duas colunas
   deixavam Desvios sozinho na segunda fileira, com meia faixa vazia ao lado.
   A grade agora decide pela largura que o bloco tem de fato (consulta de
   contêiner): três colunas quando cabem, uma embaixo da outra quando não. */
@media screen {
  .app .dashboard-chart-grid {
    container: faixa-grafico / inline-size;
  }
  .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) {
    grid-template-columns: 1fr;
  }
  .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card {
    border-right: 0;
    border-bottom: var(--rule-hair) solid var(--console-line);
  }
  .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card:last-child {
    border-bottom: 0;
  }
  @container faixa-grafico (min-width: 520px) {
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card {
      border-bottom: 0;
      border-right: var(--rule-hair) solid var(--console-line);
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card:last-child {
      border-right: 0;
    }
  }
}
@media screen and (min-width: 1024px) {
  @container faixa-grafico (min-width: 520px) {
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) {
      grid-template-columns: 1fr;
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card {
      border-right: 0;
      border-bottom: var(--rule-hair) solid var(--console-line);
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card:last-child {
      border-bottom: 0;
    }
  }
  /* Ao lado do gráfico, cada coluna tem metade da faixa: três colunas só
     quando a metade passa de 460 px. */
  @container faixa-grafico (min-width: 940px) {
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card {
      border-bottom: 0;
      border-right: var(--rule-hair) solid var(--console-line);
    }
    .app .dashboard-chart-grid > .stats:has(> .stat-card:nth-child(3):last-child) > .stat-card:last-child {
      border-right: 0;
    }
  }
}

/* ── Relatório diário no celular: histórico e materiais cedidos (14/10/2026) ──
   O histórico tinha 979 px numa área de 322 px: o Fiscal via a data e o nome
   e tinha de deslizar para achar o turno e o botão Abrir. Cada relatório vira
   um cartão: data e ações no alto; fiscal, turma e turno e a hora de salvar
   embaixo. A linha do mês continua separando os grupos. */
@media screen and (max-width: 720px) {
  .app .table-wrap:has(> .daily-history-table) {
    overflow: visible;
  }
  .app .table-wrap:has(> .daily-history-table)::after {
    display: none !important;
  }
  .app .daily-history-table,
  .app .daily-history-table tbody {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .app .daily-history-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .app .daily-history-table tr.daily-history-mes {
    display: block;
  }
  .app .daily-history-table tr.daily-history-mes th {
    display: block;
    padding-inline: var(--org-x, 20px);
  }
  .app .daily-history-table tr:not(.daily-history-mes) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--sp-1) var(--sp-3);
    padding: var(--sp-3) var(--org-x, 20px);
    border-bottom: var(--rule-hair) solid var(--border);
  }
  .app .table-wrap .daily-history-table td {
    position: static;
    display: block;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    white-space: normal;
  }
  .app .view :is(.card, .daily-block, .daily-card) > .table-wrap .daily-history-table :is(th, td):is(:first-child, :last-child) {
    padding-inline: 0;
  }
  .app .view .daily-card > .table-wrap .daily-history-table tr.daily-history-mes th {
    padding-inline: var(--org-x, 20px);
  }
  .app .daily-history-table td[data-label='Data'] {
    grid-column: 1;
    grid-row: 1;
    align-self: center;
  }
  .app .daily-history-table td.action-cell {
    grid-column: 2;
    grid-row: 1 / span 3;
    align-self: start;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    width: auto;
  }
  .app .daily-history-table td.action-cell > * + * {
    margin: 0;
  }
  .app .daily-history-table td:is([data-label='Fiscal'], [data-label='Turma / Turno'], [data-label='Salvo em']) {
    grid-column: 1;
  }
  /* A tabela é painel escuro: a tinta de apoio é a do console, não a do
     contexto (--text-soft dava escuro sobre escuro). */
  .app .daily-history-table td[data-label='Salvo em'] {
    color: var(--console-muted);
    font-size: var(--t-sm);
  }
  .app .daily-history-table td[data-label='Salvo em']::before {
    content: 'Salvo em ';
  }
}
/* Materiais cedidos no celular: o mesmo cartão dos equipamentos. */
@media screen and (max-width: 720px) {
  .app .table-wrap:has(> .daily-cedidos-table) {
    overflow: visible;
  }
  .app .table-wrap:has(> .daily-cedidos-table)::after {
    display: none !important;
  }
  .app .daily-cedidos-table,
  .app .daily-cedidos-table tbody {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .app .daily-cedidos-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .app .daily-cedidos-table tr {
    display: block;
    padding: var(--sp-3) var(--org-x, 20px);
    border-bottom: var(--rule-hair) solid var(--border);
  }
  .app .daily-cedidos-table tr:has(> td[data-label]) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr)) auto;
    gap: var(--sp-2) var(--sp-3);
  }
  .app .table-wrap .daily-cedidos-table td {
    position: static;
    display: block;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
  }
  .app .daily-cedidos-table td[data-label='Material'] {
    grid-column: 1 / 3;
    grid-row: 1;
  }
  .app .daily-cedidos-table td:last-child:not([data-label]) {
    grid-column: 3;
    grid-row: 1;
    align-self: end;
  }
  .app .daily-cedidos-table td[data-label='Para quem'] {
    grid-column: 1 / -1;
  }
  .app .daily-cedidos-table td[data-label='Custo (R$)'] {
    grid-column: 2 / -1;
  }
  .app .daily-cedidos-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: var(--sp-1);
    color: var(--muted);
    font-family: var(--font-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .table-wrap .daily-cedidos-table .cell-in {
    width: 100%;
    min-width: 0;
    max-width: none;
  }
}
/* "Motoristas na equipe" e "Observação" (Para o próximo turno) eram os dois
   rótulos do relatório em letra corrida; todo rótulo do sistema é a versal
   condensada do que o formulário pergunta (DESIGN.md, Tipografia). */
@media screen {
  .app .daily-drivers,
  .app .daily-passagem-campos label {
    color: var(--muted);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
}
/* Busca do quadro de atividades: 41 px no celular, abaixo do alvo de toque. */
@media screen and (max-width: 768px), screen and (pointer: coarse) {
  .app .board-search .form-control {
    min-height: 44px;
  }
}
/* A linha "nenhum registro" dessas tabelas, no celular, herdava a coluna fixa
   (sticky, 170 px de mínimo, sombra) e saía deslocada. É texto corrido. */
@media screen and (max-width: 720px) {
  .app .table-wrap :is(.consumo-tabela, .daily-cedidos-table, .daily-equipment-table, .daily-history-table) td[colspan] {
    position: static;
    display: block;
    width: auto;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    text-align: left;
    white-space: normal;
  }
  .app .consumo-tabela tr:has(> td[colspan]) {
    display: block;
    padding: var(--sp-3) var(--org-x, 20px);
  }
}
/* Presentes, Ausentes e Total: três números curtos que, empilhados no
   celular, tomavam 270 px. Lado a lado sempre que o relatório tem 330 px. */
@media screen {
  .app .daily-report {
    container: relatorio / inline-size;
  }
  @container relatorio (min-width: 330px) {
    .app .stats.daily-summary:has(> .stat-card:nth-child(3):last-child) {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .app .stats.daily-summary:has(> .stat-card:nth-child(3):last-child) > .stat-card {
      min-height: 0;
      border-bottom: 0;
      border-right: var(--rule-hair) solid var(--console-line);
    }
    .app .stats.daily-summary:has(> .stat-card:nth-child(3):last-child) > .stat-card:last-child {
      border-right: 0;
    }
  }
}
/* Gráficos do Início com altura de caixa, não de proporção: na proporção 2:1
   o celular ficava com 80 px de área útil e os meses inclinados. */
@media screen {
  .app .chart-card .chart-area {
    position: relative;
    height: 260px;
  }
}
@media screen and (max-width: 560px) {
  .app .chart-card .chart-area {
    height: 220px;
  }
}
@media screen and (max-width: 768px), screen and (pointer: coarse) {
  .app .chart-table > summary {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ── Projetos e Pré-visita (14/10/2026) ── */
@media screen {
  /* O número do projeto abria as atividades pintado na tinta do carimbo, que
     é só de autorizar (regra 2), e era um <a> sem endereço, fora do alcance
     do teclado. Agora é botão, com a tinta do texto e sublinhado. */
  .app button.link {
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    cursor: pointer;
  }
  .app button.link:hover {
    text-decoration-thickness: 2px;
  }
  /* "Editar painéis" no lugar da nota da célula, e não solto ao lado do número. */
  .app .stat-card .stat-acao {
    align-self: flex-start;
    margin-top: var(--sp-2);
  }
  .app .technical-visit-status > span {
    color: var(--muted);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
}
/* Linha de tabela sob o ponteiro: realce neutro. A tinta do carimbo dizia
   "autorizar" em toda linha por onde o mouse passava (regra 2). */
@media screen {
  .app tr:hover td,
  .terceirizada-page tr:hover td {
    background: var(--console-panel-2);
  }
}

/* ── Mapa (14/10/2026) ──
   Seis recuos numa tela (15, 9, 9, 11, 14 e 14 px). Agora tudo começa a 20 px
   da borda, como nos cartões. "Anotações carregadas do servidor" vinha no
   verde de liberado: é estado do registro, não classe de risco, e fica na
   tinta neutra (DESIGN.md, Estados). A falha continua destacada. */
@media screen {
  .app :is(.map-library-head, .map-document-head) {
    padding: var(--org-y) var(--org-x);
  }
  .app :is(.map-group-tabs, .map-list) {
    padding: var(--sp-3) var(--org-x);
  }
  .app .map-editor-toolbar {
    padding: var(--sp-3) var(--org-x);
  }
  .app .map-sync-status {
    padding: var(--sp-2) var(--org-x);
  }
  .app .map-sync-ok {
    color: var(--console-muted);
  }
  .app .map-canvas-scroll {
    padding: var(--org-x);
  }
}
/* No celular, o lápis de renomear o mapa ocupava a linha inteira. */
@media screen and (max-width: 768px) {
  .app .map-document-head {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
  }
  .app .map-document-actions {
    display: flex;
    flex: none;
    width: auto;
  }
  .app .map-document-actions .btn {
    width: 44px;
    min-width: 44px;
  }
}

/* ── Correias (14/10/2026) ── */
@media screen {
  /* Cartão de rota com a margem dos outros cartões (era 16 px). */
  .app .rota-cartao {
    padding: var(--org-x);
    container: rota / inline-size;
  }
  /* "Transportadores" não cabia nos 96 px úteis da coluna e encostava na
     divisória. A primeira coluna ganha a folga; abaixo de 440 px de cartão,
     duas por linha. */
  .app .rota-cartao-metricas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  @container rota (min-width: 440px) {
    .app .rota-cartao-metricas {
      grid-template-columns: minmax(0, 1.35fr) repeat(3, minmax(0, 1fr));
    }
  }
}
/* Os cinco filtros da malha numa linha só: Cadastro caía sozinho embaixo. */
@media screen and (min-width: 1100px) {
  .app .malha-filtros {
    grid-template-columns: minmax(0, 2fr) repeat(4, minmax(0, 1fr));
  }
  .app .malha-filtros > * {
    grid-column: auto;
  }
}
/* Histórico de inspeções: a tarja da classe de risco ia na lateral, a forma
   que o DESIGN.md reserva ao topo ("nunca faixa lateral"); e a classe
   `.situacao-*` pintava o nome da rota com a tinta escura das etiquetas, preto
   sobre o painel escuro. */
@media screen {
  .app .historico-item:is(.situacao-conforme, .situacao-atencao, .situacao-critico, .situacao-pendente, .situacao-naoAplicavel) {
    border-inline-start: 0;
    border-top: 6px solid var(--console-line-strong);
    background: var(--console-panel);
    color: var(--console-text);
  }
  .app .historico-item.situacao-conforme { border-top-color: var(--risk-clear-edge); }
  .app .historico-item.situacao-atencao { border-top-color: var(--risk-attention-edge); }
  .app .historico-item.situacao-critico { border-top-color: var(--risk-blocked-edge); }
  .app .historico-item strong {
    color: var(--console-text);
  }
}
/* Ficha de cálculo: a coluna da unidade tem largura fixa. Sem unidade ela
   ficava com 0 px e o campo andava 22 px para a direita; os valores não
   formavam coluna. No celular, as ações do cabeçalho quebram linha em vez de
   empurrar "Excluir" para fora da tela. */
@media screen {
  .app .ficha-linha > .ficha-campo + span {
    flex: 0 0 3rem;
    min-width: 3rem;
  }
}
@media screen and (max-width: 768px) {
  .app .ficha-cabecalho-acoes {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
  }
  .app .ficha-cabecalho-acoes > .btn {
    flex: 1 1 auto;
  }
}
/* Pendências da malha no celular: oito colunas em 364 px viravam rolagem
   lateral (1173 px). Cada pendência vira cartão, com o rótulo de cada dado;
   transportador e item no alto, as ações no pé. */
@media screen and (max-width: 720px) {
  .app .table-wrap:has(> .pendencias-tabela) {
    overflow: visible;
  }
  .app .table-wrap:has(> .pendencias-tabela)::after {
    display: none !important;
  }
  .app .pendencias-tabela,
  .app .pendencias-tabela tbody {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .app .pendencias-tabela thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .app .pendencias-tabela tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-3) var(--org-x, 20px);
    border-bottom: var(--rule-hair) solid var(--border);
  }
  .app .table-wrap .pendencias-tabela td {
    position: static;
    display: block;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    white-space: normal;
  }
  .app .pendencias-tabela td:is([data-label='Transportador'], [data-label='Item'], .action-cell) {
    grid-column: 1 / -1;
  }
  .app .pendencias-tabela td:not([data-label='Transportador'])[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: var(--sp-1);
    color: var(--muted);
    font-family: var(--font-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .pendencias-tabela td.action-cell {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-1);
  }
  .app .pendencias-tabela td.action-cell > .btn {
    flex: 1 1 auto;
  }
}
/* Tabela que vira cartão no celular não tem teto de altura: com o teto de 70%
   da tela e o transbordo liberado, os últimos cartões passavam por baixo da
   moldura e sobre o bloco seguinte (os nove equipamentos do relatório). */
@media screen and (max-width: 720px) {
  .app .table-wrap:has(> :is(.pendencias-tabela, .daily-history-table, .daily-equipment-table, .daily-cedidos-table, .consumo-tabela)) {
    max-height: none;
  }
}
/* O cabeçalho escondido dessas tabelas continuava com as células na largura
   original (o recorte só apaga a pintura): a 320 px uma célula vazia passava
   da tela. Como bloco, o overflow do cabeçalho de 1 px vale. */
@media screen and (max-width: 720px) {
  .app :is(.pendencias-tabela, .daily-history-table, .daily-equipment-table, .daily-cedidos-table) thead {
    display: block;
  }
}

/* ── Tabelas do motor de cadastro no celular (14/10/2026) ──
   Efetivo, subestações, câmaras, intervenções, alarmes, itens de contrato e
   alterações de intertravamento: no celular a coluna fixa do nome ocupava a
   largura toda e o resto ficava atrás da rolagem lateral (1867 px no Efetivo).
   Cada registro vira cartão: a primeira coluna como título, os outros campos
   em duas colunas com o rótulo, e as ações no pé. */
@media screen and (max-width: 720px) {
  .app .table-wrap:has(> .cadastro-tabela) {
    overflow: visible;
    max-height: none;
  }
  .app .table-wrap:has(> .cadastro-tabela)::after {
    display: none !important;
  }
  .app .cadastro-tabela,
  .app .cadastro-tabela tbody {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .app .cadastro-tabela thead {
    position: absolute;
    display: block;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .app .cadastro-tabela tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-3) var(--org-x, 20px);
    border-bottom: var(--rule-hair) solid var(--border);
  }
  .app .table-wrap .cadastro-tabela td {
    position: static;
    display: block;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    white-space: normal;
  }
  .app .view :is(.card, .daily-block, .daily-card) > .table-wrap .cadastro-tabela :is(td:first-child, td:last-child) {
    padding-inline: 0;
  }
  .app .cadastro-tabela td:first-child {
    grid-column: 1 / -1;
    font-weight: 700;
  }
  .app .cadastro-tabela td:not(:first-child)[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: var(--sp-1);
    color: var(--muted);
    font-family: var(--font-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
  .app .cadastro-tabela td.action-cell {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-1);
  }
  .app .cadastro-tabela td.action-cell > * {
    margin: 0;
  }
  .app .cadastro-tabela td.action-cell > .btn {
    flex: 1 1 auto;
  }
}

/* ── Barra de filtros (contratos, equipes, ativos…) — 14/10/2026 ──
   Em grade, cada botão caía numa coluna: no Efetivo, "Cadastrar pessoa" e
   "Importar planilha" ficavam a 270 px um do outro, alinhados aos campos de
   cima. Agora os campos crescem e o que não é campo (caixa de marcar e botões)
   fica junto, no fim da linha. */
@media screen and (min-width: 769px) {
  .app .contratos-barra {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--sp-3);
  }
  .app .contratos-barra > .form-group {
    flex: 1 1 200px;
    min-width: 0;
  }
  .app .contratos-barra > .form-group:first-child:has(> input) {
    flex: 2 1 320px;
  }
  .app .contratos-barra > :not(.form-group) {
    flex: none;
  }
  .app .contratos-barra > .form-group + :not(.form-group) {
    margin-left: auto;
  }
  .app .contratos-barra > .cadastro-check {
    align-self: center;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}
/* Caixa de marcar e botões da barra, juntos: quebram linha inteiros. */
@media screen {
  .app .contratos-barra-acoes {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
  }
}
@media screen and (min-width: 769px) {
  .app .contratos-barra > .contratos-barra-acoes {
    margin-left: auto;
  }
}
@media screen and (max-width: 768px) {
  .app .contratos-barra-acoes {
    grid-column: 1 / -1;
  }
  .app .contratos-barra-acoes > .btn {
    flex: 1 1 100%;
  }
}

/* ── Ativos (14/10/2026) ──
   "Pede atenção" com três etiquetas numa linha sem quebra: a terceira e a
   coluna Abrir ficha saíam pela direita da tabela de subestações. As
   etiquetas quebram linha dentro da célula, e a célula tem um mínimo. */
@media screen {
  .app .pills-lista {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1) var(--sp-2);
  }
  .app .pills-lista > .status-pill {
    white-space: normal;
    text-align: left;
  }
  .app td.celula-pills {
    width: 50%;
    min-width: 16rem;
    white-space: normal;
  }
}
@media screen and (max-width: 720px) {
  .app .cadastro-tabela td.celula-pills {
    grid-column: 1 / -1;
    min-width: 0;
  }
}
@media screen {
  /* `min-width: max-content` (regra geral das tabelas) fazia a tabela crescer
     até caber todas as etiquetas numa linha só. Aqui ela cabe na moldura. */
  .app table:has(td.celula-pills) {
    width: 100%;
    min-width: 0;
  }
}
/* Remotas: cinco indicadores numa grade de quatro deixavam três células
   vazias em cinza (a cor do fio entre as células). Cinco colunas quando
   cabem; e o último indicador sempre vai até o fim da fileira. */
@media screen {
  .app .remotas-resumo {
    grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  }
  .app .remotas-resumo > :last-child {
    grid-column: auto / -1;
  }
  /* Depois do cabeçalho do cartão, o vão é o do cabeçalho: a margem do
     primeiro parágrafo somava outra e deixava 44 px em branco. */
  .app .view .card > .card-head + p {
    margin-top: 0;
  }
}
/* Cartão de cadastro das remotas é grade: o vão de 12 px somava aos 16 da
   margem do cabeçalho. Um vão só, o de 16 px. */
@media screen {
  .app .view .card.remotas-cadastro {
    gap: var(--org-y);
  }
  .app .view .card.remotas-cadastro > .card-head {
    margin-bottom: 0;
  }
}

/* ── Financeiro (14/10/2026) ──
   "Precisam de resposta": a classe de risco ia numa faixa lateral, a forma
   que o DESIGN.md reserva ao topo; e a margem do quadro era 16 px. */
@media screen {
  .app .contratos-alerta {
    padding-inline: var(--org-x);
  }
  .app .contratos-alerta li {
    border-inline-start: 0;
    border-top: var(--rule-heavy) solid var(--console-line-strong);
    padding: var(--sp-3) var(--org-x);
  }
  .app .contratos-alerta li.vencido {
    border-top-color: var(--danger);
  }
  .app .contratos-alerta li.a-vencer {
    border-top-color: var(--warning);
  }
}
@media screen and (max-width: 768px), screen and (pointer: coarse) {
  .app .contrato-atalho {
    min-height: 44px;
  }
}
/* O mesmo para o resumo dos contratos (seis indicadores) e das remotas. */
@media screen and (min-width: 561px) {
  .app .contratos-resumo:has(> :nth-child(6):last-child) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media screen {
  .app :is(.contratos-resumo, .remotas-resumo) > :last-child {
    grid-column: auto / -1;
  }
}

/* ── Administração (14/10/2026) ──
   A tabela de contas só tem campos: com `min-width: max-content` e os campos
   na largura de 20 caracteres, ela passava 47 px da moldura a 1366 px e o
   botão Excluir saía cortado. Cabe na moldura; os campos encolhem. */
@media screen and (min-width: 769px) {
  .app #view-training .table-wrap > table {
    width: 100%;
    min-width: 0;
  }
  .app #view-training .table-wrap td :is(.form-control, .cell-in) {
    width: 100%;
    min-width: 9rem;
  }
  .app #view-training .table-wrap td select:is(.form-control, .cell-in) {
    min-width: 10rem;
  }
}
/* "Nenhum registro" dentro de tabela é texto do sistema, não valor lançado:
   fonte de texto, não a monoespaçada das células. */
@media screen {
  .app .table-wrap td:is(.empty, .daily-photo-empty, [colspan]) {
    font-family: var(--font-text);
  }
}
/* Formulário de rota: `.form-grid` e `.form-actions` não tinham estilo — sete
   campos de 1020 px um embaixo do outro, e Salvar e Cancelar a 3 px. */
@media screen {
  .app .form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--org-y);
  }
  .app .form-grid > .form-group {
    margin-bottom: 0;
  }
  .app .form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
  }
}
/* Ficha de ativo (e as outras listas de dados): o nome do dado é rótulo, na
   versal condensada; o valor segue na monoespaçada. Vinham em letra corrida. */
@media screen {
  .app :is(.ativo-dados, .ficha-dados, .contrato-dados) dt {
    color: var(--muted);
    font-family: var(--font-label);
    font-stretch: var(--stretch-label);
    font-size: var(--t-label);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }
}
/* Tabelas do motor de cadastro no computador: o Efetivo tinha 1867 px e a
   coluna de ações ficava fora da vista até a 1920 px. Nome e função quebram
   linha entre palavras; o resto fica numa linha; e a coluna de ações fica
   presa à direita, à vista enquanto o resto da tabela rola. */
@media screen and (min-width: 721px) {
  .app .cadastro-tabela td:is([data-label='Nome'], [data-label='Função'], [data-label='Objeto'], [data-label='Descrição']) {
    min-width: 13rem;
    white-space: normal;
    overflow-wrap: normal;
    word-break: normal;
  }
  .app .table-wrap .cadastro-tabela:has(td.action-cell) :is(td.action-cell, thead th:last-child) {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--console-panel);
    box-shadow: -1px 0 0 var(--console-line);
  }
}
@media screen and (min-width: 721px) {
  /* As três ações quebram em duas linhas: com 468 px a coluna presa cobria
     metade da tabela. */
  .app .table-wrap .cadastro-tabela td.action-cell {
    width: 15rem;
    min-width: 15rem;
    max-width: 15rem;
    white-space: normal;
  }
  .app .table-wrap .cadastro-tabela td.action-cell > .btn {
    margin: 2px 4px 2px 0;
  }
  .app .table-wrap .cadastro-tabela:has(td.action-cell) thead th:last-child {
    position: sticky;
    right: 0;
    z-index: 3;
  }
}
/* Parâmetros do planejamento no computador: o nome e a explicação do
   parâmetro não quebravam linha, e Máximo e Unidade ficavam fora da janela. */
@media screen and (min-width: 721px) {
  .app #planningParamsBody table {
    width: 100%;
    min-width: 0;
  }
  .app #planningParamsBody td[data-label='Parâmetro'] {
    white-space: normal;
  }
  .app #planningParamsBody td:is([data-label='Mínimo'], [data-label='Máximo']) {
    width: 8rem;
  }
  .app #planningParamsBody td:is([data-label='Mínimo'], [data-label='Máximo']) .cell-in {
    min-width: 0;
  }
}
/* Início: "Treinamentos em alerta" entrou no painel de atenção; o quadro de
   aniversariantes, sozinho na faixa, ocupa a largura em vez de meia fileira. */
@media screen {
  .app .dashboard-alerts:has(> :only-child) {
    grid-template-columns: minmax(0, 1fr);
  }
}
