/* =========================================================
   Dispositivos 2: layout premium (claro/escuro + densidade)
   Tudo namespaced com prefixo .d2- / variáveis --d2-* para não
   colidir com o CSS global (style.css, stylenovo.css...).
   ========================================================= */

:root {
  --d2-font-sans: 'IBM Plex Sans', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --d2-font-mono: 'JetBrains Mono', ui-monospace, Menlo, Consolas, monospace;

  /* Status (Ravi) */
  --d2-st-1: #6A6666; /* offline   */
  --d2-st-2: #6c93c4; /* pausado   */
  --d2-st-3: #e29b37; /* atenção   */
  --d2-st-4: #d23939; /* crítico   */
  --d2-st-5: #a8a8a8; /* não testado */
  --d2-st-6: #00c95c; /* ok        */

  --d2-brand: #10b981;
  --d2-brand-dim: #059669;

  --d2-radius-sm: 4px;
  --d2-radius-md: 6px;
  --d2-radius-lg: 10px;

  /* Densidade: defaults (médio) */
  --d2-row-pad: 8px;
  --d2-dev-pad-y: 8px;
  --d2-dev-pad-x: 10px;
  --d2-dev-min-h: 52px;
  --d2-sensor-min-w: 170px;
  --d2-sensor-min-h: 52px;
  --d2-sensor-pad-y: 8px;
  --d2-sensor-pad-x: 10px;
  --d2-gap: 6px;
  --d2-name-fs: 12.5px;
  --d2-ip-fs: 11px;
  --d2-status-fs: 11.5px;
  --d2-sensor-name-fs: 11px;
  --d2-vendor-size: 22px;
  --d2-vendor-fs: 9px;
  --d2-device-col: 220px;
  --d2-status-ind: 6px;
  --d2-bar-w: 4px;
  --d2-group-pad: 8px 12px;
  --d2-group-children-pad: 16px;
  --d2-group-name-fs: 13.5px;

  /* Tema claro */
  --d2-bg: #fafaf9;
  --d2-bg-elevated: #ffffff;
  --d2-bg-subtle: #f5f5f4;
  --d2-bg-hover: #f0efed;
  --d2-border: #e7e5e4;
  --d2-border-strong: #d6d3d1;
  --d2-text: #1c1917;
  --d2-text-muted: #57534e;
  --d2-text-faint: #a8a29e;
  --d2-tree-line: #d6d3d1;
  --d2-shadow-sm: 0 1px 2px rgba(28,25,23,.05);
  --d2-shadow-md: 0 1px 3px rgba(28,25,23,.07), 0 1px 2px rgba(28,25,23,.04);
}

html[data-theme="dark"] {
  /* Paleta azul-escura padronizada com o Flow (--fl-bg/--fl-card/--fl-bd) */
  --d2-bg: #0d1117;
  --d2-bg-elevated: #161b22;
  --d2-bg-subtle: #0f1623;
  --d2-bg-hover: #1f2733;
  --d2-border: #272e3a;
  --d2-border-strong: #3a4250;
  --d2-text: #e6edf3;
  --d2-text-muted: #8b949e;
  --d2-text-faint: #6e7681;
  --d2-tree-line: #3a4250;
  --d2-shadow-sm: 0 1px 2px rgba(0,0,0,.3);
  --d2-shadow-md: 0 1px 3px rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3);
}

/* ---------- barra de rolagem da casa (todas as telas) ---------- */
/* Um fio de 4px arredondado na cor da borda, trilho transparente; escurece no
   hover. Vale para qualquer scroller (vertical e horizontal). No Chromium os
   pseudo-elementos -webkit fazem o trabalho; o Firefox nao os entende e cai no
   bloco @supports com scrollbar-width: thin. NUNCA declarar scrollbar-width
   fora desse bloco: no Chromium a propriedade padrao desliga os
   pseudo-elementos e a barra volta a ser a nativa. */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--d2-border); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--d2-border-strong); }
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: thin; scrollbar-color: var(--d2-border) transparent; }
}

html[data-density="compact"] {
  --d2-row-pad: 3px; --d2-dev-pad-y: 5px; --d2-dev-pad-x: 8px; --d2-dev-min-h: 38px;
  --d2-sensor-min-w: 145px; --d2-sensor-min-h: 38px; --d2-sensor-pad-y: 4px; --d2-sensor-pad-x: 8px;
  --d2-gap: 3px; --d2-name-fs: 11.5px; --d2-ip-fs: 10px; --d2-status-fs: 10.5px; --d2-sensor-name-fs: 10px;
  --d2-vendor-size: 18px; --d2-vendor-fs: 8px; --d2-device-col: 180px; --d2-status-ind: 5px; --d2-bar-w: 3px;
  --d2-group-pad: 5px 10px; --d2-group-children-pad: 12px; --d2-group-name-fs: 12.5px;
}

html[data-density="spacious"] {
  --d2-row-pad: 12px; --d2-dev-pad-y: 12px; --d2-dev-pad-x: 14px; --d2-dev-min-h: 66px;
  --d2-sensor-min-w: 210px; --d2-sensor-min-h: 66px; --d2-sensor-pad-y: 12px; --d2-sensor-pad-x: 14px;
  --d2-gap: 10px; --d2-name-fs: 13.5px; --d2-ip-fs: 12px; --d2-status-fs: 12.5px; --d2-sensor-name-fs: 12px;
  --d2-vendor-size: 28px; --d2-vendor-fs: 10px; --d2-device-col: 250px; --d2-status-ind: 7px; --d2-bar-w: 5px;
  --d2-group-pad: 10px 14px; --d2-group-children-pad: 20px; --d2-group-name-fs: 14.5px;
}

/* ---------- container ---------- */
/* zera o padding global do body (style.css: body{padding:5px}) só nesta página,
   p/ a toolbar/faixa do topo encostar nas bordas (full-bleed, como no modelo) */
html body { padding: 0; }

.disp2 {
  font-family: var(--d2-font-sans);
  color: var(--d2-text);
  background: var(--d2-bg);   /* fundo stone do modelo cobre a página inteira (não herda o #0f1117 do tema global) */
  padding: 63px 0 0;          /* topo = altura do header fixo; sem padding lateral (toolbar full-bleed; conteúdo centralizado abaixo) */
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
.disp2 *, .disp2 *::before, .disp2 *::after { box-sizing: border-box; }
.disp2 button { font-family: inherit; cursor: pointer; }

/* ---------- toolbar ---------- */
.d2-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 0;
  /* faixa full-width colada no header (igual ao modelo): fundo próprio + borda inferior */
  background: var(--d2-bg);
  border-bottom: 1px solid var(--d2-border);
  padding: 12px 24px;
  /* fica grudada logo abaixo do header fixo (63px) ao rolar a página */
  position: sticky; top: 63px; z-index: 30;
}
.d2-view-tabs, .d2-density-selector {
  display: flex; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border);
  border-radius: var(--d2-radius-md); padding: 2px; gap: 2px;
}
.d2-view-tab {
  padding: 5px 12px; font-size: 12.5px; font-weight: 500; color: var(--d2-text-muted);
  border: none; background: none; border-radius: 4px; transition: all .15s; text-decoration: none;
}
.d2-view-tab.active { background: var(--d2-bg-subtle); color: var(--d2-text); box-shadow: var(--d2-shadow-sm); }
.d2-view-tab:not(.active):hover { color: var(--d2-text); }
/* os tabs são <a>; sobrepõe a cor de link global (html[data-theme=dark] a { color:#5b9cf6 }) */
.d2-view-tabs a.d2-view-tab { color: var(--d2-text-muted); }
.d2-view-tabs a.d2-view-tab.active { color: var(--d2-text); }
.d2-view-tabs a.d2-view-tab:hover { color: var(--d2-text); }

/* itens de menu (dropdown Adicionar, menu do servidor, menu flutuante) também são <a>;
   o global html[data-theme=dark] a {color:#5b9cf6} (0,1,2) vence as classes (0,1,1).
   Prefixa com o tema p/ subir a especificidade e manter tudo cinza (nunca azul). */
html[data-theme="dark"] .d2-add-dd a,
html[data-theme="dark"] .d2-server-menu-list a,
html[data-theme="dark"] .d2-server-menu-list a.danger,
html[data-theme="dark"] .d2-floatmenu a,
html[data-theme="dark"] .d2-floatmenu a.danger { color: var(--d2-text); }

.d2-toolbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* "Densidade" + botões = UM componente só (uma caixa, com separador sutil no meio) */
.d2-density {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--d2-bg-elevated); border: 1px solid var(--d2-border);
  border-radius: var(--d2-radius-md); padding: 3px 4px 3px 11px;
}
.d2-density-label { font-size: 11.5px; color: var(--d2-text-muted); font-weight: 500; white-space: nowrap; }
/* dentro do componente, o seletor perde a própria caixa (só um separador à esquerda) */
.d2-density .d2-density-selector {
  background: none; border: none; border-radius: 0; padding: 0;
  border-left: 1px solid var(--d2-border); padding-left: 8px;
}

/* conteúdo (servidores/dispositivos) centralizado com limite PERCENTUAL: o teto fixo
   de 1800px deixava metade de um monitor 4K vazia (reclamação de provedor, 17/08) , 
   a grade de chips preenche qualquer largura sem perder leitura; o divisor vem da
   borda inferior da toolbar (full-width) */
#d2-tree {
  max-width: 96%; margin: 0 auto;
  padding: 24px 24px 80px;   /* respiro do modelo + folga p/ o rodapé fixo */
}
.d2-density-btn {
  width: 30px; height: 26px; display: grid; place-items: center; border: none; background: none;
  border-radius: 4px; color: var(--d2-text-muted); transition: all .15s;
}
/* ativo = sem bloco branco; só destaca pelas LINHAS brancas/mais fortes + fundo bem sutil */
.d2-density-btn.active { background: var(--d2-bg-hover); color: var(--d2-text); box-shadow: none; }
.d2-density-btn.active svg { stroke-width: 2.7; }
.d2-density-btn:hover { color: var(--d2-text); }
.d2-density-btn svg { width: 14px; height: 14px; }

