/* ==========================================================================
   O que é nosso, por cima do style.css da referência.

   Regra: nada aqui redesenha o que a referência já resolve. São só as peças
   que ela não tem — a porta de login como camada sobre o painel, o palco de
   edição e os avisos de somente-leitura — usando as mesmas variáveis dela,
   para claro e escuro continuarem funcionando sozinhos.
   ========================================================================== */

/* -------- palco de edição do painel -------- */
/* A esfera fica no mesmo canto do botão "+" de adicionar card. Em edição,
   quem manda ali é o "+". */
body.editando-painel .global-ai-launcher,
body.editando-painel .global-ai-chat,
body.editando-painel .global-ai-command { display: none !important; }

/* O conteúdo do card grande tem que caber no espaço que a grade deu a ele.
   Sem isto, o card cresce pela altura do próprio conteúdo e invade o grupo
   de baixo. */
.dashboard-card-samples > .trend-card {
  height: 100%;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.dashboard-card-samples > .trend-card > svg {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
}
.dashboard-card-samples > .trend-card > .lista-rolavel {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  gap: 8px;
  align-content: start;
}
.dashboard-card-samples .card-heading { flex: 0 0 auto; }
.dashboard-card-samples .card-heading h3 { margin: 0; font-size: 1rem; }
.dashboard-card-samples .card-heading p { margin: 0; }

/* Respiro entre o grupo dos grandes e o dos pequenos. */
.dashboard-canvas { row-gap: 28px; }
.dashboard-canvas-group + .dashboard-canvas-group { margin-top: 4px; }

/* -------- redimensionar card --------
   Sem alça: a borda do card é a alça, como janela de sistema. O contorno
   pontilhado só aparece com o ponteiro perto da borda, para não poluir a
   tela de edição inteira. */
.dashboard-manager-shell.is-editing .dashboard-card {
  touch-action: none;
}
.dashboard-manager-shell.is-editing .dashboard-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-xl, 20px);
  border: 1px dashed color-mix(in srgb, var(--primary, #b4160f) 45%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 3;
}
.dashboard-manager-shell.is-editing .dashboard-card:hover::before { opacity: 0.6; }
.dashboard-card.is-resizing::before { opacity: 1 !important; border-style: solid; }
.dashboard-card.is-resizing { z-index: 6; }
/* durante o arrasto o cursor é do card, não do que estiver embaixo dele */
/* Subir e descer card só existem no celular, onde arrastar não funciona.
   No desktop quem manda é o punho de arrastar, e duas setas a mais só
   poluiriam o canto do card. */
.dashboard-card-tool-mover { display: none; }

/* No desktop o cabeçalho da tabela é clicável e já ordena; a lista só
   apareceria repetindo o que a coluna faz melhor. */
.table-ordenar-celular { display: none; }

body.dashboard-card-resizing,
body.dashboard-card-resizing * { user-select: none !important; }

.card-resize-medida {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 7;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  background: var(--primary, #b4160f);
  pointer-events: none;
}

/* -------- papel do usuário -------- */
.perfil-papel {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.72;
}

/* Somente leitura: o operador vê a tabela inteira, mas as caixas de seleção
   e os botões de criar somem em vez de ficarem ali para falhar depois. */
body.somente-leitura .row-check,
body.somente-leitura .head-check,
body.somente-leitura [data-criar] { display: none; }

.aviso-somente-leitura {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: var(--radius-md, 14px);
  border: 1px solid var(--line, rgba(22, 22, 26, 0.1));
  background: var(--surface-soft, rgba(180, 22, 15, 0.06));
  color: var(--muted, #5b5b66);
  font-size: 0.86rem;
}

/* Quem não troca de loja não precisa de um seletor com uma opção só. */
body.loja-unica .client-dropdown-arrow { display: none; }
body.loja-unica .client-dropdown-trigger { cursor: default; }

/* -------- lista de carregadores dentro do card -------- */
.linha-ponto {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius-md, 14px);
  border: 1px solid var(--line, rgba(22, 22, 26, 0.08));
  background: var(--surface-soft, rgba(255, 255, 255, 0.5));
}
.linha-ponto-copy { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.linha-ponto-copy strong {
  font-size: 0.9rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.linha-ponto-copy span { font-size: 0.78rem; color: var(--muted, #5b5b66); }

/* -------- avatar com foto -------- */
.avatar.tem-foto { padding: 0; overflow: hidden; }
.avatar.tem-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* -------- perfil: sanfonas e foto -------- */
.collapsible-card .collapse-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.22s ease;
}
.collapsible-card .collapse-body > * { overflow: hidden; }
.collapsible-card.is-open .collapse-body { grid-template-rows: 1fr; }

.foto-previa {
  display: grid;
  place-items: center;
  padding: 10px 0;
}
.foto-previa img {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--line, rgba(22, 22, 26, 0.12));
}

.profile-settings-modal .refresh-status:empty { display: none; }
.profile-settings-modal .refresh-status.is-error { color: var(--status-critical, #d64545); }
.profile-settings-modal .refresh-status.is-ok { color: var(--status-ok, #1f8a5a); }
.profile-side-card .refresh-status:empty { display: none; }


/* ==========================================================================
   Avisos

   Canto inferior direito, empilhados, cor e ícone por tipo. A barra de tempo
   embaixo é o que evita a dúvida "isso vai sumir?" — dá para ver o aviso
   indo embora, e passar o mouse por cima segura enquanto se lê.
   ========================================================================== */
.toast-stack {
  position: fixed;
  /* `top: auto` não é decoração: o style.css da referência declara
     `.toast-stack { top: 18px }`, e sobrescrever só o `bottom` deixava os
     dois valendo. Com top e bottom ao mesmo tempo o elemento estica de cima
     a baixo da tela, e o aviso dentro dele esticava junto — era a faixa que
     ocupava a lateral inteira. */
  top: auto;
  left: auto;
  right: 20px;
  bottom: 20px;
  width: auto;
  height: auto;
  z-index: 13000;
  display: grid;
  gap: 10px;
  justify-items: end;
  align-content: end;
  pointer-events: none;
}

.aviso {
  --av-cor: var(--primary, #b4160f);
  position: relative;
  align-self: end;
  height: auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 11px;
  width: min(370px, calc(100vw - 40px));
  padding: 13px 14px 15px;
  border-radius: 15px;
  background: var(--surface-strong, #fff);
  border: 1px solid var(--line, rgba(22, 22, 26, 0.1));
  border-left: 3px solid var(--av-cor);
  box-shadow: 0 12px 32px rgba(10, 32, 54, 0.16);
  pointer-events: auto;
  overflow: hidden;
  opacity: 0;
  transform: translateY(10px) scale(0.98);
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(.22,.9,.3,1);
}
.aviso.is-visivel { opacity: 1; transform: none; }
.aviso.is-saindo { opacity: 0; transform: translateX(14px) scale(0.98); }

.aviso.is-ok      { --av-cor: var(--status-ok, #1f8a5a); }
.aviso.is-erro    { --av-cor: var(--status-critical, #d64545); }
.aviso.is-atencao { --av-cor: var(--status-warning, #d99114); }
.aviso.is-info,
.aviso.is-andando { --av-cor: var(--primary, #b4160f); }

.aviso-icone {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  color: var(--av-cor);
  background: color-mix(in srgb, var(--av-cor) 14%, transparent);
}
.aviso-icone svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.aviso-girando { animation: aviso-gira 0.9s linear infinite; transform-origin: center; }
@keyframes aviso-gira { to { transform: rotate(360deg); } }

.aviso-copy { display: grid; gap: 2px; min-width: 0; }
.aviso-copy strong {
  font-size: 0.89rem;
  font-weight: 650;
  line-height: 1.35;
  color: var(--text, #16161a);
}
.aviso-copy small {
  font-size: 0.79rem;
  line-height: 1.45;
  color: var(--muted, #5b5b66);
}

.aviso-fechar {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin: -2px -2px 0 0;
  padding: 0;
  border: 0;
  border-radius: 7px;
  font-size: 1rem;
  line-height: 1;
  color: var(--muted, #5b5b66);
  background: transparent;
  cursor: pointer;
}
.aviso-fechar:hover { background: var(--line, rgba(22, 22, 26, 0.08)); color: var(--text, #16161a); }

/* barra de tempo: mostra o aviso indo embora, e o mouse por cima segura */
.aviso:not(.is-andando)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--av-cor);
  opacity: 0.35;
  transform-origin: left;
  animation: aviso-tempo linear forwards;
  animation-duration: 4s;
}
.aviso.is-erro::after { animation-duration: 9s; }
.aviso:hover::after { animation-play-state: paused; }
@keyframes aviso-tempo { to { transform: scaleX(0); } }

@media (max-width: 640px) {
  .toast-stack { top: auto; right: 12px; left: 12px; bottom: 12px; justify-items: stretch; }
  .aviso { width: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .aviso, .aviso::after, .aviso-girando { transition: none; animation: none; }
}

/* ==========================================================================
   Curva de recarga — o card detalhado

   Duas grandezas em escalas diferentes: kW à esquerda, % à direita. Legenda
   no cabeçalho e não dentro do gráfico, para não roubar área de desenho num
   card que já é o mais denso do painel.
   ========================================================================== */
.curva-card {
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 20px 14px;
  border-radius: var(--radius-xl, 20px);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.curva-topo {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}
.curva-titulo p { margin: 0; }
.curva-titulo h3 {
  margin: 2px 0 0;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
}
.curva-lateral {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.curva-legenda { display: flex; gap: 14px; flex-wrap: wrap; }
.curva-chave {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.76rem;
  color: var(--muted);
  white-space: nowrap;
}
.curva-chave i { width: 14px; height: 2px; border-radius: 2px; flex: 0 0 auto; }

.curva-escolha {
  font: inherit;
  font-size: 0.78rem;
  padding: 5px 9px;
  color: var(--text);
  background: var(--surface-soft, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--line);
  border-radius: 9px;
  max-width: 190px;
}

.curva-area { position: relative; flex: 1 1 auto; min-height: 0; }
.curva-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.curva-captura { cursor: crosshair; }

/* a dica segue o ponteiro; `left` vem do JS, o translate centraliza nela */
.curva-dica {
  position: absolute;
  top: 4px;
  transform: translateX(-50%);
  display: grid;
  gap: 3px;
  padding: 9px 11px;
  border-radius: 11px;
  background: var(--surface-strong, #fff);
  border: 1px solid var(--line);
  box-shadow: 0 10px 26px rgba(10, 32, 54, 0.18);
  font-size: 0.76rem;
  white-space: nowrap;
  pointer-events: none;
  z-index: 4;
}
.curva-dica[hidden] { display: none; }
.curva-dica strong { font-size: 0.72rem; color: var(--muted); font-weight: 600; }
.curva-dica span { display: flex; align-items: center; gap: 6px; color: var(--muted); }
.curva-dica i { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.curva-dica b { color: var(--text); font-variant-numeric: tabular-nums; }

.curva-vazio {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 0.85rem;
}

@media (max-width: 720px) {
  .curva-lateral { width: 100%; justify-content: flex-start; }
  .curva-escolha { max-width: none; flex: 1 1 auto; }
}

/* linha de resumo abaixo do gráfico da curva */
.curva-resumo {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  flex: 0 0 auto;
  padding-top: 4px;
  font-size: 0.78rem;
  color: var(--muted);
}
.curva-resumo b { color: var(--text); font-variant-numeric: tabular-nums; }

/* o clique tem que mudar algo antes de a permissão ser resolvida */
.global-ai-chat-audio.is-processing { opacity: 0.75; cursor: progress; }

/* ==========================================================================
   Balões da conversa

   O style.css da referência não estiliza .global-ai-chat-message — eram
   textos soltos um embaixo do outro, sem nada dizendo quem falou o quê.

   Lado e cor carregam a mesma informação, de propósito: quem só vê a
   posição entende, quem não distingue as cores também. A ponta quadrada de
   cada balão aponta para o lado de quem falou.
   ========================================================================== */
.global-ai-chat-message {
  --balao-fundo: var(--surface-strong, #fff);
  --balao-borda: var(--line, rgba(22, 22, 26, 0.1));
  max-width: 86%;
  padding: 9px 13px;
  border-radius: 16px;
  background: var(--balao-fundo);
  border: 1px solid var(--balao-borda);
  box-shadow: 0 1px 2px rgba(10, 32, 54, 0.06);
  animation: balao-entra 0.2s ease;
}
.global-ai-chat-message p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text, #16161a);
  /* pergunta colada de outro lugar não pode estourar a largura do balão */
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

/* minhas mensagens: à direita, fundo claro */
.global-ai-chat-message.is-user {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
}

/* respostas da assistente: à esquerda, no vermelho da marca */
.global-ai-chat-message.is-assistant {
  --balao-fundo: color-mix(in srgb, var(--primary, #b4160f) 11%, var(--surface-strong, #fff));
  --balao-borda: color-mix(in srgb, var(--primary, #b4160f) 26%, transparent);
  align-self: flex-start;
  border-bottom-left-radius: 5px;
}

:root[data-theme="dark"] .global-ai-chat-message {
  /* branco puro num painel escuro cega; o que importa é o contraste entre os
     dois lados, e não o branco literal */
  --balao-fundo: rgba(255, 255, 255, 0.09);
  --balao-borda: rgba(255, 255, 255, 0.14);
  box-shadow: none;
}
:root[data-theme="dark"] .global-ai-chat-message.is-assistant {
  --balao-fundo: color-mix(in srgb, var(--primary, #ff4d42) 24%, transparent);
  --balao-borda: color-mix(in srgb, var(--primary, #ff4d42) 38%, transparent);
}

@keyframes balao-entra {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .global-ai-chat-message { animation: none; }
}

/* ==========================================================================
   Celular

   O style.css da referência já vira a barra lateral em gaveta abaixo de
   1180px, mas para de aí: a grade continua com duas colunas de card e altura
   travada em linhas de 96px. Num aparelho de 375px isso dá card de 167px —
   largura em que um gráfico de linha vira um risco e um número de quatro
   dígitos encosta nas duas bordas.

   Daqui para baixo, então, o painel é outro desenho, e não o mesmo apertado:
   uma coluna, altura pelo conteúdo, tabela em forma de lista e alvo de toque
   grande o bastante para um dedo. 720px é o corte porque é onde duas colunas
   deixam de caber sem espremer.
   ========================================================================== */
@media (max-width: 720px) {

  /* ---- grade: uma coluna, altura pelo conteúdo ---- */
  /* O !important é obrigatório: a referência declara o span do card com
     !important dentro do próprio media query dela. */
  .dashboard-canvas-grid-large,
  .dashboard-canvas-grid-small {
    grid-template-columns: 1fr !important;
    grid-auto-rows: auto !important;
    gap: 12px !important;
  }
  #dashboardCanvas [data-dashboard-card] {
    grid-column: 1 / -1 !important;
    grid-row: auto !important;
  }

  /* A altura no celular não vem daqui: a referência a calcula a partir de
     --dashboard-mobile-row-span, e quem decide esse número por card é o
     aplicarSpans() do app.js. Aqui só cuidamos da largura. */

  /* A referência esconde a linha de contexto do KPI no celular, e faz sentido
     no desenho dela: lá o card tem metade da tela. Aqui ele tem a tela toda,
     e sem essa linha sobra um número sem o que ele significa. */
  .dashboard-canvas-grid-small > [data-dashboard-card],
  .dashboard-kpi-card { height: auto !important; min-height: 108px !important; }
  .dashboard-kpi-card .dashboard-kpi-meta { display: block; }

  .dashboard-canvas { padding: 0; }
  .dashboard-canvas-group + .dashboard-canvas-group { margin-top: 18px; }

  /* ---- ferramentas do card ---- */
  /* Arrastar card é HTML5 drag-and-drop, que o toque não dispara. No celular
     o punho sai e entram duas setas — a ordem é vertical mesmo, então subir e
     descer dizem exatamente o que vai acontecer. */
  .dashboard-card-tool-handle { display: none !important; }
  .dashboard-card-tool-mover { display: inline-flex; }
  .dashboard-card-tool { min-width: 34px; min-height: 34px; }

  /* ---- topo ---- */
  .topbar { gap: 10px; padding: 12px; }
  .topbar-side { flex-wrap: wrap; gap: 8px; }
  #topbarActions .primary-button { flex: 1 1 auto; min-height: 42px; }
  .global-ai-command-field { min-height: 46px; }
  /* a moldura tem 46px, mas quem recebe o toque é o input — e ele tinha 19 */
  .global-ai-command-field input { min-height: 40px; }

  /* ---- abrir a gaveta ---- */
  /* A referência põe esse botão colado na borda esquerda, com 30px e metade
     para fora da tela — some atrás do dedo antes de ser tocado. No celular
     ele vira um alvo redondo de 48px na parte de baixo, que é onde o polegar
     alcança sem trocar a mão de posição. */
  .sidebar-toggle.sidebar-edge-toggle {
    top: auto !important;
    bottom: 18px;
    left: 14px !important;
    width: 48px;
    height: 48px;
    border-radius: 999px;
    transform: none !important;
    box-shadow: 0 8px 22px rgba(10, 12, 20, 0.28);
  }
  .sidebar-edge-toggle svg { width: 17px; height: 17px; }

  /* ---- painéis e biblioteca ---- */
  .dashboard-workspaces-menu {
    left: 12px !important;
    right: 12px !important;
    width: auto !important;
    max-width: none !important;
    max-height: 70vh;
    overflow-y: auto;
  }
  /* A barra de edição é item de grade dentro da casca, não uma faixa solta:
     posicionar por left/right aqui não faria nada. O que muda é a quebra —
     nome numa linha, os dois botões dividindo a de baixo. */
  .dashboard-manager-shell.is-editing .dashboard-manager-editbar {
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px;
  }
  .dashboard-manager-editbar-title { flex: 1 1 100%; }
  .dashboard-manager-editbar-actions { flex: 1 1 100%; }
  .dashboard-manager-editbar-actions > * { flex: 1 1 0; min-height: 42px; }
  /* o aviso de que o menu lateral não se edita só ocupa altura numa tela
     onde o menu lateral nem está à vista */
  .dashboard-manager-sidebar-placeholder { display: none; }
  .dashboard-library-fab { right: 14px; bottom: 18px; width: 52px; height: 52px; }

  /* ---- conversa com a assistente ---- */
  .global-ai-chat {
    left: 8px !important; right: 8px !important;
    top: 8px !important; bottom: 8px !important;
    width: auto !important; height: auto !important;
    /* Com o teclado aberto, `bottom` continua medindo a janela inteira e o
       campo de escrever fica atrás do teclado. `dvh` mede o que sobrou de
       fato; onde não existir, o max-height simplesmente não se aplica e a
       conversa volta a ser o que era. */
    max-height: calc(100dvh - 16px) !important;
  }
  .global-ai-chat-message { max-width: 92%; }

  /* ---- tabela vira lista ---- */
  /* Rolar 768px de tabela dentro de 315px de tela é procurar a coluna com o
     dedo. Cada linha vira um cartão com rótulo à esquerda e valor à direita:
     some a rolagem lateral e o registro passa a ser lido de uma vez. */
  .table-screen .table-scroll { overflow: visible; }
  .table-screen thead { display: none; }
  .table-screen table,
  .table-screen tbody,
  .table-screen tr,
  .table-screen td { display: block; width: 100%; }
  .table-screen tbody tr {
    position: relative;
    border: 1px solid var(--line, rgba(22, 22, 26, 0.12));
    border-radius: 14px;
    padding: 10px 46px 10px 12px;
    margin-bottom: 10px;
    background: var(--surface-strong, #fff);
  }
  .table-screen tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    border: 0;
    padding: 5px 0;
    text-align: right;
  }
  .table-screen tbody td::before {
    content: attr(data-rotulo);
    flex: 0 0 40%;
    text-align: left;
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--muted);
  }
  /* a caixa de seleção não é um campo do registro: vai no canto do cartão */
  .table-screen tbody td:first-child {
    position: absolute;
    top: 10px; right: 12px;
    width: auto;
    padding: 0;
  }
  .table-screen tbody td:first-child::before { content: none; }
  /* a linha de "nada encontrado" não é registro: sem rótulo, sem canto */
  .table-screen tbody td[colspan] { padding-right: 0; text-align: left; }
  .table-screen tbody tr:has(td[colspan]) { padding-right: 12px; }

  /* cada linha já virou um cartão com borda; a moldura do card em volta só
     estaria cobrando 32px de largura para desenhar a mesma coisa duas vezes */
  .table-card { padding: 10px; }
  /* a caixa de seleção é o único alvo de toque do cartão: 18px é metade do
     que um polegar acerta, e errar aqui marca a linha errada */
  .table-screen tbody td:first-child { width: 32px; }
  .table-screen .row-check,
  .table-screen .head-check { width: 22px; height: 22px; }

  .table-toolbar { flex-wrap: wrap; gap: 10px; }
  .toolbar-left, .toolbar-right { flex: 1 1 100%; flex-wrap: wrap; }
  .table-search { flex: 1 1 100%; }
  /* height, não min-height: o style.css da referência fixa a altura do campo,
     e um mínimo menor que um valor declarado não muda nada */
  .table-search input { width: 100%; height: 42px; }
  /* `.toolbar-left` é display:contents, então quem organiza estes três é a
     `.table-toolbar` — e ela é grade, não flex. Largura e coluna cobrem os
     dois casos sem depender de qual é. */
  .table-ordenar-celular {
    display: block;
    flex: 1 1 100%;
    width: 100%;
    grid-column: 1 / -1;
  }
  .table-ordenar-celular select {
    width: 100%;
    min-height: 42px;
    padding: 0 10px;
    border-radius: 10px;
    border: 1px solid var(--line, rgba(22, 22, 26, 0.14));
    background: var(--surface-strong, #fff);
    color: var(--text);
    font: inherit;
  }

  /* ---- gaveta de edição ---- */
  .editor-shell { width: auto; max-width: none; margin: 0 10px; }
  .editor-body { max-height: 60vh; }
  .editor-footer { flex-wrap: wrap; gap: 8px; }
  .editor-footer button { flex: 1 1 auto; min-height: 42px; }
}

/* Dedo, não ponteiro: o corte é o apontador, porque quem erra um alvo de
   36px é o dedo — num celular de 375px ou num tablet de 1024px. */
@media (pointer: coarse) {
  .icon-button,
  .global-ai-command-submit,
  .global-ai-chat-close { min-width: 42px; min-height: 42px; }
}

/* Tela muito estreita (iPhone SE e afins): o número do KPI é o que estoura
   primeiro, porque a referência o dimensiona por vw. */
@media (max-width: 380px) {
  .dashboard-kpi-value { font-size: 1.35rem; }
  .table-screen tbody td::before { flex-basis: 46%; }
}