.d2-search {
  display: flex; align-items: center; gap: 8px; background: var(--d2-bg-elevated);
  border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 6px 10px; width: 260px;
  transition: border-color .15s, box-shadow .15s;
}
.d2-search:focus-within { border-color: var(--d2-brand); box-shadow: 0 0 0 3px rgba(16,185,129,.12); }
.d2-search input { border: none; outline: none; background: transparent; color: var(--d2-text); font-size: 13px; width: 100%; }
.d2-search input::placeholder { color: var(--d2-text-faint); }
.d2-search svg { width: 14px; height: 14px; color: var(--d2-text-faint); flex-shrink: 0; }

.d2-btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 13px; font-weight: 500;
  border-radius: var(--d2-radius-md); background: var(--d2-bg-elevated); border: 1px solid var(--d2-border);
  color: var(--d2-text); transition: all .15s;
}
.d2-btn:hover { background: var(--d2-bg-hover); border-color: var(--d2-border-strong); }
.d2-btn svg { width: 14px; height: 14px; }
.d2-btn-primary { background: var(--d2-brand); color: #052e1f; font-weight: 600; border-color: var(--d2-brand); }
.d2-btn-primary:hover { background: var(--d2-brand-dim); border-color: var(--d2-brand-dim); color: #052e1f; }
/* WhatsApp "Adicionar" (RaviContatos) dentro dos modais do d2: alinha ao verde da
   marca com texto escuro legível, sem alterar o componente global. */
.d2-modal .flc-add-btn { background: var(--d2-brand); color: #052e1f; }
.d2-modal .flc-add-btn:hover { background: var(--d2-brand-dim); }
.d2-btn-dark { background: var(--d2-text); color: var(--d2-bg-elevated); border-color: var(--d2-text); }
.d2-btn-dark:hover { background: var(--d2-text-muted); border-color: var(--d2-text-muted); }

/* dropdown do "Adicionar" */
.d2-add-wrap { position: relative; }
.d2-add-dd { position: absolute; right: 0; top: calc(100% + 4px); min-width: 200px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); box-shadow: var(--d2-shadow-md); padding: 4px; z-index: 40; display: none; }
.d2-add-wrap.open .d2-add-dd { display: block; }
.d2-add-dd a { display: block; padding: 8px 11px; font-size: 13px; color: var(--d2-text); text-decoration: none; border-radius: 4px; }
.d2-add-dd a:hover { background: var(--d2-bg-hover); }

/* ---------- server node ---------- */
.d2-server-node { margin-bottom: 24px; animation: d2-fade .25s ease-out backwards; }
.d2-server-header {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  background: var(--d2-bg-elevated); border: 1px solid var(--d2-border);
  border-radius: var(--d2-radius-lg); margin-bottom: 12px; box-shadow: var(--d2-shadow-sm);
}
.d2-server-icon { width: 32px; height: 32px; border-radius: var(--d2-radius-md); display: grid; place-items: center; background: var(--d2-bg-subtle); color: var(--d2-text-muted); flex-shrink: 0; }
.d2-server-icon svg { width: 16px; height: 16px; }
.d2-server-icon.local  { background: rgba(16,185,129,.12); color: var(--d2-st-6); }
.d2-server-icon.remote { background: rgba(59,130,246,.12); color: #3b82f6; }
.d2-server-icon.offline { background: rgba(106,102,102,.15); color: var(--d2-st-1); }

.d2-server-info { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.d2-server-name { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; }
.d2-dot-sep { color: var(--d2-text-faint); font-weight: 400; }
.d2-server-meta { font-size: 11.5px; color: var(--d2-text-muted); font-family: var(--d2-font-mono); margin-top: 1px; }
.d2-server-meta .sep { margin: 0 6px; color: var(--d2-text-faint); }

.d2-tag { font-size: 9.5px; font-weight: 600; padding: 2px 6px; border-radius: 3px; letter-spacing: .06em; text-transform: uppercase; }
.d2-tag-local  { background: rgba(16,185,129,.12); color: var(--d2-st-6); }
.d2-tag-remote { background: rgba(59,130,246,.12); color: #3b82f6; }
.d2-tag-off    { background: rgba(106,102,102,.18); color: var(--d2-st-1); }

.d2-latency { display: inline-flex; align-items: center; gap: 4px; font-family: var(--d2-font-mono); font-size: 11px; color: var(--d2-st-6); padding: 2px 6px; background: rgba(16,185,129,.1); border-radius: 3px; }
.d2-latency.off { color: var(--d2-st-1); background: rgba(106,102,102,.12); }
.d2-latency .pdot { width: 6px; height: 6px; border-radius: 50%; background: var(--d2-st-6); animation: d2-pulse 2s ease-in-out infinite; }
.d2-latency.off .pdot { background: var(--d2-st-1); animation: none; }

/* contadores de status */
.d2-counters { display: flex; gap: 3px; align-items: center; flex-shrink: 0; }
.d2-counter { display: inline-flex; align-items: center; padding: 3px 8px; border-radius: var(--d2-radius-sm); font-size: 11.5px; font-weight: 600; font-family: var(--d2-font-mono); color: #fff; min-width: 26px; justify-content: center; cursor: default; }
.d2-counter.s1 { background: var(--d2-st-1); }
.d2-counter.s2 { background: var(--d2-st-2); }
.d2-counter.s3 { background: var(--d2-st-3); }
.d2-counter.s4 { background: var(--d2-st-4); }
.d2-counter.s5 { background: var(--d2-st-5); }
/* verde do contador um pouco mais fundo que o --d2-st-6 (#00c95c) só no FUNDO,
   para o texto branco ficar legível; o verde de status em texto/cards continua o mesmo */
.d2-counter.s6 { background: #00a34a; }
.d2-counter[data-st] { cursor: pointer; }
.d2-counter[data-st]:hover { filter: brightness(1.12); }
.d2-counter.active { box-shadow: 0 0 0 2px var(--d2-bg-elevated), 0 0 0 4px currentColor; }

/* tag de filtro de status ativo */
.d2-filter-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: 999px; padding: 5px 6px 5px 12px; font-size: 12.5px; color: var(--d2-text); margin-bottom: 12px; }
.d2-filter-chip .d2-counter { min-width: auto; padding: 0; background: none !important; color: inherit; }
.d2-chip-x { width: 22px; height: 22px; border: none; background: var(--d2-bg-subtle); border-radius: 50%; color: var(--d2-text-muted); font-size: 16px; line-height: 1; cursor: pointer; }
.d2-chip-x:hover { background: var(--d2-bg-hover); color: var(--d2-text); }

/* ---------- grupo ---------- */
.d2-group { margin-left: 16px; margin-bottom: 12px; position: relative; }
.d2-group-header { display: flex; align-items: center; gap: 8px; padding: var(--d2-group-pad); cursor: pointer; border-radius: var(--d2-radius-md); transition: background-color .15s; user-select: none; }
.d2-group-header:hover { background: var(--d2-bg-hover); }
.d2-chevron { width: 14px; height: 14px; color: var(--d2-text-muted); transition: transform .2s; flex-shrink: 0; }
.d2-group.collapsed > .d2-group-header .d2-chevron { transform: rotate(-90deg); }
.d2-group-icon { width: 18px; height: 18px; color: var(--d2-text-muted); flex-shrink: 0; }
.d2-group-name { font-size: var(--d2-group-name-fs); font-weight: 600; }
.d2-group-children { display: flex; flex-direction: column; gap: var(--d2-row-pad); margin-left: 12px; padding-left: var(--d2-group-children-pad); border-left: 1px dashed var(--d2-tree-line); margin-top: 4px; }
.d2-group.collapsed > .d2-group-children { display: none; }
.d2-group-empty { font-size: 12.5px; color: var(--d2-text-faint); font-style: italic; padding: 8px 4px; }

/* ---------- device ---------- */
.d2-device { display: grid; grid-template-columns: var(--d2-device-col) 1fr; gap: 12px; align-items: start; padding: var(--d2-row-pad); border-radius: var(--d2-radius-md); transition: background-color .15s; }
.d2-device:hover { background: var(--d2-bg-elevated); }
.d2-device-info { display: flex; align-items: center; gap: 8px; padding: var(--d2-dev-pad-y) var(--d2-dev-pad-x); background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); min-height: var(--d2-dev-min-h); cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.d2-device-info:hover { border-color: var(--d2-border-strong); box-shadow: var(--d2-shadow-sm); }
.d2-vendor { width: var(--d2-vendor-size); height: var(--d2-vendor-size); border-radius: 4px; display: grid; place-items: center; flex-shrink: 0; font-size: var(--d2-vendor-fs); font-weight: 700; color: #fff; background: var(--d2-text-muted); overflow: hidden; }
.d2-vendor img { width: 100%; height: 100%; object-fit: contain; }
.d2-device-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.d2-device-name { font-size: var(--d2-name-fs); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.d2-device-ip { font-size: var(--d2-ip-fs); font-family: var(--d2-font-mono); color: var(--d2-text-muted); margin-top: 1px; }

/* ---------- sensores ---------- */
.d2-sensors { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--d2-sensor-min-w), 1fr)); gap: var(--d2-gap); }
.d2-sensor { display: flex; align-items: stretch; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); overflow: hidden; min-height: var(--d2-sensor-min-h); cursor: pointer; transition: border-color .15s, box-shadow .15s, transform .1s; }
.d2-sensor:hover { border-color: var(--d2-border-strong); box-shadow: var(--d2-shadow-sm); }
.d2-sensor:active { transform: translateY(1px); }
/* barra de status (esquerda) desenhada via ::before: sem nó DOM por sensor */
.d2-sensor::before { content: ""; width: var(--d2-bar-w); flex-shrink: 0; align-self: stretch; }
.d2-sensor-content { flex: 1; padding: var(--d2-sensor-pad-y) var(--d2-sensor-pad-x); display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.d2-sensor-status { display: flex; align-items: center; gap: 5px; font-size: var(--d2-status-fs); font-weight: 600; }
.d2-sensor-status .ind { width: var(--d2-status-ind); height: var(--d2-status-ind); border-radius: 50%; flex-shrink: 0; }
.d2-sensor-name { font-size: var(--d2-sensor-name-fs); color: var(--d2-text-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: var(--d2-font-mono); }

.d2-sensor.s1::before { background: var(--d2-st-1); } .d2-sensor.s1 .d2-sensor-status, .d2-sensor.s1 .d2-sensor-status .ind { color: var(--d2-st-1); background: none; } .d2-sensor.s1 .d2-sensor-status .ind { background: var(--d2-st-1); }
.d2-sensor.s2::before { background: var(--d2-st-2); } .d2-sensor.s2 .d2-sensor-status { color: var(--d2-st-2); } .d2-sensor.s2 .d2-sensor-status .ind { background: var(--d2-st-2); }
.d2-sensor.s3::before { background: var(--d2-st-3); } .d2-sensor.s3 .d2-sensor-status { color: var(--d2-st-3); } .d2-sensor.s3 .d2-sensor-status .ind { background: var(--d2-st-3); }
.d2-sensor.s4::before { background: var(--d2-st-4); } .d2-sensor.s4 .d2-sensor-status { color: var(--d2-st-4); } .d2-sensor.s4 .d2-sensor-status .ind { background: var(--d2-st-4); animation: d2-pulse 1.5s ease-in-out infinite; }
.d2-sensor.s5::before { background: var(--d2-st-5); } .d2-sensor.s5 .d2-sensor-status { color: var(--d2-text-faint); } .d2-sensor.s5 .d2-sensor-status .ind { background: var(--d2-st-5); }
.d2-sensor.s6::before { background: var(--d2-st-6); } .d2-sensor.s6 .d2-sensor-status { color: var(--d2-st-6); } .d2-sensor.s6 .d2-sensor-status .ind { background: var(--d2-st-6); }

/* card "+ Novo sensor" (igual mockup) */
.d2-sensor-add { display: flex; align-items: center; justify-content: center; gap: 6px; background: transparent; border: 1px dashed var(--d2-border-strong); border-radius: var(--d2-radius-md); min-height: var(--d2-sensor-min-h); color: var(--d2-text-faint); font-size: var(--d2-status-fs); font-weight: 500; cursor: pointer; transition: all .15s; font-family: var(--d2-font-sans); }
.d2-sensor-add:hover { border-color: var(--d2-brand); color: var(--d2-brand); background: rgba(16,185,129,.04); }
.d2-sensor-add svg { width: 13px; height: 13px; }

/* ---------- grupos de sensores (dentro de um dispositivo) ---------- */
/* container da coluna 2 do device quando há grupos: empilha lista solta + blocos */
.d2-sensors-wrap { display: flex; flex-direction: column; gap: var(--d2-row-pad); min-width: 0; }
.d2-sgroup { border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); background: var(--d2-bg-subtle); overflow: hidden; }
.d2-sgroup-header { display: flex; align-items: center; gap: 8px; padding: 6px 10px; cursor: pointer; user-select: none; transition: background-color .15s; }
.d2-sgroup-header:hover { background: var(--d2-bg-hover); }
.d2-sgroup-header .d2-chevron { width: 13px; height: 13px; color: var(--d2-text-muted); transition: transform .2s; flex-shrink: 0; }
.d2-sgroup.collapsed > .d2-sgroup-header .d2-chevron { transform: rotate(-90deg); }
.d2-sgroup-dot { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
.d2-sgroup-name { font-size: var(--d2-name-fs); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.d2-sgroup-count { font-size: 11px; font-weight: 600; font-family: var(--d2-font-mono); color: var(--d2-text-muted); background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: 10px; padding: 1px 7px; flex-shrink: 0; }
.d2-sgroup-header .d2-counters { margin-left: auto; }
.d2-sgroup-header .d2-counter { min-width: 22px; padding: 2px 6px; font-size: 11px; cursor: default; }
.d2-sgroup-body { padding: var(--d2-row-pad) 10px 10px; }
.d2-sgroup.collapsed > .d2-sgroup-body { display: none; }

/* device sem sensores */
.d2-no-sensors { display: flex; align-items: center; color: var(--d2-text-faint); font-size: var(--d2-status-fs); font-style: italic; padding-left: 4px; }

/* ---------- add remote node card ---------- */

/* ---------- empty / waiting states ---------- */
.d2-waiting { margin: 4px 16px 0; padding: 18px; border: 1px dashed var(--d2-border-strong); border-radius: var(--d2-radius-md); display: flex; align-items: center; gap: 12px; color: var(--d2-text-muted); font-size: 13px; background: var(--d2-bg-subtle); }
.d2-waiting .spin { width: 16px; height: 16px; border: 2px solid var(--d2-border-strong); border-top-color: var(--d2-brand); border-radius: 50%; animation: d2-spin .9s linear infinite; flex-shrink: 0; }
.d2-empty { text-align: center; padding: 60px 20px; color: var(--d2-text-faint); }
.d2-empty .ic { font-size: 42px; margin-bottom: 14px; color: var(--d2-text-faint); }

/* gear menu na sonda remota */
.d2-server-menu { position: relative; flex-shrink: 0; }
.d2-server-menu-btn { width: 30px; height: 30px; border: none; background: none; border-radius: var(--d2-radius-md); color: var(--d2-text-faint); display: grid; place-items: center; }
.d2-server-menu-btn:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-server-menu-list { position: absolute; right: 0; top: 34px; min-width: 180px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); box-shadow: var(--d2-shadow-md); padding: 4px; z-index: 30; display: none; }
.d2-server-menu.open .d2-server-menu-list { display: block; }
.d2-server-menu-list a { display: block; padding: 8px 10px; font-size: 13px; color: var(--d2-text); text-decoration: none; border-radius: 4px; }
.d2-server-menu-list a:hover { background: var(--d2-bg-hover); }
.d2-server-menu-list a.danger { color: var(--d2-text); }

/* ---------- botão de menu (⋮) por nó + menu flutuante ---------- */
.d2-menu-btn { width: 24px; height: 24px; border: none; background: none; border-radius: 6px; color: var(--d2-text-faint); display: grid; place-items: center; cursor: pointer; flex-shrink: 0; opacity: 0; transition: opacity .12s, background .12s, color .12s; }
.d2-menu-btn:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-menu-btn::before { content: "\22EE"; font-size: 18px; line-height: 1; font-weight: 700; }
.d2-menu-btn svg { width: 16px; height: 16px; }
.d2-menu-btn.always { opacity: 1; }
.d2-group-header { position: relative; }
.d2-group-header .d2-menu-btn { margin-left: auto; }
.d2-device-info .d2-menu-btn { margin-left: auto; }
.d2-group-header:hover .d2-menu-btn,
.d2-device:hover .d2-menu-btn,
.d2-sensor:hover .d2-menu-btn { opacity: 1; }
.d2-sensor { position: relative; }
.d2-sensor .d2-menu-btn { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; background: var(--d2-bg-elevated); }
.d2-sensor .d2-menu-btn::before { font-size: 16px; }
.d2-sensor .d2-menu-btn svg { width: 14px; height: 14px; }

.d2-floatmenu { position: fixed; min-width: 184px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); box-shadow: var(--d2-shadow-md); padding: 4px; z-index: 100040; }
.d2-floatmenu a { display: block; padding: 8px 11px; font-size: 13px; color: var(--d2-text); text-decoration: none; border-radius: 4px; cursor: pointer; }
.d2-floatmenu a:hover { background: var(--d2-bg-hover); }
.d2-floatmenu a.danger { color: var(--d2-text); }

.d2-grp-sensores { max-height: 240px; overflow-y: auto; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 8px 10px; }

/* ---------- Condições de alerta (nativo) ---------- */
.d2-cond-toggle { display: flex; align-items: center; gap: 10px; }
.d2-badge-on { font-size: 12px; font-weight: 600; color: var(--d2-brand); }
.d2-cond { border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 10px 12px; margin-top: 10px; }
.d2-cond-head { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; color: var(--d2-text); margin-bottom: 6px; }
.d2-cond-acts { display: flex; gap: 4px; }
.d2-iconbtn { width: 24px; height: 24px; border: 1px solid var(--d2-border); background: var(--d2-bg-elevated); border-radius: 6px; color: var(--d2-text-muted); cursor: pointer; font-size: 13px; line-height: 1; }
.d2-iconbtn:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-iconbtn.danger:hover { color: var(--d2-st-4); border-color: var(--d2-st-4); }
.d2-cond-rule { font-size: 12.5px; color: var(--d2-text-muted); padding: 4px 0; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.d2-cond-rule .d2-counter { min-width: auto; padding: 1px 7px; }
.d2-cond-rule-acts { margin-left: auto; display: flex; gap: 4px; }
.d2-cond-rule-acts .d2-iconbtn { width: 22px; height: 22px; font-size: 12px; }
.d2-cond-when { font-weight: 600; color: var(--d2-text); }

/* ---------- SNMP walk (F4b) ---------- */
.d2-walk-progress { display: flex; align-items: center; gap: 10px; padding: 24px; color: var(--d2-text-muted); font-size: 14px; }
.d2-walk-table { max-height: 56vh; overflow: auto; font-size: 12.5px; }
.d2-walk-table table { border-collapse: collapse; width: 100%; }
.d2-walk-table td, .d2-walk-table th { padding: 5px 8px; border-bottom: 1px solid var(--d2-border); color: var(--d2-text); text-align: left; }
.d2-walk-table tr:hover td { background: var(--d2-bg-hover); }
.d2-walk-table input[type="text"] { width: 100%; padding: 5px 8px; border: 1px solid var(--d2-border); border-radius: 5px; background: var(--d2-bg-elevated); color: var(--d2-text); font-size: 12.5px; }
.d2-walk-table input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }
.d2-walk-table img { display: none; }
.d2-walk-table .imputPesqOLT { margin-bottom: 10px; max-width: 260px; }

/* ---------- catálogo de sensores (F4) ---------- */
.d2-cat-wrap { display: grid; grid-template-columns: 210px 1fr; gap: 16px; min-height: 340px; }
.d2-cat-list { display: flex; flex-direction: column; gap: 2px; max-height: 58vh; overflow-y: auto; border-right: 1px solid var(--d2-border); padding-right: 10px; }
.d2-cat { padding: 8px 11px; font-size: 13px; color: var(--d2-text-muted); border-radius: var(--d2-radius-md); text-decoration: none; transition: background .12s, color .12s; line-height: 1.35; }
.d2-cat:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-cat.active { background: rgba(16,185,129,.12); color: var(--d2-brand); font-weight: 600; }
.d2-cat-main { min-width: 0; display: flex; flex-direction: column; }
.d2-model-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 12px; max-height: 62vh; overflow-y: auto; padding: 2px; align-content: start; }
.d2-model-card { display: flex; flex-direction: row; align-items: stretch; gap: 12px; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 12px 14px; cursor: pointer; background: var(--d2-bg-elevated); transition: border-color .12s, box-shadow .12s, transform .1s; min-width: 0; }
.d2-model-card:hover { border-color: var(--d2-brand); box-shadow: 0 4px 14px rgba(16,185,129,.12); transform: translateY(-1px); }
.d2-model-card { position: relative; }
.d2-model-card.sel { border-color: var(--d2-brand); box-shadow: 0 0 0 2px rgba(16,185,129,.25); background: rgba(16,185,129,.06); }
.d2-model-check { position: absolute; top: 8px; right: 8px; width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--d2-border-strong); background: var(--d2-bg-elevated); display: grid; place-items: center; color: #fff; transition: all .12s; z-index: 2; }
.d2-model-check svg { width: 12px; height: 12px; opacity: 0; transition: opacity .1s; }
.d2-model-card.sel .d2-model-check { background: var(--d2-brand); border-color: var(--d2-brand); }
.d2-model-card.sel .d2-model-check svg { opacity: 1; }
.d2-model-logo { width: 46px; flex-shrink: 0; display: grid; place-items: center; background: #fff; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 5px; align-self: flex-start; }
.d2-model-logo img { max-width: 100%; max-height: 36px; object-fit: contain; }
.d2-model-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.d2-model-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-right: 24px; }
.d2-model-name { font-size: 14px; font-weight: 600; color: var(--d2-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.d2-model-desc { font-size: 12px; color: var(--d2-text-muted); line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.9em; }
.d2-model-foot { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: auto; }
.d2-model-tag { font-size: 10.5px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px; background: var(--d2-bg-subtle); color: var(--d2-text-muted); border: 1px solid var(--d2-border); }
.d2-model-tag.walk { background: rgba(59,130,246,.12); color: #3b82f6; border-color: rgba(59,130,246,.3); }
.d2-model-badge { font-size: 10.5px; font-family: var(--d2-font-mono); color: var(--d2-text-faint); background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-sm); padding: 2px 6px; }
.d2-impact { display: inline-flex; gap: 2px; flex-shrink: 0; align-items: center; }
.d2-impact i { width: 4px; height: 11px; border-radius: 1px; background: var(--d2-border-strong); }
.d2-impact i.on { background: var(--d2-brand); }
.d2-cfg-pane { max-width: 520px; margin: 0 auto; padding: 6px 0; }

/* config de Ping com N alvos: linha = (nome+ip) + botão remover */
.d2-ping-row { display: flex; align-items: flex-start; gap: 10px; }
.d2-ping-row .d2-field-row { flex: 1; }
.d2-ping-del { flex: 0 0 auto; margin-top: 26px; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--d2-border); border-radius: 8px; background: transparent; color: var(--d2-text-muted); cursor: pointer; }
.d2-ping-del:hover { border-color: var(--d2-st-4); color: var(--d2-st-4); }
.d2-ping-del svg { width: 16px; height: 16px; }
.d2-ping-add { margin-top: 4px; padding: 8px 14px; border: 1px dashed var(--d2-border-strong); border-radius: 8px; background: transparent; color: var(--d2-brand); font-weight: 600; cursor: pointer; }
.d2-ping-add:hover { background: var(--d2-bg-subtle); }

/* catálogo de Adicionar sensor: grade de logos das categorias (estilo legado) */
/* busca bem mais alta no catálogo de sensores: fundo transparente (sem faixa tom-sobre-tom no dark) */
.d2-search-tall { padding: 16px 16px; gap: 11px; background: transparent; }
.d2-search-tall input { font-size: 15px; }
.d2-search-tall svg { width: 18px; height: 18px; }
/* o CSS global (dark-theme.css) pinta input[type=text] com #1e2130 e dá glow AZUL no :focus, e
   carrega DEPOIS deste arquivo: então uso o ID do input (especificidade máxima) p/ vencer.
   O input fica transparente e sem anel próprio (o anel verde fica no container .d2-search). */
html[data-theme="dark"] input#d2s-search,
html[data-theme="dark"] input#d2s-search:focus,
html[data-theme="dark"] input#d2-search-input,
html[data-theme="dark"] input#d2-search-input:focus { background-color: transparent !important; border: none !important; box-shadow: none !important; }

/* catálogo: só os logos em tiles cinza compactos; nome aparece em tooltip no hover (como no original) */
.d2-catgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; padding: 2px 2px 6px; }
.d2-cattile { position: relative; display: grid; place-items: center; height: 64px; padding: 3px 5px; background: #cdd2d9; border: 1px solid #b8bec8; border-radius: var(--d2-radius-md); cursor: pointer; transition: border-color .12s, box-shadow .12s, transform .1s; overflow: hidden; }
.d2-cattile:hover { border-color: var(--d2-brand); box-shadow: 0 3px 12px rgba(0,0,0,.18); transform: translateY(-1px); z-index: 5; }
.d2-cattile-img { display: grid; place-items: center; width: 100%; height: 100%; }
.d2-cattile-img img { max-width: 100%; max-height: 58px; object-fit: contain; }
/* tooltip premium do nome da categoria: bolha flutuante (no body, sem ser
   cortada pelo overflow:hidden do tile). Preenchida por sensor.js (bindTips). */
.d2-floattip {
  position: fixed; transform: translate(-50%, -100%); pointer-events: none; z-index: 100100;
  background: #14181f; color: #f3f4f6; font-size: 12px; font-weight: 600;
  white-space: nowrap; padding: 6px 11px; border-radius: 7px; border: 1px solid rgba(255,255,255,.08);
  box-shadow: 0 8px 24px rgba(0,0,0,.45); opacity: 0; transition: opacity .12s ease, transform .12s ease; letter-spacing: .01em;
}
.d2-floattip::after {
  content: ''; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #14181f;
}
.d2-floattip.show { opacity: 1; transform: translate(-50%, calc(-100% - 2px)); }
/* alvo colado no topo: a bolha abre abaixo dele, com a seta virada para cima */
.d2-floattip.abaixo { transform: translate(-50%, 0); }
.d2-floattip.abaixo::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: #14181f; }
.d2-floattip.abaixo.show { transform: translate(-50%, 2px); }

/* tooltip da mensagem do problema (sensor em alerta/crítico): bolha única no body,
   preenchida por tree.js via delegação. Cabeçalho com a cor do status + corpo multi-linha.
   Segue o tema: claro no light (card branco), escuro no dark (--tip-bg alimenta a seta). */
.d2-sensortip {
  --tip-bg: var(--d2-bg-elevated);
  --tip-divider: rgba(0,0,0,.09);
  position: fixed; transform: translate(-50%, -100%); pointer-events: none; z-index: 100100;
  max-width: 340px; min-width: 160px;
  background: var(--tip-bg); color: var(--d2-text); border: 1px solid var(--d2-border-strong);
  border-radius: 9px; box-shadow: 0 10px 30px rgba(0,0,0,.2);
  opacity: 0; transition: opacity .12s ease, transform .12s ease;
}
html[data-theme="dark"] .d2-sensortip {
  --tip-bg: #14181f;
  --tip-divider: rgba(255,255,255,.1);
  color: #e5e7eb; border-color: rgba(255,255,255,.09); box-shadow: 0 10px 30px rgba(0,0,0,.5);
}
.d2-sensortip.show { opacity: 1; transform: translate(-50%, calc(-100% - 3px)); }
.d2-sensortip.below { transform: translate(-50%, 0); }
.d2-sensortip.below.show { transform: translate(-50%, 3px); }
.d2-sensortip-head {
  display: flex; align-items: center; gap: 7px; padding: 7px 12px 6px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  border-bottom: 1px solid var(--tip-divider);
}
.d2-sensortip-head .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.d2-sensortip.s2 .d2-sensortip-head { color: var(--d2-st-2); }
.d2-sensortip.s2 .d2-sensortip-head .dot { background: var(--d2-st-2); box-shadow: 0 0 8px var(--d2-st-2); }
.d2-sensortip.s3 .d2-sensortip-head { color: var(--d2-st-3); }
.d2-sensortip.s3 .d2-sensortip-head .dot { background: var(--d2-st-3); box-shadow: 0 0 8px var(--d2-st-3); }
.d2-sensortip.s4 .d2-sensortip-head { color: var(--d2-st-4); }
.d2-sensortip.s4 .d2-sensortip-head .dot { background: var(--d2-st-4); box-shadow: 0 0 8px var(--d2-st-4); }
.d2-sensortip-body { padding: 8px 12px 9px; font-size: 12px; line-height: 1.45; }
.d2-sensortip-line + .d2-sensortip-line { margin-top: 7px; padding-top: 7px; border-top: 1px dashed var(--tip-divider); }
/* seta: segue o centro do sensor via --tip-arrow-x (a bolha pode estar clampada na borda) */
.d2-sensortip::after {
  content: ''; position: absolute; left: var(--tip-arrow-x, 50%); top: 100%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--tip-bg);
}
.d2-sensortip.below::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--tip-bg); }
.d2-cat-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.d2-cat-title { font-size: 14px; font-weight: 700; color: var(--d2-text); }
.d2-back { display: inline-flex; align-items: center; font-size: 13px; font-weight: 600; color: var(--d2-brand); background: none; border: none; cursor: pointer; padding: 4px 6px; border-radius: var(--d2-radius-sm); }
.d2-back:hover { background: var(--d2-bg-hover); }

/* ---------- Mapa de Calor (F13) ---------- */
/* ---- Mapa de Calor TEMPORAL (matriz dispositivo × tempo) ---- */
.d2-heat-controls { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 14px; }
.d2-heat-legend { display: flex; flex-wrap: wrap; gap: 14px; }
.d2-heatmap { overflow-x: auto; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); }
.d2-heatmap table { border-collapse: collapse; width: 100%; }
.d2-heatmap th, .d2-heatmap td { padding: 0; }
.d2-hm-corner { width: 200px; min-width: 200px; position: sticky; left: 0; z-index: 2; background: var(--d2-bg-elevated); }
.d2-hm-h { height: 26px; vertical-align: bottom; padding-bottom: 4px; }
.d2-hm-h span { display: inline-block; font-size: 10px; color: var(--d2-text-faint); font-family: var(--d2-font-mono); white-space: nowrap; transform: translateX(-2px); }
.d2-hm-dev { width: 200px; min-width: 200px; max-width: 200px; position: sticky; left: 0; z-index: 1; background: var(--d2-bg-elevated); padding: 0 12px !important; height: 24px; font-size: 12.5px; font-weight: 600; color: var(--d2-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; border-right: 1px solid var(--d2-border); border-top: 1px solid var(--d2-border); }
.d2-hm-dev:hover { color: var(--d2-brand); }
.d2-hm-c { height: 24px; min-width: 16px; border-top: 1px solid var(--d2-bg-elevated); border-left: 1px solid var(--d2-bg-elevated); transition: outline .1s; }
.d2-hm-c:not(.empty) { cursor: default; }
.d2-hm-c:not(.empty):hover { outline: 2px solid var(--d2-text); outline-offset: -2px; }
.d2-hm-c.empty { background: var(--d2-bg-subtle); }

/* ---------- 3D (F11) ---------- */
.d2-3d { height: calc(100vh - 200px); min-height: 420px; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-lg); overflow: hidden; background: var(--d2-bg-subtle); }

/* ---------- GEO (F12) ---------- */
.d2-geo-map { height: calc(100vh - 200px); min-height: 420px; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-lg); overflow: hidden; }
.leaflet-tooltip { font-family: var(--d2-font-sans); }

/* ---------- detalhe do sensor (F5) ---------- */
.d2-chart { width: 100%; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 6px; }
.d2-chart svg { width: 100%; height: 240px; display: block; }
/* container do gráfico interativo do detalhe (Highcharts Stock): mesma moldura
   do .d2-chart, mas sem forçar tamanho no <svg> (o Highcharts governa o dele) */
.d2-chart-hc { width: 100%; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 6px; }
.d2-chart-hc .highcharts-background { fill: transparent; }
.d2-axis { stroke: var(--d2-border-strong); stroke-width: 1; }
.d2-axis-lbl { fill: var(--d2-text-faint); font-size: 10px; font-family: var(--d2-font-mono); }
.d2-legend { display: flex; flex-wrap: wrap; gap: 12px; margin: 10px 0 14px; }
.d2-leg { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--d2-text-muted); }
.d2-leg i { width: 12px; height: 3px; border-radius: 2px; display: inline-block; }
.d2-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; }
.d2-stat { border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 10px 12px; }
.d2-stat-t { font-size: 12px; font-weight: 700; color: var(--d2-text); margin-bottom: 6px; }
.d2-stat-row { display: flex; justify-content: space-between; font-size: 12px; color: var(--d2-text-muted); margin-top: 2px; }
.d2-stat-row b { color: var(--d2-text); font-family: var(--d2-font-mono); }
/* data/hora em que o pico Mín/Máx ocorreu (alinhada sob o valor) */
.d2-stat-when { font-size: 10.5px; color: var(--d2-text-faint); font-family: var(--d2-font-mono); text-align: right; margin: -1px 0 2px; }

/* período personalizado (detalhe do sensor): gatilho + seletorPeriodo (atalhos + calendário duplo) */
.d2-range-bar { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; position: relative; }
.d2-dr-trigger { display: inline-flex; align-items: center; gap: 8px; font-family: var(--d2-font-mono); font-size: 12.5px; }
.d2-dr-caret { font-size: 10px; opacity: .7; }
.d2-dr-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 80; display: flex;
  background: var(--d2-bg-elevated); border: 1px solid var(--d2-border-strong);
  border-radius: var(--d2-radius-md); box-shadow: 0 14px 38px rgba(0, 0, 0, .35); overflow: hidden;
}
.d2-dr-presets { display: flex; flex-direction: column; gap: 2px; padding: 10px 8px; border-right: 1px solid var(--d2-border); min-width: 138px; }
.d2-dr-preset { text-align: left; background: none; border: 0; color: var(--d2-text-muted); font-size: 12.5px; padding: 6px 10px; border-radius: 6px; cursor: pointer; font-family: inherit; white-space: nowrap; }
.d2-dr-preset:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-dr-cal { padding: 10px 12px; }
.d2-dr-months { display: flex; gap: 18px; }
.d2-dr-mtitle { position: relative; display: flex; align-items: center; justify-content: center; height: 26px; font-size: 12.5px; font-weight: 700; color: var(--d2-text); margin-bottom: 6px; }
.d2-dr-nav { position: absolute; top: 0; width: 26px; height: 26px; border: 1px solid var(--d2-border); background: var(--d2-bg-subtle); border-radius: 6px; color: var(--d2-text-muted); cursor: pointer; font-size: 15px; line-height: 1; padding: 0; }
.d2-dr-nav:hover:not(:disabled) { background: var(--d2-bg-hover); color: var(--d2-text); }
.d2-dr-nav:disabled { opacity: .3; cursor: default; }
.d2-dr-nav.prev { left: 0; }
.d2-dr-nav.next { right: 0; }
.d2-dr-nav.movel { display: none; }
.d2-dr-grid { display: grid; grid-template-columns: repeat(7, 30px); gap: 1px; }
.d2-dr-wd { font-size: 10.5px; color: var(--d2-text-faint); text-align: center; padding: 3px 0; text-transform: uppercase; }
.d2-dr-day { height: 28px; border: 0; background: none; color: var(--d2-text); font-size: 12px; border-radius: 6px; cursor: pointer; font-family: var(--d2-font-mono); padding: 0; }
.d2-dr-day:hover:not(:disabled) { background: var(--d2-bg-hover); }
.d2-dr-day:disabled { color: var(--d2-text-faint); opacity: .35; cursor: default; }
.d2-dr-day.in { background: rgba(16, 185, 129, .16); border-radius: 0; }
.d2-dr-day.sel { background: var(--d2-brand); color: #052e1f; font-weight: 700; }
.d2-dr-foot { display: flex; align-items: center; gap: 6px; margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--d2-border); flex-wrap: wrap; }
.d2-dr-foot .d2-btn { padding: 5px 13px; font-size: 12.5px; }
.d2-dr-sel { font-size: 12px; color: var(--d2-text-muted); font-family: var(--d2-font-mono); margin-right: auto; padding-right: 8px; }
.d2-dr-time { width: auto; min-width: 78px; max-width: 106px; padding: 4px 6px; font-size: 12px; border: 1px solid var(--d2-border); border-radius: 6px; background: var(--d2-bg-elevated); color: var(--d2-text); font-family: var(--d2-font-mono); color-scheme: light; }
.d2-dr-time:focus { outline: none; border-color: var(--d2-brand); }
html[data-theme="dark"] .d2-dr-time { color-scheme: dark; }
.d2-dr-hsep { color: var(--d2-text-faint); font-size: 12px; }
.d2-dr-actions { display: flex; gap: 8px; margin-left: 6px; }
@media (max-width: 640px) {
  .d2-dr-panel { flex-direction: column; max-width: min(94vw, 320px); }
  .d2-dr-month.esq { display: none; }   /* no celular, um mês só */
  .d2-dr-nav.movel { display: block; }
  .d2-dr-presets { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--d2-border); min-width: 0; }
}
.d2-range-bar .d2-btn { padding: 6px 14px; }

/* arraste (reordenar) */
.d2-dragging { opacity: .45; }
.d2-device[draggable="true"] .d2-device-info,
.d2-group[draggable="true"] > .d2-group-header { cursor: grab; }
.d2-sensor[draggable="true"] { cursor: grab; }

/* ---------- token / pareamento (modal) ---------- */
.d2-token-box { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.d2-token { flex: 1; font-family: var(--d2-font-mono); font-size: 13px; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 10px 12px; color: var(--d2-text); word-break: break-all; user-select: all; }
.d2-modal-field { width: 100%; padding: 10px 12px; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); background: var(--d2-bg-elevated); color: var(--d2-text); font-size: 14px; margin-top: 8px; }
.d2-modal-field:focus { outline: none; border-color: var(--d2-brand); box-shadow: 0 0 0 3px rgba(16,185,129,.12); }
.d2-modal-hint { font-size: 12.5px; color: var(--d2-text-muted); margin-top: 8px; line-height: 1.5; }
/* meta técnica do sensor (ID · tag · interface): selecionável p/ copiar sem abrir o detalhe */
.d2-dash-meta { font-size: 10.5px; font-family: var(--d2-font-mono); color: var(--d2-text-muted); opacity: .85; margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; user-select: text; cursor: text; }

/* ---------- footer (igual dispositivos) ---------- */
.footer-fixed { position: fixed; bottom: 0; left: 0; right: 0; background: #f8f8f8; padding: 10px 20px; border-top: 1px solid #ddd; display: flex; justify-content: space-between; align-items: center; z-index: 998; font-size: 13px; }
html[data-theme="dark"] .footer-fixed { background: #1a1d27 !important; border-top-color: #2a2e3a !important; color: #6b7280 !important; }
html[data-theme="dark"] .footer-fixed a { color: #6b7280 !important; }
html[data-theme="dark"] .ravi-loader-light { display: none !important; }
html[data-theme="dark"] .ravi-loader-dark { display: inline !important; }

/* ---------- modal próprio (premium) ---------- */
/* o modal é anexado ao <body> (fora de .disp2), então precisa do seu próprio reset de box-sizing
  : senão width:100% + padding (ex.: a busca) estoura para fora da modal */
.d2-ovl, .d2-ovl *, .d2-ovl *::before, .d2-ovl *::after { box-sizing: border-box; }
.d2-ovl { position: fixed; top: 0; right: 0; bottom: 0; left: 0; inset: 0; background: rgba(12,10,9,.55); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); display: flex; align-items: center; justify-content: center; z-index: 100050; opacity: 0; pointer-events: none; transition: opacity .18s ease; padding: 20px; }
.d2-ovl.open { opacity: 1; pointer-events: auto; }
.d2-modal { width: 100%; max-width: 460px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-lg); box-shadow: 0 20px 60px rgba(0,0,0,.35); transform: translateY(8px) scale(.98); transition: transform .18s ease; overflow: hidden; font-family: var(--d2-font-sans); }
.d2-ovl.open .d2-modal { transform: translateY(0) scale(1); }
.d2-modal-head { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border-bottom: 1px solid var(--d2-border); }
.d2-modal-head .ic { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; background: rgba(16,185,129,.12); color: var(--d2-brand); flex-shrink: 0; }
.d2-modal-head .ic svg { width: 18px; height: 18px; }
.d2-modal-title { font-size: 15px; font-weight: 600; color: var(--d2-text); }
.d2-modal-body { padding: 18px; color: var(--d2-text); }
.d2-modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 18px; border-top: 1px solid var(--d2-border); background: var(--d2-bg-subtle); }

/* ---------- toast ---------- */
.d2-toasts { position: fixed; bottom: 56px; right: 18px; display: flex; flex-direction: column; gap: 8px; z-index: 100060; }
.d2-toast { display: flex; align-items: center; gap: 8px; background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-left: 3px solid var(--d2-brand); border-radius: var(--d2-radius-md); box-shadow: var(--d2-shadow-md); padding: 10px 14px; font-size: 13px; color: var(--d2-text); font-family: var(--d2-font-sans); transform: translateX(120%); transition: transform .25s ease; max-width: 320px; }
.d2-toast.show { transform: translateX(0); }
.d2-toast.err { border-left-color: var(--d2-st-4); }
.d2-toast.ok { border-left-color: var(--d2-st-6); }

/* ===========================================================
   DESIGN SYSTEM (F2): modal sizes, close, busy, tabs, campos
   =========================================================== */
.d2-modal.sm { max-width: 420px; }
.d2-modal.md { max-width: 480px; }
.d2-modal.lg { max-width: 720px; }
.d2-modal.xl { max-width: 980px; }
.d2-modal.xxl { max-width: min(1100px, 92vw); }
.d2-modal.full { max-width: min(1500px, 96vw); }
.d2-modal-head { position: relative; }
/* separador visual entre seções dentro de uma modal */
.d2-sep { border: 0; border-top: 1px solid var(--d2-border); margin: 18px 0 14px; }
.d2-sec-title { font-size: 11.5px; font-weight: 700; color: var(--d2-text-muted); text-transform: uppercase; letter-spacing: .04em; margin: 0 0 10px; }
.d2-modal-x { position: absolute; right: 12px; top: 12px; width: 28px; height: 28px; border: none; background: none; color: var(--d2-text-faint); font-size: 22px; line-height: 1; border-radius: 6px; cursor: pointer; }
.d2-modal-x:hover { background: var(--d2-bg-hover); color: var(--d2-text); }
/* corpo rola só na vertical; overflow-x explícito evita barra horizontal espúria
   (com overflow-y:auto e overflow-x:visible, o CSS computa AMBOS como auto) */
.d2-modal-body { max-height: 72vh; overflow-y: auto; overflow-x: hidden; }

/* busy overlay no modal */
.d2-modal { position: relative; }
.d2-modal-busy { position: absolute; top: 0; right: 0; bottom: 0; left: 0; inset: 0; background: rgba(0,0,0,.35); background: color-mix(in srgb, var(--d2-bg-elevated) 70%, transparent); display: none; align-items: center; justify-content: center; border-radius: var(--d2-radius-lg); z-index: 5; }
.d2-modal.busy .d2-modal-busy { display: flex; flex-direction: column; gap: 12px; }
.d2-busy-msg { font-size: 13px; color: var(--d2-text-muted); font-weight: 500; }
.d2-busy-msg:empty { display: none; }
.d2-spin { width: 26px; height: 26px; border: 3px solid var(--d2-border-strong); border-top-color: var(--d2-brand); border-radius: 50%; animation: d2-spin .8s linear infinite; }

.d2-btn-danger { background: var(--d2-st-4); color: #fff; border-color: var(--d2-st-4); }
.d2-btn-danger:hover { background: #b52d2d; border-color: #b52d2d; }
.d2-btn:disabled { opacity: .5; cursor: default; }

.d2-confirm-msg { font-size: 14px; color: var(--d2-text); margin-bottom: 4px; }

/* ---- campos de formulário ---- */
.d2-field { margin-bottom: 14px; }
.d2-field:last-child { margin-bottom: 0; }
.d2-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--d2-text-muted); margin-bottom: 5px; }
.d2-req { color: var(--d2-st-4); }
.d2-field-hint { font-size: 11.5px; color: var(--d2-text-faint); margin-top: 4px; line-height: 1.4; }
.d2-control {
  width: 100%; padding: 9px 11px; font-size: 13.5px; font-family: var(--d2-font-sans);
  border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md);
  background: var(--d2-bg-elevated); color: var(--d2-text); transition: border-color .15s, box-shadow .15s;
}
textarea.d2-control { resize: vertical; min-height: 60px; }
select.d2-control { cursor: pointer; }
.d2-control:focus { outline: none; border-color: var(--d2-brand); box-shadow: 0 0 0 3px rgba(16,185,129,.12); }
.d2-control:disabled { background: var(--d2-bg-subtle); color: var(--d2-text-faint); cursor: not-allowed; }
.d2-control.d2-invalid { border-color: var(--d2-st-4); box-shadow: 0 0 0 3px rgba(210,57,57,.12); }
.d2-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.d2-field-row.c3 { grid-template-columns: 1fr 1fr 1fr; }
/* Nome/IP ficam dentro de #d2f-single; como o último campo do wrapper perde a
   margem (.d2-field:last-child), a linha Grupo/Equipamento colava no IP de cima.
   Recompõe o respiro no próprio wrapper. */
#d2f-single, #d2f-multi-wrap { margin-bottom: 14px; }

/* checkbox custom */
.d2-field-check { margin-bottom: 12px; }
.d2-check { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13.5px; color: var(--d2-text); user-select: none; }
.d2-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.d2-check-box { width: 18px; height: 18px; border: 1px solid var(--d2-border-strong); border-radius: 5px; flex-shrink: 0; position: relative; transition: all .15s; }
.d2-check input:checked + .d2-check-box { background: var(--d2-brand); border-color: var(--d2-brand); }
.d2-check input:checked + .d2-check-box::after { content: ''; position: absolute; left: 5px; top: 1.5px; width: 5px; height: 10px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.d2-check input:focus-visible + .d2-check-box { box-shadow: 0 0 0 3px rgba(16,185,129,.2); }

/* toggle on/off (switch) */
.d2-field-switch { margin-bottom: 12px; }
/* position: relative é OBRIGATÓRIO aqui: o input real é absolute/left:0/top:0 (logo abaixo)
   e, sem um ancestral posicionado, ele ancora no canto superior esquerdo do DOCUMENTO.
   O clique de mouse foca o input e o navegador rola até ele, jogando a tela para o topo , 
   quanto mais para baixo o switch, maior o salto (bronca de 07/08 na aba Rotinas do CPE). */
.d2-switch { display: inline-flex; align-items: center; gap: 11px; cursor: pointer; user-select: none; position: relative; }
/* o dark-theme.css força os checkbox para relative/block/24px; aqui o input do
   switch precisa ocupar ZERO espaço (senão empurra o track). Especificidade alta. */
html[data-theme="dark"] .d2-switch input[type="checkbox"],
.d2-switch input[type="checkbox"], .d2-switch input {
  position: absolute !important; left: 0 !important; top: 0 !important;
  width: 1px !important; height: 1px !important; min-width: 0 !important;
  margin: 0 !important; padding: 0 !important; opacity: 0 !important; display: inline-block !important; appearance: none !important;
}
.d2-switch-track { position: relative; width: 42px; height: 23px; background: var(--d2-border-strong); border-radius: 12px; transition: background .18s ease; flex-shrink: 0; }
.d2-switch-thumb { position: absolute; top: 2px; left: 2px; width: 19px; height: 19px; background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,.35); transition: transform .18s cubic-bezier(.4,0,.2,1); }
.d2-switch input:checked + .d2-switch-track { background: var(--d2-brand); }
.d2-switch input:checked + .d2-switch-track .d2-switch-thumb { transform: translateX(19px); }
.d2-switch input:focus-visible + .d2-switch-track { box-shadow: 0 0 0 3px rgba(16,185,129,.25); }
.d2-switch-label { font-size: 13.5px; font-weight: 600; color: var(--d2-text); }

.d2-link { color: var(--d2-brand); font-size: 12.5px; font-weight: 600; text-decoration: none; }
.d2-link:hover { text-decoration: underline; }

/* flash sutil quando um sensor muda de status (overlay que esvanece: não mexe no layout) */
@keyframes d2-flash-bad { from { box-shadow: inset 0 0 0 200px rgba(210,57,57,.20); } to { box-shadow: inset 0 0 0 200px rgba(210,57,57,0); } }
@keyframes d2-flash-good { from { box-shadow: inset 0 0 0 200px rgba(0,201,92,.20); } to { box-shadow: inset 0 0 0 200px rgba(0,201,92,0); } }
.d2-sensor.d2-flash-bad { animation: d2-flash-bad 1.5s ease-out; }
.d2-sensor.d2-flash-good { animation: d2-flash-good 1.5s ease-out; }

.d2-feat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 16px; margin: 2px 0 14px; }

/* seções de formulário */
.d2-form-section { border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 14px; margin-bottom: 14px; }
.d2-form-section-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--d2-text-faint); margin-bottom: 12px; }

/* ---- abas ---- */
.d2-tabs-head { display: flex; gap: 2px; border-bottom: 1px solid var(--d2-border); margin-bottom: 16px; flex-wrap: wrap; }
.d2-tab { padding: 8px 14px; font-size: 13px; font-weight: 500; color: var(--d2-text-muted); border: none; background: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; transition: color .15s, border-color .15s; }
.d2-tab:hover { color: var(--d2-text); }
.d2-tab.active { color: var(--d2-brand); border-bottom-color: var(--d2-brand); }
.d2-tabpane { display: none; }
.d2-tabpane.active { display: block; animation: d2-fade .2s ease-out; }

@keyframes d2-pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(.9); } }
@keyframes d2-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes d2-spin { to { transform: rotate(360deg); } }

/* ---------------- Terminal SSH ---------------- */
.d2-term-wrap { display: flex; flex-direction: column; gap: 0; }
.d2-term-head { font-family: 'JetBrains Mono', monospace; font-size: 12.5px; color: var(--d2-text-soft); padding: 8px 12px; background: #0b0e14; border: 1px solid #1c2230; border-bottom: none; border-radius: var(--d2-radius-md) var(--d2-radius-md) 0 0; }
.d2-term { background: #0b0e14; border-left: 1px solid #1c2230; border-right: 1px solid #1c2230; height: 360px; padding: 6px 8px; overflow: hidden; }
.d2-term .xterm { height: 100%; }
.d2-term-pre { margin: 0; color: #d6deeb; font-family: 'JetBrains Mono', monospace; font-size: 13px; white-space: pre-wrap; word-break: break-all; height: 100%; overflow-y: auto; }
.d2-term-input { display: flex; align-items: center; gap: 8px; background: #0b0e14; border: 1px solid #1c2230; border-top: 1px solid #1c2230; border-radius: 0 0 var(--d2-radius-md) var(--d2-radius-md); padding: 8px 12px; }
.d2-term-prompt { color: #38d39f; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.d2-term-input input { flex: 1; background: transparent; border: none; outline: none; color: #d6deeb; font-family: 'JetBrains Mono', monospace; font-size: 13px; }
.d2-term-input input::placeholder { color: #5a6473; }
.d2-term-input input:disabled { opacity: .5; }
/* terminal INTERATIVO (iframe do cmd.php -> /shell/ ttyd) */
.d2-term-frame-wrap { width: 100%; height: 70vh; background: #0b0e14; border: 1px solid #1c2230; border-radius: var(--d2-radius-md); overflow: hidden; }
.d2-term-frame { width: 100%; height: 100%; border: 0; display: block; background: #0b0e14; }

/* ===========================================================
   RESPONSIVO: tablet e celular
   =========================================================== */

/* Toque (sem hover): os botões de menu (⋮) por nó precisam estar sempre
   visíveis: senão o menu inteiro (editar/pausar/excluir/add sensor) fica
   inacessível em celular/tablet. Idem o card "+ Novo sensor". */
@media (hover: none), (pointer: coarse) {
  .d2-menu-btn { opacity: 1; }
  .d2-sensor .d2-menu-btn { background: var(--d2-bg-elevated); }

  /* PERFORMANCE iOS/Safari mobile: em telas grandes há centenas de sensores
     críticos pulsando ao mesmo tempo (cada um cria uma camada compositada),
     o que trava o WebKit no iPhone. Mantém a cor (vermelho/verde), só remove o
     loop de animação. Também derruba o backdrop-filter (blur sobre milhares de
     nós é caríssimo no iOS). */
  .d2-sensor.s4 .d2-sensor-status .ind { animation: none; }
  .d2-latency .pdot { animation: none; }
  .d2-sensor.d2-flash-bad, .d2-sensor.d2-flash-good { animation: none; }
  .d2-ovl { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* Acessibilidade + performance: respeita quem pediu menos movimento (e cobre
   Safari/macOS quando o usuário ativa "Reduzir movimento"). */
@media (prefers-reduced-motion: reduce) {
  .d2-sensor.s4 .d2-sensor-status .ind,
  .d2-latency .pdot,
  .d2-sensor.d2-flash-bad,
  .d2-sensor.d2-flash-good { animation: none !important; }
  .d2-ovl { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .d2-ovl, .d2-modal { transition: none; }
}

/* ---- Tablet e abaixo (≤1024px) ---- */
@media (max-width: 1024px) {
  .disp2 { padding: 74px 16px 70px; }
  .d2-toolbar { top: 74px; }   /* header é mais alto neste breakpoint */
  /* catálogo de detalhe (lista lateral) empilha */
  .d2-cat-wrap { grid-template-columns: 1fr; min-height: 0; }
  .d2-cat-list { flex-direction: row; flex-wrap: wrap; max-height: none; overflow: visible;
    border-right: none; border-bottom: 1px solid var(--d2-border); padding: 0 0 8px; }
  /* cards de modelo do "Adicionar sensor": nunca forçar 330px (estourava no mobile) */
  .d2-model-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); max-height: 64vh; }
  .d2-cfg-pane { max-width: 100%; }
}

/* ---- Tablet retrato e abaixo (≤900px) ---- */
@media (max-width: 900px) {
  /* dispositivo: card de info em cima, sensores embaixo (largura cheia) */
  .d2-device { grid-template-columns: 1fr; gap: 8px; }
}

/* ---- Celular (≤640px) ---- */
@media (max-width: 640px) {
  .disp2 { padding: 70px 10px 76px; }

  /* toolbar empilha em 4 linhas no celular; fixá-la comeria ~70% da tela, então
     no celular ela rola normalmente com a página (sticky só no desktop/tablet) */
  .d2-toolbar { gap: 10px; margin-bottom: 14px; position: static; }
  .d2-view-tabs { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .d2-view-tabs::-webkit-scrollbar { display: none; }
  .d2-view-tab { flex: 1 0 auto; text-align: center; white-space: nowrap; }
  .d2-toolbar-right { width: 100%; gap: 8px; }
  .d2-density-label { display: none; }
  .d2-search { flex: 1 1 100%; width: auto; order: 9; }   /* busca ocupa a última linha inteira */
  .d2-add-wrap { margin-left: auto; }

  /* modais usam quase toda a largura/altura da tela */
  .d2-ovl { padding: 10px; }
  .d2-modal, .d2-modal.sm, .d2-modal.md, .d2-modal.lg, .d2-modal.xl, .d2-modal.xxl { max-width: 100%; }
  .d2-modal-body { max-height: 76vh; padding: 14px; }
  .d2-modal-head { padding: 14px 16px; }
  .d2-modal-foot { padding: 12px 16px; }

  /* linhas de formulário de 2/3 colunas empilham */
  .d2-field-row, .d2-field-row.c3 { grid-template-columns: 1fr; gap: 0; }
  .d2-feat-grid { grid-template-columns: 1fr; }
  .d2-stats { grid-template-columns: 1fr; }

  /* grade de categorias e modelos: 1 coluna confortável */
  .d2-catgrid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
  .d2-model-grid { grid-template-columns: 1fr; }
  .d2-model-card { padding: 10px 12px; gap: 10px; }

  /* nó do servidor: cabeçalho pode quebrar contadores p/ baixo sem cortar */
  .d2-server-header { flex-wrap: wrap; row-gap: 6px; }
  .d2-server-info { flex: 1 1 60%; }

  /* group-header: permite que os contadores encolham p/ o menu btn caber no viewport */
  .d2-counters { flex-shrink: 1; max-width: 55%; overflow: hidden; }
  .d2-group-name { flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 120px; }

  /* mapa de calor: coluna fixa menor p/ caber mais tempo na tela */
  .d2-hm-corner, .d2-hm-dev { width: 132px; min-width: 132px; max-width: 132px; }

  /* rodapé mais enxuto */
  .footer-fixed { font-size: 11.5px; padding: 8px 12px; }
  .footer-center { display: none; }   /* "próxima atualização" sai no celular p/ não amontoar */

  /* terminal SSH com altura menor */
  .d2-term { height: 280px; }

  /* logs: colunas visíveis agora são escolhidas no seletor (logs.js);
     em tela estreita o PADRÃO inicial já omite Envio/Tempo: sem esconder via CSS,
     senão a escolha do usuário não teria efeito */
  .d2-logs-msg { max-width: unset; }
}

/* ---- Celular estreito (≤380px) ---- */
@media (max-width: 380px) {
  .d2-catgrid { grid-template-columns: 1fr 1fr; }
  .d2-view-tab { padding: 5px 10px; font-size: 12px; }
}

/* ====================== LOGS (histórico de incidentes) ====================== */
.d2-logs { display: flex; flex-direction: column; gap: 10px; }
.d2-logs-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.d2-logs-filters { display: inline-flex; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); padding: 2px; }
.d2-logs-f { border: none; background: none; color: var(--d2-text-muted); font-family: var(--d2-font-sans); font-size: 13px; font-weight: 600; padding: 6px 14px; border-radius: 6px; cursor: pointer; transition: background .12s, color .12s; }
.d2-logs-f:hover { color: var(--d2-text); }
.d2-logs-f.active { background: var(--d2-bg-elevated); color: var(--d2-text); box-shadow: var(--d2-shadow-sm); }
.d2-logs-search { position: relative; flex: 1; min-width: 180px; display: flex; align-items: center; }
.d2-logs-search svg { position: absolute; left: 10px; width: 16px; height: 16px; color: var(--d2-text-faint); pointer-events: none; }
.d2-logs-search input { width: 100%; height: 34px; padding: 0 12px 0 32px; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); background: var(--d2-bg-elevated); color: var(--d2-text); font-size: 14px; font-family: var(--d2-font-sans); }
.d2-logs-search input:focus { outline: none; border-color: var(--d2-brand); }
html[data-theme="dark"] .d2-logs-search input { background-color: var(--d2-bg-elevated) !important; }
.d2-logs-count { font-size: 12.5px; color: var(--d2-text-faint); }
.d2-logs-openc { color: var(--d2-st-4); font-weight: 600; }
/* min-height: além de dar respiro com poucos logs, garante espaço p/ o dropdown
   de colunas (a modal tem overflow hidden e cortaria o menu) */
.d2-logs-wrap { max-height: 70vh; min-height: 46vh; overflow: auto; border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md); }

/* seletor de colunas (dropdown: mesmo padrão do olt2/concentradora2) */
.d2-colbtn { position: relative; }
.d2-coldd {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 60; min-width: 220px; max-height: 340px; overflow: auto;
  background: var(--d2-bg-elevated); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-md);
  box-shadow: var(--d2-shadow-md); padding: 6px; display: none;
}
.d2-colbtn.open .d2-coldd { display: block; }
.d2-coldd label { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 4px; font-size: 13px; cursor: pointer; color: var(--d2-text); }
.d2-coldd label:hover { background: var(--d2-bg-hover); }
.d2-logs-empty { padding: 28px 12px; text-align: center; color: var(--d2-text-faint); font-style: italic; font-size: 14px; }

.d2-logs-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.d2-logs-table thead th { position: sticky; top: 0; z-index: 1; background: var(--d2-bg-subtle); color: var(--d2-text-muted); font-weight: 600; text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--d2-border); white-space: nowrap; font-size: 12.5px; text-transform: uppercase; letter-spacing: .03em; }
.d2-logs-table tbody td { padding: 9px 12px; border-bottom: 1px solid var(--d2-border); color: var(--d2-text); vertical-align: middle; }
.d2-logs-table tbody tr:hover { background: var(--d2-bg-hover); }
.d2-logs-table tbody tr:last-child td { border-bottom: none; }
.d2-logs-date, .d2-logs-elapsed { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--d2-text-muted); }
.d2-logs-msg { max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.d2-logs-sensor { display: inline-block; padding: 2px 9px; border-radius: 6px; background: var(--d2-bg-subtle); border-left: 3px solid var(--d2-st-5); font-weight: 600; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.d2-logs-sensor.d2-sev-1 { border-left-color: var(--d2-st-1); }
.d2-logs-sensor.d2-sev-2 { border-left-color: var(--d2-st-2); }
.d2-logs-sensor.d2-sev-3, .d2-logs-sensor.d2-sev-7 { border-left-color: var(--d2-st-3); }
.d2-logs-sensor.d2-sev-4, .d2-logs-sensor.d2-sev-10 { border-left-color: var(--d2-st-4); }
.d2-logs-sensor.d2-sev-5 { border-left-color: var(--d2-st-5); }

.d2-logs-ch { white-space: nowrap; }
.d2-logs-pill { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 5px; font-size: 11px; font-weight: 700; color: #fff; margin-right: 3px; }
.d2-logs-pill.sent { background: var(--d2-st-6); }
.d2-logs-pill.fail { background: var(--d2-st-4); }
.d2-logs-dash { color: var(--d2-text-faint); }
.d2-logs-st { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.d2-logs-st.ok { background: rgba(0,201,92,.15); background: color-mix(in srgb, var(--d2-st-6) 16%, transparent); color: var(--d2-st-6); }
.d2-logs-st.bad { background: rgba(210,57,57,.15); background: color-mix(in srgb, var(--d2-st-4) 16%, transparent); color: var(--d2-st-4); }

@media (max-width: 720px) {
  /* colunas visíveis são escolhidas no seletor (logs.js define o padrão p/ tela estreita) */
  .d2-logs-msg { max-width: 160px; }
}

/* ---- detalhe do sensor: tabela de leituras (igual ao dispositivos legado) ---- */
.d2-readings-wrap { margin-top: 18px; }
.d2-readings-head { font-size: 12.5px; color: var(--d2-text-muted); font-weight: 600; margin-bottom: 8px; }
.d2-readings-head b { color: var(--d2-text); }
table.d2-readings { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.d2-readings thead th { position: sticky; top: 0; background: var(--d2-bg-elevated); text-align: left; padding: 7px 10px; font-weight: 600; color: var(--d2-text-muted); border-bottom: 1px solid var(--d2-border-strong); white-space: nowrap; }
table.d2-readings td { padding: 6px 10px; border-bottom: 1px solid var(--d2-border); white-space: nowrap; }
table.d2-readings tr:hover td { background: var(--d2-bg-hover); }
.d2-readings .d2-rd-data { color: var(--d2-text-muted); font-family: var(--d2-font-mono); font-size: 11.5px; }
.d2-readings .d2-rd-st { width: 14px; padding-right: 0; }
.d2-rd-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--d2-st-6); }
.d2-rd-dot.s1 { background: var(--d2-st-1); } .d2-rd-dot.s2 { background: var(--d2-st-2); }
.d2-rd-dot.s3 { background: var(--d2-st-3); } .d2-rd-dot.s4 { background: var(--d2-st-4); }
.d2-rd-dot.s5 { background: var(--d2-st-5); } .d2-rd-dot.s6 { background: var(--d2-st-6); }
.d2-rd-row.s1 td, .d2-rd-row.s4 td { color: var(--d2-text); }
.d2-readings-pg { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.d2-rd-pginfo { font-size: 12px; color: var(--d2-text-muted); }
.d2-rd-per { margin-left: auto; background: var(--d2-bg-elevated); color: var(--d2-text); border: 1px solid var(--d2-border); border-radius: var(--d2-radius-sm); padding: 4px 8px; font-size: 12px; }

/* ===== Detecção automática (autoscan): painel de progresso ===== */
.d2-scan-note { margin-top: 12px; font-size: 13px; color: var(--d2-text-muted); background: var(--d2-bg-subtle); border: 1px dashed var(--d2-border-strong); border-radius: var(--d2-radius-md); padding: 10px 12px; }
.d2-scan-wrap { margin-top: 14px; border-top: 1px solid var(--d2-border); padding-top: 14px; }
.d2-scan-actions { display: flex; gap: 8px; }
.d2-scan-prog { margin-top: 12px; }
.d2-scan-bar { height: 8px; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-radius: 999px; overflow: hidden; }
.d2-scan-fill { display: block; height: 100%; width: 0; background: var(--d2-brand); border-radius: 999px; transition: width .4s ease; }
.d2-scan-fill.done { background: var(--d2-st-6); }
.d2-scan-fill.err  { background: var(--d2-st-4); }
.d2-scan-fill.indet { width: 35% !important; animation: d2-scan-slide 1.1s ease-in-out infinite; }
@keyframes d2-scan-slide { 0% { margin-left: -35%; } 100% { margin-left: 100%; } }
.d2-scan-msg { margin-top: 8px; font-size: 13px; color: var(--d2-text); min-height: 18px; }
.d2-scan-stats { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 14px; font-size: 12px; color: var(--d2-text-muted); }
.d2-scan-stats b { color: var(--d2-text); font-weight: 600; }

/* ===== Progresso inline da detecção automática (dentro do grupo na árvore) ===== */
.d2-scan-inline { margin: 6px 0 10px; padding: 10px 12px; background: var(--d2-bg-subtle); border: 1px solid var(--d2-border); border-left: 3px solid var(--d2-brand); border-radius: var(--d2-radius-md); }
.d2-scan-inline-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.d2-scan-inline-spin { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--d2-border-strong); border-top-color: var(--d2-brand); animation: d2-spin .8s linear infinite; flex: 0 0 auto; }
.d2-scan-inline-msg { font-size: 13px; color: var(--d2-text); font-weight: 500; }
.d2-scan-inline-stat { margin-left: auto; font-size: 12px; color: var(--d2-text-muted); font-family: var(--d2-font-mono); }

/* ---------- grupo do servidor Ravi conectado (páginas de OLT e Concentradora) ---------- */
/* Cada servidor entra na MESMA fileira dos cards locais como um GRUPO leve:
   um divisor vertical em degradê separa dos locais, a etiqueta do servidor
   flutua acima (no respiro da faixa) com o pulso "ao vivo", e os cartões são
   IDÊNTICOS aos locais em tamanho: a marca deles é um fio azul no topo. */
.rvq-group { position: relative; display: flex; gap: 10px; flex: 0 0 auto; margin-left: 32px; }
.rvq-group::before {
  content: ''; position: absolute; left: -17px; top: 4px; bottom: 4px; width: 2px; border-radius: 2px;
  background: linear-gradient(180deg, rgba(59,130,246,.65), rgba(16,185,129,.35));
}
.rvq-group.erro::before { background: linear-gradient(180deg, rgba(210,57,57,.6), rgba(210,57,57,.2)); }
.rvq-group-tag {
  position: absolute; top: -14px; left: 1px; display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: #3b82f6; white-space: nowrap; pointer-events: none;
}
.rvq-group.erro .rvq-group-tag { color: var(--d2-st-4); }
/* pulso "ao vivo": dado chegando do outro servidor */
.rvq-live { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
  background: var(--d2-st-6); animation: rvq-pulse 2.2s ease-out infinite; }
.rvq-live.off { background: var(--d2-st-4); animation: none; }
@keyframes rvq-pulse {
  0% { box-shadow: 0 0 0 0 rgba(16,185,129,.45); }
  70% { box-shadow: 0 0 0 6px rgba(16,185,129,0); }
  100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }
}
@media (prefers-reduced-motion: reduce) { .rvq-live { animation: none; } }
/* fio azul no topo: amarra o card ao servidor sem mudar o tamanho dele */
.rvq-card { box-shadow: inset 0 2px 0 rgba(59,130,246,.5) !important; }
.rvq-card:hover { transform: none !important; border-color: var(--d2-border-strong) !important;
  box-shadow: inset 0 2px 0 rgba(59,130,246,.5) !important; }
.rvq-card.active { box-shadow: inset 0 2px 0 rgba(59,130,246,.5), 0 0 0 2px rgba(16,185,129,.18) !important; }
/* sem estrela e sem kebab, o card remoto perderia altura em relação ao local;
   o respiro à direita do cabeçalho compensa e os cartões ficam da mesma altura */
.rvq-card .o2-olt-card-top, .rvq-card .c2-olt-card-top { padding-right: 0; }
.rvq-erro { font-size: 12.5px; color: var(--d2-text-muted); align-self: center; padding: 6px 4px; max-width: 320px; }
/* colmeia do painel remoto: a largura de 100% do canvas local é amarrada ao id
   (#o2-colmeia/#c2-colmeia); o canvas remoto precisa da própria regra, senão
   fica nos 300px padrão do elemento */
#rv-colmeia { display: block; width: 100%; cursor: default; }
/* menu de ações do equipamento remoto (editar/excluir no outro servidor) */
.rvq-menu { position: fixed; z-index: 9999; min-width: 200px; }
.rvq-card .o2-olt-kebab, .rvq-card .c2-olt-kebab { opacity: .5; }
.rvq-card:hover .o2-olt-kebab, .rvq-card:hover .c2-olt-kebab { opacity: 1; }
