/* =====================================================================
   i3Track — Identidade de marca oficial i3TECH (override sobre o bundle)
   Paleta: Azul Primário #0052E6 · Azul Profundo #003A99 · Azul Claro #66A3FF
           Off-White #F7F7F7 · Carvão #242424 (dark neutro, não preto-azulado)
   Tipografia: Bricolage Grotesque (títulos + interface), Inter (corpo denso).
   Mantém toda a estrutura/lógica; muda cor, tipografia e estilo.
   ===================================================================== */

@font-face{
  font-family:'Bricolage Grotesque';
  src:url('/assets/fonts/BricolageGrotesque.ttf') format('truetype-variations'),
      url('/assets/fonts/BricolageGrotesque.ttf') format('truetype');
  font-weight:300 800;
  font-stretch:75% 100%;
  font-style:normal;
  font-display:swap;
}

/* ===================== 1. TOKENS DE TEMA ===================== */
:root[data-theme="dark"]{
  /* Dark = Carvão neutro sofisticado (IDV i3TECH), não preto absoluto */
  --bg:#191919;
  --surface:#1F1F1F;
  --surface-2:#242424;
  --surface-card:#242424;
  --surface-card-inner:#1C1C1C;
  --surface-user-card:#1C1C1C;
  --card:#242424;
  --bg-card:#242424;
  --border:#353535;
  --accent-border:rgba(102,163,255,.90);
  --accent-border-soft:rgba(102,163,255,.42);
  --border-active-gradient:linear-gradient(135deg,#0052E6,#66A3FF);
  --card-header-gradient:linear-gradient(180deg,rgba(0,82,230,.10) 0%,rgba(36,36,36,0) 70%);
  --primary:#0052E6;
  --primary-hover:#2E6BFF;
  --primary-soft:rgba(0,82,230,.18);
  --focus-ring:rgba(0,82,230,.45);
  --ring-active:var(--focus-ring);
  --ring-selected:var(--focus-ring);
  --field-bg:#1E1E1E;
  --field-bg-focus:#262626;
  --field-bg-hover:#262626;
  --field-bg-disabled:#1A1A1A;
  --text:#F7F7F7;
  --text-2:#A1A1A1;
  --muted:#A1A1A1;
  --avatar-fallback-bg:#242424;
  --avatar-fallback-text:#F7F7F7;
  --chart-tooltip-bg:#242424;
  --chart-tooltip-border:#353535;
  --chart-tooltip-text:#F7F7F7;
  --shadow-1:0 10px 30px rgba(0,0,0,.45);
  --shadow-2:0 24px 70px rgba(0,0,0,.55);
  --sidebar:#171717;
  --layer:#242424;
  --stroke:#2E2E2E;
  --sub:#A1A1A1;
  --placeholder:#7A7A7A;
  --success:#22C55E; --success-soft:rgba(34,197,94,.16);
  --warning:#F59E0B; --warning-soft:rgba(245,158,11,.16);
  --danger:#EF4444;  --danger-soft:rgba(239,68,68,.16);
  /* Tokens dedicados do SIDEBAR (navy da identidade) — NÃO afetam o conteúdo (slate) */
  --sidebar-bg:#0E1A30;      /* navy de fundo do sidebar */
  --sidebar-surface:#14213B; /* card de conta / hover interno */
  --sidebar-border:#1E2E4C;  /* bordas e divisores internos */
}
:root[data-theme="light"]{
  --bg:#F7F7F7;
  --surface:#FFFFFF;
  --surface-2:#EFEFEF;
  --surface-card:#FFFFFF;
  --surface-card-inner:#F7F7F7;
  --card:#FFFFFF;
  --bg-card:#FFFFFF;
  --border:#E4E4E4;
  --accent-border:rgba(0,82,230,.55);
  --accent-border-soft:rgba(0,82,230,.28);
  --border-active-gradient:linear-gradient(135deg,#003A99,#0052E6);
  --card-header-gradient:linear-gradient(180deg,rgba(0,82,230,.08) 0%,rgba(255,255,255,0) 70%);
  --primary:#0052E6;
  --primary-hover:#003A99;
  --primary-soft:rgba(0,82,230,.10);
  --focus-ring:rgba(0,82,230,.25);
  --field-bg:#FFFFFF;
  --field-bg-focus:#FFFFFF;
  --field-bg-hover:#EFEFEF;
  --text:#242424;
  --text-2:#6B6B6B;
  --muted:#6B6B6B;
  --sidebar:#F0F0F0;
  --layer:#EFEFEF;
  --stroke:#E4E4E4;
  --sub:#6B6B6B;
  --placeholder:#9A9A9A;
  --success:#16A34A; --success-soft:rgba(34,197,94,.12);
  --warning:#D97706; --warning-soft:rgba(245,158,11,.12);
  --danger:#DC2626;  --danger-soft:rgba(239,68,68,.12);
  /* Sidebar no tema claro: mantém o claro atual (navy é identidade do tema escuro) */
  --sidebar-bg:#F0F0F0; --sidebar-surface:#FFFFFF; --sidebar-border:#E4E4E4;
}

/* ===================== 2. TIPOGRAFIA (Bricolage Grotesque) ===================== */
body, #root{ font-family:'Bricolage Grotesque','Inter',ui-sans-serif,system-ui,sans-serif; }
h1,h2,h3,h4,h5,h6{
  font-family:'Bricolage Grotesque','Inter',ui-sans-serif,system-ui,sans-serif;
  letter-spacing:-.015em; font-weight:600;
}
/* tabelas densas e campos: Inter melhora leitura em corpo pequeno */
table, .tabular, input, select, textarea{ font-family:'Inter','Bricolage Grotesque',ui-sans-serif,system-ui,sans-serif; }

/* ===================== 3. ACENTO / BOTÕES / SPINNERS ===================== */
/* Spinners/loaders SEMPRE azul, nunca amarelo */
[class*="animate-spin"]{ color:#0052E6 !important; border-top-color:#0052E6 !important; }

/* ===================== 4. LOGO DO TOP BAR (segue o tema) ===================== */
img[src*="i3track-logo.svg"]{ content:url('/assets/topbar-dark.png'); }
:root[data-theme="light"] img[src*="i3track-logo.svg"]{ content:url('/assets/topbar-light.png'); }

/* ===================== 5. LOGIN (eagle) — identidade i3Track ===================== */
:root[data-theme] .eagle-login, :root[data-theme] .eagle-loader,
.eagle-login, .eagle-loader{
  background:#191919 !important;
  font-family:'Bricolage Grotesque','Inter',ui-sans-serif,system-ui,sans-serif !important;
}
:root[data-theme] .eagle-login .eagle-bg, :root[data-theme] .eagle-loader .eagle-bg{
  background:
    radial-gradient(1100px 560px at 50% -12%, rgba(0,82,230,.30), transparent 60%),
    radial-gradient(760px 480px at 82% 112%, rgba(102,163,255,.10), transparent 60%),
    #191919 !important;
}
:root[data-theme] .eagle-login .eagle-grid, :root[data-theme] .eagle-loader .eagle-grid{
  background-image:
    linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px) !important;
  background-size:46px 46px !important; opacity:.45 !important;
}
:root[data-theme] .eagle-login .eagle-noise{ opacity:.03 !important; }

/* Card translúcido com borda fina */
:root[data-theme] .eagle-card{
  background:rgba(28,28,28,.80) !important;
  border:1px solid rgba(255,255,255,.08) !important;
  border-radius:18px !important;
  box-shadow:0 30px 80px rgba(0,0,0,.55), 0 0 60px rgba(0,82,230,.16) !important;
  backdrop-filter:blur(10px) !important;
}

/* Marca (águia -> ícone i3track) */
:root[data-theme] .eagle-sprite--mark{
  background-image:url('/assets/loader-icon.png') !important;
  background-position:center !important; background-size:contain !important;
  background-repeat:no-repeat !important; width:48px !important; height:48px !important; filter:none !important;
}
:root[data-theme] .eagle-titles h1{ color:#FFFFFF !important; font-weight:700 !important; letter-spacing:-.01em !important; }
:root[data-theme] .eagle-titles p{ color:#A1A1A1 !important; }

/* Campos */
:root[data-theme] .eagle-label{ color:#A1A1A1 !important; }
:root[data-theme] .eagle-input{
  background:rgba(255,255,255,.045) !important;
  border:1px solid rgba(255,255,255,.10) !important;
  border-radius:12px !important;
}
:root[data-theme] .eagle-input:focus-within{
  border-color:#0052E6 !important; box-shadow:0 0 0 3px rgba(0,82,230,.28) !important;
}
:root[data-theme] .eagle-input svg{ color:#A1A1A1 !important; }
:root[data-theme] .eagle-toggle{ color:#A1A1A1 !important; }
:root[data-theme] .eagle-input input::placeholder{ color:rgba(139,152,169,.6) !important; }
/* vence a regra global de input do tema claro (cadeia :not) */
:root[data-theme] .eagle-login .eagle-input input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]):not([type=button]):not([type=submit]):not([type=reset]):not([type=hidden]),
:root[data-theme] .eagle-loader .eagle-input input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]):not([type=button]):not([type=submit]):not([type=reset]):not([type=hidden]){
  background-color:transparent !important; border-color:transparent !important; color:#FFFFFF !important;
}

/* Botão Entrar — azul com brilho */
:root[data-theme] .eagle-btn{
  background:linear-gradient(135deg,#0052E6,#66A3FF) !important;
  background-image:linear-gradient(135deg,#0052E6,#66A3FF) !important;
  border:none !important; border-radius:12px !important; color:#fff !important; font-weight:600 !important;
  box-shadow:0 10px 28px rgba(0,82,230,.42) !important; transition:filter .15s ease, transform .15s ease !important;
}
:root[data-theme] .eagle-btn:hover{ filter:brightness(1.08) !important; transform:translateY(-1px); }

:root[data-theme] .eagle-link{ color:#66A3FF !important; }
:root[data-theme] .eagle-check{ color:#A1A1A1 !important; }
:root[data-theme] .eagle-meta{ display:none !important; }

/* ===================== 6. LOADER — logo i3track ===================== */
:root[data-theme] .eagle-sprite--loader{
  background-image:url('/assets/login-dark.png') !important;
  background-position:center !important; background-size:contain !important; background-repeat:no-repeat !important;
  width:290px !important; height:112px !important;
  animation:i3-pulse 1.5s ease-in-out infinite !important;
}
@keyframes i3-pulse{ 0%,100%{opacity:.5; transform:scale(.98)} 50%{opacity:1; transform:scale(1)} }

/* Tela "Carregando permissões..." -> só o ícone i3track (sem card, sem texto) */
[class*="0b0f17"]{ background:#191919 !important; }
/* remove o card quadrado (borda / fundo / sombra / padding) */
[class*="0b0f17"] [class*="rounded-2xl"]{
  background:transparent !important; border:0 !important; box-shadow:none !important;
  padding:0 !important; max-width:none !important;
}
/* remove os textos "Carregando permissões..." / "Preparando o ambiente..."
   SÓ na tela de carregamento. Antes era `[class*="0b0f17"] p` solto: qualquer
   elemento com esse hex na classe perdia todos os parágrafos de dentro — foi
   assim que os nomes dos comandos sumiram na tela de Comandos, deixando onze
   botões "Enviar" sem dizer qual era qual. O `:has` amarra a regra ao ícone
   pulsante, que só existe no splash. */
[class*="0b0f17"]:has([class*="animate-pulse"][class*="rounded-full"]) p{ display:none !important; }
/* mantém só o ícone i3track pulsando */
[class*="0b0f17"] [class*="animate-pulse"][class*="rounded-full"]{
  width:84px !important; height:84px !important; margin:0 auto !important;
  border:0 !important; background:transparent !important;
  background-image:url('/assets/loader-icon.png') !important;
  background-size:contain !important; background-repeat:no-repeat !important; background-position:center !important;
  border-radius:0 !important; animation:i3-pulse 1.4s ease-in-out infinite !important;
}

/* ===================== 7. SIDEBAR — identidade i3Track ===================== */
.app-shell__sidebar{
  background:var(--sidebar-bg) !important;
  border-right:1px solid var(--sidebar-border) !important;
}
/* Cabeçalhos de seção do menu (NEGÓCIOS, CADASTRO...) */
.app-shell__sidebar [class*="uppercase"][class*="tracking"]{ color:#6B7789 !important; }
/* Item ativo IGUAL AO MOCKUP (.nav-item.active): tint suave + PÍLULA curta (3x22px,
   cantos direitos arredondados, centralizada) à esquerda + ícone azul + negrito.
   SEM anel/contorno, SEM barra de altura cheia, SEM animação. */
.app-shell__sidebar a[aria-current="page"]{
  position:relative !important;
  background-color:rgba(0,82,230,.12) !important;
  color:#FFFFFF !important; font-weight:600 !important;
  box-shadow:none !important;
  border-color:transparent !important; outline:none !important;
  transition:none !important;
}
.app-shell__sidebar a[aria-current="page"]::before{
  content:"" !important;
  position:absolute !important;
  left:0 !important; top:50% !important;
  transform:translateY(-50%) !important;
  width:3px !important; height:22px !important;
  border-radius:0 3px 3px 0 !important;
  background:#0052E6 !important;
}
.app-shell__sidebar a[aria-current="page"] svg{ color:#66A3FF !important; }
/* Hover dos itens inativos */
.app-shell__sidebar a:not([aria-current="page"]):hover{
  background-color:rgba(255,255,255,.04) !important; color:#FFFFFF !important;
}

/* ===================== 8. ACENTOS GENÉRICOS (sky -> azul da marca) ===================== */
/* Muitos CTAs usam sky-… / text-black do Tailwind; remapeia p/ identidade i3Track.
   (O comentário original escrevia "sky-*" seguido de barra: o "*" com a "/" ao
   lado FECHA o comentário no meio da frase, e o resto virava CSS quebrado.) */
.bg-sky-500,.bg-sky-600{ background-color:#0052E6 !important; }
.hover\:bg-sky-400:hover,.hover\:bg-sky-600:hover{ background-color:#66A3FF !important; }
.text-sky-400,.text-sky-500{ color:#66A3FF !important; }
.border-sky-500{ border-color:#0052E6 !important; }
.ring-sky-500{ --tw-ring-color:#0052E6 !important; }
/* CTA com fundo azul: texto branco (não preto) */
button.bg-sky-500,a.bg-sky-500,button.bg-sky-600{ color:#FFFFFF !important; }
button.bg-sky-500 *,a.bg-sky-500 *{ color:#FFFFFF !important; }

/* ===================== 9. EMPTY-STATE / BOTÕES SUAVES (NEUTROS, sem azul) ===================== */
/* "Limpar filtros", "Atualizar", "Exportar", "Exibir colunas" e afins = secundários NEUTROS */
button[class*="bg-white/10"],a[class*="bg-white/10"]{
  background-color:var(--surface-2) !important;
  border:1px solid var(--border) !important;
  color:var(--text) !important;
}
button[class*="bg-white/10"]:hover,a[class*="bg-white/10"]:hover{
  background-color:var(--field-bg-hover) !important; border-color:var(--sub) !important;
}
/* Ícone/círculo do empty-state (border-white/20 bg-white/10) -> neutro */
[class*="border-white/20"][class*="bg-white/10"][class*="rounded-full"]{
  border-color:var(--border) !important;
  background-color:var(--surface-2) !important;
}

/* ===================== 10. UNIFICAÇÃO DE AZUIS — um só accent (--primary) =====================
   Causa-raiz da "cara inconsistente": vários azuis soltos (sky-400 #38bdf8, sky-500 #0EA5E9,
   blue-600 #2563eb, 5A9BFF...) cravados em UTILITÁRIOS Tailwind e componentes do mapa/rota,
   que não passam por var(--primary). Os CSS de rota são injetados DEPOIS do brand.css, então
   subimos a especificidade (:root[data-theme] …) + !important pra vencer sempre.
   Regra de ouro: nada de azul cru — tudo vira #0052E6 / #66A3FF / rgba(0,82,230,*). */

/* 10.1 tokens azuis protegidos (chunks de rota redefinem --accent-border/soft com outro azul) */
:root[data-theme="dark"]{
  --primary:#0052E6 !important; --primary-hover:#2E6BFF !important; --primary-soft:rgba(0,82,230,.18) !important;
  --accent-border:rgba(102,163,255,.90) !important; --accent-border-soft:rgba(102,163,255,.42) !important;
  --focus-ring:rgba(0,82,230,.45) !important;
}
:root[data-theme="light"]{
  --primary:#0052E6 !important; --primary-hover:#003A99 !important; --primary-soft:rgba(0,82,230,.10) !important;
  --accent-border:rgba(0,82,230,.55) !important; --accent-border-soft:rgba(0,82,230,.28) !important;
  --focus-ring:rgba(0,82,230,.25) !important;
}

/* 10.2 Tailwind sky/blue SÓLIDOS (pills "TODOS", CTAs, empty-state) -> azul da marca */
:root[data-theme] .bg-sky-400,:root[data-theme] .bg-sky-500,:root[data-theme] .bg-sky-600{ background-color:var(--primary) !important; color:#fff !important; }
:root[data-theme] .bg-sky-400.text-black,:root[data-theme] .bg-sky-500.text-black,:root[data-theme] .bg-sky-600.text-black{ color:#fff !important; }
:root[data-theme] .hover\:bg-sky-400:hover,:root[data-theme] .hover\:bg-sky-500:hover,:root[data-theme] .hover\:bg-sky-600:hover{ background-color:var(--primary-hover) !important; }

/* 10.3 tints de opacidade -> tint azul da marca (preserva a intensidade) */
:root[data-theme] .bg-sky-400\/10,:root[data-theme] .bg-sky-500\/10{ background-color:rgba(0,82,230,.10) !important; }
:root[data-theme] .bg-sky-400\/15,:root[data-theme] .bg-sky-500\/15,:root[data-theme] .bg-sky-500\/12{ background-color:rgba(0,82,230,.15) !important; }
:root[data-theme] .bg-sky-400\/20,:root[data-theme] .bg-sky-500\/20,:root[data-theme] .bg-blue-500\/20,:root[data-theme] .bg-indigo-500\/20{ background-color:rgba(0,82,230,.20) !important; }
:root[data-theme] .bg-sky-400\/25,:root[data-theme] .bg-blue-500\/25,:root[data-theme] .hover\:bg-sky-400\/25:hover{ background-color:rgba(0,82,230,.25) !important; }

/* 10.4 bordas sky/cyan -> azul claro da marca */
:root[data-theme] .border-sky-400\/30,:root[data-theme] .border-sky-500\/30,:root[data-theme] .border-cyan-300\/30{ border-color:rgba(102,163,255,.30) !important; }
:root[data-theme] .border-sky-400\/40,:root[data-theme] .border-sky-500\/40,:root[data-theme] .border-cyan-300\/40{ border-color:rgba(102,163,255,.40) !important; }
:root[data-theme] .border-sky-400\/50,:root[data-theme] .border-cyan-300\/50{ border-color:rgba(102,163,255,.50) !important; }
:root[data-theme] .border-sky-400\/60{ border-color:rgba(102,163,255,.60) !important; }

/* 10.5 texto/ring/gradiente sky|cyan -> azul da marca */
:root[data-theme] .text-sky-300,:root[data-theme] .text-sky-400,:root[data-theme] .text-sky-500,:root[data-theme] .text-cyan-300{ color:#66A3FF !important; }
:root[data-theme] .ring-sky-300\/60,:root[data-theme] .focus-visible\:ring-sky-300\/60:focus-visible{ --tw-ring-color:rgba(0,82,230,.55) !important; }
:root[data-theme] .to-blue-400{ --tw-gradient-to:#66A3FF !important; }

/* 10.6 componentes nomeados (dark cravava #38bdf8/#2563eb; espelha o que o light já faz c/ var(--primary)) */
:root[data-theme=dark] .map-tool-button:hover,
:root[data-theme=dark] .map-layer-option:hover,
:root[data-theme=dark] .map-layer-option.is-active{ border-color:rgba(102,163,255,.6) !important; background:rgba(0,82,230,.12) !important; color:#fff !important; }
:root[data-theme=dark] .map-tool-button.is-active{ background:linear-gradient(135deg,rgba(0,82,230,.20),rgba(0,82,230,.10)) !important; border-color:var(--primary) !important; color:#66A3FF !important; }
:root[data-theme=dark] .map-status-pill--emphasis{ border-color:rgba(102,163,255,.45) !important; background:rgba(0,82,230,.22) !important; color:#fff !important; }
:root[data-theme=dark] .map-status-pill .dot{ background:var(--primary) !important; box-shadow:0 0 0 2px rgba(0,82,230,.25) !important; }
:root[data-theme=dark] .map-search-input:focus{ border-color:rgba(0,82,230,.75) !important; box-shadow:0 0 0 2px rgba(0,82,230,.30) !important; }
:root[data-theme=dark] .route-search-item:hover,
:root[data-theme=dark] .route-search-item.is-active{ background:rgba(0,82,230,.12) !important; border-color:rgba(0,82,230,.4) !important; }
:root[data-theme=dark] .route-search-highlight{ background:rgba(0,82,230,.30) !important; color:#E7ECF5 !important; }
:root[data-theme] .route-pin-icon--origin .route-pin{ background:var(--primary) !important; }
:root[data-theme] .nt-exec-meter__bar i{ background:linear-gradient(180deg,#66A3FF,#0052E6) !important; box-shadow:0 0 24px rgba(0,82,230,.20) !important; }
:root[data-theme] .negocios-scope .expected{ background:linear-gradient(180deg,#66A3FF,#003A99) !important; }
:root[data-theme=dark] .dashboard-hero{ background:linear-gradient(145deg,rgba(0,82,230,.12),rgba(102,163,255,.05)),var(--mesh-gradient,transparent) !important; }

/* ===================== 11. FORMA (do HTML de exemplo): card de conta + botões ===================== */
/* Card "Administrador" perde o gradiente próprio -> surface + tint + barra de accent à esquerda */
:root[data-theme] .sidebar-user-card{
  background:var(--sidebar-surface) !important;
  border:1px solid var(--sidebar-border) !important;
  border-left:3px solid var(--primary) !important;   /* barra de accent (azul) — mantida */
  box-shadow:none !important;
}
:root[data-theme] .sidebar-user-card[data-collapsed=false]{ background:var(--sidebar-surface) !important; }
:root[data-theme] .sidebar-user-card:hover{ background:rgba(255,255,255,.05) !important; }
/* avatar do card -> gradiente da marca (igual ao .avatar do exemplo) */
:root[data-theme] .sidebar-user-card .sidebar-avatar,
:root[data-theme] .sidebar-avatar--fallback{
  background:linear-gradient(145deg,#0052E6,#003A99) !important;
  border:0 !important; color:#fff !important; box-shadow:none !important;
}

/* Botões "Exportar PDF/Excel" = SECUNDÁRIOS neutros (não disputam com o primário) */
:root[data-theme] .vehicle-export-button{
  background:var(--surface-2) !important; color:var(--text) !important;
  border:1px solid var(--stroke) !important;
}
:root[data-theme] .vehicle-export-button:hover{
  background:var(--field-bg-hover) !important; border-color:var(--accent-border-soft) !important;
}

/* ===================== 12. SIDEBAR — títulos fixos + itens/seções ocultos =====================
   Cabeçalhos de seção (NEGÓCIOS/CADASTRO/PRINCIPAIS/FROTAS/TELEMETRIA/ADMINISTRAÇÃO)
   viram TÍTULO fixo: sem ícone, sem seta, sem abrir/fechar (i3track-sidebar.js mantém aberto). */
.app-shell__sidebar button[aria-label^="Alternar se"]{
  pointer-events:none !important; cursor:default !important;
  color:var(--sub) !important; margin-top:12px;
}
.app-shell__sidebar button[aria-label^="Alternar se"]:hover{ color:var(--sub) !important; }
/* esconde ícone (svg no span) do cabeçalho */
.app-shell__sidebar button[aria-label^="Alternar se"] svg{ display:none !important; }
/* esconde a seta ▾ (é um <span aria-hidden> com o glifo, não um svg) */
.app-shell__sidebar button[aria-label^="Alternar se"] > span[aria-hidden="true"]{ display:none !important; }
/* remove o gap que sobrava do ícone: o rótulo cola na margem esquerda */
.app-shell__sidebar button[aria-label^="Alternar se"] > span{ gap:0 !important; padding-left:0 !important; }

/* 12.2 Seções ocultas do menu (as ROTAS/páginas continuam existindo) */
.app-shell__sidebar div:has(> button[aria-label$="NEGÓCIOS"]),
.app-shell__sidebar div:has(> button[aria-label$="TELEMETRIA I3TRACK"]){ display:none !important; }

/* 12.2b Submenus ocultos (cabeçalho + itens) — páginas continuam existindo */
.app-shell__sidebar div:has(> button[aria-label="Sentinel"]),
.app-shell__sidebar div:has(> button[aria-label="Documentos"]){ display:none !important; }

/* 12.3 Itens ocultos do menu (as ROTAS/páginas continuam existindo) */
.app-shell__sidebar a[href="/sentinel"],
.app-shell__sidebar a[href="/sentinel/chat"],
.app-shell__sidebar a[href="/sentinel/learning"],
.app-shell__sidebar a[href="/sentinel/plans"],
.app-shell__sidebar a[href="/itineraries"],
.app-shell__sidebar a[href="/deliveries"],
.app-shell__sidebar a[href="/analytics/heatmap"],
/* Espelhamento sai da ADMINISTRAÇÃO e vira "Compartilhamento" no card da conta (i3track-sidebar.js) */
.app-shell__sidebar a[href="/mirrors/received"]{ display:none !important; }
/* o link real de Ação Condicional vive na seção Telemetria (oculta); o clone em FROTAS mostra */

/* ===================== 13. TOPBAR — limpa e padronizada =====================
   Sem hambúrguer (nem sidebar nem topbar), sem logo duplicada (logo só no sidebar).
   Busca vira pill; tema/notificações/perfil viram quadrados 36px uniformes. */
/* 13.1 Remove hambúrguer (colapso do sidebar) e o hambúrguer mobile da topbar.
   Especificidade extra (.btn) p/ vencer §13.4 que reestiliza header button.btn. */
.app-shell__sidebar button[aria-label="Alternar menu"],
header button.btn[aria-label="Abrir menu"],
header button[aria-label="Abrir menu"]{ display:none !important; }

/* 13.2 Logo/wordmark duplicada da topbar (fica só no sidebar) — topbar começa pela busca */
header img[src*="i3track-logo.svg"]{ display:none !important; }

/* 13.0 Layout (estilo do mockup): [busca][cliente] à ESQUERDA (onde ficava a logo);
   ícones à direita. kid0 (hambúrguer+logo ocultos) é colapsado p/ não reservar espaço.
   O seletor de cliente é movido via i3track-topbar.js pra logo após a busca. */
header > div.flex.w-full{ justify-content:flex-start !important; }
/* kid0: hambúrguer + logo (ambos ocultos) -> não ocupa largura */
header > div.flex.w-full > div.flex.flex-1.items-center.gap-3{
  flex:0 0 auto !important; width:0 !important; min-width:0 !important;
  padding:0 !important; margin:0 !important; gap:0 !important; overflow:hidden !important;
}
/* busca (form) encostada à esquerda, largura fixa */
header > div.flex.w-full > form.flex-1{ flex:0 0 auto !important; width:360px !important; max-width:40vw !important; }
header input[placeholder^="Buscar veículo"]{ width:100% !important; }
/* cliente movido: não estica */
header [data-i3-client-moved]{ flex:0 0 auto !important; }
header input[aria-label="Selecionar cliente"]{ width:230px !important; }
/* ícones no canto direito */
header > div.flex.w-full > div.flex.items-center.gap-2{ margin-left:auto !important; }

/* 13.2b Logo no topo do SIDEBAR (agora a logo vive só aqui). Substitui o texto "I3TRACK"
   pela wordmark (tema-aware). O <span> vira caixa com a imagem de fundo. */
.app-shell__sidebar nav > div:first-child > span:first-child{
  display:block !important; color:transparent !important;
  font-size:0 !important; line-height:0 !important;
  width:150px; height:34px; max-width:100%;
  background:url('/assets/topbar-dark.png') left center / contain no-repeat !important;
}
:root[data-theme="light"] .app-shell__sidebar nav > div:first-child > span:first-child{
  background-image:url('/assets/topbar-light.png') !important;
}

/* 13.3 Busca: pill arredondada (999px, estilo mockup), surface-2 + borda sutil. Foco neutro. */
header input[placeholder^="Buscar veículo"]{
  background:var(--surface-2) !important;
  border:1px solid var(--border) !important;
  border-radius:999px !important;
}
header input[placeholder^="Buscar veículo"]:focus{
  border-color:var(--sub) !important; box-shadow:none !important;
}
header input[placeholder^="Buscar veículo"]::placeholder{ color:var(--placeholder) !important; }
/* Lupa da busca em tom neutro (muted) */
header svg.lucide-search{ color:var(--sub) !important; }

/* 13.4 Seletor de cliente: pill arredondada com rótulo "CLIENTE" INLINE à esquerda (estilo mockup) */
header input[aria-label="Selecionar cliente"]{
  background:var(--surface-2) !important;
  border:1px solid var(--border) !important;
  border-radius:999px !important;
  padding:8px 34px 8px 64px !important; font-size:13px !important;
}
header input[aria-label="Selecionar cliente"]:focus{ border-color:var(--sub) !important; box-shadow:none !important; }
header [data-i3-clientlabel]{
  position:absolute; top:50%; transform:translateY(-50%); left:15px; z-index:1; pointer-events:none;
  font:600 10px/1 'Inter',sans-serif; letter-spacing:.06em; text-transform:uppercase;
  color:var(--placeholder);
}

/* 13.5 Ícones da direita (painel, tema, notificações, perfil): quadrados 36px NEUTROS */
header button.btn{
  height:36px !important; width:36px !important; min-width:36px !important; padding:0 !important;
  display:inline-flex !important; align-items:center !important; justify-content:center !important;
  border:1px solid var(--border) !important; border-radius:8px !important;
  background:var(--surface-2) !important; color:var(--sub) !important;
}
header button.btn:hover{
  background:var(--field-bg-hover) !important; color:var(--text) !important;
  border-color:var(--placeholder) !important;   /* borda "strong" neutra — NUNCA azul */
}
header button.btn svg{ width:18px !important; height:18px !important; }

/* 13.6 Ponto de notificação = âmbar (warning), nunca azul */
header button[aria-label="Abrir notificações"] span[class*="rounded-full"],
header button[aria-label="Abrir notificações"] ~ span[class*="rounded-full"],
header div:has(> button[aria-label="Abrir notificações"]) span[class*="bg-"]{
  background-color:var(--warning) !important; color:#1a1205 !important; border-color:var(--warning) !important;
}

/* ===================== 14. BOTÕES SECUNDÁRIOS/NEUTROS — zero azul (varredura) =====================
   Botões outline/ghost (pílulas com border-white/10|20, bg-transparent/bg-white/10) NÃO podem ter
   azul (tint #5A9BFF, box-shadow inset azul, borda azulada). Viram surface-2 + borda neutra.
   Os PRIMÁRIOS (bg-sky/bg-primary sólido) e itens ATIVOS (border-primary/aria-current) NÃO são
   alcançados aqui — continuam com o azul da marca. */
:root[data-theme] main button[class*="border-white/10"]:not([aria-current="page"]),
:root[data-theme] main button[class*="border-white/20"]:not([aria-current="page"]),
:root[data-theme] main a[class*="border-white/10"]:not([aria-current="page"]),
:root[data-theme] main button[class*="border-white/15"]:not([aria-current="page"]){
  background-color:var(--surface-2) !important;
  border-color:var(--border) !important;
  box-shadow:none !important;
  color:var(--text) !important;
}
:root[data-theme] main button[class*="border-white/10"]:not([aria-current="page"]):hover,
:root[data-theme] main button[class*="border-white/20"]:not([aria-current="page"]):hover,
:root[data-theme] main a[class*="border-white/10"]:not([aria-current="page"]):hover{
  background-color:var(--field-bg-hover) !important; border-color:var(--sub) !important;
}
/* Ícones/textos internos desses botões seguem neutros (não herdam azul) */
:root[data-theme] main button[class*="border-white/10"]:not([aria-current="page"]) svg{ color:var(--sub) !important; }

/* 14.1 Paginação (Primeira/Anterior/Próxima/Última) + "itens por página" = neutros */
:root[data-theme] main [class*="pagination"] button,
:root[data-theme] main nav[aria-label*="agina"] button{
  background-color:var(--surface-2) !important; border-color:var(--border) !important;
  color:var(--text) !important; box-shadow:none !important;
}

/* 14.2 Mata qualquer box-shadow inset azul (#5A9BFF) remanescente em inputs/cards neutros */
:root[data-theme] main input:focus, :root[data-theme] main select:focus{
  border-color:var(--sub) !important;
}

/* ===================== 15. TOKENS DE BOTÃO NEUTROS — mata o tint #5A9BFF =====================
   O bundle define --btn-bg/--btn-border com azul (#5A9BFF) — isso pinta TODO botão
   secundário (.btn-outline/.btn-ghost/.btn-secondary: Limpar filtros, Atualizar, Exportar,
   paginação Primeira/Anterior/Próxima/Última). Neutralizamos os tokens na raiz. */
:root[data-theme=dark]{
  --btn-bg:var(--surface-2) !important; --btn-border:var(--border) !important;
  --btn-bg-hover:var(--field-bg-hover) !important; --btn-border-hover:var(--sub) !important;
  --btn-bg-active:var(--field-bg-hover) !important; --btn-border-active:var(--sub) !important;
}
:root[data-theme=light]{
  --btn-bg:var(--surface-2) !important; --btn-border:var(--border) !important;
  --btn-bg-hover:var(--field-bg-hover) !important; --btn-border-hover:var(--sub) !important;
  --btn-bg-active:var(--field-bg-hover) !important; --btn-border-active:var(--sub) !important;
}
/* Texto/ícone dos secundários = neutro (não herdam o azul de --accent-color) */
:root[data-theme] .btn-outline,
:root[data-theme] .btn-ghost,
:root[data-theme] .btn-secondary{ color:var(--text) !important; }
:root[data-theme] .btn-outline svg,
:root[data-theme] .btn-ghost svg,
:root[data-theme] .btn-secondary svg{ color:var(--sub) !important; }
/* .btn-primary continua AZUL (ação principal) — não é tocado aqui */

/* 15.1 Cabeçalhos de tabela = neutros (não azul) */
:root[data-theme] main thead th,
:root[data-theme] main thead td,
:root[data-theme] main table thead,
:root[data-theme] main [role="columnheader"]{ color:var(--sub) !important; }

/* 15.2 Inputs/selects: sem borda/anel/sombra azul (inclui "Buscar endereço" no Estoque) */
:root[data-theme] main input:not([type=checkbox]):not([type=radio]):not([type=range]),
:root[data-theme] main select, :root[data-theme] main textarea{ box-shadow:none !important; }
:root[data-theme] main input:not([type=checkbox]):not([type=radio]):not([type=range]):focus,
:root[data-theme] main select:focus, :root[data-theme] main textarea:focus{
  border-color:var(--sub) !important; box-shadow:none !important;
}

/* ===================== 16. VIAGENS (/trips) — seleção divide a tela =====================
   Regra: sem viagem selecionada, só a LISTA aparece (largura total). Ao selecionar uma
   viagem, a tela DIVIDE: lista à esquerda + detalhe (mapa/replay estilo Uber + posições
   embaixo) à direita. O estado é marcado por i3track-viagens.js via data-i3-trip-sel. */

/* Nada selecionado -> só a lista, largura total; painel de detalhe oculto */
:root[data-theme] section.app-shell__content main[data-i3-trip-sel="0"]{
  grid-template-columns:minmax(0,1fr) !important;
}
:root[data-theme] section.app-shell__content main[data-i3-trip-sel="0"] > :nth-child(2){
  display:none !important;
}
:root[data-theme] section.app-shell__content main[data-i3-trip-sel="0"] > aside{
  width:100% !important; max-width:none !important; min-width:0 !important;
}

/* Viagem selecionada -> divide: lista estreita à esquerda, detalhe amplo à direita
   (mapa/replay ganha o máximo de espaço, com as posições/eventos empilhados embaixo). */
:root[data-theme] section.app-shell__content main[data-i3-trip-sel="1"]{
  grid-template-columns:minmax(320px,32%) minmax(0,1fr) !important;
}
:root[data-theme] section.app-shell__content main[data-i3-trip-sel="1"] > aside{
  width:100% !important; max-width:none !important; min-width:0 !important;
}

/* Abaixo de 1100px o app já empilha (grid-cols-1) — mantemos esse comportamento */
@media (max-width:1100px){
  :root[data-theme] section.app-shell__content main[class*="grid-cols-"],
  :root[data-theme] section.app-shell__content main[data-i3-trip-sel]{
    grid-template-columns:minmax(0,1fr) !important;
  }
}

/* ===================== 17. SUPERFÍCIES NAVY -> CINZA NEUTRO =====================
   Os tokens (--field-bg/--surface/--surface-2) já são cinza; os inputs também.
   O navy que sobra vem de HEX hardcoded nas classes (não passam por token):
     - bg-[#0B0F16] -> container + aside da página Viagens  => base neutra (--bg)
     - bg-[#0f141c] (e /60) -> paginação, thead, painéis do mapa => --surface-2
     - .monitoring-search-shell -> shell de busca (Estoque)  => --surface-2
     - controles do mapa (navy + borda slate)                => neutro
   Só cor de superfície/borda — sem alterar layout/comportamento. */
:root[data-theme] main [class*="0B0F16"],
:root[data-theme] main [class*="0b0f16"]{ background-color:var(--bg) !important; }

:root[data-theme] main [class*="0f141c"]{ background-color:var(--surface-2) !important; }

:root[data-theme] .monitoring-search-shell{
  background-color:var(--surface-2) !important; border-color:var(--border) !important;
}

/* Controles/toolbar do mapa: fundo navy (rgba(10,15,25,.9)) + borda slate -> neutro */
:root[data-theme] .map-tool-button,
:root[data-theme] .map-toolbar-zoom-button,
:root[data-theme] .map-layer-control{
  background-color:var(--surface-2) !important; border-color:var(--border) !important;
}

/* Defensivo: slate/navy escuro (Tailwind) em superfícies de conteúdo -> neutro */
:root[data-theme] main [class*="bg-slate-950"],
:root[data-theme] main [class*="bg-slate-900"],
:root[data-theme] main [class*="bg-slate-800"],
:root[data-theme] main [class*="bg-blue-950"],
:root[data-theme] main [class*="bg-blue-900"],
:root[data-theme] main [class*="bg-indigo-950"],
:root[data-theme] main [class*="bg-indigo-900"]{ background-color:var(--surface-2) !important; }
:root[data-theme] main [class*="border-slate-800"],
:root[data-theme] main [class*="border-slate-700"]{ border-color:var(--border) !important; }

/* ===================== 18. GATILHO + MENU DE AÇÕES (injetado) =====================
   Desenho único para os menus que os scripts injetam na barra de ferramentas:
     - Veículos: "Exportar PDF/Excel" viram um ícone com menu (i3track-vehicles.js);
     - Entregas: as ações secundárias viram "Ações ▾"      (i3track-entregas.js).
   Estilo neutro, alinhado à toolbar (mesma altura h-10 dos outros botões).
   Os dois pares de atributos existem porque o gatilho de Veículos diz
   "Exportar" e o de Entregas diz "Ações" — o nome do atributo acompanha o que
   o botão faz, e o desenho é o mesmo para os dois. */
:root[data-theme] [data-i3-exportwrap],
:root[data-theme] [data-i3-acoeswrap]{ position:relative; display:inline-flex; }
:root[data-theme] [data-i3-exporttrigger],
:root[data-theme] [data-i3-acoestrigger]{
  display:inline-flex; align-items:center; gap:7px; height:40px; padding:0 12px;
  border:1px solid var(--border); border-radius:8px; background:var(--surface-2);
  color:var(--text); font-size:13px; font-weight:500; line-height:1; cursor:pointer;
}
:root[data-theme] [data-i3-exporttrigger] svg,
:root[data-theme] [data-i3-acoestrigger] svg{ color:var(--sub); }
:root[data-theme] [data-i3-exporttrigger]:hover,
:root[data-theme] [data-i3-acoestrigger]:hover{ border-color:var(--sub); }
:root[data-theme] [data-i3-exportmenu],
:root[data-theme] [data-i3-acoesmenu]{
  position:absolute; top:calc(100% + 6px); right:0; min-width:190px; z-index:70;
  background:var(--surface-2); border:1px solid var(--border); border-radius:10px;
  padding:6px; box-shadow:0 12px 34px rgba(0,0,0,.38);
}
:root[data-theme] [data-i3-exportitem],
:root[data-theme] [data-i3-acoesitem]{
  display:block; width:100%; text-align:left; padding:8px 10px; border-radius:6px;
  background:transparent; border:0; color:var(--text); font-size:13px; cursor:pointer;
  white-space:nowrap;
}
:root[data-theme] [data-i3-exportitem]:hover,
:root[data-theme] [data-i3-acoesitem]:hover{ background:var(--field-bg-hover); }
:root[data-theme] [data-i3-acoesitem]:disabled{ opacity:.45; cursor:default; }

/* ===================== 19. PAGINAÇÃO compacta (setas « ‹ › ») =====================
   Os 4 botões largos "Primeira/Anterior/Próxima/Última" viram botões-ícone quadrados
   (o texto é trocado por setas em i3track-pager.js). O select "Itens por página" limpo. */
:root[data-theme] main [data-i3-pagerbtn]{
  height:32px !important; width:32px !important; min-width:32px !important;
  padding:0 !important; display:inline-flex !important; align-items:center !important; justify-content:center !important;
  border:1px solid var(--border) !important; border-radius:8px !important;
  background:var(--surface-2) !important; color:var(--text) !important;
  font-size:16px !important; line-height:1 !important;
}
:root[data-theme] main [data-i3-pagerbtn]:hover:not(:disabled){ border-color:var(--sub) !important; }
:root[data-theme] main [data-i3-pagerbtn]:disabled{ opacity:.4 !important; }
:root[data-theme] main [data-i3-pagerselect]{
  height:32px !important; min-width:76px !important; border-radius:8px !important;
  border:1px solid var(--border) !important; background:var(--surface-2) !important;
  color:var(--text) !important; padding:0 10px !important; font-size:13px !important;
}

/* ===================== 20. SIDEBAR DUO (rail + painel) — estilo do mockup =====================
   Esconde o sidebar React original (os <a> continuam no DOM p/ delegar navegação) e
   monta o Duo (i3track-duo.js). AZUL nos 2 temas. O grid do shell vira "auto 1fr" p/ o
   conteúdo EXPANDIR quando o painel recolhe (responsivo). */
aside.app-shell__sidebar{ display:none !important; }
/* conteúdo empurrado pela largura do Duo (fixo). Recolhido => só o rail (68px) => expande. */
:root{ --i3duo-w:300px; }
body.i3duo-collapsed{ --i3duo-w:76px; }
.app-shell{ display:block !important; padding-left:var(--i3duo-w) !important;
  transition:padding-left .18s ease; }
/* O padding acima reserva a faixa assim que o React monta o app-shell, mas o
   .i3duo é criado por JS logo depois. Nesse intervalo a faixa aparecia vazia
   (branca no tema claro, preta no escuro). Este ::before já pinta a faixa nas
   cores do rail+painel; quando o .i3duo (z-index 40) monta, ele cobre isto. */
.app-shell::before{ content:""; position:fixed; left:0; top:0; height:100vh;
  width:var(--i3duo-w); z-index:39; pointer-events:none;
  background:linear-gradient(to right, #2563EB 0 76px, #1B49C0 76px 100%); }
/* conteúdo usa toda a largura disponível (mais espaço, ainda mais ao recolher o menu) */
.app-shell .app-page-wrapper{ max-width:none !important; }

.i3duo{ position:fixed; left:0; top:0; height:100vh; display:flex; z-index:40;
  --i3s:#2563EB; --i3s2:#1B49C0; --i3stext:#EAF0FF;
  --i3smuted:rgba(234,240,255,.64); --i3sfaint:rgba(234,240,255,.42);
  --i3sactive:rgba(255,255,255,.17); --i3shover:rgba(255,255,255,.10); }

/* rail de ícones */
.i3duo-rail{ width:76px !important; flex:0 0 76px !important; background:var(--i3s); color:var(--i3stext);
  height:100vh; display:flex; flex-direction:column; align-items:center;
  padding:14px 0; gap:6px; box-sizing:border-box; }
/* símbolo (sem card): só o ícone, em branco sobre o rail azul */
.i3duo-logo{ width:46px; height:46px; background:transparent !important; border-radius:0;
  display:grid; place-items:center; margin-bottom:10px; cursor:pointer; flex:0 0 auto; }
.i3duo-logo img{ width:36px; height:36px; object-fit:contain; filter:brightness(0) invert(1); }
.i3duo-ico{ width:44px; height:44px; border-radius:12px; display:grid; place-items:center;
  color:var(--i3smuted); cursor:pointer; position:relative; flex:0 0 auto; }
.i3duo-ico svg{ width:21px; height:21px; fill:none; stroke:currentColor; stroke-width:1.85; }
.i3duo-ico:hover{ background:var(--i3shover); color:#fff; }
.i3duo-ico.active{ background:var(--i3sactive); color:#fff; }
.i3duo-ico.active::before{ content:""; position:absolute; left:-12px; top:11px; bottom:11px; width:3px;
  border-radius:0 3px 3px 0; background:#fff; }
.i3duo-tip{ position:absolute; left:56px; white-space:nowrap; background:#0d1b3d; color:#fff;
  font-size:12px; font-weight:600; padding:6px 10px; border-radius:7px; opacity:0; pointer-events:none;
  transition:opacity .12s; z-index:60; }
body.i3duo-collapsed .i3duo-ico:hover .i3duo-tip{ opacity:1; }
.i3duo-spacer{ margin-top:auto; }
/* Rodapé do rail. Aqui havia a pastilha "AD" (`.i3duo-ava`): enfeite, não
   clicava em nada. Agora é a engrenagem de Configurações — mesmo desenho dos
   outros ícones do rail, só um respiro embaixo para não colar na borda. */
.i3duo-ico--rodape{ margin-bottom:6px; }

/* painel de itens */
.i3duo-panel{ width:224px !important; flex:0 0 224px !important; background:var(--i3s2); color:var(--i3stext);
  height:100vh; display:flex; flex-direction:column; overflow:hidden; box-sizing:border-box;
  transition:width .18s ease, flex-basis .18s ease, opacity .18s ease; }
body.i3duo-collapsed .i3duo-panel{ width:0 !important; flex-basis:0 !important; }
body.i3duo-collapsed .i3duo-panel{ width:0; flex-basis:0; opacity:0; pointer-events:none; }
.i3duo-phead{ display:flex; align-items:center; gap:8px; padding:16px 12px 10px; }
.i3duo-ptitle{ font-size:17px; font-weight:700; letter-spacing:-.01em; white-space:nowrap; flex:1; }
.i3duo-collapse{ width:30px; height:30px; flex:0 0 auto; border:none; border-radius:8px;
  background:rgba(255,255,255,.12); color:#fff; display:grid; place-items:center; cursor:pointer; }
.i3duo-collapse:hover{ background:rgba(255,255,255,.22); }
.i3duo-collapse svg{ width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:2; }
.i3duo-acct{ margin:2px 10px 8px; background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.14);
  border-radius:11px; padding:10px 11px; display:flex; align-items:center; gap:10px; cursor:pointer; }
.i3duo-acct .a{ width:32px; height:32px; border-radius:9px; background:rgba(255,255,255,.2);
  display:grid; place-items:center; font-weight:700; font-size:11px; color:#fff; flex:0 0 auto; }
/* O nome e o cliente agora vem da sessao (i3track-duo.js, pintaConta) —
   antes eram dois textos curtos cravados no HTML e nada precisava caber.
   `min-width:0` e o que deixa a caixa encolher dentro do flex; sem ele o
   texto empurra a largura e transborda em vez de cortar. */
.i3duo-acct .w{ line-height:1.2; white-space:nowrap; overflow:hidden; min-width:0; }
.i3duo-acct .w b{ display:block; overflow:hidden; text-overflow:ellipsis;
  font-size:13px; font-weight:600; }
.i3duo-acct .w small{ display:block; overflow:hidden; text-overflow:ellipsis;
  color:var(--i3smuted); font-size:11px; }
.i3duo-pitems{ flex:1; overflow-y:auto; padding:2px 10px 14px; }
.i3duo-pitems::-webkit-scrollbar{ width:6px; }
.i3duo-pitems::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.2); border-radius:6px; }
.i3duo-item{ display:flex; align-items:center; gap:10px; padding:9px 11px; border-radius:8px;
  color:var(--i3smuted); cursor:pointer; font-size:13.5px; font-weight:500; position:relative;
  margin-bottom:2px; line-height:1.3; white-space:normal; word-break:break-word; }
.i3duo-item .d{ width:5px; height:5px; border-radius:50%; background:currentColor; opacity:.55; flex:0 0 auto; margin-top:5px; align-self:flex-start; }
.i3duo-item:hover{ background:var(--i3shover); color:#fff; }
.i3duo-item.active{ background:var(--i3sactive); color:#fff; font-weight:600; }
.i3duo-item.active .d{ opacity:1; }
.i3duo-item.active::before{ content:""; position:absolute; left:-10px; top:8px; bottom:8px; width:3px;
  border-radius:0 3px 3px 0; background:#fff; }
.i3duo-grp{ font-size:10px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:var(--i3sfaint); padding:12px 11px 6px; }

/* ===== §21 Estoque (/devices/stock) — cards + dropdown de abas ===== */
/* (a) chips de contagem -> cards KPI com listra colorida */
[data-i3-eststats]{ display:grid !important; grid-template-columns:repeat(auto-fill,minmax(158px,1fr)) !important;
  gap:10px !important; }
/* obs.: a listra (border-left) e a neutralização do fundo azul do chip ativo são
   aplicadas inline !important pelo JS — o React reconcilia estes botões e regras
   de folha de estilo não vencem o `border` do bundle. Aqui fica só o layout. */
[data-i3-statcard]{ position:relative !important; text-align:left !important; text-transform:none !important;
  letter-spacing:normal !important; border-radius:14px !important; padding:13px 15px 13px 17px !important;
  border-top:1px solid var(--border) !important; border-right:1px solid var(--border) !important;
  border-bottom:1px solid var(--border) !important;
  display:flex !important; flex-direction:column !important;
  gap:3px !important; min-height:64px !important; cursor:pointer; transition:border-color .15s ease; }
[data-i3-statcard] .i3est-val{ font-size:22px; font-weight:700; line-height:1.05; color:var(--text); }
[data-i3-statcard] .i3est-lbl{ font-size:10.5px; color:var(--sub); text-transform:uppercase;
  letter-spacing:.045em; font-weight:600; line-height:1.25; }

/* (b) esconde a linha original de abas; injeta trigger dropdown ao lado de Transferir */
[data-i3-esttabs]{ display:none !important; }
.i3est-tabtrigger{ display:inline-flex; align-items:center; gap:7px; border-radius:12px;
  background:var(--field-bg); border:1px solid var(--border); color:var(--text);
  padding:8px 12px; font-size:13.5px; font-weight:500; cursor:pointer; transition:background .15s ease, border-color .15s ease; }
.i3est-tabtrigger:hover{ background:var(--field-bg-hover); border-color:var(--sub); }
.i3est-tabtrigger svg{ opacity:.8; }
#i3est-tabmenu{ min-width:170px; background:var(--surface) !important; border:1px solid var(--border);
  border-radius:12px; padding:6px; box-shadow:0 12px 34px rgba(0,0,0,.4); z-index:1000; }
.i3est-tabitem{ display:block; width:100%; text-align:left; background:transparent; border:none;
  color:var(--text); padding:9px 11px; border-radius:8px; font-size:13.5px; cursor:pointer; }
.i3est-tabitem:hover{ background:var(--field-bg-hover); }
.i3est-tabitem.is-active{ background:var(--primary); color:#fff; font-weight:600; }

/* Badge "Build (UTC-3): ..." no canto inferior direito — remover */
.app-shell > div[class*="fixed"][class*="bottom-3"][class*="right-3"]{ display:none !important; }

/* (c) aba Mapa/Região — layout tipo "Técnico": mapa full-width grande em cima, lista embaixo */
[data-i3-estmapgrid]{ display:flex !important; flex-direction:column !important; gap:16px !important; }
[data-i3-estmapgrid] > *{ width:100% !important; max-width:none !important; min-width:0 !important; }
[data-i3-estmapbox]{ height:64vh !important; min-height:460px !important; }
[data-i3-estmapbox] .leaflet-container{ height:100% !important; }

/* (d) aba Produto (Kit) — "Modelos de Produto" plano (sem card), na própria página */
[data-i3-produtocard]{ position:relative !important; border:0 !important; background:transparent !important;
  border-radius:0 !important; padding:0 !important; }
[data-i3-kittabs]{ border-bottom:1px solid var(--border) !important; gap:8px !important; padding-bottom:6px !important; }
[data-i3-kittabs] > button{ border-radius:10px !important; }
/* esconde a sub-aba "Produto" (virou botão "Criar Produto") e o bloco de cliente */
[data-i3-hidesubtab]{ display:none !important; }
[data-i3-clientrow]{ display:none !important; }

/* ===== §22 Logo na topbar ===== */
.i3-topbar-logo{ display:inline-flex; align-items:center; height:40px; flex:0 0 auto; margin-right:2px; cursor:pointer; }
.i3-topbar-logo img{ height:26px; width:auto; max-width:160px; object-fit:contain; display:block; }

/* ===== §23 Estoque › sub-aba "Estoque Produto": filtros na mesma linha ===== */
[data-i3-prodfilters]{ display:grid !important;
  grid-template-columns:minmax(150px,1.3fr) minmax(120px,150px) minmax(120px,150px) minmax(160px,1.6fr) !important;
  gap:12px !important; align-items:end !important; }
[data-i3-prodfilters] > *:nth-child(5){ grid-column:1 / -1 !important; }
[data-i3-prodfilters] select, [data-i3-prodfilters] input{ margin-top:6px !important; }

/* ===== §24 Estoque › sub-aba "Modelo": lista em grid + TELA dedicada de criação ===== */
/* lista de modelos como TABELA (estilo Excel): só leitura, sem "Salvar" */
[data-i3-modellist]{ display:flex !important; flex-direction:column !important; gap:0 !important;
  border:1px solid var(--border) !important; border-radius:12px !important; overflow:hidden !important;
  background:var(--surface) !important; }
[data-i3-modellist] > *{ margin-top:0 !important; }
/* cabeçalho */
[data-i3-modellist] > [data-i3-listhead]{ display:grid !important; grid-template-columns:96px 1fr !important;
  gap:14px !important; padding:10px 16px !important; background:var(--surface-2) !important;
  border-bottom:1px solid var(--border) !important; font-size:11px !important; font-weight:700 !important;
  text-transform:uppercase !important; letter-spacing:.05em !important; color:var(--sub) !important; }
/* linhas de dados */
[data-i3-modellist] > div:not([data-i3-listhead]){ display:grid !important; grid-template-columns:96px 1fr !important;
  align-items:center !important; gap:14px !important; border:0 !important; border-bottom:1px solid var(--border) !important;
  border-radius:0 !important; background:transparent !important; padding:11px 16px !important; }
[data-i3-modellist] > div:not([data-i3-listhead]):last-child{ border-bottom:0 !important; }
[data-i3-modellist] > div:not([data-i3-listhead]):hover{ background:var(--surface-2) !important; }
/* esconde os botões "Salvar" na visão lista */
[data-i3-modellist] > div button{ display:none !important; }
/* input do nome vira texto puro (somente leitura visual) */
[data-i3-modellist] > div input{ border:0 !important; background:transparent !important; padding:0 !important;
  color:var(--text) !important; font-weight:500 !important; pointer-events:none !important; box-shadow:none !important;
  width:100% !important; }

/* grupo de botões (Criar modelo + Criar Produto) no topo-direito */
.i3-btngroup{ position:absolute !important; top:0; right:0; display:flex; gap:8px; }
.i3-crear-btn{ display:inline-flex; align-items:center; gap:7px; border-radius:10px; background:var(--primary);
  color:#fff; border:1px solid var(--primary); padding:8px 14px; font-size:13px; font-weight:600; cursor:pointer; }
.i3-crear-btn:hover{ filter:brightness(1.08); }
.i3-crear-btn.i3-crear-ghost{ background:var(--field-bg); color:var(--text); border-color:var(--border); }
.i3-crear-btn.i3-crear-ghost:hover{ background:var(--field-bg-hover); border-color:var(--sub); filter:none; }

/* form de cadastro fica escondido na página; só aparece dentro do popup */
[data-i3-createform]:not([data-i3-modalform]){ display:none !important; }

/* ===== §25b POPUP (modal) de criação ===== */
body.i3pop-open{ overflow:hidden !important; }
/* a topbar do app tem z-[9998]; rebaixa enquanto o modal está aberto p/ o popup cobrir tudo */
body.i3pop-open header{ z-index:0 !important; }
#i3pop{ position:fixed; inset:0; z-index:9990; }
#i3pop .i3pop-back{ position:absolute; inset:0; background:rgba(0,0,0,.55); backdrop-filter:blur(2px); }
#i3pop .i3pop-bar{ position:absolute; top:0; left:0; right:0; height:56px; display:flex; align-items:center; gap:12px;
  padding:0 20px; background:var(--surface); border-bottom:1px solid var(--border); }
#i3pop .i3pop-title{ font-size:16px; font-weight:700; letter-spacing:-.01em; color:var(--text); }
#i3pop .i3pop-x{ margin-left:auto; width:34px; height:34px; display:grid; place-items:center; border-radius:9px;
  background:var(--field-bg); border:1px solid var(--border); color:var(--text); cursor:pointer; }
#i3pop .i3pop-x:hover{ background:var(--field-bg-hover); }
/* o form real é "promovido" para o centro do modal (sem mover no DOM) */
[data-i3-modalform]{ position:fixed !important; z-index:9992 !important; left:50% !important; top:88px !important;
  transform:translateX(-50%) !important; width:min(780px,94vw) !important; max-height:calc(100vh - 116px) !important;
  overflow:auto !important; margin:0 !important; background:var(--surface) !important; border:1px solid var(--border) !important;
  border-radius:16px !important; padding:24px !important; box-shadow:0 30px 80px rgba(0,0,0,.5) !important; }
[data-i3-createform][data-i3-modalform]{ display:grid !important; }

/* ===== §25 Botão "← Painel Geral" em telas profundas (analytics/reports) ===== */
.i3-backhome{ display:inline-flex; align-items:center; gap:6px; margin-right:14px; flex:0 0 auto;
  border-radius:10px; background:var(--field-bg); border:1px solid var(--border); color:var(--text);
  padding:7px 13px; font-size:13px; font-weight:600; cursor:pointer; transition:background .15s ease, border-color .15s ease; }
.i3-backhome:hover{ background:var(--field-bg-hover); border-color:var(--sub); }
.i3-backhome svg{ opacity:.85; }

/* ===== §26 Grupos de permissões — esconder seções/itens inexistentes ===== */
[data-i3-permhide]{ display:none !important; }

/* ===== §27 Trava: header sempre segue o tema (evita topbar branco no 1º login) ===== */
:root[data-theme="dark"] header.app-shell__topbar,
:root[data-theme="dark"] header[class*="bg-surface"],
:root[data-theme="dark"] body header{ background-color:var(--surface) !important; }
:root[data-theme="light"] header.app-shell__topbar,
:root[data-theme="light"] header[class*="bg-surface"]{ background-color:var(--surface) !important; }

/* ============================================================================
 * §28 Control plane — painel "Plataformas" (overlay montado no body)
 * ========================================================================== */
body.i3plat-open { overflow: hidden; }
.i3plat { position: fixed; inset: 0; z-index: 10000; font-family: Inter, system-ui, sans-serif; }
.i3plat-back { position: absolute; inset: 0; background: rgba(4, 8, 18, .58); backdrop-filter: blur(2px); }
.i3plat-panel {
  position: absolute; top: 0; right: 0; height: 100%; width: min(760px, 100%);
  background: var(--surface, #0e1626); color: var(--text, #e6ecf5);
  border-left: 1px solid rgba(255,255,255,.08); box-shadow: -18px 0 50px rgba(0,0,0,.4);
  display: flex; flex-direction: column; animation: i3plat-in .18s ease;
}
@keyframes i3plat-in { from { transform: translateX(24px); opacity: .4; } to { transform: none; opacity: 1; } }
.i3plat-head { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border-bottom: 1px solid rgba(255,255,255,.08); }
.i3plat-head b { font-size: 17px; }
.i3plat-sub { font-size: 12px; opacity: .6; }
.i3plat-x { margin-left: auto; background: transparent; border: 0; color: inherit; font-size: 24px; line-height: 1; cursor: pointer; opacity: .7; }
.i3plat-x:hover { opacity: 1; }
.i3plat-body { padding: 16px 18px; overflow-y: auto; flex: 1; }
.i3plat-toolbar { display: flex; gap: 10px; margin-bottom: 14px; }
.i3plat-new { background: #2563eb; color: #fff; border: 0; border-radius: 9px; padding: 9px 14px; font-weight: 600; cursor: pointer; }
.i3plat-new:hover { background: #1d4ed8; }
.i3plat-reload { background: transparent; color: inherit; border: 1px solid rgba(255,255,255,.16); border-radius: 9px; padding: 9px 12px; cursor: pointer; opacity: .85; }
.i3plat-list { display: flex; flex-direction: column; gap: 10px; }
.i3plat-empty { opacity: .6; padding: 26px 4px; text-align: center; }
.i3plat-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid rgba(255,255,255,.08); border-radius: 11px; background: rgba(255,255,255,.03); }
.i3plat-rmain { flex: 1; min-width: 0; }
.i3plat-rname { font-weight: 600; }
.i3plat-tag { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; background: #a855f7; color: #fff; padding: 1px 6px; border-radius: 6px; vertical-align: middle; }
.i3plat-rsub { font-size: 12px; opacity: .6; margin-top: 2px; }
.i3plat-rerr { font-size: 12px; color: #fca5a5; margin-top: 4px; word-break: break-word; }
.i3plat-rseed { font-size: 12px; opacity: .82; margin-top: 4px; }
.i3plat-rseed code { background: rgba(255,255,255,.09); padding: 1px 5px; border-radius: 5px; }
.i3plat-badge { font-size: 11px; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.i3plat-badge.ok { background: rgba(34,197,94,.16); color: #4ade80; }
.i3plat-badge.warn { background: rgba(245,158,11,.16); color: #fbbf24; }
.i3plat-badge.err { background: rgba(239,68,68,.16); color: #f87171; }
.i3plat-badge.mut { background: rgba(148,163,184,.16); color: #cbd5e1; }
.i3plat-ractions { display: flex; gap: 6px; }
.i3plat-b { border: 1px solid rgba(255,255,255,.16); background: transparent; color: inherit; border-radius: 8px; padding: 6px 10px; font-size: 12px; cursor: pointer; }
.i3plat-b:hover { background: rgba(255,255,255,.06); }
.i3plat-b.danger { border-color: rgba(239,68,68,.4); color: #f87171; }
.i3plat-b.danger:hover { background: rgba(239,68,68,.12); }
/* form */
.i3plat-form { border: 1px solid rgba(255,255,255,.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; background: rgba(255,255,255,.03); }
.i3plat-fhead { font-weight: 600; font-size: 15px; margin-bottom: 12px; }
.i3plat-fgrp { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; opacity: .55; margin: 12px 0 6px; }
.i3plat-f { display: grid; grid-template-columns: 150px 1fr; align-items: center; gap: 10px; margin-bottom: 9px; }
.i3plat-f > span { font-size: 13px; opacity: .8; }
.i3plat-f input, .i3plat-f select { width: 100%; background: var(--bg, #0a1120); color: inherit; border: 1px solid rgba(255,255,255,.14); border-radius: 8px; padding: 8px 10px; font: inherit; }
.i3plat-f input[type=color] { padding: 2px; height: 36px; }
.i3plat-slug { display: flex; align-items: center; gap: 6px; }
.i3plat-slug input { flex: 1; }
.i3plat-slug em { opacity: .55; font-style: normal; font-size: 13px; }
.i3plat-ferr { color: #fca5a5; font-size: 13px; min-height: 18px; margin: 4px 0; }
.i3plat-factions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 8px; }
.i3plat-cancel { background: transparent; border: 1px solid rgba(255,255,255,.16); color: inherit; border-radius: 9px; padding: 9px 14px; cursor: pointer; }
.i3plat-save { background: #16a34a; color: #fff; border: 0; border-radius: 9px; padding: 9px 16px; font-weight: 600; cursor: pointer; }
.i3plat-save:hover { background: #15803d; }
.i3plat-save:disabled { opacity: .6; cursor: default; }
/* tema claro */
:root[data-theme="light"] .i3plat-panel { background: #fff; color: #0f172a; border-left-color: rgba(0,0,0,.08); }
:root[data-theme="light"] .i3plat-row, :root[data-theme="light"] .i3plat-form { background: #f8fafc; border-color: rgba(0,0,0,.08); }
:root[data-theme="light"] .i3plat-f input, :root[data-theme="light"] .i3plat-f select { background: #fff; border-color: rgba(0,0,0,.16); }
:root[data-theme="light"] .i3plat-reload, :root[data-theme="light"] .i3plat-b, :root[data-theme="light"] .i3plat-cancel { border-color: rgba(0,0,0,.16); }
:root[data-theme="light"] .i3plat-rseed code { background: rgba(0,0,0,.06); }

/* ==========================================================================
   §29 — Relatórios: exportar em menu, alinhamento da regra de velocidade e
   seletor de tipos de evento com busca. (i3track-relatorios.js)
   ========================================================================== */

/* --- 29.1 exportar: os botões originais somem, fica o ícone --- */
button.i3exp-src { display: none !important; }
.i3exp-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 14px;
  border: 1px solid rgba(255,255,255,.12); border-radius: 8px;
  background: rgba(255,255,255,.04); color: rgba(255,255,255,.85);
  font: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.i3exp-btn:hover { border-color: rgba(255,255,255,.3); color: #fff; background: rgba(255,255,255,.08); }
.i3exp-btn svg { flex: none; }

.i3exp-menu {
  position: fixed; z-index: 9999; min-width: 208px;
  padding: 6px; border-radius: 10px;
  border: 1px solid rgba(255,255,255,.12);
  background: #0f172a; color: #e2e8f0;
  box-shadow: 0 18px 42px rgba(0,0,0,.5);
}
.i3exp-item {
  display: block; width: 100%; text-align: left;
  padding: 9px 12px; border: 0; border-radius: 7px;
  background: transparent; color: inherit; font: inherit; font-size: 14px; cursor: pointer;
}
.i3exp-item:hover:not(:disabled) { background: rgba(255,255,255,.09); }
.i3exp-item:disabled { opacity: .45; cursor: default; }

/* --- 29.2 Relatório de Velocidade: a regra fica na mesma altura dos vizinhos --- */
/* O desalinhamento vinha do checkbox: com 3 colunas apertadas o texto quebrava
   em 2 linhas e esticava o bloco. Damos largura suficiente e deixamos o próprio
   grid esticar os 3 controles até a altura natural do select/input (= a dos
   campos Início/Fim). Nada de altura fixa: se o tema mudar o padding, continua
   acompanhando. */
@media (min-width: 768px) {
  [data-i3-speedrule] {
    grid-template-columns: minmax(104px, 1fr) 88px minmax(178px, 1.3fr) !important;
    align-items: stretch;
  }
  [data-i3-speedrule] > label { white-space: nowrap; padding-top: 0; padding-bottom: 0; }
  /* os campos Início/Fim (datetime-local) medem 40px; select e number param em
     38px, então a linha inteira ficava 2px mais baixa que a dos vizinhos. */
  [data-i3-speedrule] > select,
  [data-i3-speedrule] > input,
  [data-i3-speedrule] > label { min-height: 40px; }
}

/* --- 29.3 tipos de evento: campo de busca com chips --- */
select.i3evt-src { display: none !important; }
.i3evt { position: relative; margin-top: .25rem; }
.i3evt-field {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  min-height: 38px; padding: 5px 8px;
  border: 1px solid rgba(255,255,255,.1); border-radius: 8px; background: rgba(255,255,255,.05);
}
.i3evt.open .i3evt-field { border-color: rgba(59,130,246,.4); }
.i3evt-chips { display: contents; }
.i3evt-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 6px 2px 8px; border-radius: 999px;
  background: rgba(59,130,246,.18); border: 1px solid rgba(59,130,246,.35);
  font-size: 12px; color: #fff; max-width: 100%;
}
.i3evt-chip em { font-style: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.i3evt-chip b { cursor: pointer; opacity: .65; font-weight: 400; font-size: 14px; line-height: 1; }
.i3evt-chip b:hover { opacity: 1; }
.i3evt-input {
  flex: 1 1 110px; min-width: 90px; height: 26px;
  border: 0; background: transparent; outline: none;
  color: #fff; font: inherit; font-size: 14px;
}
.i3evt-input::placeholder { color: rgba(255,255,255,.4); }
.i3evt-list { display: none; }
.i3evt.open .i3evt-list {
  display: block; position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 232px; overflow-y: auto; padding: 5px;
  border: 1px solid rgba(255,255,255,.12); border-radius: 9px;
  background: #0f172a; box-shadow: 0 16px 36px rgba(0,0,0,.5);
}
.i3evt-opt { padding: 7px 10px; border-radius: 6px; font-size: 14px; color: #e2e8f0; cursor: pointer; }
.i3evt-opt:hover { background: rgba(255,255,255,.08); }
.i3evt-opt.on { color: #93c5fd; }
.i3evt-opt.on::after { content: "✓"; float: right; opacity: .8; }
.i3evt-empty { padding: 8px 10px; font-size: 13px; opacity: .55; }

/* --- 29.4 tema claro --- */
:root[data-theme="light"] .i3exp-btn { border-color: rgba(0,0,0,.16); background: #fff; color: #0f172a; }
:root[data-theme="light"] .i3exp-btn:hover { border-color: rgba(0,0,0,.32); background: #f1f5f9; }
:root[data-theme="light"] .i3exp-menu { background: #fff; color: #0f172a; border-color: rgba(0,0,0,.12); }
:root[data-theme="light"] .i3exp-item:hover:not(:disabled) { background: rgba(0,0,0,.06); }
:root[data-theme="light"] .i3evt-field { background: #fff; border-color: rgba(0,0,0,.16); }
:root[data-theme="light"] .i3evt-input { color: #0f172a; }
:root[data-theme="light"] .i3evt-input::placeholder { color: rgba(0,0,0,.4); }
:root[data-theme="light"] .i3evt.open .i3evt-list { background: #fff; border-color: rgba(0,0,0,.12); }
:root[data-theme="light"] .i3evt-opt { color: #0f172a; }
:root[data-theme="light"] .i3evt-opt:hover { background: rgba(0,0,0,.06); }
:root[data-theme="light"] .i3evt-chip { color: #0f172a; }

/* ==========================================================================
   §30 — Serviços: páginas de catálogo "Tipo de Serviços" e "Locais de
   Instalação" (i3track-servicos.js). Ocupam a área de conteúdo do app, à
   direita do menu e abaixo da topbar. O conteúdo reusa as classes do próprio
   app (page-header, data-card...), então herda o visual nativo; aqui só
   posicionamos o container. z-index abaixo do menu (40) p/ o menu continuar
   clicável e acima do conteúdo do React.
   ========================================================================== */
.i3cat {
  position: fixed; right: 0; bottom: 0; z-index: 30;
  overflow-y: auto; overflow-x: hidden;
  padding: 16px;
  /* left/top/background vêm do JS (acompanham menu recolhido, altura da
     topbar e o tema atual) */
}
.i3cat table { border-collapse: collapse; }
/* com a página aberta, o conteúdo do React sai de cena — evita telas com mapa
   (Leaflet usa z-index 400+) vazarem por cima da página de catálogo. */
body.i3cat-open section.app-shell__content { display: none !important; }

/* abas de filtro viram cards de KPI (i3track-servicos.js). As abas originais
   continuam no DOM, só escondidas — o clique no card é repassado a elas. */
.i3sc-abas-ocultas { display: none !important; }
/* uma linha só; o número de colunas vem do JS. Em tela estreita quebra sozinho
   com colunas de largura mínima, senão os cards ficariam ilegíveis. */
.i3sc-cards { display: grid; gap: .75rem; margin-bottom: .25rem; }
@media (max-width: 900px) {
  .i3sc-cards { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)) !important; }
}
.i3sc-card { cursor: pointer; }
.i3sc-card:hover { border-color: rgba(255,255,255,.25); }
.i3sc-card--ativo { box-shadow: inset 0 0 0 2px rgba(56,189,248,.55); }
.i3sc-card--info { cursor: default; opacity: .85; }
.i3sc-card--info:hover { border-color: rgba(255,255,255,.1); }
/* rótulo/valor legíveis também no tema claro */
:root[data-theme="light"] .i3sc-rot { color: rgba(15,23,42,.6); }

/* campo "Serviço" do modal de agendamento: busca por cima do <select> original */
.i3srv { position: relative; }
.i3srv-lista { display: none; }
.i3srv.aberto .i3srv-lista {
  display: block; position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 230px; overflow-y: auto; padding: 5px;
  border: 1px solid rgba(255,255,255,.12); border-radius: 10px;
  background: #0f141c; box-shadow: 0 16px 36px rgba(0,0,0,.5);
}
.i3srv-opt { padding: 8px 10px; border-radius: 7px; font-size: 14px; color: #e2e8f0; cursor: pointer; }
.i3srv-opt:hover { background: rgba(255,255,255,.08); }
.i3srv-vazio { padding: 8px 10px; font-size: 13px; opacity: .55; }

/* ==========================================================================
   §31 — Admin geral: controle "PLATAFORMA" na topbar + painel "Dados Gerais"
   consolidado de plataformas isoladas. (i3track-geral.js)
   ========================================================================== */
/* host = wrapper do seletor de cliente; vira LINHA para PLATAFORMA e CLIENTE
   ficarem lado a lado (antes empilhavam e engordavam a topbar em ~78px). */
header .i3gp-host { display: flex !important; align-items: center; gap: 8px; min-width: 470px !important; }
header .i3gp-host > * { flex: 1 1 0; min-width: 0; }
/* §13.4 fixa o input do cliente em 230px; dentro da linha isso o fazia estourar o
   wrapper e a setinha (absolute no wrapper) sobrava fora do campo. */
header .i3gp-host input[aria-label="Selecionar cliente"] { width: 100% !important; }
/* rótulo "PLATAFORMA" é mais largo que "CLIENTE" — dá um pouco mais de campo */
header .i3gp-host > .i3gp { flex: 1.25 1 0; }

/* pílula na topbar: mesmo desenho do campo CLIENTE — rótulo INLINE dentro do
   campo (§13.4), pill arredondada, chevron à direita. */
.i3gp { position: relative; display: block; }
.i3gp-lab {
  position: absolute; top: 50%; transform: translateY(-50%); left: 15px; z-index: 1; pointer-events: none;
  font: 600 10px/1 'Inter', sans-serif; letter-spacing: .06em; text-transform: uppercase;
  color: var(--placeholder);
}
.i3gp-btn {
  display: flex; align-items: center; width: 100%; height: 40px;
  background: var(--surface-2, rgba(255,255,255,.05)); color: var(--text);
  border: 1px solid var(--border, rgba(255,255,255,.14)); border-radius: 999px;
  padding: 8px 34px 8px 96px; font: inherit; font-size: 13px; cursor: pointer; text-align: left;
}
.i3gp-btn:hover { border-color: var(--placeholder); }
.i3gp-val { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.i3gp-btn svg { position: absolute; right: 13px; top: 50%; transform: translateY(-50%); opacity: .6; flex: none; }
:root[data-theme="light"] .i3gp-btn { background: #fff; border-color: rgba(0,0,0,.14); }
/* launcher fixo (quando não há topbar: master control-plane sem cliente) */
.i3gp--fab { position: fixed; top: 14px; right: 16px; z-index: 9000; width: 300px; }
.i3gp--fab .i3gp-btn { background: var(--surface, #0e1626); box-shadow: 0 8px 26px rgba(0,0,0,.35); }
:root[data-theme="light"] .i3gp--fab .i3gp-btn { background: #fff; border-color: rgba(0,0,0,.1); }

/* dropdown */
.i3gp-drop {
  position: fixed; z-index: 10050; width: 340px; max-width: calc(100vw - 16px);
  background: var(--surface, #0e1626); color: var(--text, #e6ecf5);
  border: 1px solid rgba(255,255,255,.12); border-radius: 12px;
  box-shadow: 0 18px 50px rgba(0,0,0,.45); overflow: hidden; font-size: 14px;
}
:root[data-theme="light"] .i3gp-drop { background: #fff; color: #0f172a; border-color: rgba(0,0,0,.1); }
.i3gp-search { padding: 10px; border-bottom: 1px solid rgba(255,255,255,.08); }
.i3gp-search input { width: 100%; background: var(--bg, #0a1120); color: inherit; border: 1px solid rgba(255,255,255,.14); border-radius: 8px; padding: 8px 10px; font: inherit; }
:root[data-theme="light"] .i3gp-search input { background: #f8fafc; border-color: rgba(0,0,0,.14); }
.i3gp-quick { padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.i3gp-opt { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: transparent; border: 0; color: inherit; border-radius: 8px; padding: 9px 10px; font: inherit; cursor: pointer; }
.i3gp-opt em { margin-left: auto; font-style: normal; font-size: 11px; opacity: .5; }
.i3gp-opt:hover { background: rgba(255,255,255,.07); }
:root[data-theme="light"] .i3gp-opt:hover { background: rgba(0,0,0,.05); }
.i3gp-sec, .i3gp-sec2 { font-size: 10px; text-transform: uppercase; letter-spacing: .07em; opacity: .5; padding: 8px 12px 4px; }
.i3gp-list { max-height: 320px; overflow-y: auto; padding: 4px 6px 8px; }
.i3gp-empty { opacity: .55; padding: 16px 10px; text-align: center; font-size: 13px; }
.i3gp-prow { display: flex; align-items: center; gap: 6px; }
.i3gp-pmain { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; background: transparent; border: 0; color: inherit; border-radius: 8px; padding: 8px 10px; font: inherit; cursor: pointer; text-align: left; }
.i3gp-pmain:hover { background: rgba(255,255,255,.07); }
:root[data-theme="light"] .i3gp-pmain:hover { background: rgba(0,0,0,.05); }
.i3gp-pname { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.i3gp-doc { font-style: normal; font-size: 11px; opacity: .55; font-weight: 400; }
.i3gp-pcount { font-size: 11px; opacity: .55; }
.i3gp-enter { flex: none; background: transparent; color: var(--primary, #66A3FF); border: 1px solid rgba(102,163,255,.35); border-radius: 8px; padding: 6px 9px; font-size: 12px; cursor: pointer; }
.i3gp-enter:hover { background: rgba(102,163,255,.12); }
/* plataforma sem container no ar: entrar levaria a uma tela morta */
.i3gp-enter--off { color: var(--muted, #A1A1A1); border-color: var(--border, #2E2E2E); cursor: not-allowed; }
.i3gp-enter--off:hover { background: transparent; }
.i3gp-fora { font-weight: 500; font-size: 11px; color: var(--warning, #F59E0B);
  border: 1px solid rgba(245,158,11,.35); border-radius: 999px; padding: 1px 6px; margin-left: 6px; }

/* painel Dados Gerais (overlay) */
body.i3ov-open { overflow: hidden; }
.i3ov { position: fixed; inset: 0; z-index: 10001; font-family: Inter, system-ui, sans-serif; }
.i3ov-back { position: absolute; inset: 0; background: rgba(4,8,18,.58); backdrop-filter: blur(2px); }
.i3ov-panel { position: absolute; top: 0; right: 0; height: 100%; width: min(720px, 100%); background: var(--surface, #0e1626); color: var(--text, #e6ecf5); border-left: 1px solid rgba(255,255,255,.08); box-shadow: -18px 0 50px rgba(0,0,0,.4); display: flex; flex-direction: column; animation: i3plat-in .18s ease; }
:root[data-theme="light"] .i3ov-panel { background: #fff; color: #0f172a; border-left-color: rgba(0,0,0,.08); }
.i3ov-head { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border-bottom: 1px solid rgba(255,255,255,.08); }
.i3ov-head b { font-size: 17px; }
.i3ov-sub { font-size: 12px; opacity: .6; }
.i3ov-x { margin-left: auto; background: transparent; border: 0; color: inherit; font-size: 24px; line-height: 1; cursor: pointer; opacity: .7; }
.i3ov-x:hover { opacity: 1; }
.i3ov-body { padding: 16px 18px; overflow-y: auto; flex: 1; }
.i3ov-band { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; margin-bottom: 18px; }
.i3ov-kpi { border: 1px solid rgba(255,255,255,.08); border-radius: 12px; background: rgba(255,255,255,.03); padding: 14px; border-left: 3px solid var(--primary, #0052E6); }
:root[data-theme="light"] .i3ov-kpi { background: #f8fafc; border-color: rgba(0,0,0,.08); }
.i3ov-kpi-v { font-size: 26px; font-weight: 700; line-height: 1; }
.i3ov-kpi-l { font-size: 12px; opacity: .6; margin-top: 6px; }
.i3ov-sec { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; opacity: .55; margin: 6px 0 8px; }
.i3ov-cards { display: flex; flex-direction: column; gap: 10px; }
.i3ov-card { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; border: 1px solid rgba(255,255,255,.08); border-radius: 11px; background: rgba(255,255,255,.03); padding: 12px 14px; }
:root[data-theme="light"] .i3ov-card { background: #f8fafc; border-color: rgba(0,0,0,.08); }
.i3ov-cname { font-weight: 600; }
.i3ov-tag { font-size: 11px; font-weight: 600; letter-spacing: .01em; padding: 1px 7px; border-radius: 6px; vertical-align: middle; margin-left: 6px; }
.i3ov-tag.base { background: rgba(102,163,255,.2); color: #66A3FF; }
.i3ov-tag.err { background: rgba(239,68,68,.18); color: #f87171; }
/* situação comercial da plataforma */
.i3ov-tag.ok { background: rgba(34,197,94,.18); color: #4ade80; }
.i3ov-tag.warn { background: rgba(245,158,11,.18); color: #fbbf24; }
.i3ov-tag.test { background: rgba(148,163,184,.20); color: #cbd5e1; }
.i3ov-note { display: block; margin-top: 6px; font-size: 12px; opacity: .6; }
.i3ov-sit { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.i3ov-sit .i3ov-note { margin: 0; }
/* busca dentro do painel Dados Gerais */
.i3ov-find { margin-bottom: 10px; }
.i3ov-find input {
  width: 100%; background: var(--bg, #0a1120); color: inherit;
  border: 1px solid rgba(255,255,255,.14); border-radius: 999px;
  padding: 9px 14px; font: inherit; font-size: 13px;
}
.i3ov-find input:focus { outline: none; border-color: var(--placeholder, rgba(255,255,255,.35)); }
:root[data-theme="light"] .i3ov-find input { background: #fff; border-color: rgba(0,0,0,.14); }
.i3ov-nores { padding: 18px 10px; text-align: center; font-size: 13px; opacity: .55; }
.i3ov-crow { font-size: 13px; opacity: .7; }
.i3ov-crow span { font-weight: 700; opacity: 1; }
.i3ov-enter { background: var(--primary, #0052E6); color: #fff; border: 0; border-radius: 9px; padding: 9px 14px; font-weight: 600; cursor: pointer; }
.i3ov-enter:hover { filter: brightness(1.08); }
.i3ov-enter.sm { margin-left: auto; padding: 6px 11px; font-size: 12px; }
.i3ov-enterbig { margin-top: 20px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.i3ov-hint { font-size: 12px; opacity: .55; }




/* ==========================================================================
   §32 — Scrollbars no padrão da marca (substitui a barra nativa do navegador,
   que aparecia clara/cinza no painel geral e nas tabelas).
   ========================================================================== */
/* sem `color-scheme` o Chrome desenha a barra nativa CLARA mesmo em tema escuro
   — a classe `dark` do Tailwind não informa isso ao navegador. */
:root { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
* {
  scrollbar-width: thin;                                   /* Firefox */
  scrollbar-color: var(--scroll-thumb, rgba(255,255,255,.18)) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb, rgba(255,255,255,.18));
  border: 2px solid transparent;                           /* "respiro" ao redor do polegar */
  background-clip: padding-box;
  border-radius: 999px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover, rgba(255,255,255,.32)); background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }
:root[data-theme="light"] {
  --scroll-thumb: rgba(15,23,42,.20);
  --scroll-thumb-hover: rgba(15,23,42,.35);
}
/* barras finas em áreas compactas (dropdowns, listas internas) */
.i3gp-list::-webkit-scrollbar, .i3ov-body::-webkit-scrollbar { width: 8px; }

/* ==========================================================================
   §33 — Tela "Plataformas" (i3track-plataformas-pagina.js). Mesmo padrão do
   §32/.i3cat: a tela é montada por cima da área de conteúdo do React, abaixo
   da topbar REAL e à direita do menu REAL (left = --i3duo-w). Cores só por
   token de tema — claro e escuro saem de graça.
   ========================================================================== */
.i3plat-pg {
  position: fixed; right: 0; bottom: 0; z-index: 30;
  overflow-y: auto; overflow-x: hidden; padding: 20px;
  /* left/top/background vêm do JS */
}
body.i3plat-pg-open section.app-shell__content { display: none !important; }

.i3pp-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.i3pp-head h1 { font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -.02em; color: var(--text); }
.i3pp-sub { font-size: 12px; color: var(--sub); margin: 2px 0 0; }
.i3pp-acoes { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.i3pp-busca {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 999px; padding: 9px 16px; font: inherit; font-size: 13px; width: 320px; max-width: 100%;
}
.i3pp-busca::placeholder { color: var(--placeholder); }
.i3pp-busca:focus { outline: none; border-color: var(--sub); }
.i3pp-b {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
  display: inline-block; text-decoration: none;
}
.i3pp-b:hover { border-color: var(--placeholder); }
.i3pp-b.primario { background: rgba(37,99,235,.14); border-color: rgba(37,99,235,.45); color: #66A3FF; }
:root[data-theme="light"] .i3pp-b.primario { background: rgba(37,99,235,.1); color: #2563EB; }

/* Duas ações na última coluna da grade de plataformas: ver e entrar. Sem o
   nowrap o "Entrar ↗" cai para a linha de baixo e a linha da tabela cresce. */
.i3pp-b.perigo { background: rgba(220,38,38,.12); border-color: rgba(220,38,38,.45); color: #F87171; }
:root[data-theme="light"] .i3pp-b.perigo { background: rgba(220,38,38,.08); color: #DC2626; }
.i3pp-b.perigo:hover { border-color: rgba(220,38,38,.75); }
.i3pp-acoes-linha { white-space: nowrap; }
.i3pp-acoes-linha .i3pp-b + .i3pp-b { margin-left: 6px; }
.i3pp-link {
  background: none; border: 0; padding: 0; font: inherit; font-weight: 600; color: var(--text);
  cursor: pointer; display: block; text-align: left;
}
.i3pp-link:hover { color: var(--primary); }

.i3pp-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; }
.i3pp-kpi { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
.i3pp-kpi .v { font-size: 26px; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.i3pp-kpi .l { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--sub); margin-top: 2px; }

.i3pp-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.i3pp-card.p { padding: 16px; overflow: visible; }
.i3pp-card.largo { grid-column: 1 / -1; }
.i3pp-card > h3 { margin: 0 0 12px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--sub); }
.i3pp-card-top { display: flex; align-items: baseline; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); color: var(--text); }
.i3pp-cartoes { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }

.i3pp-rolagem { overflow-x: auto; }
table.i3pp-grade { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 980px; }
table.i3pp-grade th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--sub); font-weight: 600; padding: 10px 14px; border-bottom: 1px solid var(--border);
  white-space: nowrap; cursor: pointer; user-select: none;
}
table.i3pp-grade th:hover { color: var(--text); }
table.i3pp-grade th.num, table.i3pp-grade td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.i3pp-grade td { padding: 12px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; color: var(--text); }
table.i3pp-grade tbody tr:last-child td { border-bottom: 0; }
table.i3pp-grade tbody tr:hover { background: var(--surface-2); }
table.i3pp-grade td.vazio { text-align: center; color: var(--sub); padding: 28px; }
.i3pp-dom { display: block; font-size: 11px; color: var(--sub); }
.i3pp-obs { display: block; font-size: 11px; color: var(--sub); margin-top: 3px; }

.i3pp-tag { display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: .01em; padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
.i3pp-tag.ok { background: rgba(34,197,94,.16); color: #16A34A; }
.i3pp-tag.warn { background: rgba(245,158,11,.16); color: #D97706; }
.i3pp-tag.err { background: rgba(239,68,68,.16); color: #DC2626; }
.i3pp-tag.test { background: rgba(148,163,184,.2); color: var(--sub); }
.i3pp-tag.info { background: rgba(37,99,235,.16); color: #2563EB; }
.i3pp-tag.mae { background: rgba(168,85,247,.16); color: #9333EA; }
:root[data-theme="dark"] .i3pp-tag.ok { color: #4ADE80; }
:root[data-theme="dark"] .i3pp-tag.warn { color: #FBBF24; }
:root[data-theme="dark"] .i3pp-tag.err { color: #F87171; }
:root[data-theme="dark"] .i3pp-tag.info { color: #66A3FF; }
:root[data-theme="dark"] .i3pp-tag.mae { color: #C084FC; }

.i3pp-cota { min-width: 120px; }
.i3pp-cota .barra { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.i3pp-cota .barra i { display: block; height: 100%; background: #16A34A; }
.i3pp-cota.atencao .barra i { background: #D97706; }
.i3pp-cota.estourada .barra i { background: #DC2626; }
.i3pp-cota .txt { font-size: 11px; color: var(--sub); margin-top: 3px; }
.i3pp-cota.sem { color: var(--placeholder); font-size: 11px; }
.i3pp-cota.grande .barra { height: 10px; }
.i3pp-cota.grande .num-cota { font-size: 22px; font-weight: 700; margin-bottom: 6px; color: var(--text); }

.i3pp-abas { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
.i3pp-abas .aba {
  background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--sub);
  font: inherit; font-size: 13px; font-weight: 500; padding: 10px 16px; cursor: pointer;
}
.i3pp-abas .aba:hover { color: var(--text); }
.i3pp-abas .aba.ativa { color: var(--text); border-bottom-color: var(--primary); }

.i3pp-alerta {
  border-radius: 12px; padding: 12px 16px; font-size: 13px; margin-bottom: 16px;
  border: 1px solid rgba(245,158,11,.35); background: rgba(245,158,11,.1); color: #B45309;
}
:root[data-theme="dark"] .i3pp-alerta { color: #FCD34D; }
.i3pp-alerta.grave { border-color: rgba(239,68,68,.4); background: rgba(239,68,68,.1); color: #B91C1C; }
:root[data-theme="dark"] .i3pp-alerta.grave { color: #FCA5A5; }

dl.i3pp-campos { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; margin: 0; font-size: 13px; color: var(--text); }
dl.i3pp-campos dt { color: var(--sub); }
dl.i3pp-campos dd { margin: 0; }

.i3pp-linha { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.i3pp-linha label { font-size: 12px; color: var(--sub); min-width: 190px; }
.i3pp-linha input, .i3pp-linha select, .i3pp-linha textarea {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px; font: inherit; font-size: 13px; flex: 1; min-width: 120px;
}
.i3pp-linha input:focus, .i3pp-linha select:focus, .i3pp-linha textarea:focus { outline: none; border-color: var(--placeholder); }
.i3pp-linha input[type=checkbox] { flex: none; min-width: 0; width: 16px; height: 16px; accent-color: var(--primary); }
.i3pp-acoes-form { display: flex; gap: 8px; margin-top: 12px; align-items: center; }
.i3pp-salvo { font-size: 12px; color: #16A34A; }
:root[data-theme="dark"] .i3pp-salvo { color: #4ADE80; }
.i3pp-dica { font-size: 12px; color: var(--sub); margin: 8px 0 0; }

table.i3pp-mini { width: 100%; border-collapse: collapse; font-size: 13px; color: var(--text); }
table.i3pp-mini th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--sub); font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--border);
}
table.i3pp-mini th.num, table.i3pp-mini td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.i3pp-mini td { padding: 9px 10px; border-bottom: 1px solid var(--border); }
table.i3pp-mini tfoot td { font-weight: 700; border-bottom: 0; border-top: 1px solid var(--border); }

.i3pp-graficos { display: grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 16px; }
.i3pp-gr { position: relative; height: 240px; }

.i3pp-tempo { list-style: none; margin: 0; padding: 0; font-size: 13px; color: var(--text); }
.i3pp-tempo li { padding: 10px 0 10px 16px; border-left: 2px solid var(--border); position: relative; }
.i3pp-tempo li::before {
  content: ""; position: absolute; left: -5px; top: 15px; width: 8px; height: 8px;
  border-radius: 999px; background: var(--primary);
}
.i3pp-tempo .quando { font-size: 11px; color: var(--sub); }
/* Item "Plataformas" ativo no menu enquanto a tela está aberta. Isso É CSS de
   propósito: o Duo redesenha os itens a cada 700ms, então marcar a classe por
   JS fazia o item PISCAR. Ligado ao estado do body, sobrevive a qualquer
   redesenho sem precisar de timer. */
body.i3plat-pg-open #i3duo-items .i3duo-item[data-href="#plataformas"] {
  background: var(--i3sactive); color: #fff; font-weight: 600;
}
body.i3plat-pg-open #i3duo-items .i3duo-item[data-href="#plataformas"] .d { opacity: 1; }
body.i3plat-pg-open #i3duo-items .i3duo-item[data-href="#plataformas"]::before {
  content: ""; position: absolute; left: -10px; top: 8px; bottom: 8px; width: 3px;
  border-radius: 0 3px 3px 0; background: #fff;
}

/* §34 — /dashboard fora de uso (i3track-rotas.js reescreve para /home).
   Esconde qualquer link remanescente para ela no sidebar do React. */
.app-shell__sidebar a[href="/dashboard"],
.app-shell__sidebar div:has(> a[href="/dashboard"]) { display: none !important; }
/* filtro de período do painel da plataforma + uso de vídeo medido no banco */
.i3pp-periodo {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px;
}
.i3pp-periodo label { font-size: 12px; color: var(--sub); }
.i3pp-periodo input[type=date] {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 7px 10px; font: inherit; font-size: 13px;
}
.i3pp-periodo input[type=date]:focus { outline: none; border-color: var(--placeholder); }
.i3pp-periodo .i3pp-sub { margin-left: auto; }
.i3pp-medido { flex: 1; font-size: 13px; font-weight: 600; color: var(--text); }

/* ==========================================================================
   §35 — Monitoramento refeito (i3track-monitoramento.js). Mesmo encaixe das
   demais telas injetadas: cobre a área de conteúdo, topbar e menu reais.
   ========================================================================== */
.i3mon {
  position: fixed; right: 0; bottom: 0; z-index: 30;
  display: flex; flex-direction: column; overflow: hidden;
}
body.i3mon-open section.app-shell__content { display: none !important; }

/* barra de filtros */
.i3mon-barra {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface);
}
/* campos no estilo da topbar: pílula, fundo do mesmo tom da borda (o miolo
   estava mais claro que o campo e destoava) */
.i3mon-campo {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 9px 16px; font: inherit; font-size: 13px; flex: 0 1 300px; min-width: 160px;
}
.i3mon-campo::placeholder { color: var(--placeholder); }
.i3mon-campo:focus { outline: none; border-color: var(--sub); }
.i3mon-campo::-webkit-search-cancel-button { filter: invert(.5); }

.i3mon-b {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.i3mon-b:hover { border-color: var(--placeholder); }
.i3mon-b.icone { width: 36px; height: 36px; padding: 0; justify-content: center; color: var(--sub); font-size: 15px; }
.i3mon-b.mini { padding: 5px 9px; font-size: 12px; }
.i3mon-menu { position: relative; }
.i3mon-contagem { margin-left: auto; font-size: 12px; color: var(--sub); }

/* quantos veículos por página + navegação, ao lado da contagem */
.i3mon-porpag { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--sub); }
.i3mon-porpag select {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 8px; font: inherit; font-size: 12px;
}
.i3mon-pag { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--sub); }
.i3mon-pag .i3mon-b.icone { width: 28px; height: 28px; font-size: 13px; }
.i3mon-pag span { padding: 0 4px; white-space: nowrap; }

/* sugestões dos campos de busca (veículo e endereço) */
.i3mon-sugbox { position: relative; display: flex; }
.i3mon-sug {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 10040;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 18px 50px rgba(0,0,0,.45); overflow: hidden auto; max-height: 320px; padding: 4px;
}
.i3mon-sug button {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  background: transparent; border: 0; color: inherit; border-radius: 8px;
  padding: 8px 10px; font: inherit; cursor: pointer;
}
.i3mon-sug button:hover { background: var(--surface-2); }
.i3mon-sug button strong { font-size: 13px; font-weight: 600; }
.i3mon-sug button span {
  font-size: 11px; color: var(--sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.i3mon-sug-vazio { padding: 12px; font-size: 12px; color: var(--sub); text-align: center; }

/* corpo: mapa + tabela, alternável */
/* respiro lateral: coladinho na borda a última coluna ficava cortada */
.i3mon-corpo { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 0 14px 14px; }
.i3mon-mapa { flex: 0 0 45%; min-height: 160px; border-radius: 12px; overflow: hidden; position: relative; }
/* !important porque o CSS do Leaflet e o do Mapbox GL entram no <head> DEPOIS
   do brand.css e aplicam `position:relative` no próprio container — com isso o
   `inset:0` perdia efeito e o mapa 3D ficava com altura 0. */
.i3mon-mapa2d, .i3mon-mapa3d {
  position: absolute !important; inset: 0 !important;
  width: 100% !important; height: 100% !important;
}
.i3mon-mapa2d[hidden], .i3mon-mapa3d[hidden] { display: none !important; }
/* o logotipo e a atribuição do Mapbox saem de cima do mapa: o crédito fica
   dentro do botão do símbolo da i3track, junto com o resto */
.i3mon-mapa3d .mapboxgl-ctrl-logo,
.i3mon-mapa3d .mapboxgl-ctrl-attrib,
.i3mon-mapa3d .mapboxgl-ctrl-bottom-left,
.i3mon-mapa3d .mapboxgl-ctrl-bottom-right { display: none !important; }

/* ícones dentro do próprio mapa: zoom, escolher mapa, 3D e créditos.
   Ancorados EM CIMA, crescendo para baixo.

   Estavam ancorados embaixo e subindo — no mesmo canto onde mora o botão
   flutuante "Registrar Roubo/Furto" (#i3-oc-fab, right:22px bottom:22px). Com o
   mapa ocupando a tela toda a pilha chegava lá e o botão comia os ícones de
   baixo. Anda para cima e o conflito acaba: o canto de baixo fica para a ação,
   o de cima para os controles do mapa.

   Se não couber numa coluna, quebra para o lado — não some por cima do mapa. */
.i3mon-ctrl {
  position: absolute; right: 10px; top: 10px; bottom: auto; z-index: 500;
  display: flex; flex-direction: column; gap: 6px;
  max-height: calc(100% - 76px); flex-wrap: wrap; align-content: flex-end;
}
.i3mon-mb {
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: 9px; font: inherit; font-size: 15px; font-weight: 600; line-height: 1;
  cursor: pointer; box-shadow: 0 4px 14px rgba(0,0,0,.28); padding: 0;
}
.i3mon-mb:hover { border-color: var(--primary); }
.i3mon-mb.ativo { border-color: var(--primary); color: var(--primary); }
.i3mon-mb[data-b3d] { font-size: 12px; letter-spacing: .02em; }
/* bússola: a agulha gira junto com o mapa e o botão se destaca quando o mapa
   está torto, para o usuário saber que dá para voltar ao norte num clique */
.i3mon-mb.bussola { cursor: grab; }
.i3mon-mb.bussola:active { cursor: grabbing; }
/* a agulha gira com o mapa e "deita" conforme o ângulo de visão: de cima ela
   fica redonda, inclinada ela vira elipse — igual à visão do mapa */
.i3mon-mb.bussola svg {
  transform: perspective(70px) rotateX(var(--inclina, 0deg)) rotate(var(--giro, 0deg));
  transition: transform .1s linear;
}
.i3mon-mb.bussola.torto { border-color: var(--primary); color: var(--primary); }
.i3mon-mb.credito { overflow: hidden; }
.i3mon-mb.credito img { width: 20px; height: 20px; object-fit: contain; display: block; }
.i3mon-cred { padding: 6px 10px 10px; font-size: 12px; color: var(--sub); line-height: 1.5; }
.i3mon-cred a { color: var(--primary); }
.i3mon-cred.fraco { padding-top: 0; font-size: 11px; opacity: .8; }
/* ---- marcador do veículo (mesmo desenho no 2D do Leaflet e no 3D do GL) ----
   verde = ignição ligada, vermelho = desligada, cinza = o equipamento não
   informou. A seta gira com o rumo (--rumo) e o glifo continua em pé. */
.i3-marca-wrap { background: none !important; border: 0 !important; }
.i3-marca {
  position: relative; width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; filter: drop-shadow(0 3px 6px rgba(0,0,0,.45));
}
.i3-marca .anel {
  position: absolute; left: 50%; top: 50%; width: 32px; height: 32px;
  margin: -16px 0 0 -16px; border-radius: 50%;
  background: rgba(15,23,42,.88); border: 2px solid #94A3B8;
  transition: box-shadow .15s ease;
}
/* o desenho e a seta usam currentColor: a cor sai do estado da ignição */
/* quatro estados: verde ligada, vermelho desligada, amarelo em sindicância,
   cinza sem comunicação */
.i3-marca[data-estado="ligada"] { color: #22C55E; }
.i3-marca[data-estado="desligada"] { color: #EF4444; }
.i3-marca[data-estado="sindicancia"] { color: #F59E0B; }
.i3-marca[data-estado="offline"] { color: #9CA3AF; }
.i3-marca[data-estado="ligada"] .anel { border-color: #22C55E; box-shadow: 0 0 0 3px rgba(34,197,94,.22); }
.i3-marca[data-estado="desligada"] .anel { border-color: #EF4444; box-shadow: 0 0 0 3px rgba(239,68,68,.20); }
.i3-marca[data-estado="sindicancia"] .anel { border-color: #F59E0B; box-shadow: 0 0 0 3px rgba(245,158,11,.24); }
.i3-marca[data-estado="offline"] .anel { border-color: #9CA3AF; box-shadow: 0 0 0 3px rgba(156,163,175,.18); }
.i3-marca .glifo.emoji { font-size: 17px; line-height: 1; display: block; }
.i3-marca img.glifo { object-fit: contain; border-radius: 4px; }
.i3-marca:hover .anel { box-shadow: 0 0 0 5px rgba(37,99,235,.28); }
/* o clique tem que valer para o marcador inteiro, e não para o traço do desenho */
.i3-marca > * { pointer-events: none; }
.i3-marca .glifo { position: relative; width: 21px; height: 21px; }
.i3-marca .seta {
  position: absolute; left: 50%; top: 50%; width: 13px; height: 13px;
  margin: -6.5px 0 0 -6.5px; transform-origin: 50% 50%;
  transform: rotate(var(--rumo, 0deg)) translateY(-22px);
}
.i3-marca .rotulo {
  position: absolute; top: 100%; left: 50%; transform: translate(-50%, -2px);
  max-width: 132px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 1px 6px; border-radius: 6px; font-size: 11px; font-weight: 600; line-height: 1.5;
  background: rgba(15,23,42,.86); color: #F1F5F9; border: 1px solid rgba(148,163,184,.35);
}
.i3-marca .rotulo:empty { display: none; }

/* agrupamento: o disco com a quantidade.
   Era um círculo azul chapado com borda branca de 3px — pesado sobre o mapa e
   com o azul cravado, que numa revenda de outra cor ficava fora do conjunto.
   Agora é vidro escuro com anel fino na cor da plataforma (`--primary`, que o
   §55 já troca por revenda) e um halo que respira devagar. O tamanho vem do
   JS em `--i3g-tam`, porque quantidade maior merece disco maior. */
.i3-grupo-wrap { background: none !important; border: 0 !important; }
.i3-grupo {
  position: relative; width: var(--i3g-tam, 40px); height: var(--i3g-tam, 40px);
  display: grid; place-items: center; border-radius: 50%;
  background:
    radial-gradient(circle at 50% 38%, rgba(255,255,255,.10), rgba(255,255,255,0) 60%),
    rgba(11,15,25,.78);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1.5px solid color-mix(in srgb, var(--primary, #0052E6) 85%, #fff);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.45),
    0 6px 18px rgba(0,0,0,.42),
    0 0 22px color-mix(in srgb, var(--primary, #0052E6) 38%, transparent);
  cursor: pointer;
  transition: transform .14s ease, box-shadow .14s ease;
}
.i3-grupo-num {
  position: relative; z-index: 1;
  color: #fff; font-weight: 650; font-size: 14px; line-height: 1;
  font-variant-numeric: tabular-nums; letter-spacing: .2px;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
/* O halo é um anel SEPARADO, fora do disco: pulsar a borda do próprio disco
   faria o número tremer junto. */
.i3-grupo-halo {
  position: absolute; inset: -6px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--primary, #0052E6) 55%, transparent);
  opacity: .75;
  animation: i3-grupo-respira 2.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes i3-grupo-respira {
  0%, 100% { transform: scale(1); opacity: .55; }
  50%      { transform: scale(1.14); opacity: 0; }
}
.i3-grupo:hover {
  transform: scale(1.07);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.45),
    0 8px 22px rgba(0,0,0,.5),
    0 0 30px color-mix(in srgb, var(--primary, #0052E6) 60%, transparent);
}
/* Quem pediu para o sistema não se mexer não deve ganhar um mapa piscando. */
@media (prefers-reduced-motion: reduce) {
  .i3-grupo-halo { animation: none; }
}
/* No mapa claro o vidro escuro continua legível, mas o halo some no branco:
   ganha um pouco mais de corpo. */
:root[data-theme="light"] .i3-grupo-halo { opacity: .9; }

/* balão de detalhes: cartão preso na TELA (não dentro do mapa), para caber
   mesmo quando a faixa do mapa está baixa — pode passar por cima do grid */
.i3-balao-flut {
  position: fixed; z-index: 10080; width: max-content; max-width: min(340px, calc(100vw - 20px));
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0,0,0,.5);
}
.i3-balao-flut[hidden] { display: none !important; }
.i3-balao-flut.fixado { border-color: var(--primary); }
.i3-balao-x {
  position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; padding: 0;
  display: none; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 6px;
  color: var(--sub); font-size: 17px; line-height: 1; cursor: pointer;
}
.i3-balao-flut.fixado .i3-balao-x { display: flex; }
.i3-balao-x:hover { background: var(--surface-2); color: var(--text); }

/* balão de detalhes do marcador */
.i3-popup .leaflet-popup-content-wrapper,
.i3-popup .mapboxgl-popup-content {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 18px 46px rgba(0,0,0,.45); padding: 0;
}
.i3-popup .leaflet-popup-content { margin: 0; width: auto !important; }
.i3-popup .leaflet-popup-tip { background: var(--surface); border: 1px solid var(--border); }
.i3-popup .mapboxgl-popup-tip { border-top-color: var(--surface); border-bottom-color: var(--surface); }
.i3-popup .leaflet-popup-close-button,
.i3-popup .mapboxgl-popup-close-button { color: var(--sub); font-size: 18px; }
.i3-balao { padding: 12px 14px 12px; min-width: 236px; font-size: 13px; }
.i3-balao > strong { display: block; font-size: 15px; font-weight: 700; }
.i3-balao > .sub { display: block; color: var(--sub); font-size: 12px; margin-top: 1px; }
.i3-balao > .sub:empty { display: none; }
.i3-balao .linhas {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
  margin: 10px 0 0; padding-top: 9px; border-top: 1px solid var(--border);
}
.i3-balao .linhas span { color: var(--sub); font-size: 12px; }
.i3-balao .linhas b { font-weight: 600; text-align: right; word-break: break-word; }
.i3-balao .pes { display: flex; gap: 8px; margin-top: 11px; }
.i3-balao .pes .i3mon-b { flex: 1 1 auto; justify-content: center; text-decoration: none; }
.i3mon-aviso {
  position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 10060;
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 16px; font-size: 13px; box-shadow: 0 14px 40px rgba(0,0,0,.45);
}
.i3mon-tabela {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface);
}

/* divisória arrastável entre mapa e tabela, com a porcentagem */
.i3mon-divisor {
  height: 14px; flex: 0 0 14px; cursor: row-resize; position: relative;
  display: flex; align-items: center; justify-content: center;
}
.i3mon-divisor::before {
  content: ""; position: absolute; left: 0; right: 0; top: 6px; height: 2px;
  background: var(--border); border-radius: 2px;
}
.i3mon-divisor:hover::before { background: var(--primary); }
.i3mon-pct {
  position: relative; z-index: 1; font-size: 10px; color: var(--sub);
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px;
}
body.i3mon-arrastando { cursor: row-resize; user-select: none; }
body.i3mon-arrastando-col { cursor: col-resize; user-select: none; }

/* endereço + raio grudados, como um campo só */
.i3mon-endgrupo { display: flex; align-items: stretch; flex: 0 1 420px; min-width: 220px; }
.i3mon-endgrupo .i3mon-campo { flex: 1; border-radius: 999px 0 0 999px; border-right: 0; min-width: 0; }
.i3mon-raio {
  display: flex; align-items: center; gap: 3px; padding: 0 12px 0 8px;
  background: var(--surface-2); border: 1px solid var(--border); border-left: 1px solid var(--border);
  border-radius: 0 999px 999px 0; font-size: 12px; color: var(--sub);
}
.i3mon-raio input {
  width: 46px; background: transparent; border: 0; color: var(--text);
  font: inherit; font-size: 13px; text-align: right; padding: 0;
}
.i3mon-raio input:focus { outline: none; }

/* cabeçalho: título + filtro (Excel) + puxador de largura */
.i3mon-th { display: inline-flex; align-items: center; gap: 6px; }
.i3mon-th i { font-style: normal; }
.i3mon-filtro {
  background: transparent; border: 0; color: var(--placeholder); cursor: pointer;
  padding: 2px; border-radius: 4px; line-height: 0;
}
.i3mon-filtro:hover { color: var(--text); background: var(--surface-2); }
.i3mon-filtro.ativo { color: var(--primary); }
.i3mon-puxador {
  position: absolute; top: 0; right: 0; width: 6px; height: 100%;
  cursor: col-resize; user-select: none;
}
.i3mon-puxador:hover, .i3mon-puxador.arrastando { background: var(--primary); opacity: .55; }

/* comando livre na aba Comandos */
.i3mon-livre { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.i3mon-livre input {
  flex: 1 1 260px; max-width: 420px; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; font: inherit; font-size: 13px;
}
.i3mon-livre input:focus { outline: none; border-color: var(--primary); }

/* endereço ainda não resolvido: em vez de "—" ou "pending", um botão que
   busca o endereço na hora */
.i3mon-verend {
  background: transparent; border: 0; padding: 0; font: inherit; font-size: 13px;
  color: var(--primary); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.i3mon-verend:hover { color: var(--primary-hover); }
.i3mon-verend[disabled] { color: var(--sub); cursor: default; text-decoration: none; }
.i3mon-semend { color: var(--placeholder); }
.i3mon-busca-col { padding: 6px 8px; }
.i3mon-busca-col input {
  width: 100%; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; padding: 7px 10px; font: inherit; font-size: 13px;
}
.i3mon-busca-col input:focus { outline: none; border-color: var(--placeholder); }
.i3mon-drop-pe { display: flex; gap: 6px; }
.i3mon-b.primario { background: rgba(37,99,235,.14); border-color: rgba(37,99,235,.45); color: #66A3FF; }
:root[data-theme="light"] .i3mon-b.primario { background: rgba(37,99,235,.1); color: #2563EB; }
table.i3mon-grade tbody tr[data-v] { cursor: pointer; }
/* última coluna: abrir a posição no Google Maps (o botão "Detalhes" saiu — a
   linha inteira já abre o detalhe) */
.i3mon-gmaps {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px; color: var(--sub);
  border: 1px solid var(--border); background: var(--surface-2); text-decoration: none;
}
.i3mon-gmaps:hover { color: var(--primary); border-color: var(--primary); }
.i3mon-semgps { color: var(--placeholder); }
/* "Só o mapa" / "Só a tabela": quem sobra ocupa 100% e a divisória some
   (antes ficava a listra com "85% / 15%" no meio da tela) */
.i3mon-corpo[data-modo="mapa"] .i3mon-tabela,
.i3mon-corpo[data-modo="tabela"] .i3mon-mapa,
.i3mon-corpo[data-modo="mapa"] .i3mon-divisor,
.i3mon-corpo[data-modo="tabela"] .i3mon-divisor { display: none !important; }
.i3mon-corpo[data-modo="mapa"] .i3mon-mapa { flex: 1 1 auto !important; }
.i3mon-corpo[data-modo="tabela"] .i3mon-tabela { flex: 1 1 auto !important; border-top: 0; }
.i3mon-rolagem { flex: 1; min-height: 0; overflow: auto; }

/* largura fixa: é o que faz o puxador de largura valer de verdade. Com a
   largura automática o navegador redistribuía tudo e a coluna voltava sozinha. */
table.i3mon-grade {
  width: max-content; min-width: 100%; table-layout: fixed;
  border-collapse: collapse; font-size: 13px;
}
table.i3mon-grade th.acao, table.i3mon-grade tbody td:nth-last-child(2) { width: 62px; }
/* coluna de folga: fica com a sobra, para dar e TIRAR largura das outras */
table.i3mon-grade th.folga { width: auto; }
table.i3mon-grade th {
  position: sticky; top: 0; z-index: 1; background: var(--surface);
  overflow: hidden; text-overflow: ellipsis;
  position: -webkit-sticky;
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--sub); font-weight: 600; padding: 9px 12px;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
table.i3mon-grade td {
  padding: 9px 12px; border-bottom: 1px solid var(--border);
  color: var(--text); white-space: nowrap; max-width: 320px; overflow: hidden; text-overflow: ellipsis;
}
table.i3mon-grade tbody tr:hover { background: var(--surface-2); }
table.i3mon-grade td.vazio { text-align: center; color: var(--sub); padding: 30px; white-space: normal; }

/* menus suspensos — estreitos (o popup de colunas estava largo demais) */
.i3mon-drop {
  position: fixed; z-index: 10050; width: 320px; max-width: calc(100vw - 16px);
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 18px 50px rgba(0,0,0,.45);
  overflow: hidden auto; max-height: calc(100vh - 96px); padding: 6px;
}
.i3mon-drop.estreito { width: 260px; }
.i3mon-sec { font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--sub); padding: 8px 10px 4px; }
.i3mon-opt {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: transparent; border: 0; color: inherit; border-radius: 8px;
  padding: 9px 10px; font: inherit; font-size: 13px; cursor: pointer;
}
.i3mon-opt em { margin-left: auto; font-style: normal; font-size: 12px; color: var(--sub); }
.i3mon-opt:hover { background: var(--surface-2); }
.i3mon-opt.ativo { background: var(--surface-2); font-weight: 600; }
.i3mon-cols { max-height: 320px; overflow-y: auto; padding: 2px; }
.i3mon-col { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; font-size: 13px; cursor: pointer; }
.i3mon-col:hover { background: var(--surface-2); }
.i3mon-col input { accent-color: var(--primary); }
.i3mon-drop-pe { border-top: 1px solid var(--border); padding: 8px 6px 4px; }

/* marca dos campos que o i3track calcula (não vêm prontos do Traccar) */
.i3mon-calc {
  font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: .04em;
  padding: 1px 4px; border-radius: 4px; margin-left: 5px; vertical-align: middle;
  color: var(--primary); background: rgba(37,99,235,.14); border: 1px solid rgba(37,99,235,.35);
}

/* ordem das colunas: arrastável, com ↑ ↓ para quem preferir clicar */
.i3mon-ords { max-height: 220px; overflow-y: auto; padding: 2px; }
.i3mon-ord {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border: 1px solid transparent; border-radius: 6px; font-size: 13px;
  cursor: grab; background: var(--surface-2); margin-bottom: 3px;
}
.i3mon-ord > span:nth-child(2) { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.i3mon-ord .pega { color: var(--placeholder); cursor: grab; line-height: 1; }
.i3mon-ord button {
  background: transparent; border: 0; color: var(--sub); cursor: pointer;
  font: inherit; font-size: 13px; line-height: 1; padding: 2px 4px; border-radius: 4px;
}
.i3mon-ord button:hover { color: var(--text); background: var(--surface); }
.i3mon-ord.arrastando { opacity: .45; }
.i3mon-ord.alvo { border-color: var(--primary); }

/* detalhe em tela cheia */
.i3mon-det-topo { display: flex; align-items: center; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--border); background: var(--surface); }
.i3mon-det-topo h1 { font-size: 20px; font-weight: 700; margin: 0; letter-spacing: -.02em; }
.i3mon-sub { font-size: 12px; color: var(--sub); }
.i3mon-abas { display: flex; gap: 2px; padding: 0 18px; border-bottom: 1px solid var(--border); background: var(--surface); overflow-x: auto; }
.i3mon-abas .aba {
  background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--sub);
  font: inherit; font-size: 13px; font-weight: 500; padding: 11px 14px; cursor: pointer; white-space: nowrap;
}
.i3mon-abas .aba:hover { color: var(--text); }
.i3mon-abas .aba.ativa { color: var(--text); border-bottom-color: var(--primary); }
.i3mon [data-det] { flex: 1; min-height: 0; overflow: auto; padding: 18px; }
.i3mon-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 4px 20px 16px; box-shadow: 0 1px 2px rgba(0,0,0,.16);
}
.i3mon-card-topo {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 0 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.i3mon-card-topo h3 { margin: 0; }
/* empurra só o que vem DEPOIS do título — quando o título é filho único ele
   também é :last-child e acabava jogado para a direita */
.i3mon-card-topo > :last-child:not(:first-child) { margin-left: auto; }
.i3mon-card > h3, .i3mon-card-topo h3 {
  font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--sub);
}
.i3mon-card > h3 { margin: 14px 0 10px; }

/* --- MAPA PEQUENO DA ABA "STATUS" DO MONITORAMENTO ---------------------------
   Abrir o detalhe pela linha da tabela tirava o mapa da frente do usuário: a
   lista inteira sai da tela. Este é o mapa de leitura do veículo aberto — fica
   logo abaixo do título "Situação atual", antes dos campos. */
.i3mon-mapinha {
  height: 240px;
  margin: 12px 0 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface-2, #1c1c1c);
}
.i3mon-mapinha-vazio {
  display: flex; align-items: center; justify-content: center;
  height: 100%; padding: 0 16px; text-align: center;
  font-size: 13px; color: var(--sub);
}
/* O Leaflet põe z-index alto nos painéis dele; sem isto o mapa passa por cima
   dos menus suspensos ("Personalizar a ordem") que abrem em cima do cartão. */
.i3mon-mapinha .leaflet-pane,
.i3mon-mapinha .leaflet-control { z-index: 1; }

/* faixa de números-resumo no topo das abas de histórico */
.i3mon-resumo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px; margin-bottom: 14px;
}
.i3mon-kpi {
  display: flex; flex-direction: column; gap: 4px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px;
}
.i3mon-kpi span { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--sub); }
.i3mon-kpi strong { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.i3mon-vazio.erro { color: #EF4444; }

/* lápis para renomear o campo neste veículo */
.i3mon-lapis {
  background: transparent; border: 0; color: var(--placeholder); cursor: pointer;
  font: inherit; font-size: 12px; line-height: 1; padding: 2px 4px; border-radius: 4px;
  opacity: 0; transition: opacity .12s;
}
.i3mon-campo:hover .i3mon-lapis { opacity: 1; }
.i3mon-lapis:hover { color: var(--primary); background: var(--surface-2); }

/* câmeras ao vivo */
.i3mon-cams { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.i3mon-cam { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--surface-2); }
.i3mon-cam .tela {
  aspect-ratio: 16/9; background: #000; display: flex; align-items: center; justify-content: center;
  color: var(--placeholder); font-size: 12px; text-align: center; padding: 10px;
}
.i3mon-cam .tela video { width: 100%; height: 100%; object-fit: contain; background: #000; }
.i3mon-cam .tela a { color: var(--primary); }
.i3mon-cam .pe { display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13px; }
.i3mon-cam .pe > :last-child { margin-left: auto; }
/* rótulo e valor no MESMO bloco: numa grade de colunas o dt/dd solto
   embaralhava o valor de uma linha com o rótulo da vizinha */
.i3mon-campos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 0 28px; margin: 0; font-size: 13px;
}
.i3mon-campo {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 10px; border-radius: 8px; min-width: 0;
  border-bottom: 1px solid var(--border);
}
.i3mon-campo:hover { background: var(--surface-2); }
/* o endereço ocupa a linha inteira (a largura dos três cartões), sozinho:
   endereço é texto longo e ficava espremido numa coluna só */
.i3mon-campo.largo { grid-column: 1 / -1; }
.i3mon-campo.largo .val { white-space: normal; text-align: right; line-height: 1.45; }
.i3mon-campo .rot { color: var(--sub); flex: 0 0 auto; display: inline-flex; align-items: center; }
.i3mon-campo .val {
  margin-left: auto; text-align: right; min-width: 0; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.i3mon-vazio { color: var(--sub); text-align: center; padding: 30px; font-size: 13px; }
.i3mon [data-det] > .i3mon-card + .i3mon-card { margin-top: 14px; }

/* período (De/Até) das abas que consultam histórico */
.i3mon-periodo { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.i3mon-periodo[hidden] { display: none; }
.i3mon-periodo label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--sub); }
.i3mon-periodo input {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 9px; font: inherit; font-size: 12px;
}
.i3mon-periodo input:focus { outline: none; border-color: var(--sub); }
.i3mon-periodo input::-webkit-calendar-picker-indicator { filter: invert(.6); cursor: pointer; }

/* tabelas das abas do detalhe */
.i3mon-rolagem-x { overflow-x: auto; }
table.i3mon-grade.compacta th { position: static; text-transform: none; font-size: 11px; }
table.i3mon-grade.compacta td { max-width: 380px; }
.i3mon-nota { margin: 10px 0 0; font-size: 12px; color: var(--sub); }
.i3mon-botoes { display: flex; flex-wrap: wrap; gap: 8px; }
.i3mon-tag {
  display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600;
  border: 1px solid var(--border); color: var(--sub);
}
.i3mon-tag.bom { color: #22C55E; border-color: rgba(34,197,94,.45); background: rgba(34,197,94,.12); }
.i3mon-tag.atencao { color: #F59E0B; border-color: rgba(245,158,11,.45); background: rgba(245,158,11,.12); }
.i3mon-tag.ruim { color: #EF4444; border-color: rgba(239,68,68,.45); background: rgba(239,68,68,.12); }

/* videotelemetria */
.i3mon-videos { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.i3mon-video {
  margin: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--surface-2);
}
.i3mon-video img { width: 100%; aspect-ratio: 16/9; object-fit: cover; display: block; background: #000; }
.i3mon-video figcaption { display: flex; flex-direction: column; gap: 4px; padding: 10px; font-size: 12px; }
.i3mon-video figcaption span { color: var(--sub); font-size: 11px; }
.i3mon-video figcaption a { align-self: flex-start; text-decoration: none; }
/* "Ocultar topbar" tem que esconder a topbar de verdade — só subir o painel
   para top:0 o deixava POR BAIXO dela (o header tem z-index maior). */
body.i3mon-sem-topbar header { display: none !important; }

/* ============================================================================
   §36 — Tela "Tipos de Equipamentos" (/devices/products, i3track-modelos.js).
   O bundle não tem paginação nessa lista; o script entrega o catálogo inteiro
   e esconde as linhas fora da página atual. O rodapé abaixo repete a forma da
   paginação das outras telas (§19) para não parecer um enxerto.
   ========================================================================== */
tr[data-i3mod-fora] { display: none !important; }

/* modelo de fábrica: o "×" some, mas a linha continua editável */
button[data-i3mod-padrao] { display: none !important; }

.i3mod-rodape {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
  margin-top: 12px; padding: 10px 14px;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface-2); color: var(--sub); font-size: 12px;
}
.i3mod-por { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.i3mod-por select {
  appearance: none; -webkit-appearance: none;
  padding: 6px 28px 6px 10px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font: inherit; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.i3mod-info { flex: 1 1 auto; text-align: center; }
.i3mod-nav { display: inline-flex; align-items: center; gap: 6px; }
.i3mod-nav button {
  min-width: 32px; height: 32px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--text);
  font-size: 15px; line-height: 1; cursor: pointer;
}
.i3mod-nav button:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.i3mod-nav button:disabled { opacity: .35; cursor: default; }
.i3mod-pag { padding: 0 8px; white-space: nowrap; color: var(--text); font-weight: 600; }

/* ===================== 24. LOGIN SPLIT-SCREEN (white-label) =====================
   Painel visual à esquerda (foto configurável por plataforma), formulário à
   direita. O formulário é o MESMO do bundle — `i3track-login.js` só reposiciona
   o cartão e injeta o painel; nada da lógica de autenticação é tocado.

   As variáveis --i3-brand* são escritas pelo script a partir de
   /plat-api/branding, com hover/realce derivados em HSL e o texto do botão
   escolhido por luminância. Nada de cor fixa aqui: uma revenda que escolher
   amarelo precisa continuar com botão legível.                               */

:root.i3login[data-theme] .eagle-login.i3login-wrap{
  display:grid !important;
  grid-template-columns:1.05fr .95fr;
  min-height:100vh;
  padding:0 !important;
  background:var(--bg) !important;
  place-items:stretch !important;
}

/* ---- painel visual (esquerda) ---- */
:root.i3login .i3login-hero{
  position:relative; overflow:hidden;
  display:flex; flex-direction:column; justify-content:space-between;
  padding:44px 46px; color:#fff;
  background-size:cover; background-position:center;
  /* Fundo enquanto a foto carrega — e o fundo definitivo de quem não subiu
     foto nenhuma. Deriva da cor da marca, então nunca fica um bloco cinza. */
  background-color:#0f1216;
  background-image:linear-gradient(150deg,var(--i3-brand-soft),rgba(15,18,22,.92) 55%,#0a0d10);
}
:root.i3login .i3login-hero::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(120% 80% at 20% 0%,var(--i3-brand-tint),transparent 60%);
}
:root.i3login .i3login-hero > *{ position:relative; z-index:2; }

:root.i3login .i3login-hero-top{ display:flex; align-items:center; gap:13px; }
:root.i3login .i3login-logo{
  width:56px; height:56px; border-radius:16px; flex:0 0 auto;
  background:rgba(255,255,255,.95); display:grid; place-items:center;
  box-shadow:0 10px 30px -10px rgba(0,0,0,.5);
}
:root.i3login .i3login-logo svg{ width:30px; height:30px; color:var(--i3-brand); }
:root.i3login .i3login-logo img{ width:38px; height:38px; object-fit:contain; }

:root.i3login .i3login-nome{
  font-family:'Bricolage Grotesque','Inter',sans-serif;
  font-size:22px; font-weight:700; letter-spacing:-.01em; line-height:1.2;
}
:root.i3login .i3login-nome small{
  display:block; font-family:'Inter',sans-serif; font-size:11.5px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; opacity:.72; margin-top:3px;
}

:root.i3login .i3login-mid{ max-width:460px; }
:root.i3login .i3login-mid h2{
  font-family:'Bricolage Grotesque','Inter',sans-serif;
  font-size:32px; font-weight:700; line-height:1.18; letter-spacing:-.02em; margin:0;
}
:root.i3login .i3login-mid p{
  margin-top:14px; font-size:14.5px; opacity:.78; max-width:400px; line-height:1.55;
}
:root.i3login .i3login-selos{ display:flex; gap:9px; flex-wrap:wrap; margin-top:22px; }
:root.i3login .i3login-selo{
  display:inline-flex; align-items:center; gap:7px;
  background:rgba(255,255,255,.13); border:1px solid rgba(255,255,255,.2);
  border-radius:999px; padding:7px 13px; font-size:12.5px; font-weight:600;
  backdrop-filter:blur(4px);
}
:root.i3login .i3login-selo svg{ width:14px; height:14px; }
:root.i3login .i3login-foot{ font-size:12px; opacity:.6; }

/* ---- formulário (direita) ---- */
:root.i3login[data-theme] .eagle-login.i3login-wrap .eagle-card{
  display:flex !important; align-items:center; justify-content:center;
  width:100% !important; max-width:none !important; min-height:100vh;
  margin:0 !important; padding:40px 32px !important;
  background:var(--bg) !important; border:0 !important; box-shadow:none !important;
  backdrop-filter:none !important;
}
:root.i3login[data-theme] .eagle-login.i3login-wrap .eagle-inner{
  width:100%; max-width:392px;
}

/* O botão segue a cor da plataforma, com o texto decidido por luminância. */
:root.i3login[data-theme] .eagle-btn{
  background:var(--i3-brand) !important;
  color:var(--i3-brand-ink) !important;
  border:0 !important;
}
:root.i3login[data-theme] .eagle-btn:hover{ background:var(--i3-brand-600) !important; filter:none !important; }
:root.i3login[data-theme] .eagle-input:focus-within{
  border-color:var(--i3-brand) !important;
  box-shadow:0 0 0 3px var(--i3-brand-tint) !important;
}
:root.i3login[data-theme] .eagle-link{ color:var(--i3-brand-400) !important; }
:root.i3login[data-theme] .eagle-check input:checked{
  background:var(--i3-brand) !important; border-color:var(--i3-brand) !important;
}

/* ---- uma coluna: o formulário é prioridade, o painel vira faixa ---- */
@media (max-width:940px){
  :root.i3login[data-theme] .eagle-login.i3login-wrap{ grid-template-columns:1fr; min-height:auto; }
  :root.i3login .i3login-hero{ min-height:230px; padding:26px 24px; }
  :root.i3login .i3login-mid h2{ font-size:23px; }
  :root.i3login .i3login-mid p,
  :root.i3login .i3login-selos,
  :root.i3login .i3login-foot{ display:none; }
  :root.i3login[data-theme] .eagle-login.i3login-wrap .eagle-card{
    min-height:auto; padding:32px 24px 44px !important;
  }
}

/* --- limpar o que o cartão flutuante trazia ---
   O cartão era uma caixa de vidro no meio de um fundo animado. Agora ele é a
   coluna inteira: fundo, borda, sombra e desfoque só sujariam a divisão. */
:root.i3login[data-theme] .eagle-card{
  background:transparent !important;
  border:0 !important;
  border-radius:0 !important;
  box-shadow:none !important;
  backdrop-filter:none !important;
}

/* O botão vinha com gradiente fixo azul e halo azul. Agora é a cor da
   plataforma, chapada, com o halo derivado dela. `background-image` precisa ser
   zerado explicitamente: `background` sozinho não apaga um gradiente declarado
   em `background-image` com !important. */
:root.i3login[data-theme] .eagle-btn{
  background:var(--i3-brand) !important;
  background-image:none !important;
  color:var(--i3-brand-ink) !important;
  box-shadow:0 10px 28px var(--i3-brand-tint) !important;
}
:root.i3login[data-theme] .eagle-btn:hover{
  background:var(--i3-brand-600) !important;
  background-image:none !important;
  filter:none !important;
}

:root.i3login[data-theme] .eagle-input:focus-within{
  border-color:var(--i3-brand) !important;
  box-shadow:0 0 0 3px var(--i3-brand-tint) !important;
}
:root.i3login[data-theme] .eagle-link{ color:var(--i3-brand-400) !important; }

/* A marca no topo do formulário segue a plataforma: com logo própria, o script
   troca a imagem; sem logo, fica o ícone i3track. */
:root.i3login[data-theme] .eagle-sprite--mark{
  width:44px !important; height:44px !important;
}

/* Título e subtítulo alinhados à esquerda, como no desenho. */
:root.i3login[data-theme] .eagle-titles{ text-align:left !important; }
:root.i3login[data-theme] .eagle-titles h1{
  font-family:'Bricolage Grotesque','Inter',sans-serif !important;
  font-size:27px !important; letter-spacing:-.02em !important;
}
:root.i3login .eagle-inner{ text-align:left !important; }

/* O checkbox "Manter sessão ativa" também segue a plataforma. Precisa da mesma
   seletividade de 4 níveis das outras: a regra do tema é `:root[data-theme]`. */
:root.i3login[data-theme] .eagle-check input:checked{
  background:var(--i3-brand) !important;
  border-color:var(--i3-brand) !important;
}

/* Fundo achatado na tela de login.
   O bundle pinta um halo radial azul em elementos de trás (`.eagle-bg` e o
   próprio wrapper). Esconder o `.eagle-bg` não bastou: o halo aparecia nas
   quinas da coluna direita, brigando com a cor da plataforma. Na rota de login
   o fundo é liso — quem dá cor é o painel da esquerda. */
:root.i3login body,
:root.i3login #root,
:root.i3login[data-theme] .eagle-login.i3login-wrap{
  background-image:none !important;
  background-color:var(--bg) !important;
}

/* O halo azul que sobrava no alto da coluna direita era `.eagle-card::before`:
   um `radial-gradient(... rgba(59,166,255,.22) ...)` posicionado em `inset:-2px`,
   que o bundle usa para dar brilho na borda do cartão flutuante. Sem cartão
   flutuante ele vira uma mancha azul fixa, que ainda por cima não acompanha a
   cor da plataforma — some com ele. */
:root.i3login[data-theme] .eagle-card::before,
:root.i3login[data-theme] .eagle-card::after{
  content:none !important;
  background:none !important;
}

/* Resquício da moldura do cartão antigo: qualquer borda/sombra dentro da coluna
   do formulário desenha um retângulo fantasma sobre o fundo liso. */
:root.i3login[data-theme] .eagle-card,
:root.i3login[data-theme] .eagle-card > *,
:root.i3login[data-theme] .eagle-inner{
  border:0 !important; box-shadow:none !important; outline:0 !important;
}

/* Assinatura da plataforma no painel do login.
   Altura fixa e largura automática: serve tanto para assinatura horizontal
   (a da i3track é 3468x949) quanto para marca quadrada de uma revenda, sem
   esmagar nenhuma das duas. */
:root.i3login .i3login-marca{
  height:46px; width:auto; max-width:280px; object-fit:contain; display:block;
}

/* ---- TEMA CLARO no formulário ----
   O login do bundle sempre foi um cartão ESCURO, mesmo no tema claro, então as
   regras da seção 5 fixam texto branco com !important. Ao transformar o cartão
   na coluna inteira, com o fundo do tema, esse branco passou a ficar invisível
   sobre o off-white. Aqui o texto volta a ser escuro — só no claro, e só na
   coluna do formulário. O painel da esquerda continua branco sobre foto. */
:root.i3login[data-theme="light"] .eagle-titles h1,
:root.i3login[data-theme="light"] .eagle-login .eagle-input input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]):not([type=button]):not([type=submit]):not([type=reset]):not([type=hidden]){
  color:#242424 !important;
}
:root.i3login[data-theme="light"] .eagle-titles p,
:root.i3login[data-theme="light"] .eagle-label,
:root.i3login[data-theme="light"] .eagle-check,
:root.i3login[data-theme="light"] .eagle-input svg,
:root.i3login[data-theme="light"] .eagle-toggle{
  color:#6B6B6B !important;
}
:root.i3login[data-theme="light"] .eagle-input{
  background:#FFFFFF !important;
  border:1px solid #E4E4E4 !important;
}
:root.i3login[data-theme="light"] .eagle-input input::placeholder{
  color:#9A9A9A !important;
}
:root.i3login[data-theme="light"] .eagle-check input{
  border-color:#C6D2DA !important;
  background:#FFFFFF !important;
}
:root.i3login[data-theme="light"] .eagle-check input:checked{
  background:var(--i3-brand) !important;
  border-color:var(--i3-brand) !important;
}

/* ===================== §35 DETALHE DO VEÍCULO — LISTRADO =====================
   Consome i3track-veiculo.js, que marca <body class="i3veic"> na rota
   /vehicles/:id e etiqueta os nós (.i3v-*).

   A tela era cartão dentro de cartão dentro de cartão, e os dados numa grade
   de duas colunas onde rótulo e valor não se alinhavam com nada. Aqui vira o
   mesmo desenho das listas do app: linhas planas, listra alternada e fio de
   1px separando. Sem cartão interno, sem canto arredondado no meio da lista. */

/* --- o cartão da aba vira painel; o respiro passa a ser das linhas --- */
body.i3veic .app-page-wrapper .i3v-card{
  padding:0 !important;
  overflow:hidden;
  background:var(--surface-card) !important;
  border:1px solid var(--stroke) !important;
  border-radius:12px !important;
  box-shadow:none !important;
}
/* Tudo que não é lista mantém o respiro lateral do cartão original. */
body.i3veic .i3v-card > *{ padding-left:16px !important; padding-right:16px !important; }
body.i3veic .i3v-card > *:first-child{ padding-top:14px !important; }
body.i3veic .i3v-card > *:last-child{ padding-bottom:14px !important; }
body.i3veic .i3v-card > .i3v-campos,
body.i3veic .i3v-card > .i3v-quadro,
body.i3veic .i3v-card > .e-data-table{ padding-left:0 !important; padding-right:0 !important; }

/* Título de seção do cartão, no padrão do app (I3SectionTitle). */
body.i3veic .i3v-card h2,
body.i3veic .i3v-card h3{
  font-size:11px !important;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--sub) !important;
  font-weight:600;
}

/* --- lista de campos (Resumo) --- */
body.i3veic .i3v-campos{
  display:block !important;
  gap:0 !important;
  margin:0 !important;
}
body.i3veic .i3v-campo{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  justify-content:space-between;
  gap:2px 16px;
  padding:9px 16px;
  border-top:1px solid var(--stroke);
}
body.i3veic .i3v-campo:first-child{ border-top:0; }
body.i3veic .i3v-campo:nth-child(odd){ background:var(--surface-card-inner); }
body.i3veic .i3v-rot{
  flex:0 0 auto;
  font-size:11px !important;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--sub) !important;
}
body.i3veic .i3v-val{
  flex:1 1 auto;
  min-width:0;
  text-align:right;
  color:var(--text) !important;
  font-size:13px;
  overflow-wrap:anywhere;
}
body.i3veic .i3v-mono{
  font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  letter-spacing:.02em;
}
body.i3veic .i3v-extra{
  flex:1 1 100%;
  text-align:right;
  color:var(--sub) !important;
  font-size:11px !important;
}

/* --- tabelas (Equipamentos vinculados, Ordens de Serviço, Histórico) --- */
body.i3veic .i3v-quadro{
  border:0 !important;
  border-radius:0 !important;
  overflow:visible !important;
  /* Sangra o respiro do container quando a tabela está aninhada (Histórico,
     Ordens de Serviço); quando é filha direta do cartão, a regra seguinte
     devolve a margem a zero. */
  margin-left:-16px;
  margin-right:-16px;
}
body.i3veic .i3v-card > .i3v-quadro{ margin-left:0; margin-right:0; }
body.i3veic .i3v-tabela thead{ background:transparent !important; }
body.i3veic .i3v-tabela thead th{
  padding:8px 16px !important;
  font-size:11px !important;
  letter-spacing:.12em;
  color:var(--sub) !important;
  border-bottom:1px solid var(--stroke);
}
body.i3veic .i3v-tabela tbody tr{ border-top:0 !important; }
body.i3veic .i3v-tabela tbody tr:nth-child(odd){ background:var(--surface-card-inner) !important; }
body.i3veic .i3v-tabela tbody tr + tr{ border-top:1px solid var(--stroke) !important; }
body.i3veic .i3v-tabela tbody tr:hover{ background:var(--field-bg-hover) !important; }
body.i3veic .i3v-tabela tbody td{ padding:10px 16px !important; }
/* Estado vazio: vira uma linha da lista, não um cartaz dentro da tabela. */
body.i3veic .i3v-tabela tbody td[colspan] > div{
  border:0 !important;
  background:transparent !important;
  border-radius:0 !important;
  padding:18px 0 !important;
}

/* --- formulário (Editar) --- */
body.i3veic .i3v-form{
  display:block !important;
  gap:0 !important;
  margin:0 !important;
}
body.i3veic .i3v-linha{
  padding:8px 16px;
  border-top:1px solid var(--stroke);
}
body.i3veic .i3v-linha:first-child{ border-top:0; }
body.i3veic .i3v-linha[data-i3-listra="0"]{ background:var(--surface-card-inner); }
body.i3veic .i3v-linha--rot{
  display:grid;
  grid-template-columns:minmax(120px,210px) 1fr;
  align-items:center;
  gap:16px;
}
body.i3veic .i3v-linha--rot > label{
  font-size:11px !important;
  letter-spacing:.12em;
  color:var(--sub) !important;
  margin:0;
}
body.i3veic .i3v-linha--rot > *:not(label){ margin-top:0 !important; }

/* Linha em que o próprio <label> embrulha o campo (Garantia). Sem isto o texto
   do rótulo virava uma tarja solta e o campo caía na linha de baixo, cada um
   com uma margem diferente — foi o desalinhamento reclamado na Garantia.
   O texto é um item anônimo da grade: fica na coluna 1, o campo na coluna 2. */
body.i3veic .i3v-linha--livre{
  display:grid;
  grid-template-columns:minmax(120px,210px) 1fr;
  align-items:center;
  gap:4px 16px;
}
body.i3veic .i3v-linha--livre > *{ margin-top:0 !important; }
/* A explicação em letra miúda acompanha o campo, não o rótulo. */
body.i3veic .i3v-linha--livre > span{ grid-column:2; }

@media (max-width:900px){
  body.i3veic .i3v-linha--rot,
  body.i3veic .i3v-linha--livre{ grid-template-columns:1fr; gap:4px; }
  body.i3veic .i3v-linha--livre > span{ grid-column:1; }
}

/* --- caixas internas (Configuração do Veículo) viram blocos planos --- */
body.i3veic .i3v-bloco{
  border:0 !important;
  border-radius:0 !important;
  background:transparent !important;
  padding:12px 16px !important;
}
/* Fio só quando os blocos estão EMPILHADOS. Lado a lado (grid do vínculo de
   equipamento/kit) o border-top vira um risco solto sobre a coluna direita. */
body.i3veic :not(.grid) > .i3v-bloco + .i3v-bloco{ border-top:1px solid var(--stroke) !important; }
body.i3veic .i3v-bloco .i3v-bloco{ padding:10px 0 !important; }

/* --- dica embaixo de "Buscar equipamento" (i3track-veiculo.js) ------------
   Antes, um código que não aparecia na busca não tinha explicação: sumia. */
body.i3veic .i3v-dica{
  display:block;
  margin:0 0 8px;
  padding:0 16px;
  font-size:11px;
  line-height:1.45;
  color:var(--sub);
}
body.i3veic .i3v-dica[data-i3-tom="aviso"]{ color:var(--warning); }
body.i3veic .i3v-dica[data-i3-tom="ok"]{ color:var(--success); }

/* Estado vazio dentro dos blocos (Portas, itens): era uma caixa dentro da caixa.
   Vira uma linha da lista, com o mesmo cinza dos vazios do app. */
body.i3veic .i3v-bloco > .rounded-lg.border,
body.i3veic .i3v-bloco .space-y-3 > .rounded-lg.border{
  border:0 !important;
  border-radius:0 !important;
  background:var(--surface-card-inner) !important;
  padding:14px 16px !important;
  margin-left:-16px !important;
  margin-right:-16px !important;
  color:var(--sub) !important;
}

/* --- §35.1 alinhamento dos cartões de vínculo -----------------------------
   Equipamento e kit ficam lado a lado. Um deles ganha a dica e cresce; sem
   esticar os dois e jogar o botão para o fim, os botões param em alturas
   diferentes. */
body.i3veic .i3v-vinculos{ align-items:stretch !important; }
body.i3veic .i3v-vinculos > .i3v-bloco{
  display:flex !important;
  flex-direction:column;
}
body.i3veic .i3v-vinculos > .i3v-bloco > div.flex.justify-end{ margin-top:auto; }

/* --- §35.2 título de seção e botoeira dentro do formulário --- */
body.i3veic .i3v-linha.i3v-secao{
  background:transparent !important;
  padding-top:16px;
  padding-bottom:6px;
  font-size:11px !important;
  letter-spacing:.12em;
  color:var(--sub) !important;
}
body.i3veic .i3v-linha.i3v-secao:first-child{ padding-top:12px; }
body.i3veic .i3v-linha.i3v-acoes{
  background:transparent !important;
  padding-top:14px;
  padding-bottom:14px;
}

/* --- §35.3 cabeçalho: seta no lugar do "Voltar" no fim das abas -----------
   O "Voltar" ficava no fim da fila de abas, longe de qualquer outra ação e
   parecendo mais uma aba. Vira uma seta junto de Nova OS / Excluir. */
body.i3veic .app-page-wrapper .i3v-voltar{ display:none !important; }
body.i3veic .app-page-wrapper .page-header__actions .i3v-seta{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  border-radius:10px;
  border:1px solid var(--stroke);
  background:var(--surface-2);
  color:var(--text);
  cursor:pointer;
  transition:background .15s, border-color .15s;
}
body.i3veic .app-page-wrapper .page-header__actions .i3v-seta:hover{
  background:var(--field-bg-hover);
  border-color:var(--accent-border-soft);
}

/* --- §35.4 cadastro do equipamento (/devices/:id) -------------------------
   Mesma pele da tela do veículo. O cartão aqui tem cabeçalho próprio (o X de
   fechar) e a barra de abas em versalete, que ficam com o respiro do cartão. */
body.i3veic .i3v-card > .overflow-x-hidden{ padding-left:0 !important; padding-right:0 !important; }
body.i3veic .i3v-card > .overflow-x-hidden > div.flex.flex-wrap.gap-2{
  padding:0 16px 10px;
  border-bottom:1px solid var(--stroke);
  margin-bottom:0;
}

/* --- §35.5 "Salvar tudo" no cabeçalho -------------------------------------
   Cada aba tinha o seu próprio Salvar e nenhuma sabia da outra: mexer no
   cadastro e nas portas exigia lembrar de salvar duas vezes, em dois lugares.
   Fica ao lado de Excluir, com o peso de ação principal. */
body.i3veic .app-page-wrapper .page-header__actions .i3v-salvar{
  display:inline-flex;
  align-items:center;
  height:36px;
  padding:0 14px;
  border-radius:10px;
  border:1px solid transparent;
  background:var(--primary);
  color:#FFFFFF;
  font-size:14px;
  font-weight:500;
  cursor:pointer;
  white-space:nowrap;
  transition:background .15s, opacity .15s;
}
body.i3veic .app-page-wrapper .page-header__actions .i3v-salvar:hover{ background:var(--primary-hover); }
body.i3veic .app-page-wrapper .page-header__actions .i3v-salvar:disabled{ opacity:.6; cursor:default; }

/* --- §35.6 cabeçalho vazio do cartão de equipamento -----------------------
   O cartão do cadastro abre com uma faixa que só tem o X de fechar; com o
   respiro do cartão ela virava uma tarja vazia de 60px. */
body.i3veic .i3v-card > div.flex.items-start.justify-between{
  padding:8px 16px !important;
}

/* --- §36 subtítulos de página ---------------------------------------------
   O bundle congelado traz subtítulos herdados da fase de integração que citam
   o motor de rastreamento pelo nome do projeto de origem ("Sincronizados
   diretamente com o …", "Associe dispositivos já existentes no …"). Não há
   fonte para reescrevê-los, e nome de terceiro não aparece no produto.
   Os subtítulos não carregam informação que não esteja no título. */
.page-header__subtitle{ display:none !important; }

/* --- §37 aba Dispositivos do cadastro de equipamento ----------------------
   Consome organizaDispositivos() do i3track-veiculo.js.

   Eram quatro caixas para duas decisões: dois cartões de estado numa linha e,
   embaixo, dois campos de busca dizendo quase a mesma coisa, em larguras
   diferentes. Agora são duas colunas, uma por dispositivo — em cima o que está
   vinculado, embaixo o campo para trocar. */
body.i3veic .i3v-disp{
  display:grid !important;
  grid-template-columns:1fr 1fr;
  gap:14px 20px;
  align-items:start;
}
/* As duas grades internas somem como caixa: os filhos delas passam a ser
   itens da grade do formulário, e aí dá para pareá-los por coluna. */
body.i3veic .i3v-disp > .i3v-disp-estados,
body.i3veic .i3v-disp > .i3v-disp-buscas{ display:contents !important; }

/* A busca vem PRIMEIRO: é a ação da tela. Veículo à esquerda, chip à direita,
   e embaixo a ficha do que está selecionado. */
body.i3veic .i3v-disp-veic-busca { grid-column:1; grid-row:1; }
body.i3veic .i3v-disp-chip-busca { grid-column:2; grid-row:1; }
body.i3veic .i3v-disp-chip-estado,
body.i3veic .i3v-disp-veic-estado{ display:none !important; }
/* Sem linha fixa: recolhido, o bloco de criar veículo sai da grade e a
   botoeira sobe — com grid-row fixo sobrava um vão do tamanho de uma linha. */
body.i3veic .i3v-disp-gatilho    { grid-column:1 / -1; justify-self:start; }
body.i3veic .i3v-disp-novo       { grid-column:1 / -1; }
/* Botoeira: linha própria, no fim, separada por um fio. */
body.i3veic .i3v-disp-acoes{
  grid-column:1 / -1;
  display:flex !important;
  justify-content:flex-end !important;
  gap:8px;
  margin-top:4px;
  padding-top:14px;
  border-top:1px solid var(--stroke);
}
body.i3veic .i3v-disp-acoes > div:empty{ display:none; }

/* O cartão de estado perde a moldura: ele é o VALOR da coluna, não um cartão. */
body.i3veic .i3v-disp-chip-estado,
body.i3veic .i3v-disp-veic-estado{
  border:0 !important;
  background:transparent !important;
  padding:0 0 2px !important;
  border-radius:0 !important;
}
body.i3veic .i3v-disp-veic-estado:hover{ background:transparent !important; }
/* O ícone quadrado de 40px só ocupava espaço ao lado de duas linhas de texto. */
body.i3veic .i3v-disp-chip-estado .h-10.w-10,
body.i3veic .i3v-disp-veic-estado .h-10.w-10{ display:none !important; }
/* O cartão inteiro já é o link; a legenda era redundante. */
body.i3veic .i3v-disp-veic-estado .text-primary\/80{ display:none !important; }
body.i3veic .i3v-disp-chip-busca > label,
body.i3veic .i3v-disp-veic-busca > label{
  font-size:11px !important;
  letter-spacing:.12em;
  color:var(--sub) !important;
}
body.i3veic .i3v-disp-veic-busca{ grid-column:1 !important; }

/* Criar veículo: exceção, não o caminho normal — fica recolhido. */
body.i3veic .i3v-disp-gatilho{
  border:1px solid var(--stroke);
  background:transparent;
  color:var(--sub);
  border-radius:10px;
  padding:6px 12px;
  font-size:12px;
  cursor:pointer;
}
body.i3veic .i3v-disp-gatilho:hover{ color:var(--text); border-color:var(--accent-border-soft); }
body.i3veic .i3v-disp-gatilho[data-i3-aberto="1"]{ color:var(--text); border-color:var(--accent-border-soft); }
body.i3veic .i3v-disp-novo[data-i3-aberto="0"]{ display:none !important; }

@media (max-width:820px){
  body.i3veic .i3v-disp{ grid-template-columns:1fr; }
  body.i3veic .i3v-disp-veic-busca { grid-column:1 !important; grid-row:1; }
  body.i3veic .i3v-disp-chip-busca { grid-column:1; grid-row:2; }

}

/* ============================================================
   § 38 — aba Teste do equipamento
   As linhas herdam a listra de § 35. Só o endereço precisa de
   quebra: sem ela o nome da rua estoura a linha do valor.
   ============================================================ */
body.i3veic .i3v-teste .i3v-val{ overflow-wrap:anywhere; text-align:right; }

/* ============================================================
   § 39 — aba I/O do equipamento
   A aba só sabia dizer que não havia porta configurada, sem
   lugar nenhum para configurá-la. Este é o editor.
   ============================================================ */
body.i3veic .i3v-io{
  padding:14px 16px 16px;
  border-bottom:1px solid var(--stroke);
  background:var(--surface-card-inner);
}
body.i3veic .i3v-io-tit{
  font-size:11px;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--sub);
  font-weight:600;
}
body.i3veic .i3v-io-sub{
  margin:6px 0 0;
  font-size:12px;
  line-height:1.5;
  color:var(--sub);
  max-width:70ch;
}
body.i3veic .i3v-io-conta{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  gap:16px;
  margin-top:14px;
}
body.i3veic .i3v-io-canal{ display:flex; flex-direction:column; gap:6px; }
body.i3veic .i3v-io-rot{
  font-size:11px;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--sub);
}
body.i3veic .i3v-io-grupo{
  display:flex;
  align-items:stretch;
  border:1px solid var(--stroke);
  border-radius:10px;
  overflow:hidden;
  background:var(--field-bg, transparent);
}
body.i3veic .i3v-io-passo{
  width:34px;
  border:0;
  background:transparent;
  color:var(--sub);
  font-size:16px;
  line-height:1;
  cursor:pointer;
}
body.i3veic .i3v-io-passo:hover{ color:var(--text); }
body.i3veic .i3v-io-num{
  width:58px;
  border:0;
  border-left:1px solid var(--stroke);
  border-right:1px solid var(--stroke);
  background:transparent;
  color:var(--text);
  text-align:center;
  font-size:14px;
  padding:7px 0;
  -moz-appearance:textfield;
}
body.i3veic .i3v-io-num::-webkit-outer-spin-button,
body.i3veic .i3v-io-num::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
body.i3veic .i3v-io-lista{
  display:grid;
  gap:8px;
  margin-top:16px;
}
body.i3veic .i3v-io-porta{
  display:grid;
  grid-template-columns:56px minmax(0,320px) auto;
  align-items:center;
  gap:12px;
}
body.i3veic .i3v-io-chave{
  font-size:11px;
  letter-spacing:.1em;
  color:var(--sub);
  font-variant-numeric:tabular-nums;
}
body.i3veic .i3v-io-nome{
  width:100%;
  border:1px solid var(--stroke);
  border-radius:10px;
  background:transparent;
  color:var(--text);
  font-size:13px;
  padding:7px 10px;
}
body.i3veic .i3v-io-nome:focus{ outline:none; border-color:var(--accent-border-soft, var(--stroke)); }
/* Estado lido agora. Sem leitura fica apagado: é ausência de dado, não alarme. */
body.i3veic .i3v-io-estado{ font-size:11px; color:var(--sub); }
body.i3veic .i3v-io-estado[data-i3-lido="0"]{ opacity:.5; }

body.i3veic .i3v-io-rodape{
  display:flex;
  align-items:center;
  gap:14px;
  margin-top:16px;
}
body.i3veic .i3v-io-salvar{
  border:1px solid var(--accent-border-soft, var(--stroke));
  background:transparent;
  color:var(--text);
  border-radius:10px;
  padding:8px 18px;
  font-size:12px;
  cursor:pointer;
}
body.i3veic .i3v-io-salvar:disabled{ opacity:.45; cursor:default; }
body.i3veic .i3v-io-aviso{
  font-size:11px;
  line-height:1.45;
  color:var(--sub);
}
body.i3veic .i3v-io-aviso[data-i3-tom="aviso"]{ color:var(--warning); }
body.i3veic .i3v-io-aviso[data-i3-tom="ok"]{ color:var(--success); }

@media (max-width:720px){
  body.i3veic .i3v-io-porta{ grid-template-columns:48px 1fr; }
  body.i3veic .i3v-io-estado{ grid-column:2; }
}

/* ============================================================
   § 40 — aba Massa
   Dois passos, na ordem em que se usa. Sem isso os dois blocos
   tinham o mesmo peso e nada dizia qual vinha primeiro.
   ============================================================ */
body.i3veic .i3v-massa > [data-i3-passo]{
  position:relative;
  padding:14px 16px 16px !important;
}
body.i3veic .i3v-massa > [data-i3-passo="2"]{ border-top:1px solid var(--stroke) !important; }
body.i3veic .i3v-massa > [data-i3-passo] > div.text-xs.uppercase{ color:var(--text) !important; }

/* Campos do passo 1: modelo na linha inteira, o resto lado a lado. */
body.i3veic .i3v-massa > [data-i3-passo="1"] > div.grid:first-of-type{ grid-template-columns:1fr !important; }
body.i3veic .i3v-massa > [data-i3-passo="2"] > div.grid{ grid-template-columns:1fr !important; }

body.i3veic .i3v-massa-linha{
  background:var(--surface-card-inner) !important;
  border-color:var(--stroke) !important;
}
body.i3veic .i3v-massa-conta{ color:var(--sub) !important; }

/* ============================================================
   § 41 — portas no veículo
   A mesma lista da aba I/O do equipamento, só que para ler.
   ============================================================ */
body.i3veic .i3v-portas{ display:grid; gap:8px; }
body.i3veic .i3v-portas-linha{
  display:grid;
  grid-template-columns:56px minmax(0,1fr) auto;
  align-items:baseline;
  gap:12px;
  padding:7px 0;
  border-top:1px solid var(--stroke);
}
body.i3veic .i3v-portas-linha:first-child{ border-top:0; }
body.i3veic .i3v-portas-chave{
  font-size:11px;
  letter-spacing:.1em;
  color:var(--sub);
  font-variant-numeric:tabular-nums;
}
body.i3veic .i3v-portas-nome{ font-size:13px; color:var(--text); }
body.i3veic .i3v-portas-estado{ font-size:11px; color:var(--sub); }
body.i3veic .i3v-portas-estado[data-i3-lido="0"]{ opacity:.5; }
body.i3veic .i3v-portas-nota{
  margin:4px 0 0;
  font-size:11px;
  line-height:1.45;
  color:var(--sub);
}

/* ============================================================
   § 42 — ficha do vínculo (aba Dispositivos)
   Busca em cima; embaixo, o que o operador precisa conferir
   numa instalação: o carro e o chip, por extenso.
   ============================================================ */
body.i3veic .i3v-disp-det{
  grid-column:1 / -1;
  grid-row:2;
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:16px;
  margin-top:4px;
}
body.i3veic .i3v-ficha{
  border:1px solid var(--stroke);
  border-radius:12px;
  overflow:hidden;
}
body.i3veic .i3v-ficha-tit{
  padding:10px 14px;
  font-size:11px;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--sub);
  font-weight:600;
  border-bottom:1px solid var(--stroke);
}
body.i3veic .i3v-ficha-linha{
  display:grid;
  grid-template-columns:minmax(88px,110px) minmax(0,1fr);
  align-items:baseline;
  gap:12px;
  padding:8px 14px;
  border-top:1px solid var(--stroke);
}
body.i3veic .i3v-ficha-linha:first-child{ border-top:0; }
body.i3veic .i3v-ficha-linha:nth-child(odd){ background:var(--surface-card-inner); }
body.i3veic .i3v-ficha-rot{
  font-size:11px;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--sub);
}
body.i3veic .i3v-ficha-val{ font-size:13px; color:var(--text); overflow-wrap:anywhere; }
/* Campo em branco não é erro: é coisa a preencher. Fica apagado, não vermelho. */
body.i3veic .i3v-ficha-val[data-i3-preenchido="0"]{ color:var(--sub); opacity:.6; }
body.i3veic .i3v-ficha-vazio{
  margin:0;
  padding:14px;
  font-size:12px;
  line-height:1.5;
  color:var(--sub);
}
body.i3veic .i3v-ficha-extra{ font-size:11px; line-height:1.45; color:var(--sub); }
body.i3veic .i3v-ficha-extra:not(:empty){ padding:8px 14px; border-top:1px solid var(--stroke); }
body.i3veic .i3v-ficha-extra[data-i3-tom="aviso"]{ color:var(--warning); }

@media (max-width:820px){
  body.i3veic .i3v-disp-det{ grid-template-columns:1fr; grid-row:3; }
}

/* ============================================================
   § 43 — seletor de protocolo (tela de Comandos)
   São 260 protocolos. O campo de busca É o seletor: o <select>
   original fica escondido, só guardando o valor para o React.
   ============================================================ */
body.i3cmd .i3cmd-busca{ position:relative; margin-top:8px; }
body.i3cmd .i3cmd-busca-campo{
  width:100%;
  border:1px solid var(--stroke);
  border-radius:10px;
  background:transparent;
  color:var(--text);
  font-size:13px;
  padding:8px 10px;
}
body.i3cmd .i3cmd-busca-campo:focus{ outline:none; border-color:var(--accent-border-soft, var(--stroke)); }
body.i3cmd .i3cmd-lista{
  position:absolute;
  z-index:60;
  left:0; right:0; top:calc(100% + 4px);
  max-height:280px;
  overflow-y:auto;
  border:1px solid var(--stroke);
  border-radius:10px;
  background:var(--surface, #191919);
  box-shadow:0 12px 32px rgba(0,0,0,.45);
}
body.i3cmd .i3cmd-lista[data-i3-aberta="0"]{ display:none; }
body.i3cmd .i3cmd-item{
  display:block;
  width:100%;
  text-align:left;
  border:0;
  background:transparent;
  color:var(--text);
  font-size:13px;
  padding:8px 12px;
  cursor:pointer;
}
body.i3cmd .i3cmd-item:hover{ background:var(--surface-card-inner); }
body.i3cmd .i3cmd-item[data-i3-atual="1"]{ color:var(--accent, #4c8dff); }
body.i3cmd .i3cmd-item--neutro{ color:var(--sub); border-bottom:1px solid var(--stroke); }
body.i3cmd .i3cmd-vazio{ padding:10px 12px; font-size:12px; color:var(--sub); }

body.i3cmd .i3cmd-sem-resposta{
  margin:0;
  padding:18px 2px;
  font-size:13px;
  line-height:1.5;
  color:var(--sub);
}

/* ============================================================
   § 44 — aviso de acesso entre plataformas (i3track-sso.js)

   Aparece quando a sessão desta plataforma foi aberta por concessão de
   administrador, e não pelo login de quem é de casa. Trocar de identidade em
   silêncio é como mandar comando no veículo errado: o operador precisa ver de
   onde ele está falando. Discreto e some no × — mas existe.
   ============================================================ */
#i3sso-aviso{
  position:fixed;
  left:14px;
  bottom:14px;
  z-index:2147483000;
  display:flex;
  align-items:center;
  gap:8px;
  padding:7px 8px 7px 12px;
  border-radius:999px;
  border:1px solid var(--stroke, rgba(148,163,184,.35));
  background:var(--surface-card, #131a26);
  color:var(--text, #e2e8f0);
  font-size:12px;
  line-height:1;
  box-shadow:0 6px 20px rgba(0,0,0,.28);
}
#i3sso-aviso .i3sso-ponto{
  width:7px;
  height:7px;
  border-radius:999px;
  background:var(--accent, #4c8dff);
  flex:0 0 auto;
}
#i3sso-aviso button{
  border:0;
  background:transparent;
  color:var(--sub, #94a3b8);
  font:inherit;
  cursor:pointer;
  padding:4px 6px;
  border-radius:8px;
}
#i3sso-aviso button:hover{ color:var(--text, #e2e8f0); background:var(--surface-card-inner, rgba(148,163,184,.12)); }
#i3sso-aviso button[data-sair]{ color:var(--accent, #4c8dff); font-weight:600; }
@media (max-width: 640px){
  #i3sso-aviso{ left:10px; right:10px; bottom:10px; justify-content:center; }
}

/* ============================================================
   § 45 — diálogos do sistema (i3track-dialogo.js)

   Substituem alert/confirm/prompt do navegador, que aparecem colados no topo
   com a cara do Chrome, ignoram o tema e mostram o endereço do site como se
   fosse aviso de segurança.
   ============================================================ */
body.i3dlg-aberto{ overflow:hidden; }
.i3dlg{ position:fixed; inset:0; z-index:2147483100; display:grid; place-items:center; padding:20px; }
.i3dlg-fundo{ position:absolute; inset:0; background:rgba(2,6,23,.62); backdrop-filter:blur(2px); }
.i3dlg-painel{
  position:relative;
  width:min(460px, 100%);
  max-height:min(80vh, 640px);
  overflow:auto;
  padding:22px 22px 18px;
  border-radius:16px;
  border:1px solid var(--stroke, rgba(148,163,184,.28));
  background:var(--surface-card, #131a26);
  color:var(--text, #e2e8f0);
  box-shadow:0 24px 64px rgba(0,0,0,.45);
}
.i3dlg-painel.perigo{ border-color:rgba(220,38,38,.5); }
.i3dlg-titulo{ margin:0 0 10px; font-size:16px; font-weight:700; letter-spacing:-.2px; }
.i3dlg-texto{ margin:0 0 8px; font-size:13.5px; line-height:1.55; color:var(--sub, #94a3b8); }
.i3dlg-pedido{ margin-top:14px; color:var(--text, #e2e8f0); font-weight:600; }
.i3dlg-campo{
  width:100%; margin-top:8px; padding:10px 12px; border-radius:10px;
  border:1px solid var(--stroke, rgba(148,163,184,.35));
  background:var(--surface-card-inner, rgba(148,163,184,.08));
  color:var(--text, #e2e8f0); font-size:13.5px; font-family:inherit;
}
.i3dlg-campo:focus{ outline:none; border-color:var(--accent, #4c8dff); }
.i3dlg-acoes{ display:flex; justify-content:flex-end; gap:8px; margin-top:18px; flex-wrap:wrap; }
.i3dlg-b{
  padding:9px 16px; border-radius:10px; font-size:13px; font-weight:600; cursor:pointer;
  border:1px solid var(--stroke, rgba(148,163,184,.35));
  background:transparent; color:var(--text, #e2e8f0); font-family:inherit;
}
.i3dlg-b:hover{ border-color:var(--sub, #94a3b8); }
.i3dlg-b.primario{ background:rgba(37,99,235,.16); border-color:rgba(37,99,235,.5); color:#66A3FF; }
.i3dlg-b.perigo{ background:rgba(220,38,38,.16); border-color:rgba(220,38,38,.5); color:#F87171; }
.i3dlg-b:disabled{ opacity:.45; cursor:not-allowed; }
:root[data-theme="light"] .i3dlg-b.primario{ background:rgba(37,99,235,.1); color:#2563EB; }
:root[data-theme="light"] .i3dlg-b.perigo{ background:rgba(220,38,38,.08); color:#DC2626; }
@media (max-width: 520px){
  .i3dlg-acoes{ flex-direction:column-reverse; }
  .i3dlg-b{ width:100%; }
}

/* ============================================================
   § 46 — Equipamentos: exportar e filtro de status (i3track-equipamentos.js)
   ============================================================ */
[data-i3eq-oculto="1"]{ display:none !important; }

.i3eq-exp{ position:relative; display:inline-flex; }
/* O botão herda a classe do "Atualizar" ao lado — aqui só entra o que a classe
   dele não traz: a setinha ao lado do texto. Nada de moldura, cor ou tamanho
   próprios, senão ele volta a parecer colado depois. */
.i3eq-b{ display:inline-flex; align-items:center; gap:6px; }
/* O ícone da direita entra com o mesmo tamanho dos ícones dos botões vizinhos:
   com 13px o Exportar ficava 4px mais baixo que o Atualizar ao lado. */
.i3eq-b svg{ flex:0 0 auto; }
.i3eq-menu{
  position:absolute; top:calc(100% + 6px); right:0; z-index:2147482000;
  min-width:130px; padding:5px; border-radius:10px;
  border:1px solid var(--stroke, rgba(148,163,184,.3));
  background:var(--surface-card, #131a26);
  box-shadow:0 12px 32px rgba(0,0,0,.34);
}
.i3eq-menu[hidden]{ display:none; }
.i3eq-menu button{
  display:block; width:100%; text-align:left; border:0; background:transparent;
  color:var(--text, #e2e8f0); font:inherit; font-size:13px; padding:8px 10px;
  border-radius:7px; cursor:pointer;
}
.i3eq-menu button:hover{ background:var(--surface-card-inner, rgba(148,163,184,.12)); }

/* ============================================================
   § 47 — fileira de nível injetada na tela de permissões da plataforma
   (i3track-perms.js). Copia a aparência da fileira nativa do admin geral,
   para as duas telas não parecerem produtos diferentes.
   ============================================================ */
.i3perm-nivel{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; font-size:12px; }
.i3perm-sel{
  border-radius:8px; padding:4px 8px; font-size:12px; font-family:inherit;
  border:1px solid rgba(255,255,255,.10); background:rgba(0,0,0,.30); color:#fff;
}
:root[data-theme="light"] .i3perm-sel{
  border-color:var(--stroke, rgba(148,163,184,.4)); background:#fff; color:var(--text, #111827);
}
.i3perm-b{
  border-radius:8px; padding:4px 12px; font-size:12px; font-family:inherit; cursor:pointer;
  border:1px solid rgba(255,255,255,.10); background:transparent; color:rgba(255,255,255,.7);
  transition:border-color .15s;
}
.i3perm-b:hover{ border-color:rgba(255,255,255,.3); }
:root[data-theme="light"] .i3perm-b{ border-color:var(--stroke, rgba(148,163,184,.4)); color:var(--sub, #6b7280); }

/* ============================================================
   § 48 — criador de link de compartilhamento (i3track-compartilhar.js)
   Mesmo desenho do app: alvo, prazo em fichas, duas ações.
   ============================================================ */
.i3share{
  margin:0 0 18px; padding:16px;
  border:1px solid var(--stroke, rgba(148,163,184,.2));
  border-radius:16px; background:var(--surface-card, #131c2b);
}
.i3share-topo{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:12px; }
.i3share-topo h2{ margin:0; font-size:14.5px; font-weight:700; letter-spacing:-.2px; color:var(--text); }
.i3share-topo span{ font-size:11.5px; color:var(--sub); }
.i3share-alvo{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
  padding:11px 12px; border-radius:12px; font:inherit;
  border:1px solid var(--stroke, rgba(148,163,184,.22));
  background:var(--surface-card-inner, rgba(148,163,184,.07)); color:var(--text);
}
.i3share-alvo:hover{ border-color:var(--sub); }
.i3share-alvo > span{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.i3share-alvo b{ font-size:14px; font-weight:700; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
.i3share-alvo span span{ font-size:11.5px; color:var(--sub); }
.i3share-lista{
  margin-top:8px; max-height:230px; overflow:auto; border-radius:12px;
  border:1px solid var(--stroke, rgba(148,163,184,.22));
}
.i3share-lista[hidden]{ display:none; }
.i3share-lista button{
  display:block; width:100%; text-align:left; border:0; cursor:pointer; font:inherit;
  padding:9px 12px; background:transparent; color:var(--text);
  border-bottom:1px solid var(--stroke, rgba(148,163,184,.14));
}
.i3share-lista button:last-child{ border-bottom:0; }
.i3share-lista button:hover{ background:var(--surface-card-inner, rgba(148,163,184,.1)); }
.i3share-lista b{ display:block; font-size:13px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
.i3share-lista span{ display:block; font-size:11.5px; color:var(--sub); }
.i3share-rot{ margin:14px 0 8px; font-size:9.5px; font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--sub); }
.i3share-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.i3share-chip{
  padding:6px 14px; border-radius:999px; font:inherit; font-size:12.5px; cursor:pointer;
  border:1px solid var(--stroke, rgba(148,163,184,.25)); background:transparent; color:var(--sub);
}
.i3share-chip.ativa{ border-color:rgba(76,141,255,.5); background:rgba(76,141,255,.14); color:#8fb8ff; }
.i3share-aviso{ margin:12px 0 0; font-size:11.5px; line-height:1.4; color:var(--warning, #fbbf24); }
.i3share-aviso[hidden]{ display:none; }
.i3share-acoes{ display:flex; gap:9px; margin-top:14px; flex-wrap:wrap; }
.i3share-b{
  flex:1 1 160px; min-height:42px; border-radius:12px; font:inherit; font-size:13px; font-weight:600;
  cursor:pointer; border:1px solid var(--stroke, rgba(148,163,184,.3));
  background:transparent; color:var(--text);
}
.i3share-b.primario{ background:rgba(37,99,235,.16); border-color:rgba(37,99,235,.5); color:#66A3FF; }
.i3share-b:disabled{ opacity:.45; cursor:not-allowed; }
.i3share-como{ margin:14px 0 0; padding-left:18px; color:var(--sub); font-size:11.5px; line-height:1.6; }
[data-i3share-oculto="1"]{ display:none !important; }
.i3share-busca{
  width:100%; padding:9px 12px; font:inherit; font-size:13px;
  border:0; border-bottom:1px solid var(--stroke, rgba(148,163,184,.2));
  background:var(--surface-card-inner, rgba(148,163,184,.07)); color:var(--text);
}
.i3share-busca:focus{ outline:none; border-bottom-color:var(--accent, #4c8dff); }
.i3share-lista button.sem{ opacity:.6; }
.i3share-vazio{ padding:10px 12px; font-size:12px; color:var(--sub); }

/* ==========================================================================
   § 49 — Importar cadastros por planilha (/services/import,
   i3track-importar.js). Mesmo encaixe do §33: a tela é montada por cima da
   área de conteúdo do React, abaixo da topbar REAL e à direita do menu REAL.
   As tabelas são LISTRADAS como no §35 — em lista longa de colunas ou de
   resultado, a listra é o que impede o olho de pular de linha.
   ========================================================================== */
.i3imp-pg {
  position: fixed; right: 0; bottom: 0; z-index: 30;
  overflow-y: auto; overflow-x: hidden; padding: 20px 22px 44px;
  /* left/top/background vêm do JS */
}
body.i3imp-pg-open section.app-shell__content { display: none !important; }

.i3imp-head { display: flex; align-items: flex-start; gap: 20px; flex-wrap: wrap; margin-bottom: 16px; }
.i3imp-head h1 { font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -.02em; color: var(--text); }
.i3imp-sub { font-size: 12.5px; line-height: 1.5; color: var(--sub); margin: 4px 0 0; max-width: 62ch; }
.i3imp-cli { margin-left: auto; display: flex; flex-direction: column; gap: 5px; min-width: 220px; }
.i3imp-cli label {
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--sub);
}
/* O cliente não se escolhe aqui — quem manda é a barra do topo. Isto é
   leitura, e por isso não tem cara de campo: sem moldura, sem cursor de
   clique. Um campo desabilitado convidaria a tentar mexer. */
.i3imp-cli-nome { font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.2; }
.i3imp-cli > span { font-size: 11px; color: var(--sub); }

/* Submenu das planilhas. Cada aba é um tipo de cadastro. */
.i3imp-abas {
  display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 18px;
  border-bottom: 1px solid var(--border); padding-bottom: 0;
}
.i3imp-aba {
  background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
  padding: 9px 14px; font: inherit; font-size: 13px; font-weight: 600; color: var(--sub); cursor: pointer;
}
.i3imp-aba:hover { color: var(--text); }
.i3imp-aba.ativa { color: var(--text); border-bottom-color: #4c8dff; }

.i3imp-card {
  background: var(--surface-card, rgba(148,163,184,.05));
  border: 1px solid var(--border); border-radius: 14px;
  padding: 18px 20px; margin-bottom: 16px;
}
.i3imp-passo { display: flex; align-items: flex-start; gap: 13px; flex-wrap: wrap; }
.i3imp-passo > span {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 999px;
  display: grid; place-items: center; font-size: 12.5px; font-weight: 700;
  background: rgba(76,141,255,.16); color: #8fb8ff;
}
:root[data-theme="light"] .i3imp-passo > span { background: rgba(37,99,235,.1); color: #2563EB; }
.i3imp-passo h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); }
.i3imp-passo p { margin: 3px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--sub); max-width: 74ch; }
.i3imp-passo > .i3imp-b { margin-left: auto; }

.i3imp-nota {
  margin: 14px 0 0; font-size: 12px; line-height: 1.55; color: var(--sub);
  padding: 10px 12px; border-radius: 10px;
  background: var(--surface-card-inner, rgba(148,163,184,.07));
}
.i3imp-nota b { color: var(--text); }

.i3imp-b {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 9px 14px; font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; white-space: nowrap; min-height: 40px;
}
.i3imp-b:hover:not(:disabled) { border-color: var(--placeholder); }
.i3imp-b.primario { background: rgba(37,99,235,.14); border-color: rgba(37,99,235,.45); color: #66A3FF; }
:root[data-theme="light"] .i3imp-b.primario { background: rgba(37,99,235,.1); color: #2563EB; }
.i3imp-b:disabled { opacity: .45; cursor: not-allowed; }

.i3imp-arquivo { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.i3imp-nome { font-size: 12.5px; color: var(--sub); }
.i3imp-acoes { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 14px; }

/* Tabelas listradas — colunas do modelo e resultado da importação. */
.i3imp-tab { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 12.5px; }
.i3imp-tab th {
  text-align: left; padding: 8px 10px; font-size: 9.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--sub);
  border-bottom: 1px solid var(--border);
}
.i3imp-tab td { padding: 9px 10px; color: var(--text); vertical-align: top; }
.i3imp-tab tbody tr:nth-child(odd) { background: var(--surface-card-inner, rgba(148,163,184,.055)); }
.i3imp-tab b { font-weight: 600; }
.i3imp-ex { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--sub); }
.i3imp-ajuda { color: var(--sub); line-height: 1.5; }

.i3imp-marca {
  display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 10.5px; font-weight: 700;
  border: 1px solid var(--border); color: var(--sub); white-space: nowrap;
}
.i3imp-marca.obrig { background: rgba(245,158,11,.14); border-color: rgba(245,158,11,.4); color: #FBBF24; }
.i3imp-marca.vinc { background: rgba(59,130,246,.14); border-color: rgba(59,130,246,.4); color: #93C5FD; }
:root[data-theme="light"] .i3imp-marca.obrig { background: rgba(245,158,11,.12); color: #B45309; }
:root[data-theme="light"] .i3imp-marca.vinc { background: rgba(59,130,246,.1); color: #1D4ED8; }

/* Placar do resultado. */
.i3imp-placar { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.i3imp-p {
  flex: 1 1 120px; padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--surface-card-inner, rgba(148,163,184,.06));
}
.i3imp-p b { display: block; font-size: 22px; font-weight: 700; color: var(--text); line-height: 1.1; }
.i3imp-p span { display: block; margin-top: 2px; font-size: 11px; color: var(--sub); }
.i3imp-p.ok { border-color: rgba(34,197,94,.4); }
.i3imp-p.ok b { color: #4ADE80; }
.i3imp-p.rep { border-color: rgba(148,163,184,.35); }
.i3imp-p.err { border-color: rgba(239,68,68,.4); }
.i3imp-p.err b { color: #F87171; }
:root[data-theme="light"] .i3imp-p.ok b { color: #15803D; }
:root[data-theme="light"] .i3imp-p.err b { color: #DC2626; }

.i3imp-faixa { margin: 14px 0 0; font-size: 12.5px; line-height: 1.5; padding: 10px 12px; border-radius: 10px; }
.i3imp-faixa.conf { background: rgba(59,130,246,.12); color: #93C5FD; }
.i3imp-faixa.feito { background: rgba(34,197,94,.12); color: #4ADE80; }
:root[data-theme="light"] .i3imp-faixa.conf { color: #1D4ED8; }
:root[data-theme="light"] .i3imp-faixa.feito { color: #15803D; }

.i3imp-sit {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; white-space: nowrap;
  border: 1px solid var(--border); color: var(--sub);
}
.i3imp-sit.ok { background: rgba(34,197,94,.14); border-color: rgba(34,197,94,.4); color: #4ADE80; }
.i3imp-sit.erro { background: rgba(239,68,68,.14); border-color: rgba(239,68,68,.42); color: #F87171; }
.i3imp-sit.repetido { background: rgba(148,163,184,.14); }
:root[data-theme="light"] .i3imp-sit.ok { color: #15803D; }
:root[data-theme="light"] .i3imp-sit.erro { color: #DC2626; }
.i3imp-tab.res tr.s-erro td { color: var(--text); }

.i3imp-erro {
  margin-top: 16px; padding: 12px 14px; border-radius: 12px;
  border: 1px solid rgba(239,68,68,.42); background: rgba(239,68,68,.1);
}
.i3imp-erro b { display: block; font-size: 13px; color: #F87171; }
.i3imp-erro span { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.5; color: var(--text); }
:root[data-theme="light"] .i3imp-erro b { color: #DC2626; }

.i3imp-vazio { margin-top: 16px; font-size: 12.5px; color: var(--sub); }

/* §49.1 — a planilha também exclui e (des)vincula. Cada desfecho tem cor
   própria: cadastrar é verde, excluir é vermelho, vínculo é azul, e "não
   estava lá" fica neutro porque não é erro nem trabalho feito. */
.i3imp-p.del { border-color: rgba(239,68,68,.4); }
.i3imp-p.del b { color: #F87171; }
.i3imp-p.vinc { border-color: rgba(59,130,246,.4); }
.i3imp-p.vinc b { color: #93C5FD; }
:root[data-theme="light"] .i3imp-p.del b { color: #DC2626; }
:root[data-theme="light"] .i3imp-p.vinc b { color: #1D4ED8; }

.i3imp-sit.excluido { background: rgba(239,68,68,.14); border-color: rgba(239,68,68,.42); color: #F87171; }
.i3imp-sit.vinculado { background: rgba(59,130,246,.14); border-color: rgba(59,130,246,.42); color: #93C5FD; }
.i3imp-sit.ausente { background: rgba(148,163,184,.14); }
:root[data-theme="light"] .i3imp-sit.excluido { color: #DC2626; }
:root[data-theme="light"] .i3imp-sit.vinculado { color: #1D4ED8; }

/* A lista de ações fica ao lado do passo 1: é a chave para entender que a
   mesma planilha faz quatro coisas diferentes. */
.i3imp-acoes-tipos { display: grid; gap: 8px; margin-top: 14px; }
.i3imp-at {
  display: flex; gap: 10px; align-items: baseline; font-size: 12.5px; line-height: 1.5;
  padding: 9px 12px; border-radius: 10px;
  background: var(--surface-card-inner, rgba(148,163,184,.06));
}
.i3imp-at b { flex: 0 0 auto; min-width: 96px; color: var(--text); font-weight: 700; }
.i3imp-at span { color: var(--sub); }

/* §50 — Plano e menus na criação da plataforma (i3track-plataformas.js).
   As caixas ficam agrupadas como no menu do sistema: quem vende reconhece
   "Inteligência de Frota" muito antes de reconhecer doze rotas soltas. */
.i3plat-planoresumo { font-size: 12px; color: var(--sub); margin: -4px 0 10px; line-height: 1.5; }
.i3plat-menus { margin-bottom: 14px; }
.i3plat-menus-vazio { font-size: 12.5px; color: var(--sub); padding: 8px 0; }
.i3plat-menus-g {
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--sub); margin: 12px 0 6px;
}
.i3plat-menus-l { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 6px 12px; }
.i3plat-menu {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text);
  padding: 5px 8px; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent;
}
.i3plat-menu:hover { background: var(--surface-card-inner, rgba(148,163,184,.08)); }
.i3plat-menu input { accent-color: #2563eb; width: 15px; height: 15px; cursor: pointer; }

/* §50.1 — "Nova plataforma" como PÁGINA (i3track-plataformas-pagina.js).
   Era um formulário espremido em painel lateral com rolagem própria; criar
   plataforma é o ato principal desta tela e ganhou a largura toda. */
.i3pp-nova { max-width: 940px; }
.i3pp-nova .i3pp-card { margin-bottom: 14px; }
.i3pp-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px 18px; padding: 4px 0 2px; }
.i3pp-campo { display: flex; flex-direction: column; gap: 5px; }
.i3pp-campo > span {
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--sub);
}
.i3pp-campo input, .i3pp-campo select {
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 9px 11px; font: inherit; font-size: 13px; width: 100%;
}
.i3pp-campo input[type="color"] { padding: 4px; height: 38px; cursor: pointer; }
.i3pp-campo input:focus, .i3pp-campo select:focus { outline: none; border-color: var(--sub); }
.i3pp-campo[hidden] { display: none; }
.i3pp-slug { display: flex; align-items: center; gap: 6px; }
.i3pp-slug input { flex: 1 1 auto; }
.i3pp-slug em { font-size: 12px; color: var(--sub); font-style: normal; white-space: nowrap; }

.i3pp-menus { margin-top: 6px; }
.i3pp-menus-g {
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--sub); margin: 14px 0 7px;
}
.i3pp-menus-l { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 5px 14px; }
.i3pp-menu {
  display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text);
  padding: 6px 9px; border-radius: 8px; cursor: pointer;
}
.i3pp-menu:hover { background: var(--surface-card-inner, rgba(148,163,184,.09)); }
.i3pp-menu input { accent-color: #2563eb; width: 15px; height: 15px; cursor: pointer; }

.i3pp-erro {
  margin: 4px 0 12px; padding: 11px 13px; border-radius: 10px; font-size: 12.5px;
  border: 1px solid rgba(239,68,68,.42); background: rgba(239,68,68,.1); color: #F87171;
}
:root[data-theme="light"] .i3pp-erro { color: #DC2626; }
.i3pp-erro[hidden] { display: none; }
.i3pp-rodape { display: flex; gap: 9px; justify-content: flex-end; padding-bottom: 24px; }


/* ==========================================================================
   §51 — FASE 3: COMPONENTES ÚNICOS
   Um desenho só para cada coisa. Os valores vêm de i3track-tokens.css
   (--i3t-*), com fallback literal para o caso de o arquivo de tokens não
   ter carregado — nenhuma tela pode ficar sem borda por causa disso.
   Etiquetagem em i3track-ui.js.
   ========================================================================== */

/* --------------------------------------------------------------------------
   §51.1 — CONTROLE DA TOPBAR
   Antes: busca 44px/pílula, PLATAFORMA 40px/12px, CLIENTE 40px/pílula em 13px,
   idioma 44px/12px e os ícones 36px/8px. Cinco alturas e três cantos numa
   barra de 5cm. Agora é um controle só: 40px de altura, pílula, mesma borda,
   mesmo corpo de texto. Ícone vira círculo de 40px — mesma altura da linha,
   forma diferente porque é outra função (ação, não campo).
   -------------------------------------------------------------------------- */
header input[placeholder^="Buscar veículo"],
header input[aria-label="Selecionar cliente"],
header .i3gp-btn {
  height: 40px !important;
  min-height: 40px !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  border: 1px solid var(--border) !important;
  background: var(--surface-2) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
  line-height: 1.2 !important;
}
:root[data-theme="light"] header .i3gp-btn { background: var(--surface-2) !important; }

/* O rótulo inline (PLATAFORMA / CLIENTE) é o mesmo tipo nos dois controles.
   O corpo fica em 10px, NÃO no token de legenda (11px): o recuo do campo é
   fixo em pixels (96px para PLATAFORMA, 64px para CLIENTE, §13.4/§31) e um
   milímetro a mais de rótulo faz ele encostar no valor — "PLATAFORMATodas as
   plataformas". Enquanto o recuo for constante literal, o rótulo também é. */
header [data-i3-clientlabel],
header .i3gp-lab {
  font: var(--i3t-weight-semibold, 600) 10px / 1 var(--i3t-font-body, 'Inter', sans-serif) !important;
  letter-spacing: var(--i3t-tracking-eyebrow, .08em) !important;
  /* `--sub`, não `--placeholder`: medido, o placeholder dá 2,81:1 no claro e
     3,84:1 no escuro — abaixo do mínimo de 4,5:1 para texto de 10px. E não é
     texto decorativo: é o rótulo que diz se você está olhando UMA plataforma
     ou TODAS. Ler errado aqui é agir na base errada. */
  color: var(--sub) !important;
}

/* Ícones da direita: 40px redondos. Vence o §13.5 (que fixa 36px com
   !important) por especificidade — :root soma um seletor a mais. */
:root header button.btn {
  height: 40px !important; width: 40px !important; min-width: 40px !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
}

/* Seletor de idioma, quando aparece, na mesma métrica. */
header select {
  height: 40px !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
}

/* Foco visível e igual em toda a barra — a marca, nunca o azul do sistema. */
header input:focus-visible,
header .i3gp-btn:focus-visible,
header button.btn:focus-visible {
  outline: 2px solid var(--i3t-focus-ring, rgba(102,163,255,.55)) !important;
  outline-offset: 2px !important;
}

/* --------------------------------------------------------------------------
   §51.2 — BOTÃO
   Três famílias conviviam (.btn, .drivers-button, .videos-toolbar-button) mais
   Tailwind cru, em sete alturas (26, 32, 34, 38, 39, 40, 42, 42.8, 48.6px).
   Agora: 40px, PÍLULA, 14px/600. A cor diz o peso da ação, não a tela em
   que ela está. A pílula veio depois, junto com a dos campos (§54.1): campo
   redondo ao lado de botão de canto 10px é a mesma emenda de antes, só que
   entre componentes em vez de dentro de um.

   Só alcança o que i3track-ui.js etiquetou — chip, aba, badge e botão de
   linha de tabela ficam de fora de propósito.
   -------------------------------------------------------------------------- */
main [data-i3t-btn] {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: var(--i3t-space-2, 8px) !important;
  height: 40px !important;
  min-height: 40px !important;
  /* Pílula pede mais respiro lateral que canto reto: com 16px o rótulo
     encosta na curva. 20px literal — não há token nesse degrau (space-4 é 16,
     space-5 é 24, e 24 já empurra demais a barra de oito botões da Entregas). */
  padding: 0 20px !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  border: 1px solid transparent !important;
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  line-height: 1 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  white-space: nowrap !important;
  cursor: pointer;
  transition: background-color var(--i3t-transition-fast, 120ms ease),
              border-color var(--i3t-transition-fast, 120ms ease),
              color var(--i3t-transition-fast, 120ms ease);
}
main [data-i3t-btn] svg { width: 16px !important; height: 16px !important; flex: none; }

/* Primário: um por região. Fundo cheio na cor da marca. */
main [data-i3t-btn="primario"] {
  background: var(--i3t-brand-solid, #0052E6) !important;
  border-color: var(--i3t-brand-solid, #0052E6) !important;
  color: #FFFFFF !important;
}
main [data-i3t-btn="primario"]:hover:not(:disabled) {
  background: var(--i3t-brand-solid-hover, #0047C7) !important;
  border-color: var(--i3t-brand-solid-hover, #0047C7) !important;
}

/* Secundário: o resto. Superfície elevada e borda — legível sem competir. */
main [data-i3t-btn="secundario"] {
  background: var(--surface-2) !important;
  border-color: var(--border) !important;
  color: var(--text) !important;
}
main [data-i3t-btn="secundario"]:hover:not(:disabled) {
  border-color: var(--placeholder) !important;
  background: var(--field-bg-hover, var(--surface-2)) !important;
}

/* Destrutivo: vermelho de contorno. Sólido só depois da confirmação, e isso
   é decisão de produto, não de estilo. */
main [data-i3t-btn="perigo"] {
  background: transparent !important;
  border-color: var(--i3t-danger, #EF4444) !important;
  color: var(--i3t-danger, #EF4444) !important;
}
main [data-i3t-btn="perigo"]:hover:not(:disabled) {
  background: var(--i3t-danger-soft, rgba(239,68,68,.16)) !important;
}

main [data-i3t-btn]:disabled,
main [data-i3t-btn][aria-disabled="true"] {
  opacity: .5 !important;
  cursor: not-allowed;
}
main [data-i3t-btn]:focus-visible {
  outline: 2px solid var(--i3t-focus-ring, rgba(102,163,255,.55)) !important;
  outline-offset: 2px !important;
}

/* O azul sólido do botão primário é o MESMO nos dois temas: é a cor da marca
   impressa, e trocá-la por tema faria a mesma ação parecer duas ações. O que
   muda é o entorno, não ele. */
:root { --i3t-brand-solid: #0052E6; --i3t-brand-solid-hover: #0047C7; }
:root[data-theme="dark"] { --i3t-brand-solid: #0052E6; --i3t-brand-solid-hover: #1a63ea; }
:root[data-theme="light"] { --i3t-brand-solid: #0052E6; --i3t-brand-solid-hover: #0047C7; }

/* --------------------------------------------------------------------------
   §51.3 — ESTADO VAZIO DE /drivers (correção de defeito, não de estilo)
   `.drivers-empty` pinta o texto em rgba(255,255,255,.58) sem distinguir tema.
   No claro isso é branco sobre branco: contraste 1.00:1 — a frase "Nenhum
   motorista encontrado para os filtros aplicados." simplesmente não existe
   para quem usa o tema claro, e a tela parece quebrada em vez de vazia.
   As outras telas já eram resgatadas pela varredura de `text-white/60`;
   esta tinha regra própria e ficou de fora.
   -------------------------------------------------------------------------- */
:root[data-theme="light"] .drivers-empty,
:root[data-theme="light"] .drivers-empty * {
  color: var(--sub, #545454) !important;
}


/* --------------------------------------------------------------------------
   §52 — CABEÇALHO DE PÁGINA (Fase 3, lote 3)

   O QUE HAVIA
   Duas gramáticas. Sete telas usam o componente compartilhado `.page-header`
   e mostram o nome da página como um rótulo de 13,6px em CAIXA ALTA, cinza a
   50% — parece etiqueta de seção, não título. Três telas (Motoristas, Vídeos,
   Reconhecimento Facial) trazem cabeçalho próprio dentro de um card-herói com
   gradiente, borda tingida, canto de 28px e sombra de 56px, com o título em
   43-45px. A mesma informação — "que tela é esta" — aparecia com quatro vezes
   a diferença de corpo dependendo do dia em que a tela foi feita.

   O QUE PASSA A VALER
   Um cabeçalho só: eyebrow opcional (11px, 600, caixa alta, tom secundário)
   + título 24px em Bricolage + descrição 14px. Sem card em volta. O card
   voltava a informação para dentro de uma moldura que nenhuma outra tela
   tinha, e era ele que fazia as telas parecerem produtos diferentes.

   Nada é removido: chip vira eyebrow, título continua título, descrição
   continua descrição. Só param de gritar em volumes diferentes.
   -------------------------------------------------------------------------- */

/* --- TÍTULO (o nome da tela) --- */
main .page-header__title,
main .drivers-title,
main .videos-hero__title {
  font-family: var(--i3t-font-display, 'Bricolage Grotesque', 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-h1, 1.5rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  line-height: var(--i3t-leading-tight, 1.2) !important;
  letter-spacing: -0.01em !important;
  text-transform: none !important;
  color: var(--text) !important;
  margin: 0 !important;
}

/* --- EYEBROW (o contexto acima do título) --- */
main .drivers-chip,
main .videos-overline {
  display: inline-block !important;
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: var(--i3t-tracking-eyebrow, .08em) !important;
  text-transform: uppercase !important;
  color: var(--sub) !important;
  /* a pílula de Motoristas some: era o único eyebrow do sistema com fundo,
     borda e ícone, e o fundo tingido concorria com o título logo abaixo. */
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 0 var(--i3t-space-2, 8px) !important;
}
main .drivers-chip svg { display: none !important; }

/* --- DESCRIÇÃO --- */
main .page-header__subtitle,
main .drivers-subtitle,
main .videos-hero__subtitle {
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
  font-weight: var(--i3t-weight-regular, 400) !important;
  line-height: var(--i3t-leading-normal, 1.55) !important;
  color: var(--sub) !important;
  margin: var(--i3t-space-2, 8px) 0 0 !important;
}

/* --- FIM DO CARD-HERÓI ---
   Gradiente, borda tingida, canto de 28px e sombra saem. O conteúdo continua
   inteiro; só deixa de morar dentro de uma moldura que só ele tinha. */
main .drivers-hero,
main .videos-hero {
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
}
main .drivers-hero::before, main .drivers-hero::after,
main .videos-hero::before, main .videos-hero::after {
  background: none !important;
  box-shadow: none !important;
  border: 0 !important;
}
/* o respiro que o padding do card dava fica entre cabeçalho e conteúdo */
main .drivers-hero__top { margin-bottom: var(--i3t-space-5, 24px) !important; }
main .videos-hero__copy { margin-bottom: var(--i3t-space-5, 24px) !important; }

/* Lavagem colorida de página inteira: `.videos-page::before` pinta um
   radial ciano sobre TODA a tela de Vídeos e de Reconhecimento Facial. Não é
   o card-herói (esse já saiu acima) — é um fundo que só essas duas telas têm,
   e é ele que ainda faz o Vídeos parecer outro produto depois de o cabeçalho
   já estar padronizado. Nenhuma outra tela tem fundo tingido. */
main .videos-page::before, main .videos-page::after,
main .drivers-page::before, main .drivers-page::after {
  background: none !important;
  background-image: none !important;
  box-shadow: none !important;
}


/* --------------------------------------------------------------------------
   §53 — CARD DE INDICADOR (Fase 3, lote 4)

   Quatro desenhos viravam um. A cor à esquerda é o que distingue um cartão do
   outro numa linha de seis — ela NÃO significa estado. Estado continua sendo
   dito por texto e por badge, onde a leitura é inequívoca; se a cor também
   quisesse dizer estado, "ATIVOS em verde" e "o terceiro cartão é verde"
   competiriam pelo mesmo canal e nenhum dos dois seria confiável.

   Ordem fixa por posição: o mesmo cartão tem sempre a mesma cor. Paleta
   validada para protan/deutan em i3track-tokens.css. Etiquetagem em
   i3track-ui.js.
   -------------------------------------------------------------------------- */
main [data-i3t-kpi] {
  background: var(--surface-2) !important;
  background-image: none !important;
  border: 1px solid var(--border) !important;
  border-left: var(--i3t-kpi-accent-width, 4px) solid var(--i3t-kpi-cor, var(--i3t-kpi-1)) !important;
  border-radius: var(--i3t-radius-lg, 16px) !important;
  padding: var(--i3t-space-4, 16px) !important;
  box-shadow: none !important;
}
main [data-i3t-kpi="1"] { --i3t-kpi-cor: var(--i3t-kpi-1); }
main [data-i3t-kpi="2"] { --i3t-kpi-cor: var(--i3t-kpi-2); }
main [data-i3t-kpi="3"] { --i3t-kpi-cor: var(--i3t-kpi-3); }
main [data-i3t-kpi="4"] { --i3t-kpi-cor: var(--i3t-kpi-4); }
main [data-i3t-kpi="5"] { --i3t-kpi-cor: var(--i3t-kpi-5); }
main [data-i3t-kpi="6"] { --i3t-kpi-cor: var(--i3t-kpi-6); }
main [data-i3t-kpi="7"] { --i3t-kpi-cor: var(--i3t-kpi-7); }
main [data-i3t-kpi="8"] { --i3t-kpi-cor: var(--i3t-kpi-8); }

/* O ícone que só Vídeos e Face tinham vira decoração discreta em vez de um
   segundo foco disputando com o número. */
main [data-i3t-kpi] .videos-stat-icon {
  background: transparent !important;
  opacity: .45 !important;
}

/* Dois cartões da Home (`.alert-card`) trazem lavagem vermelha de 6% vinda do
   bundle com `!important` e especificidade (0,3,1). Fica vermelha mesmo com
   ZERO alertas — não é sinal de estado, é decoração fixa, e um cartão que
   parece alarmado quando não há nada errado ensina a ignorar o alarme. O
   estado real já está no número. `html:root` sobe para (0,3,2) e vence.
   Para devolver a lavagem, basta apagar este bloco. */
html:root[data-theme] main [data-i3t-kpi] {
  background-color: var(--surface-2) !important;
  background-image: none !important;
}


/* --------------------------------------------------------------------------
   §54 — CAMPO, RÓTULO, BADGE, TABELA E ESTADO VAZIO (Fase 3, lote 5)
   Etiquetagem em i3track-ui.js, exceto tabela e rótulo, que já têm seletor
   próprio bom o bastante.
   -------------------------------------------------------------------------- */

/* --- §54.1 CAMPO DE FILTRO ---
   Sete alturas viravam uma: 40px, igual à do botão que fica ao lado. Campo e
   botão numa mesma barra com alturas diferentes é o defeito mais visível de
   toda a tela, porque a linha de base não fecha. */
main [data-i3t-campo] {
  height: 40px !important;
  min-height: 40px !important;
  /* PÍLULA, igual à da topbar. Antes eram cinco cantos diferentes na mesma
     tela — 10, 12, 8, 0 e pílula —, e é o canto, mais que a altura, que faz a
     linha de filtros parecer remendada. A métrica é copiada do §51.1, que é
     o que o dono apontou como certo. */
  border-radius: var(--i3t-radius-pill, 999px) !important;
  border: 1px solid var(--border) !important;
  /* Um fundo só. Havia quatro convivendo: #1E1E1E, #242424, #1C1C1C e
     transparente. `--surface-2` é o da busca da topbar. */
  background-color: var(--surface-2) !important;
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
  line-height: 1.2 !important;
  color: var(--text) !important;
  /* Só o recuo VERTICAL é zerado. `.drivers-select` tinha 13px em cima e
     embaixo; com a altura travada em 40px o texto transbordava e "Todos os
     documentos" ficava cortado ao meio. O recuo horizontal fica intacto de
     propósito: vários campos reservam 36-40px à esquerda para a lupa, e
     zerar isso jogaria o texto por baixo do ícone. */
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}
main textarea[data-i3t-campo] {
  height: auto !important; min-height: 80px !important;
  padding: 10px 12px !important;
}
main [data-i3t-campo]:focus,
main [data-i3t-campo]:focus-visible {
  outline: 2px solid var(--i3t-focus-ring, rgba(102,163,255,.55)) !important;
  outline-offset: 1px !important;
  border-color: var(--placeholder) !important;
  box-shadow: none !important;
}
/* Vídeos e Face: quem desenha o campo é a casca, não o input. Mesma métrica. */
main .videos-filter-shell {
  min-height: 40px !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  border: 1px solid var(--border) !important;
  background-color: var(--surface-2) !important;
  box-shadow: none !important;
}
/* ...mas no TEMA CLARO o fundo tem de ser BRANCO, não `--surface-2`.
   Medido nas duas telas: no tema escuro o campo de /videos e /face fica
   #242424, igual ao de /vehicles — lá não há divergência. No tema claro o
   campo do resto do sistema resolve para #FFFFFF e só estes dois ficavam em
   #EFEFEF, o cinza do `--surface-2`. Um campo cinza ao lado de campos brancos
   na mesma tela lê como campo desabilitado, e era esse o incômodo.
   Duas regras alcançam a casca (esta e a de `[data-i3t-campo]`, que o
   i3track-ui.js também põe nela), então o seletor precisa vencer as duas:
   `:root[data-theme="light"] main .videos-filter-shell` = (0,3,2). */
:root[data-theme="light"] main .videos-filter-shell,
:root[data-theme="light"] main .videos-filter-shell[data-i3t-campo] {
  background-color: var(--field-bg) !important;
}

/* --- §54.2 RÓTULO DE CAMPO ---
   Onde existe rótulo, ele é o mesmo tipo do eyebrow: 11px, 600, caixa alta.
   Onde não existe, NÃO foi inventado — inventar rótulo é mexer em conteúdo. */
main .videos-filter-label,
main [class*="filter-label"],
main .page-header ~ * label > span:first-child {
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: var(--i3t-tracking-eyebrow, .08em) !important;
  text-transform: uppercase !important;
  color: var(--sub) !important;
}

/* --- §54.3 BADGE DE ESTADO (dentro de tabela) ---
   Só a forma é unificada. A cor continua sendo do estado: é ela que diz
   "online" e "sem comunicação", e trocá-la por cor de índice apagaria a
   única informação que o badge carrega. */
main [data-i3t-badge] {
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  /* min-height, não height: "Sem transmissão 1-6h" ocupa duas linhas e
     altura fixa cortaria a segunda. O que é padronizado é o tipo, o canto e o
     respiro; o tamanho quem decide é o texto, que é conteúdo. */
  min-height: 22px !important;
  padding: 3px var(--i3t-space-2, 8px) !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: .02em !important;
  line-height: 1.3 !important;
}

/* --- §54.4 TABELA ---
   Cabeçalho no mesmo tipo do rótulo. Altura de linha vinha de padding entre
   8px e 24px — 37px numa tela e 73px na outra para a mesma densidade de
   informação. Passa a 12px em toda parte; o que exceder isso vem do conteúdo
   da célula, que é onde a altura deve mesmo ser decidida. */
main table th {
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: var(--i3t-tracking-eyebrow, .08em) !important;
  text-transform: uppercase !important;
  color: var(--sub) !important;
  padding: var(--i3t-space-3, 12px) !important;
  text-align: left;
  white-space: nowrap;
}
main table td {
  font-size: var(--i3t-text-body, 0.875rem) !important;
  padding: var(--i3t-space-3, 12px) !important;
  color: var(--text);
}
main table tbody tr { border-bottom: 1px solid var(--border) !important; }
main table tbody tr:last-child { border-bottom: 0 !important; }

/* --- §54.5 ESTADO VAZIO ---
   Sem moldura. A caixa tracejada de canto 22px que só Motoristas tinha
   desenhava uma ausência com mais ênfase do que a tela dá à presença. */
main [data-i3t-vazio] {
  display: block !important;
  padding: var(--i3t-space-6, 32px) var(--i3t-space-4, 16px) !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  text-align: center !important;
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-body, 0.875rem) !important;
  font-weight: var(--i3t-weight-regular, 400) !important;
  color: var(--sub) !important;
}


/* --------------------------------------------------------------------------
   §56 — INTELIGÊNCIA DOS EVENTOS no padrão das outras telas

   Era a única tela que morava dentro de uma moldura própria: `.ei-header-shell`
   com gradiente radial, canto de 28px, borda e sombra de 56px envolvendo
   cabeçalho, indicadores, abas e período. Dentro dela, cada indicador ganhava
   ainda um segundo invólucro (`.ei-header-chart-card`, canto 24px) — card
   dentro de card dentro de card, três molduras para um número.
   -------------------------------------------------------------------------- */
main .ei-header-shell {
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
}
/* `.ei-header-chart-card` passa a SER o cartão de indicador (§53 desenha a
   superfície e o acento). Quem perde a moldura é o bloco de dentro: com os
   dois desenhados, era cartão dentro de cartão de novo. */
main .ei-header-chart-card {
  background-image: none !important;
  box-shadow: none !important;
}
/* o brilho de topo do cartão vinha de um pseudo-elemento, não do fundo —
   zerar só `background-image` deixava uma faixa clara sobre a superfície */
main .ei-header-chart-card::before, main .ei-header-chart-card::after,
main .ei-header-chart-card__top::before, main .ei-header-chart-card__top::after {
  background: none !important;
  background-image: none !important;
  box-shadow: none !important;
  border: 0 !important;
}
main .ei-header-chart-card__top {
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 0 var(--i3t-space-3, 12px) !important;
}
main .ei-header-shell::before, main .ei-header-shell::after {
  background: none !important;
  box-shadow: none !important;
}

/* O nome da tela era um texto de 11px dentro da moldura. Vira título, como em
   todas as outras páginas (§52). */
main .ei-header-shell__kicker {
  font-family: var(--i3t-font-display, 'Bricolage Grotesque', 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-h1, 1.5rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  line-height: var(--i3t-leading-tight, 1.2) !important;
  letter-spacing: -0.01em !important;
  text-transform: none !important;
  color: var(--text) !important;
}

/* Linha que repete o que o topo do cartão já disse (i3track-ui.js). */
main [data-i3t-repetido] { display: none !important; }

/* O rosquinha herói tinha 460px de altura contra 280px dos gráficos da própria
   tela e do Painel Geral. Um gráfico de um número não precisa de meia tela. */
main div[class*="h-[460px]"] { height: 280px !important; }

/* As abas eram três botões com gradiente e canto de 12px dentro de uma caixa —
   pareciam ação, não navegação. Viram abas: a ativa é marcada por baixo. */
main .ei-view-tab {
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  border-bottom: 2px solid transparent !important;
  padding: 0 var(--i3t-space-3, 12px) !important;
  height: 34px !important;
  color: var(--sub) !important;
  font-weight: var(--i3t-weight-medium, 500) !important;
}
main .ei-view-tab[aria-selected="true"],
main .ei-view-tab.is-active,
main .ei-view-tab[data-ativo="true"] {
  color: var(--text) !important;
  border-bottom-color: var(--i3t-brand-solid, #0052E6) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
}


/* --------------------------------------------------------------------------
   §57 — BLOCO DE FILTROS COMPACTO (Vídeos, Reconhecimento Facial)

   Oito campos em três colunas viravam TRÊS fileiras de rótulo + campo, cada
   uma com ~103px: o bloco comia 310px antes de a tela começar. Em quatro
   colunas os mesmos oito campos cabem em duas fileiras.

   Só a partir de 1280px. Abaixo disso o próprio bundle já desce para 3, 2 e 1
   coluna, e forçar quatro num monitor estreito espremeria "CONFIANÇA EXTERNA
   MÍNIMA" a ponto de virar reticências.
   -------------------------------------------------------------------------- */
@media (min-width: 1280px) {
  main .videos-filter-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
    gap: 10px 12px !important;
  }
}
/* O rótulo colava no campo com quase 18px de folga — respiro de título, não
   de rótulo de campo. */
main .videos-filter-grid > * > label,
main .videos-filter-grid > label {
  display: flex !important;
  flex-direction: column !important;
  gap: 5px !important;
}
main .videos-filter-panel { gap: 12px !important; }

/* Campo de filtro tirado da tela por i3track-filtros-video.js.
   Precisa ser CSS, e com `!important`: a regra logo acima trava o <label> em
   `display:flex !important`, e estilo inline SEM important perde para ela —
   o script escondia e a tela ignorava, sem erro nenhum. Etiqueta em JS,
   desenho no CSS, como o resto do sistema visual.
   `> label[data-i3-filtro-fora]` = (0,3,1), vence os (0,2,1) de cima. */
main .videos-filter-grid > label[data-i3-filtro-fora],
main .videos-filter-grid > * > label[data-i3-filtro-fora],
main [data-i3-filtro-fora] { display: none !important; }


/* --------------------------------------------------------------------------
   §58 — INTELIGÊNCIA DOS EVENTOS: CARTÃO SEM SUB-INFORMAÇÃO

   Cada indicador trazia embaixo um mini-gráfico vazio mais uma lista
   ("ADAS 0 / DSM 0 / Live Recording 0", "Fora do SLA", "Incidência crítica /
   Volume total", "Revisado / Pendente"). São 144px por cartão para repetir,
   miúdo, o que o número de cima já diz — e como cada cartão tinha uma
   quantidade diferente de linhas, os quatro ficavam com alturas diferentes.

   Escondido, não removido: o dado continua no DOM.
   -------------------------------------------------------------------------- */
main .ei-header-chart-card__visual { display: none !important; }
/* Esconder o bloco não encolhe o cartão: a altura vinha da grade, que estica
   todos à altura do maior. Sem isto sobram 130px de vazio embaixo do número.
   O esticar da grade fica: é ele que mantém os quatro do mesmo tamanho quando
   "TAXA DE REVISÃO" quebra o rótulo em duas linhas. */
main .ei-header-chart-card {
  height: auto !important;
  min-height: 0 !important;
}
main .ei-header-chart-card__top { height: auto !important; min-height: 0 !important; }


/* --------------------------------------------------------------------------
   §59 — A ROSQUINHA NO PADRÃO DO PAINEL GERAL

   No Painel Geral o gráfico mora num cartão com borda e superfície, tem cerca
   de 240px e as fatias são de cor CHEIA. Aqui ele flutuava solto sobre um
   gradiente radial, com 460px de altura e as fatias em 38% de opacidade — daí
   parecerem duas telas de produtos diferentes.

   Limite honesto: são componentes recharts distintos compilados dentro do
   bundle. Dá para igualar moldura, tamanho e cor; trocar um pelo outro exige
   o código-fonte, que não compila nesta máquina. A opacidade das fatias é
   corrigida em i3track-ui.js, porque o alfa vem dentro do próprio `fill`.
   -------------------------------------------------------------------------- */
main div[class*="radial-gradient"]:has(.recharts-responsive-container) {
  background-image: none !important;
  background-color: var(--surface-1, #1E1E1E) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--i3t-radius-lg, 16px) !important;
  padding: var(--i3t-space-4, 16px) !important;
}
/* 240px cortava a rosquinha em cima e embaixo: o contêiner tem
   `overflow-hidden` e o recharts não recalcula o raio a tempo. 300px é a
   menor altura em que ela cabe inteira — ainda menos da metade dos 460px
   originais. */
main div[class*="h-[460px]"] { height: 300px !important; }
main div[class*="radial-gradient"]:has(.recharts-responsive-container) {
  overflow: visible !important;
}


/* --------------------------------------------------------------------------
   §60 — CARTÃO DE INDICADOR JÁ NASCE NO TOM CERTO (fim do pisca)

   O §53 desenha o cartão a partir de `data-i3t-kpi`, que é etiqueta do JS —
   ou seja, chega DEPOIS da primeira pintura. Medido em /drivers: aos 400ms o
   cartão ainda era o do bundle (gradiente branco 8%, borda de 1px, canto 22px)
   e só perto dos 3s virava o novo. Quem abre a página vê a troca.

   A cura é repetir a superfície do §53 nas CLASSES DO PRÓPRIO BUNDLE, que já
   estão no HTML quando o React renderiza. O JS deixa de ser responsável pelo
   tom e passa a cuidar só do acento colorido — que é uma faixa de 4px, e
   aparecer 200ms depois não incomoda como o cartão inteiro mudando de cor.

   Mantém `!important` porque `.drivers-stat-card` traz gradiente próprio.
   -------------------------------------------------------------------------- */
main .videos-stat-card,
main .drivers-stat-card,
main .ei-kpi-card,
main .ei-ops-metric-card,
main .alert-card {
  background: var(--surface-2) !important;
  background-image: none !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--i3t-radius-lg, 16px) !important;
  padding: var(--i3t-space-4, 16px) !important;
  box-shadow: none !important;
}

/* E o acento também, por POSIÇÃO — é a mesma conta que o JS faz, só que sem
   esperar por ele. Assim o cartão nasce inteiro: tom e faixa. O JS continua
   escrevendo o acento inline (é o único jeito de vencer o inline `!important`
   de Veículos e Entregas), mas escreve a MESMA cor, então não há troca
   visível. Só as famílias que ficam numa linha de irmãos; onde o cartão mora
   em invólucro próprio, quem resolve continua sendo o JS. */
main .videos-stat-card:nth-of-type(1), main .drivers-stat-card:nth-of-type(1) { border-left: 4px solid var(--i3t-kpi-1) !important; }
main .videos-stat-card:nth-of-type(2), main .drivers-stat-card:nth-of-type(2) { border-left: 4px solid var(--i3t-kpi-2) !important; }
main .videos-stat-card:nth-of-type(3), main .drivers-stat-card:nth-of-type(3) { border-left: 4px solid var(--i3t-kpi-3) !important; }
main .videos-stat-card:nth-of-type(4), main .drivers-stat-card:nth-of-type(4) { border-left: 4px solid var(--i3t-kpi-4) !important; }
main .videos-stat-card:nth-of-type(5), main .drivers-stat-card:nth-of-type(5) { border-left: 4px solid var(--i3t-kpi-5) !important; }
main .videos-stat-card:nth-of-type(6), main .drivers-stat-card:nth-of-type(6) { border-left: 4px solid var(--i3t-kpi-6) !important; }


/* --------------------------------------------------------------------------
   §61 — MOTORISTAS NO PADRÃO DE VEÍCULOS

   Três diferenças em relação a /vehicles, que é a tela que o dono apontou
   como certa.
   -------------------------------------------------------------------------- */

/* 61.1 — Os botões sobem para a direita do título.
   `.drivers-hero__top` já é `flex` com `space-between`; o que jogava os botões
   para baixo era o `flex-wrap: wrap` somado a um bloco de texto largo demais
   para caber ao lado. Sem mover nó nenhum: o texto passa a poder encolher
   (`min-width: 0`) e a linha para de quebrar. */
main .drivers-hero__top {
  flex-wrap: nowrap !important;
  align-items: flex-start !important;
}
main .drivers-hero__top > *:first-child { min-width: 0 !important; flex: 1 1 auto !important; }
main .drivers-actions { flex: 0 0 auto !important; flex-wrap: wrap !important; justify-content: flex-end !important; }

/* 61.2 — Sai a legenda de dentro do cartão ("Motoristas disponíveis no
   cadastro"), como em /vehicles, onde o cartão é só rótulo e número. É ela que
   faz o cartão de Motoristas ficar 40px mais alto que o de Veículos. */
main .drivers-stat-card__hint { display: none !important; }

/* 61.3 — A linha de filtros sai de dentro do cartão e fica no tom da página.
   `.driver-panel` é canto de 24px, borda e sombra em volta de quatro campos
   que já têm moldura própria: caixa dentro de caixa. */
main .driver-panel {
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
}


/* --------------------------------------------------------------------------
   §62 — SELETOR DA LIVE PARA DE CORTAR O RÓTULO

   A grade da barra de filtros da Live fixa colunas mínimas de 118px e 132px.
   Com os 30px de recuo da casca sobram ~90px para o texto, e "Todos os status"
   virava "Todos os stat⌄". Defeito antigo, não veio da padronização — mas está
   na mesma barra que acabou de ser padronizada, e rótulo cortado é pior do que
   qualquer emenda.

   Os mínimos novos somam ~1050px numa faixa de ~1100: continua cabendo em uma
   fileira. Só acima de 1280px; abaixo disso a grade do bundle já empilha.
   -------------------------------------------------------------------------- */
@media (min-width: 1280px) {
  main .videos-filter-rail {
    grid-template-columns:
      minmax(150px, .8fr) minmax(165px, .9fr) minmax(165px, .9fr)
      minmax(170px, 1fr) minmax(240px, 1.6fr) auto !important;
  }
}
/* 12px em vez de 15,2px: devolve 6px de texto por campo sem colar na curva. */
main .videos-filter-shell { padding-left: 12px !important; padding-right: 12px !important; }


/* --------------------------------------------------------------------------
   §63 — CABEÇALHO ENXUTO: SÓ O NOME DA PÁGINA

   Motoristas trazia eyebrow ("CADASTRO DE MOTORISTAS") mais um parágrafo de
   três linhas explicando a tela; Vídeos, a mesma coisa ("I3TRACK VIEW" e
   "Catálogo operacional de mídia..."). Veículos, que é a tela de referência,
   tem só o nome. Texto que explica o que a tela é serve para quem chega uma
   vez; para quem usa todo dia é altura roubada do conteúdo.

   Escondido, não removido — o texto continua no DOM.
   -------------------------------------------------------------------------- */
main .drivers-chip,
main .drivers-subtitle,
main .videos-overline,
main .videos-hero__subtitle,
/* "Período sincronizado com o recorte atual." — nota de rodapé que subiu junto
   com os botões para a linha do título, onde não é nota de nada e ainda comia
   280px da faixa. */
main .videos-filter-panel__hint { display: none !important; }

/* A legenda de dentro do cartão de Vídeos ("nenhum evento no recorte", "sem
   mídia pendente no recorte"...) some pelo mesmo motivo que a de Motoristas:
   é ela que faz o cartão ficar 102px onde Veículos usa 77px. Não tem classe
   própria — o único traço estável é o corpo de 11px, que ali só ela usa
   (o rótulo é 10px e o número é `text-xl`). */
main .videos-stat-card [class*="text-[11px]"] { display: none !important; }


/* --------------------------------------------------------------------------
   §64 — "CÂMERAS": A LIVE GANHA TÍTULO EM VEZ DE PÍLULA

   A tela não tinha título — tinha um chip teal
   (`rgba(8,145,178,.16)` com borda da mesma cor) escrito "CENTRO DE
   VIDEOTELEMETRIA". Era o azul solto no meio de uma tela de tons neutros.
   Vira título de página, igual ao "Motoristas". O texto é trocado em
   i3track-ui.js, porque conteúdo não se muda por CSS.
   -------------------------------------------------------------------------- */
main .videos-inline-chip--accent {
  display: block !important;
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  font-family: var(--i3t-font-titulo, 'Bricolage Grotesque', sans-serif) !important;
  font-size: var(--i3t-text-h1, 1.5rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: normal !important;
  text-transform: none !important;
  color: var(--text) !important;
}
main .videos-inline-chip--accent svg { display: none !important; }


/* --------------------------------------------------------------------------
   §65 — VÍDEOS: AÇÕES EM CIMA E FILTRO EM UMA FILEIRA SÓ

   Os quatro botões (Verificar todos, Aplicar período, Limpar filtros,
   Atualizar) ficavam no RODAPÉ do bloco de filtros, longe do título. Sobem
   por `order`, não por mudança de árvore — tirar nó do lugar estoura o React.
   -------------------------------------------------------------------------- */
main .videos-filter-panel { display: flex !important; flex-direction: column !important; }
main .videos-filter-panel__footer {
  order: -1 !important;
  justify-content: flex-end !important;
  padding-top: 0 !important;
  border-top: 0 !important;
}

/* Seis campos numa fileira só. `auto-fit` em vez de número fixo porque a
   mesma regra atende Vídeos (6 campos) e Reconhecimento Facial (8): a faixa
   comporta 6 colunas de 160px, então Vídeos fecha em uma linha e Face em duas,
   sem regra separada para cada tela. */
@media (min-width: 1280px) {
  main .videos-filter-grid {
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)) !important;
  }
}


/* --------------------------------------------------------------------------
   §66 — O NÚMERO E O RÓTULO DO CARTÃO, IGUAIS EM TODA PARTE

   Medido: o número tinha 32px/700 em Motoristas, 24px/600 em Veículos e
   20px/600 em Vídeos; o rótulo variava entre 10 e 11px e entre peso 400 e 700.
   A mesma informação, três desenhos.

   Fica o de VEÍCULOS, que é a tela que o dono escolheu como referência:
   número em 24px/600 (`--i3t-text-h1`) e rótulo em 11px caixa alta. Motoristas
   é que estava fora, com 32px — e como Veículos mostra SEIS cartões na mesma
   faixa, um número de 32px ali não caberia junto do rótulo.

   Etiquetagem por estrutura em i3track-ui.js (dentro do cartão, o maior texto
   com dígito é o número; o menor é o rótulo).
   -------------------------------------------------------------------------- */
main [data-i3t-kpi] [data-i3t-kpi-valor] {
  font-family: var(--i3t-font-body, 'Inter', sans-serif) !important;
  font-size: var(--i3t-text-h1, 1.5rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  line-height: 1.15 !important;
  color: var(--text) !important;
}
main [data-i3t-kpi] [data-i3t-kpi-rotulo] {
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  letter-spacing: var(--i3t-tracking-eyebrow, .08em) !important;
  text-transform: uppercase !important;
  color: var(--sub) !important;
}

/* As mesmas medidas pelas classes do bundle, para o cartão já NASCER assim —
   mesma razão do §60: o que o olho vê primeiro não pode depender do JS. */
main .videos-stat-card [class*="text-[10px]"],
main .drivers-stat-card__label {
  font-size: var(--i3t-text-caption, 0.6875rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
}
main .videos-stat-card [class*="text-xl"],
main .drivers-stat-card__value {
  font-size: var(--i3t-text-h1, 1.5rem) !important;
  font-weight: var(--i3t-weight-semibold, 600) !important;
  line-height: 1.15 !important;
}

/* O ícone é decoração, não segundo foco: a caixa de 44px disputava atenção
   com o número. */
main [data-i3t-kpi] .videos-stat-icon,
main .videos-stat-card .videos-stat-icon {
  width: 32px !important; height: 32px !important;
  flex: 0 0 32px !important;
}


/* --------------------------------------------------------------------------
   §67 — AS AÇÕES DE VÍDEOS SOBEM ACIMA DOS INDICADORES

   O §65 já as tinha tirado do rodapé, mas elas paravam entre os indicadores e
   os filtros. Para passarem ACIMA dos indicadores precisam ser irmãs deles, e
   são netas: moram dentro de `.videos-filter-panel`.

   `display: contents` resolve sem mexer na árvore — o painel deixa de gerar
   caixa e seus dois filhos passam a ser itens da grade do `.videos-hero`, ao
   lado do título e dos indicadores. Aí `order` funciona entre os quatro.
   Mover o nó de verdade estouraria `removeChild` na renderização seguinte.
   -------------------------------------------------------------------------- */
main .videos-hero .videos-filter-panel { display: contents !important; }

/* E na MESMA LINHA do título, como em Motoristas e em Câmeras: o cabeçalho
   vira duas colunas, o nome à esquerda e as ações à direita. Os indicadores e
   os filtros atravessam as duas.

   Posicionamento explícito em vez de `order`: com `order` os quatro blocos
   continuariam empilhados, um por linha. */
main .videos-hero {
  grid-template-columns: 1fr auto !important;
  align-items: center !important;
}
main .videos-hero .videos-hero__copy { grid-column: 1 !important; grid-row: 1 !important; }
main .videos-hero .videos-filter-panel__footer {
  grid-column: 2 !important; grid-row: 1 !important;
  flex-wrap: wrap !important;
  justify-content: flex-end !important;
}
main .videos-hero .videos-dashboard-grid { grid-column: 1 / -1 !important; }
main .videos-hero .videos-filter-grid { grid-column: 1 / -1 !important; }


/* ==========================================================================
   §68 — TELAS OPERACIONAIS DE FROTA
   Manutenção, Drive Behavior, Compliance e Combustível

   As quatro nasceram com o mesmo esqueleto — título, faixa de indicadores,
   blocos analíticos, barra de filtros, tabela — e com os mesmos quatro
   defeitos de composição. Estão corrigidos aqui, e não tela a tela, porque
   são o mesmo defeito repetido: cada regra abaixo descreve uma FORMA, não
   uma rota.
   ========================================================================== */

/* --- §68.1 PAINEL DE DIÁLOGO SEM FUNDO --------------------------------------
   Bug, não gosto: "Novo item de compliance" e "Registrar abastecimento" abriam
   TRANSPARENTES — dava para ler a tabela e os botões da página através do
   formulário.

   A causa não está no diálogo. O painel pede `bg-[#0b1320]`, e essa classe
   NÃO EXISTE na folha compilada: conferido, o bundle não traz uma única
   `bg-[#...]` de valor arbitrário (`grep` na CSS servida: zero ocorrências),
   enquanto o JavaScript escreve 29 hexadecimais diferentes assim. Quem pede
   uma dessas classes não recebe cor nenhuma — recebe transparente.

   O §17 já vinha remendando isso um hexadecimal por vez (`0B0F16`, `0f141c`).
   Aqui a regra é pela FORMA: painel que é filho direto de uma sobreposição
   `fixed inset-0` e declara fundo em hexadecimal arbitrário. Cobre os dois
   diálogos e qualquer outro construído do mesmo jeito, sem ter de catalogar
   os 29 valores. */
:root[data-theme] div.fixed.inset-0 > div[class*="bg-[#"] {
  background-color: var(--surface-card) !important;
}

/* --- §68.2 FAIXA DE INDICADORES: UMA LINHA SÓ -------------------------------
   Combustível declara quatro colunas e entrega CINCO cartões: o quinto
   ("Consumo CAN médio") caía sozinho numa segunda fileira, com três quartos
   da largura vazios ao lado. O mesmo acontecia em Drive Behavior, ao
   contrário: quatro colunas para DOIS cartões de tipo de evento.

   `auto-fit` faz a grade contar os cartões em vez de o desenvolvedor contar:
   as trilhas que sobram colapsam e os cartões dividem a largura. Não é
   remendo para cinco — é a grade deixar de ter um número cravado.

   Os cartões são reconhecidos pela etiqueta que o i3track-ui.js já põe
   (`data-i3t-kpi`), então a regra vale onde há indicador e em lugar nenhum
   além disso. */
main section.app-shell__content div.grid:has(> [data-i3t-kpi]) {
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)) !important;
  align-items: stretch !important;
}

/* --- §68.3 INDICADOR QUE É TEXTO, NÃO NÚMERO --------------------------------
   Manutenção e Drive Behavior põem "PERÍODO 05/07/26 até 04/08/26" na faixa,
   ao lado de VEÍCULOS 11 e SCORE MÉDIO 93. Em 24px esse texto quebra em duas
   linhas e ESTICA A FAIXA INTEIRA: os cinco cartões passam de 78px para
   102px por causa de um só.

   O valor continua inteiro — só desce para o corpo de 16px, que é o tamanho
   de texto do sistema. Um intervalo de datas não é um número para bater o
   olho; é uma referência, e referência se lê, não se escaneia.
   A etiqueta "longo" vem do i3track-ui.js, que mede o valor ao classificar. */
main [data-i3t-kpi] [data-i3t-kpi-valor="longo"] {
  font-size: var(--i3t-text-body-lg, 1rem) !important;
  line-height: 1.3 !important;
}

/* --- §68.4 O PERÍODO NO MESMO GABARITO DOS OUTROS CONTROLES -----------------
   Na barra de filtros, De/Até vinham numa caixa própria — com borda, fundo e
   recuo — de 79px de altura, ao lado de campos e botões de 40px. Uma caixa
   dentro da barra, quase o dobro da altura de tudo, é o que faz a linha
   parecer montada por duas pessoas diferentes.

   A caixa se dissolve e os dois campos viram controles como os outros; o
   rótulo (DE / ATÉ) passa a ficar À ESQUERDA do campo, em vez de acima. Nada
   de rótulo escondido: o que muda é a direção, não a informação.

   `:has(> div > label > input[type=date])` prende a regra à barra que
   REALMENTE tem um intervalo de datas — o mesmo par de campos dentro de um
   formulário de diálogo continua empilhado, que é o certo lá. */
main .flex.flex-wrap.items-center.gap-2 > div:has(> label > input[type="date"]) {
  border: 0 !important;
  background: transparent !important;
  padding: 0 !important;
  gap: var(--i3t-space-2, 8px) !important;
  align-items: center !important;
}
main .flex.flex-wrap.items-center.gap-2 > div:has(> label > input[type="date"]) > label {
  display: flex !important;
  align-items: center !important;
  gap: var(--i3t-space-2, 8px) !important;
  white-space: nowrap !important;
}
main .flex.flex-wrap.items-center.gap-2 > div:has(> label > input[type="date"]) > label > input {
  margin-top: 0 !important;
}

/* --- §68.5 A BARRA DE FILTROS NÃO QUEBRA EM DUAS FILEIRAS -------------------
   Em Manutenção a barra somava 1346px numa área de 1268: "Exportar XLSX"
   descia sozinho para uma segunda fileira, e a tabela ia junto, 56px mais
   para baixo. `flex-wrap` quebra ANTES de encolher — por isso o campo de
   busca ficava nos seus 320px enquanto a barra transbordava.

   A partir de 1280px a barra passa a caber por encolhimento: a busca cede o
   que for preciso (nunca abaixo de 160px, que ainda mostra uma placa
   inteira) e os botões ficam intactos. Abaixo de 1280px a quebra continua
   valendo — ali ela é o comportamento certo, não o defeito. */
@media (min-width: 1280px) {
  main .flex.flex-wrap.items-center.gap-2:has(> div > label > input[type="date"]) {
    flex-wrap: nowrap !important;
  }
  main .flex.flex-wrap.items-center.gap-2:has(> div > label > input[type="date"]) > input {
    flex: 1 1 200px !important;
    min-width: 160px !important;
  }
  main .flex.flex-wrap.items-center.gap-2:has(> div > label > input[type="date"]) > button,
  main .flex.flex-wrap.items-center.gap-2:has(> div > label > input[type="date"]) > div {
    flex: 0 0 auto !important;
  }
}

/* --- §68.6 ESTADO VAZIO DENTRO DE CARTÃO PEQUENO ---------------------------
   "Sem dados." ocupava 80px dentro de um cartão de 142px em Combustível —
   32px de recuo em cima e embaixo para três palavras.

   O recuo cai pela metade, e não mais que isso de propósito: esses três
   cartões são o pódio dos consumos, e vão receber três linhas assim que
   houver abastecimento lançado. Encolher até o texto faria a tela inteira
   pular no dia em que o dado chegar. */
main div[class*="rounded-2xl"] > [data-i3t-vazio],
main div[class*="rounded-xl"] > [data-i3t-vazio] {
  padding: var(--i3t-space-4, 16px) var(--i3t-space-4, 16px) !important;
}


/* --------------------------------------------------------------------------
   §69 — COMPLIANCE: O TRABALHO PRIMEIRO, A REFERÊNCIA NO FIM

   A tela abria com "Escopo de compliance" e três colunas de categorias —
   690px de material de consulta — antes do filtro e da tabela. E dizia a
   mesma coisa duas vezes: o escopo enumera as categorias em texto e as
   colunas as listam item por item.

   Ordem nova: indicadores → alertas → filtros → tabela → escopo → categorias.
   Alerta sobe junto com o trabalho, porque alerta é ação.

   Nada sai da árvore: o contêiner vira coluna e cada bloco recebe `order`.
   A etiquetagem (por título) está em i3track-compliance.js.
   -------------------------------------------------------------------------- */
main [data-i3t-fluxo="compliance"] {
  display: flex !important;
  flex-direction: column !important;
  gap: var(--i3t-space-4, 16px) !important;
}
/* O `space-y-4` do bundle põe margem no irmão seguinte. Numa coluna
   reordenada essa margem cai no lugar errado — quem espaça agora é o `gap`,
   que é indiferente à ordem. */
main [data-i3t-fluxo="compliance"] > * { margin-top: 0 !important; }

/* Bloco que só existia para agrupar dois blocos de destinos opostos: deixa
   de gerar caixa e os filhos entram na coluna. */
main [data-i3t-fluxo="compliance"] [data-i3t-solto] { display: contents !important; }

main [data-i3t-fluxo="compliance"] [data-i3t-ordem="0"]  { order: 0 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="10"] { order: 10 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="20"] { order: 20 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="30"] { order: 30 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="40"] { order: 40 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="50"] { order: 50 !important; }
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="60"] { order: 60 !important; }


/* --------------------------------------------------------------------------
   §70 — O CARTÃO NASCE CARTÃO

   O dono viu os indicadores abrirem de um jeito e virarem outro cerca de um
   segundo depois. Duas causas, e esta é a primeira.

   `bg-white/[0.04]` é valor arbitrário do Tailwind e NÃO está na folha
   compilada — medido: 59 elementos com essa classe, todos com
   `background-color: rgba(0,0,0,0)`. Enquanto o i3track-ui.js não etiqueta o
   cartão, não existe cartão na tela: existe um retângulo sem fundo. O §53 só
   desenha depois, a partir de `data-i3t-kpi`.

   (A irmã `bg-white/[0.03]` está compilada e pinta normalmente — por isso o
   defeito parecia aleatório de tela para tela.)

   Aqui a superfície vem das CLASSES DO PRÓPRIO BUNDLE, então chega no
   primeiro quadro, antes de qualquer JavaScript. É a mesma razão do §60: o
   que o olho vê primeiro não pode depender do JS. O valor é o mesmo
   `--surface-card` que o §53 aplica depois — assim não há troca de cor
   nenhuma quando a etiqueta chega, só o acento colorido entrando.

   A caixa do período (§68.4) continua transparente: aquele seletor é bem
   mais específico e vence este.
   -------------------------------------------------------------------------- */
:root[data-theme] main [class*="bg-white/[0.04]"] {
  background-color: var(--surface-card) !important;
}


/* --------------------------------------------------------------------------
   §71 — ÁREA DE RISCO: A AÇÃO NA LINHA DO TÍTULO

   Abaixo do título havia uma faixa só com duas frases de instrução e, à
   direita, o botão "Nova área". Tirados os parágrafos (i3track-areas-risco.js),
   sobrava uma moldura de 74px em volta de um botão — caixa em volta de nada.

   O botão sobe para a linha do título, que é onde Chip e Veículos põem a ação
   principal da tela. A faixa perde borda, fundo e recuo: deixa de ser cartão
   e passa a ser o que sempre foi, um lugar para o botão.

   Nada sai da árvore: o contêiner vira grade de duas colunas, título e ação
   ocupam a primeira linha, e todo o resto atravessa as duas.
   -------------------------------------------------------------------------- */
main [data-i3t-fluxo="area-risco"] {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) auto !important;
  align-items: center !important;
  gap: var(--i3t-space-4, 16px) !important;
}
/* `space-y-4` põe margem no irmão seguinte; numa grade a margem cai no lugar
   errado. Quem espaça agora é o `gap`. */
main [data-i3t-fluxo="area-risco"] > * { margin-top: 0 !important; grid-column: 1 / -1; }
main [data-i3t-fluxo="area-risco"] > [data-i3t-cabecalho] {
  grid-column: 1 !important; grid-row: 1 !important;
}
main [data-i3t-fluxo="area-risco"] > [data-i3t-acao] {
  grid-column: 2 !important; grid-row: 1 !important;
  border: 0 !important;
  background: transparent !important;
  padding: 0 !important;
  box-shadow: none !important;
}


/* --------------------------------------------------------------------------
   §72 — COMPLIANCE EM DUAS ABAS, E A LEGENDA DA ÁREA DE RISCO EM DIÁLOGO
   -------------------------------------------------------------------------- */

/* --- §72.1 ABAS "STATUS" / "ESCOPO" ---
   Mesma pílula segmentada dos filtros da própria tela (Todos/Vencidos/…),
   para não inventar um terceiro desenho de aba no sistema. */
main [data-i3t-abas] {
  display: inline-flex !important;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--i3t-radius-pill, 999px);
  background: var(--surface-card);
  width: fit-content;
}
main [data-i3t-abas] > [data-i3t-aba-alvo] {
  border: 0;
  background: transparent;
  color: var(--sub);
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  font-size: var(--i3t-text-body, 0.875rem);
  font-weight: var(--i3t-weight-semibold, 600);
  line-height: 1;
  padding: 8px 18px;
  border-radius: var(--i3t-radius-pill, 999px);
  cursor: pointer;
}
main [data-i3t-abas] > [data-i3t-aba-alvo]:hover { color: var(--text); }
main [data-i3t-abas] > [data-i3t-aba-alvo][data-ativa] {
  background: var(--field-bg-hover, var(--surface-2));
  color: var(--text);
}

/* Cada aba mostra os blocos que são dela. Descendente e não filho direto:
   "Alertas" (20) e "Escopo" (50) moram dentro do agrupador que virou
   `display:contents`, então não são filhos do contêiner. */
main [data-i3t-fluxo="compliance"][data-i3t-aba="status"] [data-i3t-ordem="50"],
main [data-i3t-fluxo="compliance"][data-i3t-aba="status"] [data-i3t-ordem="60"],
main [data-i3t-fluxo="compliance"][data-i3t-aba="escopo"] [data-i3t-ordem="10"],
main [data-i3t-fluxo="compliance"][data-i3t-aba="escopo"] [data-i3t-ordem="20"],
main [data-i3t-fluxo="compliance"][data-i3t-aba="escopo"] [data-i3t-ordem="30"],
main [data-i3t-fluxo="compliance"][data-i3t-aba="escopo"] [data-i3t-ordem="40"] {
  display: none !important;
}
main [data-i3t-fluxo="compliance"] [data-i3t-ordem="5"] { order: 5 !important; }

/* --- §72.2 DIÁLOGO DA LEGENDA (Área de Risco) ---
   O diálogo do sistema é estreito porque nasceu para pergunta e confirmação.
   A legenda é um cartão de seis tipos de risco: precisa de largura e de
   rolagem própria, senão vira uma coluna de uma palavra por linha. */
.i3dlg-painel.i3area-legenda {
  max-width: 720px !important;
  width: min(720px, calc(100vw - 32px)) !important;
  text-align: left !important;
}
.i3dlg-painel.i3area-legenda > div:first-child {
  max-height: min(70vh, 620px);
  overflow-y: auto;
}


/* --------------------------------------------------------------------------
   §73 — TELA "DETALHES DE COMPLIANCE" DO VEÍCULO (injetada)

   Mesmo encaixe da tela de Plataformas: fixa sobre a área de conteúdo, abaixo
   da topbar real e à direita do menu real. Topbar, menu e tema são os do app.
   -------------------------------------------------------------------------- */
.i3cvp {
  position: fixed; left: var(--i3duo-w, 292px); right: 0; bottom: 0;
  overflow: auto; z-index: 40;
  padding: var(--i3t-space-5, 24px) var(--i3t-space-6, 32px) 48px;
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  color: var(--text);
}
body.i3cvp-open section.app-shell__content { display: none !important; }

.i3cvp-msg, .i3cvp-falha { padding: 32px 4px; color: var(--sub); font-size: var(--i3t-text-body, .875rem); }
.i3cvp-falha { color: var(--i3t-danger, #EF4444); }

.i3cvp-topo { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.i3cvp-ident { display: flex; flex-direction: column; line-height: 1.25; }
.i3cvp-ident b { font-size: var(--i3t-text-h1, 1.5rem); font-weight: var(--i3t-weight-semibold, 600); }
.i3cvp-ident span { font-size: var(--i3t-text-caption, .6875rem); letter-spacing: .08em;
  text-transform: uppercase; color: var(--sub); font-weight: 600; }
.i3cvp-cob { margin-left: auto; padding: 6px 14px; border-radius: var(--i3t-radius-pill, 999px);
  border: 1px solid var(--border); background: var(--surface-card); color: var(--sub);
  font-size: 13px; font-weight: 600; }
.i3cvp-cob.ok { border-color: rgba(34,197,94,.45); color: #4ADE80; }

/* Semáforo. As cores são as mesmas do resto do sistema — aqui elas carregam
   informação (vencido/vencendo), então não entram no rodízio de cor do KPI. */
.i3cvp-selo { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: .02em; border: 1px solid; white-space: nowrap; }
.i3cvp-selo.ok   { border-color: rgba(34,197,94,.42);  background: rgba(34,197,94,.10);  color: #4ADE80; }
.i3cvp-selo.warn { border-color: rgba(245,158,11,.45); background: rgba(245,158,11,.10); color: #FBBF24; }
.i3cvp-selo.err  { border-color: rgba(239,68,68,.45);  background: rgba(239,68,68,.10);  color: #F87171; }
.i3cvp-selo.off  { border-color: var(--border); background: transparent; color: var(--sub); }

.i3cvp-abas { display: inline-flex; gap: 2px; padding: 3px; margin-bottom: 18px;
  border: 1px solid var(--border); border-radius: var(--i3t-radius-pill, 999px); background: var(--surface-card); }
.i3cvp-abas button { border: 0; background: transparent; color: var(--sub); cursor: pointer;
  font: inherit; font-size: var(--i3t-text-body, .875rem); font-weight: 600; line-height: 1;
  padding: 8px 18px; border-radius: var(--i3t-radius-pill, 999px); }
.i3cvp-abas button:hover { color: var(--text); }
.i3cvp-abas button[data-ativa] { background: var(--field-bg-hover, var(--surface-2)); color: var(--text); }

/* Uma categoria por linha, sempre as dez. A que falta aparece igual às
   outras, em cinza — é a ausência que precisa ficar visível. */
.i3cvp-lista { display: grid; gap: 10px; }
.i3cvp-doc { display: grid; gap: 10px; align-items: center; padding: 14px 16px;
  grid-template-columns: minmax(180px, 1fr) minmax(0, 2.2fr) auto;
  border: 1px solid var(--border); border-left: 4px solid var(--border);
  border-radius: 14px; background: var(--surface-card); }
.i3cvp-doc.err  { border-left-color: #EF4444; }
.i3cvp-doc.warn { border-left-color: #F59E0B; }
.i3cvp-doc.ok   { border-left-color: #22C55E; }
.i3cvp-doc-n { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.i3cvp-doc-n b { font-size: var(--i3t-text-body, .875rem); font-weight: 600; }
.i3cvp-doc-d { display: flex; gap: 26px; flex-wrap: wrap; }
.i3cvp-doc-d span { display: flex; flex-direction: column; font-size: var(--i3t-text-body, .875rem); color: var(--text); }
.i3cvp-doc-d i { font-style: normal; font-size: var(--i3t-text-caption, .6875rem); letter-spacing: .08em;
  text-transform: uppercase; color: var(--sub); font-weight: 600; margin-bottom: 2px; }
.i3cvp-doc-a { display: flex; gap: 8px; justify-content: flex-end; }
.i3cvp-doc-obs { grid-column: 1 / -1; font-size: 13px; color: var(--sub); border-top: 1px solid var(--border); padding-top: 8px; }
@media (max-width: 1100px) {
  .i3cvp-doc { grid-template-columns: 1fr; }
  .i3cvp-doc-a { justify-content: flex-start; }
}

.i3cvp-b { height: 34px; padding: 0 14px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 13px; font-weight: 500; line-height: 1; }
.i3cvp-b:hover { border-color: var(--sub); }
.i3cvp-b.perigo { color: var(--i3t-danger, #EF4444); border-color: rgba(239,68,68,.45); }

.i3cvp-ats { display: grid; gap: 10px; }
.i3cvp-at { display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 14px 16px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface-card); }
.i3cvp-at b { display: block; font-size: var(--i3t-text-body, .875rem); font-weight: 600; }
.i3cvp-at small { display: block; margin-top: 3px; font-size: 13px; color: var(--sub); }
.i3cvp-sem { font-size: 12px; color: var(--sub); font-style: italic; white-space: nowrap; }

/* Formulário do documento. */
.i3dlg-painel.i3cvp-form { max-width: 560px !important; width: min(560px, calc(100vw - 32px)) !important; text-align: left !important; }
.i3cvp-form .i3cvp-sub { margin: -6px 0 14px; font-size: var(--i3t-text-caption, .6875rem);
  letter-spacing: .08em; text-transform: uppercase; color: var(--sub); font-weight: 600; }
.i3cvp-grade2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.i3cvp-form label { display: flex; flex-direction: column; gap: 5px;
  font-size: var(--i3t-text-caption, .6875rem); letter-spacing: .08em; text-transform: uppercase;
  color: var(--sub); font-weight: 600; }
.i3cvp-form input, .i3cvp-form textarea {
  height: 40px; padding: 0 12px; border-radius: var(--i3t-radius-pill, 999px);
  border: 1px solid var(--border); background: var(--field-bg); color: var(--text);
  font: inherit; font-size: var(--i3t-text-body, .875rem); text-transform: none; letter-spacing: normal; }
.i3cvp-form textarea { height: auto; padding: 10px 14px; border-radius: 14px; resize: vertical; }
.i3cvp-form .i3cvp-obs { margin-top: 12px; }
.i3cvp-form .i3cvp-aviso { margin: 12px 0 0; font-size: 13px; color: var(--i3t-danger, #EF4444); }


/* --------------------------------------------------------------------------
   §74 — FILTRO DE DESTAQUE DENTRO DA GRADE

   Os cartões de "top 5" de Drive Behavior, Combustível e Ranking viraram
   botões em cima da própria tabela (i3track-destaques.js). Mesmo desenho da
   pílula segmentada que a casa já usa nos filtros — nenhum terceiro estilo
   de chip entra no sistema.
   -------------------------------------------------------------------------- */
main [data-i3-destaques] {
  display: flex !important;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: var(--i3t-space-3, 12px);
}
main [data-i3-destaques] > [data-f] {
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--sub);
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  height: 32px;
  padding: 0 14px;
  border-radius: var(--i3t-radius-pill, 999px);
  cursor: pointer;
}
main [data-i3-destaques] > [data-f]:hover { border-color: var(--sub); color: var(--text); }
main [data-i3-destaques] > [data-f][data-ativa] {
  background: var(--field-bg-hover, var(--surface-2));
  border-color: var(--placeholder);
  color: var(--text);
  font-weight: 600;
}
main [data-i3-destaques-conta] {
  font-size: 12px;
  color: var(--sub);
  margin-left: 2px;
}


/* --------------------------------------------------------------------------
   §75 — LIVE: OS FILTROS VOLTAM À COR DA CASA

   A tela Live injeta a própria folha (`LivePageTheme.jsx`) e nela redefine as
   superfícies em NAVY: `--videos-soft-bg: rgba(12,18,30,.84)`. A casca dos
   campos usa essa variável com `!important` e especificidade (0,2,0) —
   ganhava do §54.1 `main .videos-filter-shell` (0,1,1), que também é
   `!important`. Resultado: em Vídeos e Face o campo era cinza neutro e na
   Live era azul-marinho, na mesma sessão e no mesmo tema.

   A correção é na RAIZ, não campo a campo: as três variáveis de superfície da
   Live passam a apontar para os tokens do sistema. Assim casca de campo,
   pílula e botão secundário acertam de uma vez, e o dia em que a Live ganhar
   mais um componente que use `--videos-soft-bg` ele já nasce certo.

   `:root[data-theme] main .live-videos-page` = (0,3,2), vence o `.live-videos-page`
   (0,1,0) da folha da própria tela.
   -------------------------------------------------------------------------- */
:root[data-theme] main .live-videos-page,
:root[data-theme] .live-videos-page {
  --videos-soft-bg: var(--surface-2) !important;
  --videos-soft-bg-strong: var(--field-bg-hover, var(--surface-2)) !important;
  --videos-soft-border: var(--border) !important;
}


/* --------------------------------------------------------------------------
   §76 — COMBUSTÍVEL: O INDICADOR ABRE O PRÓPRIO GRÁFICO

   Os dois gráficos de 12 meses viviam lado a lado com 180px de altura: doze
   meses viram doze riscos colados. Apertando o indicador correspondente, um
   deles ocupa a linha inteira com o dobro da altura. Etiquetagem em
   i3track-combustivel.js.
   -------------------------------------------------------------------------- */
main [data-i3-graf-alvo] { cursor: pointer; }
main [data-i3-graf-alvo]:hover { border-color: var(--sub) !important; }
/* Indicador aberto: anel de foco discreto, para saber de quem é o gráfico
   grande que está no meio da tela. */
main [data-i3-graf-ativo] { box-shadow: 0 0 0 2px var(--accent-border-soft) !important; }

/* NADA ABERTO POR PADRÃO. Os dois gráficos nasciam na tela e ocupavam meia
   página para dizer pouco (doze meses em 180px de altura). Agora quem manda é
   o indicador: fechado, o gráfico não existe; aberto, ele aparece. Abrir os
   dois volta ao lado a lado; abrir um dá a linha inteira a ele. */
main [data-i3-graf-abertos] > [data-i3-graf] { display: none !important; }
main [data-i3-graf-abertos~="gasto"] > [data-i3-graf="gasto"],
main [data-i3-graf-abertos~="consumo"] > [data-i3-graf="consumo"] { display: block !important; }
/* Com um só aberto a grade vira de uma coluna; com os dois, o bundle já faz
   duas e não se mexe em nada. */
main [data-i3-graf-abertos="gasto"],
main [data-i3-graf-abertos="consumo"] { grid-template-columns: minmax(0, 1fr) !important; }
/* Nenhum aberto: some a CAIXA inteira. Esconder só os gráficos deixava a
   moldura na tela — borda, fundo e 34px de altura anunciando nada. */
main [data-i3-graf-caixa][data-i3-graf-vazio] { display: none !important; }

/* SÓ A LARGURA. Forçar a altura não funciona e ainda estraga: o Recharts
   recebe a altura como número fixo, então esticar a caixa para 420px deixava
   o desenho nos mesmos 180px e sobravam 240px de vazio embaixo do eixo —
   parecia gráfico quebrado. A largura ele acompanha sozinho (ResizeObserver),
   e é a largura que resolve o problema real: doze meses deixam de ser doze
   riscos colados. */


/* --------------------------------------------------------------------------
   §77 — COMPLIANCE: RISCO NA FRENTE, E EM COR

   A lista de conformidade vinha em ordem de placa. Numa frota grande, o único
   veículo vencido pode estar na linha 137 — a tela que existe para avisar não
   avisava. Agora vencido vem primeiro e em vermelho; vencendo em seguida, em
   laranja. Dentro de cada faixa a ordem de placa continua a mesma.

   A lista vira coluna flex só para poder usar `order`; nenhum nó é movido.
   O `space-y-2` do bundle põe margem no irmão seguinte, e numa coluna
   reordenada essa margem cai no lugar errado — por isso quem espaça passa a
   ser o `gap`.
   -------------------------------------------------------------------------- */
main [data-i3t-risco-lista] {
  display: flex !important;
  flex-direction: column !important;
  gap: var(--i3t-space-2, 8px) !important;
}
main [data-i3t-risco-lista] > * { margin-top: 0 !important; }

main [data-i3t-risco-ordem="0"] { order: 0 !important; }
main [data-i3t-risco-ordem="1"] { order: 1 !important; }
main [data-i3t-risco-ordem="2"] { order: 2 !important; }
main [data-i3t-risco-ordem="3"] { order: 3 !important; }

/* A cor é do ESTADO, como no badge de tabela (§54.3): não entra no rodízio de
   cor dos indicadores. Só quem exige ação ganha cor — "sem cadastro" e
   "em dia" continuam neutros, senão a lista inteira vira semáforo e nada
   chama atenção. */
/* Cor pela LONGHAND e com especificidade alta.
   Com o atalho `border-left: 4px solid <cor>` a largura pegava (4px) e a cor
   não: alguma regra posterior escreve `border-color` nas quatro bordas com
   `!important`, e o atalho perdia só na cor — a linha ficava com um traço
   grosso cinza, que parece defeito, não alerta. `border-left-color` sozinho,
   em `:root[data-theme] main [attr]` (0,2,2), fecha essa brecha. */
:root[data-theme] main [data-i3t-risco="vencido"] {
  border-left-width: 4px !important;
  border-left-style: solid !important;
  border-left-color: var(--i3t-danger, #EF4444) !important;
  background: rgba(239, 68, 68, .06) !important;
}
:root[data-theme] main [data-i3t-risco="proximo"] {
  border-left-width: 4px !important;
  border-left-style: solid !important;
  border-left-color: var(--i3t-warning, #F59E0B) !important;
  background: rgba(245, 158, 11, .06) !important;
}


/* --------------------------------------------------------------------------
   §78 — REGRA CONDICIONAL: PÁGINA COM ABAS, NÃO POP-UP

   O formulário tinha 945px de altura com rolagem PRÓPRIA dentro de uma janela
   de 1050 — cinco blocos empilhados atrás de uma barra de rolagem que não é a
   da página. As cinco seções viram abas e o cartão ocupa a área de conteúdo,
   encaixado abaixo da topbar real e à direita do menu real: topbar, menu e
   tema continuam sendo os do app.

   O nó continua onde o React o pôs — o que muda é o encaixe. Etiquetagem em
   i3track-regra-condicional.js.
   -------------------------------------------------------------------------- */
/* A sobreposição deixa de ser sobreposição. */
:root[data-theme] div.fixed.inset-0:has(> div > [data-i3-regra-pg]) {
  position: fixed !important;
  inset: var(--i3t-topbar-h, 64px) 0 0 var(--i3duo-w, 292px) !important;
  padding: 0 !important;
  overflow: hidden !important;
  background: var(--bg) !important;
  z-index: 40 !important;
}
/* O fundo escuro do modal e o teto de largura saem juntos. */
:root[data-theme] div.fixed.inset-0:has(> div > [data-i3-regra-pg]) > .absolute.inset-0 { display: none !important; }
:root[data-theme] div.fixed.inset-0:has(> div > [data-i3-regra-pg]) > div {
  max-width: none !important;
  width: 100% !important;
  height: 100% !important;
}
:root[data-theme] [data-i3-regra-pg] {
  max-height: none !important;
  height: 100% !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  padding: var(--i3t-space-5, 24px) var(--i3t-space-6, 32px) !important;
}

/* Abas. Mesma pílula segmentada do resto do sistema. */
[data-i3-regra-abas] {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin: 0 0 var(--i3t-space-4, 16px);
  border: 1px solid var(--border);
  border-radius: var(--i3t-radius-pill, 999px);
  background: var(--surface-card);
  width: fit-content;
}
[data-i3-regra-abas] > [data-aba] {
  border: 0; background: transparent; color: var(--sub); cursor: pointer;
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  font-size: var(--i3t-text-body, .875rem); font-weight: 600; line-height: 1;
  padding: 9px 20px; border-radius: var(--i3t-radius-pill, 999px);
}
[data-i3-regra-abas] > [data-aba]:hover { color: var(--text); }
[data-i3-regra-abas] > [data-aba][data-ativa] {
  background: var(--field-bg-hover, var(--surface-2)); color: var(--text);
}

/* Só a seção da aba escolhida. */
[data-i3-regra-pg][data-i3-regra-aba="a"] [data-i3-regra-sec]:not([data-i3-regra-sec="a"]),
[data-i3-regra-pg][data-i3-regra-aba="b"] [data-i3-regra-sec]:not([data-i3-regra-sec="b"]),
[data-i3-regra-pg][data-i3-regra-aba="c"] [data-i3-regra-sec]:not([data-i3-regra-sec="c"]),
[data-i3-regra-pg][data-i3-regra-aba="d"] [data-i3-regra-sec]:not([data-i3-regra-sec="d"]),
[data-i3-regra-pg][data-i3-regra-aba="e"] [data-i3-regra-sec]:not([data-i3-regra-sec="e"]) {
  display: none !important;
}
/* Sem moldura na seção: a aba já diz onde se está, e caixa dentro de caixa
   dentro de página é o que fazia o formulário parecer um formulário. */
[data-i3-regra-pg] [data-i3-regra-sec] {
  border: 0 !important;
  background: transparent !important;
  padding: 0 !important;
}

/* --- §78.1 CERCA / ALVO / ROTA PELO NOME ---
   O campo de ID continua no formulário, escondido: é ele que o React lê. Se a
   lista de nomes falhar, basta esta regra sair e o campo volta. */
[data-i3-regra-oculto] { display: none !important; }
[data-i3-regra-caixa] {
  display: flex; flex-direction: column; gap: 5px;
  font-size: var(--i3t-text-caption, .6875rem); letter-spacing: .08em;
  text-transform: uppercase; color: var(--sub); font-weight: 600;
}
[data-i3-regra-caixa] > label {
  font-size: var(--i3t-text-caption, .6875rem); letter-spacing: .08em;
  text-transform: uppercase; color: var(--sub); font-weight: 600;
}
/* O poço ancora o menu de resultados. */
[data-i3-regra-poco] { position: relative; }
[data-i3-regra-escolha] {
  width: 100%; height: 40px; padding: 0 14px;
  border-radius: var(--i3t-radius-pill, 999px);
  border: 1px solid var(--border);
  background: var(--field-bg); color: var(--text);
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  font-size: var(--i3t-text-body, .875rem);
  text-transform: none; letter-spacing: normal; font-weight: 400;
}
[data-i3-regra-escolha]:focus, [data-i3-regra-escolha]:focus-visible {
  outline: 2px solid var(--i3t-focus-ring, rgba(102,163,255,.55));
  outline-offset: 1px; border-color: var(--placeholder);
}
[data-i3-regra-escolha]:disabled { opacity: .6; cursor: default; }

/* Resultados. Sai do fluxo para não empurrar o formulário a cada tecla. */
[data-i3-regra-menu] {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 80;
  max-height: 260px; overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--border); border-radius: 14px;
  background: var(--surface-card);
  box-shadow: 0 14px 38px rgba(0,0,0,.38);
}
[data-i3-regra-item] {
  display: block; width: 100%; text-align: left;
  padding: 9px 12px; border: 0; border-radius: 8px;
  background: transparent; color: var(--text); cursor: pointer;
  font-family: var(--i3t-font-body, 'Inter', sans-serif);
  font-size: var(--i3t-text-body, .875rem);
  text-transform: none; letter-spacing: normal; font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
[data-i3-regra-item]:hover { background: var(--field-bg-hover, var(--surface-2)); }
[data-i3-regra-nada] {
  padding: 10px 12px; color: var(--sub);
  font-size: 13px; text-transform: none; letter-spacing: normal; font-weight: 400;
}


/* ==========================================================================
   §79 — ROTAS, CERCAS E ALVOS: MAPA COMO PARTE DA PÁGINA, NÃO COMO FUNDO

   Nas três telas o mapa ocupava 100% da área e tudo o mais flutuava por cima:
   a barra de busca cobria justamente o trecho onde se clica para marcar
   ponto, e o painel comia 460px do mapa sem poder ser fechado enquanto se
   cria. A área vira uma grade — busca em cima, mapa e painel lado a lado —
   no mesmo arranjo do Monitoramento. Etiquetagem em i3track-mapas.js.
   ========================================================================== */
main [data-i3-mapa] {
  display: grid !important;
  /* PAINEL À ESQUERDA, mapa à direita: a leitura começa pela lista e pelo
     formulário, que é onde se trabalha; o mapa é a confirmação do que se fez. */
  grid-template-columns: 380px minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--i3t-space-3, 12px);
  height: 100%;
  min-height: 0;
}
/* Só mapa: uma coluna, e o painel some (escondido, nunca desmontado). */
main [data-i3-mapa="so-mapa"] { grid-template-columns: minmax(0, 1fr); }
main [data-i3-mapa="so-mapa"] [data-i3-mapa-painel] { display: none !important; }
main [data-i3-mapa="so-mapa"] [data-i3-mapa-tela],
main [data-i3-mapa="so-mapa"] [data-i3-mapa-ferramentas],
main [data-i3-mapa="so-mapa"] [data-i3-mapa-status] { grid-column: 1 !important; }

/* A camada e a coluna deixam de gerar caixa: os filhos entram na grade. */
main [data-i3-mapa-camada],
main [data-i3-mapa-coluna] {
  display: contents !important;
  position: static !important;
}

/* Linha 1: a busca, fora do mapa, atravessando as duas colunas. */
main [data-i3-mapa-busca] {
  position: static !important;
  grid-column: 1 / -1 !important;
  grid-row: 1 !important;
  width: 100% !important;
  max-width: none !important;
  margin: 0 !important;
}
/* NA PÁGINA, NÃO NUM CARTÃO. Ela vinha embrulhada em `rounded-2xl` com borda
   e fundo — uma caixa em volta de um campo e sete ícones. Fora do mapa isso
   vira moldura sem conteúdo: some a moldura, ficam os controles. */
main [data-i3-mapa-busca],
main [data-i3-mapa-busca] > * {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}
main [data-i3-mapa-busca] > * { padding: 0 !important; }

/* Linha 2: mapa à esquerda, painel à direita. */
main [data-i3-mapa-tela] {
  grid-column: 2 !important;
  grid-row: 2 !important;
  position: relative !important;
  min-height: 0 !important;
  border-radius: 16px;
  overflow: hidden;
}
main [data-i3-mapa-painel] {
  position: static !important;
  grid-column: 1 !important;
  grid-row: 2 !important;
  width: auto !important;
  max-width: none !important;
  max-height: none !important;
  height: 100% !important;
  min-height: 0 !important;
  overflow-y: auto !important;
  margin: 0 !important;
}

/* Ferramentas e status continuam SOBRE o mapa — é lá que fazem sentido —
   mas presas à célula do mapa, não à página inteira. */
main [data-i3-mapa-ferramentas] {
  grid-column: 2 !important;
  grid-row: 2 !important;
  position: relative !important;
  justify-self: end !important;
  align-self: start !important;
  margin: 12px !important;
  inset: auto !important;
  z-index: 30;
}
main [data-i3-mapa-status] {
  grid-column: 2 !important;
  grid-row: 2 !important;
  position: relative !important;
  justify-self: start !important;
  align-self: end !important;
  margin: 12px !important;
  inset: auto !important;
  z-index: 30;
}
/* A pílula "0 rotas" / "0 cercas" flutua SOBRE o mapa, e o mapa é claro nos
   dois temas. Ela vinha translúcida com texto claro: no tema claro ainda dava
   para ler, no escuro sumia em cima das ruas. Superfície sólida e a cor de
   texto do sistema — quem flutua sobre conteúdo alheio precisa de fundo
   próprio, é a mesma regra do aviso da Área de Risco (§68/54.5). */
main [data-i3-mapa-status],
main [data-i3-mapa-status] > * {
  background: var(--surface-card) !important;
  color: var(--text) !important;
  border-color: var(--border) !important;
  backdrop-filter: none !important;
}
main [data-i3-mapa-status] {
  border: 1px solid var(--border) !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .28) !important;
  padding: 4px 12px !important;
}
main [data-i3-mapa-status] * { color: var(--text) !important; }

/* --- §79.3 O PAINEL DE CERCAS E ALVOS ERA AZUL ---
   Em Rotas o painel usa `bg-[#0f141c]`, que o §17 já mapeia para a superfície
   neutra — computa cinza #242424. Em Cercas e Alvos o painel tem classe
   própria (`.geofence-panel`) e ficou de fora desse mapeamento: renderizava
   `rgba(11,15,23,.97)`, azul-marinho, ao lado de telas irmãs cinzas.
   Mesma superfície e mesma borda das outras, nos dois temas. */
main .geofence-panel,
main [data-i3-mapa-painel].geofence-panel {
  background: var(--surface-2) !important;
  border-color: var(--border) !important;
  backdrop-filter: none !important;
}
/* Caixas internas do painel que repetem o navy do bundle. */
main .geofence-panel [class*="0b0f17"],
main .geofence-panel [class*="0f141c"],
main .geofence-panel [class*="0d1117"] {
  background-color: var(--surface-card) !important;
  border-color: var(--border) !important;
}

/* --- §79.4 SÓ A LISTA ROLA ---
   Com 30 cercas o painel media 878px de altura e 2880 de conteúdo: rolava
   INTEIRO, cabeçalho e busca junto. Quem procura uma cerca numa lista de 200
   perde de vista o campo de busca já no terceiro item.

   O painel vira coluna e não rola; a lista, sim. Cabeçalho, seletor de
   cliente e busca ficam parados no topo.

   `min-height: 0` em toda a corrente é obrigatório: sem ele, um filho flex
   nunca encolhe abaixo do próprio conteúdo e a lista continua empurrando o
   painel para fora da tela em vez de ganhar barra. */
main [data-i3-mapa-painel].geofence-panel {
  display: flex !important;
  flex-direction: column !important;
  overflow: hidden !important;
}
main [data-i3-mapa-painel].geofence-panel > :first-child { flex: 0 0 auto !important; }
main [data-i3-mapa-painel].geofence-panel > :last-child {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  display: flex !important;
  flex-direction: column !important;
}
main .geofence-panel-list {
  flex: 1 1 auto !important;
  min-height: 0 !important;
  max-height: none !important;
  overflow-y: auto !important;
  overscroll-behavior: contain;   /* chegou ao fim: não passa a rolar a página */
}

/* --- §79.5 PAGINAÇÃO DA LISTA ---
   Rolar resolve o layout, não o peso: um cliente com dois mil cartões põe dois
   mil na árvore de uma vez. O item fora da página atual sai por ATRIBUTO —
   nunca por `style.display` —, para dar para distinguir o que a paginação
   escondeu do que a busca do painel já tinha tirado. */
main .geofence-panel-list > [data-i3-pag-fora] { display: none !important; }

main [data-i3-mapa-rodape] {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--sub);
}
main [data-i3-mapa-rodape][hidden] { display: none !important; }
main [data-i3-mapa-rodape] label {
  display: inline-flex; align-items: center; gap: 6px;
  text-transform: none; letter-spacing: normal; font-weight: 400;
}
main [data-i3-mapa-rodape] select {
  height: 28px; padding: 0 6px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--field-bg); color: var(--text);
  font: inherit; font-size: 12px;
}
main [data-i3-mapa-rodape] [data-pag-conta] { margin-left: auto; white-space: nowrap; }
main [data-i3-mapa-rodape] .i3pag-nav { display: inline-flex; gap: 4px; }
main [data-i3-mapa-rodape] [data-pag] {
  width: 28px; height: 28px; line-height: 1;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface-card); color: var(--text);
  font-size: 15px; cursor: pointer;
}
main [data-i3-mapa-rodape] [data-pag]:hover:not(:disabled) { border-color: var(--sub); }
main [data-i3-mapa-rodape] [data-pag]:disabled { opacity: .4; cursor: default; }

/* --- §79.1 CONTROLES DO MAPA COMO OS DO MONITORAMENTO ---
   Lá são os controles nativos do Mapbox: um grupo único, canto superior
   direito, cantos arredondados e superfície do sistema. Aqui eram botões
   soltos de 32px em duas caixas separadas. Mesma métrica, mesmo grupo. */
main [data-i3-mapa-ferramentas] {
  display: flex !important;
  flex-direction: column !important;
  gap: 6px !important;
  width: auto !important;
  height: auto !important;
}
main [data-i3-mapa-ferramentas] .map-toolbar-zoom,
main [data-i3-mapa-ferramentas] > div {
  display: flex !important;
  flex-direction: column !important;
  gap: 1px !important;
  border-radius: 10px !important;
  border: 1px solid var(--border) !important;
  background: var(--border) !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .28) !important;
  height: auto !important;
}
/* SEM `overflow:hidden` no grupo — foi assim que eu quebrei os pop-ups.
   Arredondar o grupo escondendo o transbordo também corta o painel que
   "Layout" e "Selecionar mapa" abrem a partir de dentro dele: o botão
   respondia ao clique e nada aparecia, parecendo botão morto. O canto
   arredondado sai do primeiro e do último botão, que dá o mesmo desenho e
   não recorta nada. */
main [data-i3-mapa-ferramentas] .map-tool-button:first-child {
  border-top-left-radius: 9px !important; border-top-right-radius: 9px !important;
}
main [data-i3-mapa-ferramentas] .map-tool-button:last-child {
  border-bottom-left-radius: 9px !important; border-bottom-right-radius: 9px !important;
}
/* O pop-up desses botões nasce dentro do grupo: precisa passar por cima do
   mapa e do painel. */
main [data-i3-mapa-ferramentas] [class*="popover"],
main [data-i3-mapa-ferramentas] [class*="panel"],
main [data-i3-mapa-ferramentas] [role="dialog"],
main [data-i3-mapa-ferramentas] [role="menu"] { z-index: 60 !important; }
main [data-i3-mapa-ferramentas] .map-tool-button {
  width: 34px !important;
  height: 34px !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: var(--surface-card) !important;
  color: var(--text) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}
main [data-i3-mapa-ferramentas] .map-tool-button:hover { background: var(--field-bg-hover, var(--surface-2)) !important; }
/* Botão "só o mapa" ligado: fica marcado, senão não dá para saber por que o
   painel sumiu. */
main [data-i3-mapa-ferramentas] [data-i3-mapa-cheio][data-ativo] {
  background: var(--primary, #0052E6) !important;
  color: #fff !important;
}

/* --- §79.2 A ÁGUIA SAI DO MAPA ---
   O botão de atribuição no canto inferior esquerdo desenha a marca antiga
   (`.eagle-sprite`) — a mesma águia que o §5 já troca pelo ícone i3track na
   tela de login. Aqui faltava a variante do mapa. */
:root[data-theme] .monitoring-map-attribution-euro-icon {
  background-image: url('/assets/loader-icon.png') !important;
  background-position: center !important;
  background-size: contain !important;
  background-repeat: no-repeat !important;
  filter: none !important;
  width: 20px !important;
  height: 20px !important;
}

/* ============================================================================
   §80 — DADOS FICTÍCIOS: O BOTÃO E A MARCA DE QUE A TELA É EXEMPLO

   Plataforma nova abre tudo zerado, e quem está avaliando não vê nada
   funcionando. O botão liga uma frota de exemplo; só existe enquanto a
   plataforma tiver zero veículos (a regra vive no i3track-demo.js).

   A pílula é FIXA no canto, fora do fluxo: cada uma das doze telas tem um
   cabeçalho diferente, e enfiar um botão em doze cabeçalhos diferentes daria
   doze heurísticas para quebrar. Nas telas BI (Home e Resultados), onde o HTML
   é nosso, o botão é de verdade e fica ao lado de "Resultados".
   ========================================================================== */

/* Canto inferior CENTRAL, não direito: o direito é do botão "Registrar
   Roubo/Furto" do Monitoramento, que fica por cima e engolia a pílula
   inteira. O centro de baixo está livre em todas as doze telas. */
#i3-demo-pilula {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 18px;
  z-index: 9000;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--border, #2a2a2a);
  background: var(--surface-2, #1c1c1c);
  color: var(--text, #e7e7e7);
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .28);
  transition: background .15s, border-color .15s, transform .1s;
}
#i3-demo-pilula:hover { transform: translateX(-50%) translateY(-1px); }

/* Ligado precisa gritar. A tela inteira está mostrando número inventado; o
   botão é a única coisa que diz isso ao usuário. */
#i3-demo-pilula[data-ligado="1"] {
  background: var(--warn, #F59E0B);
  border-color: var(--warn, #F59E0B);
  color: #1a1200;
}
#i3-demo-pilula[data-ligado="1"]::before {
  content: "exemplo · ";
  font-weight: 700;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: .04em;
  opacity: .72;
}

/* Houve uma tentativa de faixa fixa no topo (`body::before`) avisando do modo.
   Ela passava POR TRÁS da sidebar e da topbar, que são fixas e opacas: sobrava
   um retângulo laranja no canto, sem texto legível. O aviso ficou onde funciona
   — a pílula laranja aqui embaixo, e, nas telas BI, uma faixa dentro do próprio
   conteúdo (.bi-demo-faixa). */

/* ==========================================================================
   §81 — VÍDEOS, LIVE, RECONHECIMENTO FACIAL E MOTORISTAS: LISTA NA PÁGINA

   As quatro telas mostravam a mesma coisa de quatro jeitos, e todas dentro de
   um cartão azulado: a Live e a Motoristas em grade de cartõezinhos, a Vídeos e
   a Face em cartões largos com cada campo dentro da SUA caixinha. Três molduras
   uma dentro da outra (cartão → caixa do campo → caixa do ícone) para mostrar
   duas palavras.

   Aqui elas viram LISTA: linha inteira na página, separada por um traço, sem
   moldura e sem fundo próprio. Nada de informação sai — o que sai é a borda.

   Não se mexe em ordem, rótulo, ação nem rota: só em como isso é desenhado.
   ========================================================================== */

/* --- §81.1 O AZUL DOS PAINÉIS SAI DA FAMÍLIA "VÍDEOS" -----------------------
   `--videos-panel-bg` é um degradê azul-noite (rgba(10,15,24)) que não existe
   em nenhuma outra tela do sistema; a casa tem `--surface-2`. Trocar o token na
   raiz da página conserta de uma vez a lista, os indicadores e a tela de
   detalhe do vídeo, que herdam todos daqui. */
main .videos-page,
main .live-videos-page,
main .videos-detail-page,
main .drivers-page {
  --videos-panel-bg: var(--surface-2, #1c1c1c);
  --videos-panel-bg-accent: var(--surface-2, #1c1c1c);
  --videos-panel-border: var(--border, #2a2a2a);
  --videos-media-bg: var(--surface-3, #141414);
}

/* --- §81.2 A LIVE DEIXA DE SER GRADE ---------------------------------------
   A grade de quatro colunas é do Tailwind, escrita na classe do elemento
   (`2xl:grid-cols-4`); só uma regra na página desmancha. Uma coluna só, e a
   linha passa a valer a largura toda — igual à Vídeos, que era o pedido. */
main .live-videos-page > section.grid {
  grid-template-columns: minmax(0, 1fr) !important;
  gap: 0 !important;
}

/* --- §81.3 A LINHA ---------------------------------------------------------
   Vale para as três telas que usam o mesmo componente: Vídeos, Live e
   Reconhecimento Facial. O traço é `border-bottom` em TODAS as linhas, não
   `+ irmão`: em Vídeos o item às vezes vem embrulhado num `__item`, e o seletor
   de irmão morreria calado ali. */
main .videos-catalog-grid,
main .videos-catalog-list,
main .video-list {
  gap: 0 !important;
}

main .video-card.videos-card {
  border: 0 !important;
  border-bottom: 1px solid var(--border, #2a2a2a) !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  padding: 1.15rem 0 !important;
}

/* Cartão levanta no hover; linha de lista, não. */
main .video-card.videos-card:hover {
  transform: none !important;
  box-shadow: none !important;
  border-color: var(--border, #2a2a2a) !important;
}

/* --- §81.4 O CAMPO PERDE A CAIXA -------------------------------------------
   `.videos-info-line` desenhava borda, fundo e raio de 18px em volta de um par
   rótulo/valor, e `__icon` repetia a dose num quadrado de 2,35rem. Sem as duas
   molduras o mesmo bloco cabe com folga e o olho corre a coluna. */
main .videos-media-card .videos-info-line,
main .video-card .videos-info-line {
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  padding: 0 !important;
  min-height: 0 !important;
  gap: 0.55rem !important;
  align-items: start !important;
}

main .videos-media-card .videos-info-line__icon,
main .video-card .videos-info-line__icon {
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  height: 1.05rem !important;
  width: 1.05rem !important;
  margin-top: 0.9rem;
  opacity: .62;
}

main .video-card .videos-media-card__info-grid {
  gap: 0.9rem 1.9rem !important;
}

/* A miniatura continua sendo miniatura — ela é o vídeo. Só perde o raio de
   24px, que era do cartão que não existe mais. */
main .video-card .videos-media-shell {
  border-radius: 12px !important;
}

/* --- §81.5 A COLUNA DE AÇÕES ----------------------------------------------
   `__aside` traz `border-top`: faz sentido quando as ações ficam EMBAIXO do
   corpo (tela estreita), e vira um risco solto quando elas estão AO LADO. */
@media (min-width: 1280px) {
  main .video-card--compact .videos-media-card__aside {
    border-top: 0 !important;
    padding-top: 0 !important;
  }
}

/* --- §81.6 MOTORISTAS: A MESMA LISTA ---------------------------------------
   Era grade de cartões de 300px com a foto num palco quadriculado e cada dado
   ("Celular", "E-mail", "Veículo atual") dentro de uma caixinha com o valor
   jogado na direita. Vira linha: foto à esquerda, identificação, e os dados em
   quatro colunas de rótulo em cima do valor — a mesma leitura das outras três
   telas.

   ATENÇÃO AO ALVO: o `.drivers-card` NÃO é o pai da foto — entre ele e o
   conteúdo existe um `<button>` que embrulha a linha inteira (é ele que abre o
   motorista). Pôr as duas colunas no `.drivers-card` jogava esse botão sozinho
   na coluna de 148px e espremia foto, nome, pílulas e dados numa tira estreita,
   com todo texto cortado em "9953…". Por isso o alvo é "quem tem a foto como
   filha", via `:has()` — assim vale tanto para o botão quanto para o dia em que
   ele deixar de existir. */
main .drivers-card-grid {
  grid-template-columns: minmax(0, 1fr) !important;
  gap: 0 !important;
}

main .drivers-card {
  display: block !important;
  border: 0 !important;
  border-bottom: 1px solid var(--border, #2a2a2a) !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  padding: 1.1rem 0 !important;
}

main .drivers-card:has(> .drivers-card__photo),
main .drivers-card > *:has(> .drivers-card__photo) {
  display: grid !important;
  grid-template-columns: 148px minmax(0, 1fr) !important;
  gap: 1.3rem !important;
  align-items: start !important;
  width: 100% !important;
  text-align: left !important;
}

main .drivers-card:hover {
  transform: none !important;
  box-shadow: none !important;
  border-color: var(--border, #2a2a2a) !important;
}

main .drivers-card__photo {
  width: 148px !important;
  height: 112px !important;
  padding: 0 !important;
  background: none !important;
}

main .drivers-photo-stage {
  height: 112px !important;
  border-radius: 12px !important;
}

main .drivers-card__body {
  padding: 0 !important;
  min-width: 0;
}

/* As pílulas (Offline, "1 veículo(s)", "0 histórico", Reconhecimento) ficavam
   empilhadas uma por linha só porque a coluna tinha 148px. Com a largura certa
   elas voltam a ser uma fileira. */
main .drivers-pill-row {
  flex-wrap: wrap !important;
  gap: 0.45rem !important;
}

main .drivers-meta-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  gap: 0.5rem 1.9rem !important;
}

/* Rótulo em cima, valor embaixo — e não mais "rótulo à esquerda, valor colado
   na direita", que só funcionava porque a caixinha segurava os dois. */
main .drivers-meta-item {
  display: grid !important;
  justify-content: start !important;
  gap: 0.12rem !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  padding: 0 !important;
  min-width: 0;
}

main .drivers-meta-item span:first-child {
  font-size: 0.65rem !important;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted, #a1a1a1) !important;
}

main .drivers-meta-item strong {
  text-align: left !important;
  font-size: 0.86rem !important;
  color: var(--text, #e7e7e7) !important;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Em tela estreita a foto ao lado espreme o resto: empilha. */
@media (max-width: 900px) {
  main .drivers-card:has(> .drivers-card__photo),
  main .drivers-card > *:has(> .drivers-card__photo) {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  main .drivers-meta-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* --- §81.7 LIVE: A MINIATURA VOLTA A SER MINIATURA -------------------------
   Desmanchar a grade (§81.2) deu à linha da Live a largura inteira — e o
   preview, que é 16:9, cresceu junto: 1268 × 713px de vídeo parado por linha,
   uma linha por tela. A Live monta o cartão diferente das outras três: o
   `__aside` mora DENTRO do `__body` e ainda existe um `.live-card-click-layer`
   (o botão que cobre o cartão inteiro; é absoluto, não ocupa coluna). Então a
   linha não tem as três zonas da Vídeos — tem duas, e é isso que se escreve
   aqui: miniatura à esquerda, o resto à direita. */
@media (min-width: 1100px) {
  main .live-videos-page .video-card.videos-card {
    grid-template-columns: minmax(0, 380px) minmax(0, 1fr) !important;
    column-gap: 1.5rem !important;
    align-items: start !important;
  }

  main .live-videos-page .video-card .videos-media-card__preview {
    grid-column: 1 !important;
  }

  main .live-videos-page .video-card .videos-media-card__body {
    grid-column: 2 !important;
  }
}

/* --- §81.8 O DETALHE DO VÍDEO TAMBÉM VAI PARA A PÁGINA ---------------------
   Aqui o azul NÃO vinha de `--videos-panel-bg` (por isso o §81.1 não o pegou):
   vinha de dois lugares escritos no próprio bloco —
     • `.videos-detail-hero.videos-surface--accent`, um brilho
       `radial-gradient(... rgba(56,189,248,.2) ...)` azul-céu no canto;
     • `.data-card`, um `linear-gradient(rgba(10,15,24,.94), rgba(8,12,20,.98))`
       com raio de 30px, que é o "cartão azul" grande do player, do mapa e das
       duas faixas de baixo.
   As seções passam a ser seções da página, separadas por traço. O que continua
   com moldura é só o que É uma tela: o quadro do vídeo e o do mapa.

   `.data-card` é classe genérica do sistema — por isso todo seletor daqui está
   preso a `.videos-detail-page`. Fora desta tela nada muda.

   O `:root` na frente não é enfeite: o bundle pinta o fundo com
   `:root[data-theme=dark] .data-card{background-color:var(--surface-card)
   !important}` — 0,3,0 de especificidade, que ganha de `main .videos-detail-page
   .data-card` (0,2,1). Sem o `:root` o degradê saía e o cinza do cartão ficava. */
:root main .videos-detail-page .videos-detail-hero,
:root main .videos-detail-page .data-card {
  background: none !important;
  background-color: transparent !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

/* O traço só entre blocos que se empilham. A coluna da direita (mapa) fica ao
   LADO do player: ali um traço embaixo seria um risco solto no meio da tela. */
main .videos-detail-page > .videos-detail-hero,
main .videos-detail-page > .data-card,
main .videos-detail-page .videos-detail-main > .data-card {
  border-bottom: 1px solid var(--border, #2a2a2a) !important;
  padding-bottom: 1.5rem !important;
}

/* O quadro do vídeo e o do mapa continuam sendo quadros — só perdem o raio de
   28px, que era do cartão que não existe mais. */
main .videos-detail-page .videos-player-frame,
main .videos-detail-page .videos-map-shell {
  border-radius: 12px !important;
}

/* Mesma decisão do §81.4: o valor não precisa de caixa em volta. Eram tijolos
   de 24px de raio com fundo tingido para mostrar "Ligada", "194 km/h". */
main .videos-detail-page .videos-metric-tile,
main .videos-detail-page .videos-side-metric {
  background: none !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
  min-height: 0 !important;
}

/* --- §82 NENHUM CARTÃO ESCURO NO TEMA CLARO -------------------------------
   O bundle traz fundos crus do desenho original (`bg-neutral-900/60`,
   `bg-black/20`, `bg-black/30`) que só fazem sentido no tema escuro. No claro
   viram uma tarja preta com texto preto em cima — foi assim que uma linha da
   tela de Eventos ficou ilegível no meio de linhas claras.

   Isto é rede de segurança, não o conserto: o conserto está em
   `i3track-ui.js` (o etiquetador parou de tratar linha de lista como campo).
   A rede existe porque legibilidade não pode depender de um script chegar a
   tempo — se ele falhar, a tela fica feia, não ilegível. */
:root[data-theme="light"] main [class*="bg-neutral-900"],
:root[data-theme="light"] main [class*="bg-neutral-800"],
:root[data-theme="light"] main [class*="bg-black\/2"],
:root[data-theme="light"] main [class*="bg-black\/3"] {
  background-color: var(--surface-2) !important;
}

/* --- §83 EMBARCAR VEÍCULOS (cercas, rotas, alvos) -------------------------
   Quadro por cima da tela, no padrão da casa: o formulário do bundle é
   congelado e não aceita campo novo. Consome i3track-embarcar.js. */
#i3emb-fundo {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
#i3emb {
  width: min(560px, 100%); max-height: min(86vh, 760px);
  display: flex; flex-direction: column; gap: 12px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 16px 18px; box-shadow: 0 24px 60px rgba(0,0,0,.45);
  overflow-y: auto;
}
#i3emb header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
#i3emb .k { margin: 0; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted, rgba(128,128,128,.9)); }
#i3emb h2 { margin: 2px 0 0; font-size: 17px; }
#i3emb-x { background: none; border: 0; color: inherit; font-size: 15px; cursor: pointer; padding: 4px 6px; }
#i3emb .ajuda { margin: 0; font-size: 12px; color: var(--muted, rgba(128,128,128,.9)); }
#i3emb .linha { display: flex; flex-direction: column; gap: 7px; font-size: 13px; }
#i3emb .linha.titulo { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted, rgba(128,128,128,.9)); margin-top: 4px; }
#i3emb label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
#i3emb .bloco { border: 1px solid var(--border); border-radius: 10px; padding: 10px; max-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
#i3emb .bloco.esconde { display: none; }
#i3emb #i3emb-busca { height: 34px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); padding: 0 12px; font-size: 13px; }
#i3emb #i3emb-lista { display: flex; flex-direction: column; gap: 6px; }
#i3emb .vazio { margin: 0; font-size: 12px; color: var(--muted, rgba(128,128,128,.9)); }
#i3emb footer { display: flex; align-items: center; gap: 10px; justify-content: flex-end; border-top: 1px solid var(--border); padding-top: 12px; }
#i3emb #i3emb-msg { margin-right: auto; font-size: 12px; color: var(--muted, rgba(128,128,128,.9)); }
#i3emb footer button { height: 36px; padding: 0 16px; border-radius: 999px; border: 1px solid transparent; background: var(--primary); color: #fff; font-size: 13px; cursor: pointer; }
#i3emb footer button.sec { background: transparent; border-color: var(--border); color: inherit; }
#i3emb footer button:disabled { opacity: .6; cursor: default; }
#i3emb .alvo { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
/* A escolha da cerca/alvo/rota é busca, não lista: com trinta desenhos no
   cliente, rolar um <select> é procurar, não escolher. */
#i3emb .escolha { position: relative; }
#i3emb #i3emb-cerca { width: 100%; height: 34px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font-size: 15px; padding: 0 8px; max-width: 100%; }
#i3emb #i3emb-cerca:focus { outline: none; }
#i3emb #i3emb-cerca-lista {
  position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
#i3emb #i3emb-cerca-lista[data-aberta="0"] { display: none; }
#i3emb #i3emb-cerca-lista button {
  display: block; width: 100%; text-align: left;
  border: 0; background: transparent; color: var(--text);
  font-size: 14px; padding: 8px 10px; cursor: pointer;
}
#i3emb #i3emb-cerca-lista button:hover { background: var(--surface-2); }
#i3emb #i3emb-cerca-lista button[data-atual="1"] { color: var(--primary); }
#i3emb #i3emb-cerca-lista .vazio { padding: 10px; }

/* --- §84 VIAGENS: UMA TELA SÓ ----------------------------------------------
   Era lista à esquerda (380–520px) e detalhe à direita; nenhum dos dois cabia.
   Agora: linha de tabela na largura toda em cima, mapa e posições embaixo.

   FLUXO DE BLOCO, NÃO GRADE. Tentei antes redefinir a grade do bundle e não
   funcionou: com `grid-auto-flow: column`, os filhos vão para colunas
   IMPLÍCITAS, e coluna implícita não se mede por `grid-template-columns` —
   por isso `1fr` não empilhava nada. E `width:100%` num item de grade resolve
   contra a área que o próprio item dimensionou: no-op. Trocando o `main` para
   `display:block`, aside e section voltam ao fluxo normal, um debaixo do
   outro, cada um na largura inteira. */
main[data-i3-viagens] {
  --i3v-cols: minmax(180px, 1.1fr) 76px 90px minmax(0, 2fr) minmax(0, 2fr) 86px;
  display: block !important;
  overflow-y: auto;
}
/* `h-full` dos filhos valia 100% da altura do `main`; em bloco isso empilharia
   duas telas cheias. A altura passa a ser a do conteúdo. */
main[data-i3-viagens] > aside,
main[data-i3-viagens] > section {
  width: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  height: auto !important;
  flex: none !important;
}
main[data-i3-viagens] > section { margin-top: 10px; }

/* A lista ganha teto e rolagem própria: sem isso, dez viagens empurram o mapa
   para fora da tela e clicar na linha não mostra nada. */
main[data-i3-viagens] > aside > div:nth-child(2) {
  max-height: 32vh;
  overflow-y: auto;
  gap: 0 !important;
  padding-right: 0 !important;
}

/* ---- a viagem vira linha de tabela ---- */
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] {
  display: grid !important;
  grid-template-columns: var(--i3v-cols);
  align-items: center;
  gap: 10px;
  border-radius: 0 !important;
  border-width: 0 0 1px 0 !important;
  padding: 7px 10px !important;
}
/* `display:contents` promove os netos a células da MESMA grade da linha — é o
   que permite virar tabela sem reescrever a árvore que o bundle desenha. */
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div,
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div > div:nth-child(2),
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div > div:nth-child(2) > div:first-child {
  display: contents !important;
}
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div > div:first-child { display: block !important; }
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div:nth-child(2) > div { display: flex !important; min-width: 0; }
/* Na árvore, o botão "Detalhes" vem ANTES de origem e destino; achatada em
   grade, ele caía na coluna da origem. `order` põe cada coisa na sua coluna
   sem tocar no HTML que o bundle desenha. */
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div > div:nth-child(2) > button { order: 9; }
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div:nth-child(2) > div:first-child { order: 4; }
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div:nth-child(2) > div:last-child { order: 5; }
/* o rótulo "Origem:"/"Destino:" dentro da célula repete o cabeçalho */
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] > div:nth-child(2) > div > span:nth-child(2) { display: none !important; }
main[data-i3-viagens] > aside > div:nth-child(2) > [role="button"] .line-clamp-2 { -webkit-line-clamp: 1 !important; }

/* Sem viagem escolhida não há o que mostrar embaixo. */
main[data-i3-viagens][data-i3-trip-sel="0"] > section { display: none !important; }

/* --- §85 EVENTOS: FILTRO NO TOPO E BUSCA DE EVENTO -------------------------
   Duas coisas na tela de Eventos.

   1. "Eventos no relatório" (Todos | Somente ativos) não é filtro de busca:
      é o que a lista mostra. Ele estava no meio da fileira de filtros, entre
      "Tipo de evento" e as datas. Sobe para junto de Mostrar / Limpar filtros.

      Sobe por CSS, não por JS: mover um nó que o React desenhou é o caminho
      curto para a aba travar (foi o que aconteceu em Viagens). O script só
      marca `data-i3-ev-topo` no rótulo e `data-i3-ev-tela` na seção; o resto
      é `position:absolute`. Sair do fluxo ainda fecha o buraco que ele
      deixava na fileira — "De" e "Até" se espalham sozinhos.

   2. O campo de busca de evento: mesmo desenho da busca de protocolo em
      Comandos (§ do body.i3cmd), com prefixo próprio porque aqui não há
      classe no <body> para pendurar.

   Só a partir de 1280px: abaixo disso não há vão livre no cabeçalho e o
   rótulo fica onde o bundle o desenhou. */
@media (min-width: 1280px) {
  section[data-i3-ev-tela] { position: relative; }
  section[data-i3-ev-tela] label[data-i3-ev-topo] {
    position: absolute;
    top: 2px;
    right: 296px;          /* 284px dos botões + 12px de respiro */
    z-index: 6;
    flex: 0 0 auto;
    width: auto;
    min-width: 0;
    margin: 0;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
    /* Sem o rótulo, o que sobra é o botão. A seção começa exatamente no alto
       da linha do "Gerar", que tem 40px: `top:0` + altura 40 + centralização
       vertical põe os dois na MESMA linha, sem depender de medida chutada. */
    top: 0;
    height: 40px;
    align-items: center;
  }
  /* O grupo do botão vem com `mt-2` — a folga que ele tinha do rótulo que
     agora não existe mais. São os 8px que o deixavam abaixo do "Gerar". */
  section[data-i3-ev-tela] label[data-i3-ev-topo] > div { margin-top: 0 !important; }
}

/* Um botão só: o apagado dizia o que a tela NÃO está mostrando. Some em
   qualquer largura — quem troca o estado é o clique repassado no JS. */
label[data-i3-ev-topo] button[data-i3-ev-ativo="0"] { display: none !important; }
label[data-i3-ev-topo] button[data-i3-ev-ativo="1"] { border-radius: 999px !important; }

.i3ev-busca { position: relative; margin-top: 8px; }
.i3ev-busca-campo {
  width: 100%;
  border: 1px solid var(--stroke);
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  padding: 8px 10px;
}
.i3ev-busca-campo:focus { outline: none; border-color: var(--accent-border-soft, var(--stroke)); }
.i3ev-lista {
  position: absolute;
  z-index: 60;
  left: 0; right: 0; top: calc(100% + 4px);
  max-height: 280px;
  overflow-y: auto;
  border: 1px solid var(--stroke);
  border-radius: 10px;
  background: var(--surface, #191919);
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
.i3ev-lista[data-i3-aberta="0"] { display: none; }
.i3ev-item {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  padding: 8px 12px;
  cursor: pointer;
}
.i3ev-item:hover { background: var(--surface-card-inner); }
.i3ev-item[data-i3-atual="1"] { color: var(--accent, #4c8dff); }
.i3ev-vazio { padding: 10px 12px; font-size: 12px; color: var(--sub); }

/* --- §86 COMANDOS: A ABA MASSA --------------------------------------------
   O mesmo comando para muitos veículos. O painel é nosso (o bundle não tem
   essa tela), então aqui está o desenho inteiro dele — mas usando os mesmos
   tokens do resto, para não parecer um enxerto. */
body.i3cmd .i3cmd-massa {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 0 4px;
}
body.i3cmd .i3cmd-massa-ajuda { font-size: 13px; color: var(--sub); max-width: 780px; }
body.i3cmd .i3cmd-massa-modo { display: flex; flex-wrap: wrap; gap: 18px; }
body.i3cmd .i3cmd-massa-modo label,
body.i3cmd .i3cmd-massa-bloco label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
}
body.i3cmd .i3cmd-massa-bloco {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
body.i3cmd .i3cmd-massa-busca {
  width: 100%;
  border: 1px solid var(--stroke);
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  padding: 8px 10px;
}
body.i3cmd .i3cmd-massa-busca:focus { outline: none; }
body.i3cmd .i3cmd-massa-lista { display: flex; flex-direction: column; gap: 6px; }
body.i3cmd .i3cmd-massa-nota { color: var(--sub); font-size: 12px; }
body.i3cmd .i3cmd-massa-vazio { font-size: 13px; color: var(--sub); }
body.i3cmd .i3cmd-massa-placar { font-size: 13px; color: var(--text); }
body.i3cmd .i3cmd-massa-alerta { color: #f0b429; }
body.i3cmd .i3cmd-massa-comandos { display: flex; flex-wrap: wrap; gap: 14px; }
body.i3cmd .i3cmd-massa-proto {
  flex: 1 1 320px;
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
body.i3cmd .i3cmd-massa-titulo { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--sub); }
/* O comando também é busca: um protocolo tem dezenas, e quem manda sabe o
   nome do que quer. */
body.i3cmd .i3cmd-massa-esc { position: relative; }
body.i3cmd .i3cmd-massa-cmd-lista {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 280px; overflow-y: auto;
  border: 1px solid var(--stroke); border-radius: 10px;
  background: var(--surface, #191919); box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
body.i3cmd .i3cmd-massa-cmd-lista[data-aberta="0"] { display: none; }
body.i3cmd .i3cmd-massa-cmd-lista button {
  display: block; width: 100%; text-align: left;
  border: 0; background: transparent; color: var(--text);
  font-size: 13px; padding: 8px 12px; cursor: pointer;
}
body.i3cmd .i3cmd-massa-cmd-lista button:hover { background: var(--surface-card-inner); }
body.i3cmd .i3cmd-massa-cmd-lista button[data-atual="1"] { color: var(--accent, #4c8dff); }
body.i3cmd .i3cmd-massa-cmd-lista .i3cmd-massa-vazio { padding: 10px 12px; }

body.i3cmd .i3cmd-massa-cmd,
body.i3cmd .i3cmd-massa-params input {
  width: 100%;
  border: 1px solid var(--stroke);
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  padding: 8px 10px;
}
body.i3cmd .i3cmd-massa-params { display: flex; flex-direction: column; gap: 8px; }
body.i3cmd .i3cmd-massa-params label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--sub); }
body.i3cmd .i3cmd-massa-rodape { display: flex; align-items: center; gap: 12px; }
body.i3cmd .i3cmd-massa-enviar {
  border: 1px solid var(--accent-border-soft, var(--stroke));
  border-radius: 12px;
  padding: 10px 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: var(--accent-soft, rgba(76,141,255,.18));
  cursor: pointer;
}
body.i3cmd .i3cmd-massa-enviar[disabled] { opacity: .6; cursor: default; }
body.i3cmd .i3cmd-massa-msg { font-size: 13px; color: var(--sub); }
body.i3cmd .i3cmd-massa-resultado { font-size: 13px; color: var(--sub); }
body.i3cmd .i3cmd-massa-resultado ul { margin: 6px 0 0; padding-left: 18px; }
body.i3cmd .i3cmd-massa-resultado li { margin: 2px 0; }

/* --- §87 LIVE: OS SELOS SAEM DE CIMA DO VÍDEO, E A LINHA GANHA A LISTRA -----
   Dois incômodos na mesma linha.

   1. ONLINE / ALERTA / DSM ficavam DENTRO da miniatura, tapando exatamente o
      pedaço da imagem que interessa quando a câmera está transmitindo. Eles
      passam para o alto da coluna da direita, onde já mora o botão da câmera.

      Vão por CSS, não por JS: a faixa é `position:absolute` dentro da moldura
      do preview, então basta empurrá-la para além da largura da moldura —
      `left: calc(100% + 24px)` cai exatamente na coluna do texto (a grade da
      §81.7 dá 380px à miniatura e 1.5rem de intervalo). Nenhum nó do React sai
      do lugar; só a pintura muda.

   2. O selo da CÂMERA sai da faixa: `DSM`/`ADAS` já aparece do lado direito
      como botão — e botão é o que abre a live. Duas vezes a mesma palavra, uma
      delas clicável e a outra não, é convite a clicar na errada. Some só o
      `--info` (a câmera); ONLINE (`--success`) e ALERTA (`--warning`) ficam.
 */
@media (min-width: 1100px) {
  /* `position: static` aqui é o truque inteiro: sem ancestral posicionado no
     caminho, a faixa passa a se medir pela LINHA (o `article`, que é relative
     logo abaixo) em vez de pela moldura da miniatura. Aí "à direita" é a
     direita da linha, e não sobra colisão com o botão da câmera, que fica na
     ponta esquerda da mesma altura. O único filho absoluto da moldura é esta
     faixa — a legenda e a imagem moram no `.relative` de dentro e não se
     mexem. */
  main .live-videos-page .videos-media-card__preview,
  main .live-videos-page .videos-media-card__preview .videos-media-shell {
    position: static;
    overflow: visible;
  }
  main .live-videos-page .videos-media-card__preview .pointer-events-none.absolute.inset-x-0.top-0 {
    left: auto;
    right: 20px;
    top: 14px;
    width: max-content;
    padding: 0;
    justify-content: flex-end;
  }
}
main .live-videos-page .videos-media-card__preview .videos-badge--info { display: none; }

/* A linha continua `position: relative`: é dela que a faixa de selos passou a
   se medir depois que a moldura da miniatura virou `static`. */
main .live-videos-page .video-card.videos-card { position: relative; }

/* --- §87.1 LIVE: A FOTO DESCE ATÉ O TRAÇO ----------------------------------
   A miniatura é 16:9 e, na largura de 380px da coluna, dá 214px de altura. A
   coluna de texto ao lado tem 328. Resultado: a foto acabava no meio da linha
   e sobrava um vão escuro de ~130px até o traço que separa um veículo do
   outro — parecia que faltava alguma coisa ali embaixo.

   A grade da §81.7 alinha as duas colunas pelo topo (`align-items: start`).
   Aqui ela passa a esticar: a moldura acompanha a altura da linha e a imagem
   preenche por `cover`. O traço encosta na foto, que é o que se espera de uma
   linha com foto à esquerda. O `aspect-ratio` precisa sair do caminho, senão
   ele continua mandando na altura. */
@media (min-width: 1100px) {
  main .live-videos-page .video-card.videos-card { align-items: stretch !important; }
  main .live-videos-page .videos-media-card__preview,
  main .live-videos-page .videos-media-card__preview .videos-media-shell,
  main .live-videos-page .videos-media-card__preview .videos-media-shell > .relative {
    height: 100% !important;
  }
  main .live-videos-page .videos-media-card__preview .aspect-video {
    aspect-ratio: auto !important;
  }
  main .live-videos-page .videos-media-card__preview img,
  main .live-videos-page .videos-media-card__preview video,
  main .live-videos-page .videos-media-card__preview canvas {
    height: 100% !important;
    width: 100% !important;
    object-fit: cover;
  }
}

/* --- §88 SLA: OS CONTATOS DO SUPORTE ---------------------------------------
   O botão "Falar com o suporte" entra como irmão do "Novo Ticket" e herda a
   classe do vizinho secundário, então não precisa de estilo nenhum. O que
   precisa é a linha de contatos logo abaixo da barra: texto de legenda,
   discreto, ali para ser encontrado quando se procura — não para disputar
   atenção com o título da tela.

   AS CORES SAEM DOS TOKENS, NÃO DE UM CINZA ESCOLHIDO NO OLHO.
   A primeira versão usava um slate fixo (#94A3B8) e ficava com 2,4:1 de
   contraste sobre o fundo claro — o mesmo defeito de "a letra some no modo
   claro" que já apareceu na busca de veículo. `--muted` é #A1A1A1 no escuro e
   #6B6B6B no claro: 6,3:1 e 4,9:1, legível nos dois.

   Os links usam `--text` com sublinhado permanente em vez de uma cor de marca:
   o azul da marca dá só 3,2:1 sobre o fundo escuro, e a 12px isso não se lê.
   Com o sublinhado, o link continua sendo obviamente um link. */
#i3sup-contatos {
  width: 100%;
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted, #6B6B6B);
  text-align: right;
}
#i3sup-contatos a {
  color: var(--text, #242424);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
#i3sup-contatos a:hover,
#i3sup-contatos a:focus-visible {
  text-decoration-thickness: 2px;
}

/* O balãozinho do chat mora no canto inferior direito. Acima das janelas do
   aplicativo para não ficar atrás de um diálogo aberto. */
#md-app-widget {
  z-index: 2147483000;
}

/* --- §89 RAIL: A AÇÃO "REGISTRAR ROUBO/FURTO" ------------------------------
   Ícone de AÇÃO no rodapé do rail, logo acima da engrenagem. Não é seção: não
   abre painel. O realce vermelho no hover é o que o separa das seções — é a
   única coisa no rail que grava um registro em vez de navegar. */
.i3duo-ico--acao:hover { background: rgba(229,83,58,.30); color: #fff; }

/* --- §89b O BALÃOZINHO DO SUPORTE DESCE ------------------------------------
   O widget nasce com `bottom: 60px` no estilo em linha, flutuando acima do
   canto. O canto inferior direito era do botão "Registrar Roubo/Furto"
   (bottom: 22px), que saiu para o menu; o balãozinho ocupa o lugar. `!important`
   porque o valor vem em atributo `style`, escrito pelo script do fornecedor. */
#md-app-widget { bottom: 22px !important; }

/* --- §90 VÍDEOS: O DETALHE EM UMA COLUNA SÓ --------------------------------
   Pedido do dono em 07/08/2026: "deixar mais simples, só o vídeo, com 15 min de
   posições antes e depois, e a tratativa".

   O detalhe era duas colunas: player à esquerda, mapa numa barra lateral de
   360 px grudada à direita. Num mapa de trajeto isso é pouca largura para
   pouca coisa — e espremia o player. Agora é UMA coluna: o vídeo em cima com a
   largura toda, o mapa logo abaixo, também com a largura toda, e na sequência
   as posições e a tratativa. A ordem já era essa no HTML; só desfizemos a
   coluna lateral. `static` desfaz o `sticky` do Tailwind, que faria o mapa
   flutuar sozinho agora que ele não tem mais uma coluna para acompanhar. */
main .videos-detail-page .videos-detail-layout { grid-template-columns: minmax(0, 1fr) !important; }
main .videos-detail-page .videos-detail-sidebar { position: static !important; align-self: stretch; }
main .videos-detail-page .videos-map-shell { min-height: 420px; }

/* Cabeçalho de seção com TRÊS linhas ("Player" / "Player operacional" /
   "Componente principal do evento, com leitura rápida do contexto...") para
   dizer uma coisa só. Fica o título. A sobrancelha repetia o título e a
   legenda explicava o óbvio em quatro seções seguidas. */
main .videos-detail-page .videos-detail-card-overline,
main .videos-detail-page .videos-detail-card-subtitle { display: none !important; }
/* Mesmo caso no topo: "Evento operacional" já está na trilha do breadcrumb. */
main .videos-detail-page .videos-detail-hero__eyebrow { display: none !important; }

/* --- §91 MOTORISTA: SEPARAR AS SEÇÕES DO CADASTRO --------------------------
   Pedido do dono: "separar por traços e listra". A ficha do motorista é uma
   coluna de cinco seções (Identificação, Habilitação, Contato e endereço,
   Complementares…) com dezenas de campos, todos do mesmo tom e à mesma
   distância um do outro. Sem marca nenhuma entre cabeçalho e campos, e sem
   marca entre um campo e o próximo, o olho não acha onde uma coisa termina.

   Duas marcas, as duas discretas:
   - um TRAÇO entre o cabeçalho da seção e os campos dela;
   - uma LISTRA em cada campo (fundo e raio próprios), que é o que separa um
     campo do vizinho sem precisar de mais uma linha.

   Tudo em tokens (--border, --layer), porque a página tem tema claro e a régua
   escrita à mão já quebrou a legenda do suporte uma vez. */
main .drivers-page .driver-form-grid {
  border-top: 1px solid var(--border);
  padding-top: 0.9rem;
  margin-top: 0.9rem;
}
main .drivers-page .driver-form-section { padding: 1.15rem; }
main .drivers-page .driver-form-section__title { letter-spacing: .01em; }
/* A listra chegou a ser uma caixa por campo (fundo, borda e raio). Saiu a
   pedido do dono em 08/08/2026: "tira os card de cada conteúdo". O campo fica
   direto na página; quem separa um do outro é o espaço e o rótulo em caixa
   alta, e quem separa uma seção da outra é o traço. */
main .drivers-page .driver-field-wrap {
  background: none;
  border: 0;
  padding: 0;
}
/* O rótulo vira a "orelha" da listra: menor, em caixa alta, colado no campo. */
main .drivers-page .driver-field-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--sub);
}

/* --- §92 VÍDEOS NO MODO CLARO: TIRAR A COR DAS PASTILHAS -------------------
   As pastilhas do detalhe (Comunicação, Ignição, Velocidade, Localização,
   Motorista) e as do mapa (Pontos, Janela, Cliente, Veículo) vêm com um "tom"
   por estado — verde, vermelho, azul. No fundo escuro isso é um véu de 8%; no
   fundo claro vira uma faixa colorida atrás de um dado que não é alerta
   nenhum ("Cliente: Demonstração" pintado de verde não quer dizer nada).
   No claro, todas ficam neutras. No escuro nada muda. */
:root[data-theme="light"] main .videos-detail-page .videos-metric-tile,
:root[data-theme="light"] main .videos-detail-page .videos-side-metric,
:root[data-theme="light"] .videos-map-modal__body .videos-side-metric[class] {
  background: var(--layer) !important;
  border-color: var(--border) !important;
  color: var(--text) !important;
}

/* O ícone de cada seção morava dentro de um quadrado com borda e fundo
   próprios — quatro caixinhas empilhadas ao longo da página, cada uma
   competindo com o cartão que a contém. Agora o ícone fica direto na página,
   que foi o pedido. */
html:root main .videos-detail-page .videos-detail-card-header > div > div:first-child {
  border: 0 !important;
  background: none !important;
  background-color: transparent !important;
  padding: 0 !important;
}

/* --- §93 "MARCAR VISTO" VIRA "TRATATIVA" -----------------------------------
   O nome da coisa na plataforma é tratativa: é o que fica gravado quando o
   vídeo é marcado como visto (causa, ação, observações). O botão dizia o
   efeito colateral ("marcar visto") em vez do que a pessoa vai fazer.

   Trocar o texto no DOM não funciona: o React redesenha e escreve por cima —
   e mexer no conteúdo de um nó que ele controla atrapalha a reconciliação.
   Então o texto some por CSS (`font-size: 0`) e o novo entra por `::after`.
   O ícone não encolhe junto porque o tamanho dele é `rem` (raiz), não `em`.
   Quem já tem tratativa registrada continua com "Ver tratativa": aí o botão
   abre o que já existe, e a distinção importa. A classe é posta pelo
   i3track-videos.js, que é quem sabe ler o rótulo. */
main .i3v-trat { font-size: 0 !important; gap: 8px !important; }
main .i3v-trat::after {
  content: "Tratativa";
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: normal;
}

/* --- §94 MOTORISTA: A FICHA EM UMA COLUNA SÓ -------------------------------
   Era duas colunas: um cartão de perfil de 320 px à esquerda (foto, status,
   quatro dados repetidos do formulário e as três caixas de upload) e, à
   direita, o cadastro inteiro espremido. Agora:

   - a foto e os status viram uma FAIXA no topo, logo abaixo do nome;
   - o formulário ocupa a largura toda;
   - os uploads saem da faixa e viram a aba "Anexos" (i3track-motorista.js);
   - nada em cartão: direto na página, separado por linha.

   O que sumiu de texto some porque virou repetição: o cabeçalho "Perfil do
   motorista / Cadastro, status e imagens principais" descrevia uma coluna que
   não existe mais, e o nome do motorista já é o título da página. Nenhum DADO
   saiu — Documento, CNH, Celular e Reconhecimento continuam na faixa. */
main .drivers-page .driver-profile-layout { grid-template-columns: minmax(0, 1fr) !important; }

/* A FAIXA fica dentro do topo, acima da barra de abas (a cópia é feita pelo
   i3track-motorista.js). O cartão original vira só o depósito das caixas de
   upload que a aba Anexos mostra — na aba Dados ele não aparece. */
main .drivers-page #i3d-faixa {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.4rem;
  margin: 0.9rem 0 1.1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
main .drivers-page #i3d-faixa .drivers-photo-stage {
  width: 116px;
  height: 116px !important;
  border-radius: 20px;
  flex: none;
}
main .drivers-page #i3d-faixa .drivers-photo-placeholder svg,
main .drivers-page #i3d-faixa .drivers-photo-placeholder span { display: none; }
main .drivers-page #i3d-faixa .drivers-photo-placeholder strong { font-size: 2rem; }
/* a primeira pastilha é o nome do motorista, que já é o título da página */
main .drivers-page #i3d-faixa .drivers-pill-row { flex: none; }
main .drivers-page #i3d-faixa .drivers-pill-row .drivers-pill:first-child { display: none; }
main .drivers-page #i3d-faixa .drivers-meta-grid {
  flex: 0 1 auto;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, max-content);
  gap: 2rem;
}
main .drivers-page #i3d-faixa .drivers-meta-item {
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 0.15rem;
  min-width: 0;
}

/* o cartão de perfil, agora, é só a casa das caixas de anexo */
main .drivers-page .driver-profile-card {
  border: 0 !important;
  background: none !important;
  padding: 0 !important;
}
main .drivers-page .driver-profile-card > .driver-panel__header,
main .drivers-page .driver-profile-card > .drivers-pill-row,
main .drivers-page .driver-profile-card > .drivers-meta-grid { display: none !important; }
main .drivers-page .driver-profile-card .drivers-photo-stage { display: none !important; }

/* o formulário sem cartão: só o traço e a listra da §91 sustentam a leitura */
main .drivers-page .driver-form-section {
  border: 0 !important;
  background: none !important;
  padding: 0 !important;
}
main .drivers-page .driver-section-stack { gap: 1.6rem; }
main .drivers-page .driver-form-section + .driver-form-section { border-top: 1px solid var(--border); padding-top: 1.4rem !important; }
main .drivers-page .driver-form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1200px) { main .drivers-page .driver-form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --- §94b A ABA "ANEXOS" ---------------------------------------------------
   Não é aba do React: é uma vista da aba Dados. Ligada, esconde o formulário e
   mostra as três caixas de upload com a largura toda. Desligada, some com as
   caixas — que é o que tira o peso da faixa do topo. */
main .drivers-page:not(.i3d-anexos) .driver-upload-grid { display: none !important; }
main .drivers-page.i3d-anexos .driver-section-stack { display: none !important; }
/* As três caixas ficam no tamanho que tinham na coluna antiga: esticadas na
   largura toda da tela, a pré-visualização virava um painel enorme para uma
   foto 3x4. Largura fixa por caixa, alinhadas à esquerda. */
main .drivers-page.i3d-anexos .driver-upload-grid {
  display: grid !important;
  grid-template-columns: repeat(3, minmax(0, 320px)) !important;
  justify-content: start;
  flex: 1 1 100%;
  margin-top: 1rem !important;
}
@media (max-width: 900px) { main .drivers-page.i3d-anexos .driver-upload-grid { grid-template-columns: 1fr !important; } }
/* enquanto Anexos está aberta, "Dados" não pode continuar parecendo a aba
   selecionada — seriam duas acesas ao mesmo tempo */
main .drivers-page.i3d-anexos .driver-tab.i3d-tab-muda {
  border-color: var(--border) !important;
  background: none !important;
  color: var(--sub) !important;
}

/* --- §95 RECONHECIMENTO FACIAL: SEM CÓPIA E SEM CARTÃO ---------------------
   O detalhe do /face usa as MESMAS classes da tela de Vídeos, então já herda a
   coluna única, o cabeçalho reduzido ao título e o ícone sem caixa (§90/§92).
   Aqui só sai o que é repetição (marcado por i3track-face.js) e o cartão de
   cada conteúdo — o que separa uma seção da outra passa a ser o traço, como no
   cadastro do motorista. */
.i3f-off { display: none !important; }
main .i3f .videos-detail-card {
  border: 0 !important;
  background: none !important;
  box-shadow: none !important;
}
main .i3f .videos-detail-card + .videos-detail-card { border-top: 1px solid var(--border) !important; }
/* NENHUM dado dentro de caixa: rótulo em cima, valor embaixo, direto na
   página. Chegou a ter um filete na lateral; saiu no mesmo dia — era outra
   moldura, só que mais fina. O que separa uma informação da outra é o espaço
   e a diferença de peso entre rótulo e valor. */
main .i3f .videos-side-metric,
main .i3f .videos-metric-tile {
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  padding: 0 !important;
  box-shadow: none !important;
}
main .i3f .videos-side-metric__label,
main .i3f .videos-metric-tile__header {
  font-size: 0.7rem !important;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sub) !important;
}
main .i3f .videos-side-metric__value,
main .i3f .videos-metric-tile__value {
  font-size: 0.95rem !important;
  font-weight: 600;
  color: var(--text) !important;
  margin-top: 0.15rem;
}
/* mais ar entre as colunas, já que não há mais borda para separá-las */
main .i3f .videos-detail-metrics-grid,
main .i3f .videos-map-metrics-grid { gap: 1.6rem 2.4rem !important; }

/* A barra de ações do topo tinha quatro botões do mesmo peso, todos pedindo
   atenção igual. Só "Validar snapshot" é a ação da tela; o resto é apoio e
   vira botão de contorno, menor. */
main .i3f .videos-detail-hero__actions { gap: 0.5rem; flex-wrap: wrap; }
main .i3f .videos-detail-hero__actions .videos-action-button,
main .i3f .videos-detail-hero__actions .videos-action-button--secondary,
main .i3f .videos-detail-hero__actions .videos-action-button--ghost {
  background: none !important;
  border: 1px solid var(--border) !important;
  color: var(--sub) !important;
  font-size: 0.78rem !important;
  padding: 0.45rem 0.8rem !important;
  min-height: 0 !important;
}
main .i3f .videos-detail-hero__actions .videos-action-button:hover { color: var(--text) !important; }

/* --- §95b FACE: AS CAIXAS DE DENTRO ----------------------------------------
   A §95 tirou o cartão de cada SEÇÃO, mas cada informação continuava dentro da
   sua própria caixinha: `.videos-technical-item` (Fonte, Provedor, Person ref,
   Confiança…), `.videos-list-item` (os passos da timeline e os eventos) e
   `.videos-timeline-card`. Eram três níveis de moldura empilhados — seção,
   grupo e item — para mostrar um par rótulo/valor.

   Agora não há moldura nenhuma: o que separa um item do outro é um fio de 1px,
   que é o mínimo para o olho achar a divisão numa lista longa. A moldura do
   mapa e das imagens FICA — ali ela delimita mídia, não informação. */
main .i3f .videos-detail-meta-card,
main .i3f .videos-quick-pair,
main .i3f .videos-detail-row,
main .i3f .videos-technical-item,
main .i3f .videos-list-item,
main .i3f .videos-timeline-card,
main .i3f .videos-stat-card {
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  padding: 0.7rem 0 !important;
}
main .i3f .videos-list-item + .videos-list-item,
main .i3f .videos-quick-pair + .videos-quick-pair,
main .i3f .videos-detail-row + .videos-detail-row,
main .i3f .videos-timeline-card + .videos-timeline-card { border-top: 1px solid var(--border) !important; }
/* o círculo numerado da timeline e a moldura do mapa FICAM: um é marcador de
   passo, o outro delimita mídia — nenhum dos dois é caixa em volta de dado */
main .i3f .videos-technical-item__label { color: var(--sub) !important; }

/* --- §95c FACE: A LISTA VIRA LISTA -----------------------------------------
   Cada motorista era um cartão com dois botões ("Abrir detecção" e
   "Histórico"). Virou linha: sem cartão, separada por um fio, e a linha
   inteira abre o detalhe — o botão "Abrir detecção" continua no DOM, só
   escondido, e é ele que o clique aciona (i3track-face.js). */
main .face-driver-card.i3f-linha {
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  box-shadow: none !important;
  cursor: pointer;
}
/* O TRAÇO ENTRE AS LINHAS. Chegou a sair e voltou no mesmo dia: com 85
   motoristas em sequência, sem nenhuma marca o olho não acha onde um registro
   termina e o próximo começa — cada linha tem oito campos, e eles se misturam.
   O que NÃO volta é o filete vertical de dentro da linha (logo abaixo): aquele
   separava o conteúdo de uma coluna de ações que hoje está vazia.
   O último não leva traço, para a lista não terminar numa borda solta. */
main .face-driver-card.i3f-linha {
  position: relative;
  padding: 0.8rem 1rem !important;
  border-bottom: 0 !important;
}
/* O traço é um `::after`, e não `border-bottom`, porque a borda acompanha a
   caixa inteira e começaria colada na margem da tela, enquanto o conteúdo
   começa recuado. Assim ele nasce exatamente onde a foto nasce e morre onde o
   conteúdo morre — o olho lê uma coluna só, do retrato ao último campo. */
main .face-driver-card.i3f-linha::after {
  content: "";
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 0;
  height: 1px;
  background: var(--border);
}
main .face-driver-card.i3f-linha:last-child::after { display: none; }
main .face-driver-card.i3f-linha:hover { background: var(--layer) !important; }
/* O filete VERTICAL dentro da linha. Ele separava o conteúdo da coluna de
   ações à direita — coluna que agora está vazia, porque os dois botões saíram.
   Sobrava um risco no meio da linha sem nada de um lado. Em tela estreita o
   mesmo elemento vira filete horizontal (`border-top`); os dois saem. */
main .face-driver-card.i3f-linha .videos-media-card__aside {
  border: 0 !important;
  padding-left: 0 !important;
  padding-top: 0 !important;
}
main .face-driver-card.i3f-linha:focus-visible { outline: 2px solid var(--primary, #0052E6); outline-offset: -2px; }

/* A confiança resgatada do bloco que saiu, recolocada na revisão manual. */
main .i3f .i3f-conf {
  font: 600 0.82rem/1.4 Inter, sans-serif;
  letter-spacing: .04em;
  color: var(--text);
  padding-bottom: 0.7rem;
  margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--border);
}

/* A pastilha "Motorista" e o status ("Online" / "Off há mais de 1h") ficavam a
   8px uma da outra — perto demais para duas coisas que dizem coisas
   diferentes: uma é o papel, a outra é o estado agora. Um respiro só depois da
   primeira, para o status ler como informação separada e não como continuação
   do rótulo. */
main .face-driver-card.i3f-linha .videos-inline-chip--accent { margin-right: 0.45rem; }

/* §51 — CENTRAL DE VIDEOTELEMETRIA: cartão do histórico e cartão da Live.
   =========================================================================
   Só CSS. As peças são alcançadas por `data-i3vc-parte`, posto por
   i3track-videocentro.js — o pacote dá a MESMA classe a três blocos com
   papéis diferentes, então classe sozinha não distingue.

   O QUE ESTAVA ERRADO, olhando a tela:

   1. Os selos se sobrepunham no canto da miniatura. Não é estilo: são duas
      camadas absolutas no mesmo ponto (a da câmera dentro da mídia, a da
      severidade fora). "ALTO" ficava impresso por cima de "Cabine (DMS)".
   2. O título de todo cartão era o MODELO — "Volvo FH 540" em todos. O que
      diferencia um cartão do outro é o EVENTO (Distração, Fadiga, Saída de
      faixa), e ele estava em cinza pequeno embaixo. Trocado.
   3. Tudo aparecia duas vezes: placa (é o veículo da própria página), câmera
      (está na miniatura e no resumo), duração (está na miniatura), severidade
      (miniatura + corpo), e "93%" (no nome do motorista e de novo em
      "Confiança 93%").
   4. Cinco botões iguais por cartão. Com seis cartões na tela são trinta
      botões competindo, e nenhum é obviamente o principal.

   A REGRA DE DESENHO: cada informação aparece UMA vez, e o olho desce numa
   ordem só — severidade na imagem, evento como título, uma linha de contexto,
   quem foi, o que fazer. */

/* ---- histórico: miniatura ---- */
/* O selo da câmera sai: a câmera já está na linha de contexto, e é ele que
   colidia com a severidade. Sobra um canto com um selo só. */
body[data-i3vc] article.videos-card [data-i3vc-parte="selo-camera"] { display: none; }

/* ---- histórico: cabeçalho do corpo ---- */
body[data-i3vc] article.videos-card [data-i3vc-parte="chips"] { display: none; }

/* Evento vira título; modelo vira a legenda. A troca é de ORDEM e de peso —
   nenhum texto é reescrito, nenhum nó é movido: o pai vira coluna e `order`
   faz o resto. */
body[data-i3vc] article.videos-card [data-i3vc-parte="textos"] {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
}
body[data-i3vc] article.videos-card [data-i3vc-parte="evento"] {
  order: 1;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  color: #fff;
}
body[data-i3vc] article.videos-card [data-i3vc-parte="titulo"] {
  order: 2;
  font-size: 0.74rem;
  font-weight: 500;
  line-height: 1.15;
  color: rgba(255, 255, 255, 0.5);
}
/* `space-y-*` do pacote empurra o segundo filho para baixo; com a ordem
   trocada isso viraria um buraco entre o título e a legenda. */
body[data-i3vc] article.videos-card [data-i3vc-parte="textos"] > * { margin-top: 0; }

/* ---- histórico: uma linha de contexto no lugar de duas colunas rotuladas ---- */
/* `nowrap` e `min-width:auto` de propósito: com quebra, o "·" que separa os
   dois dados ficava órfão no fim da primeira linha e o segundo dado descia
   sozinho e desalinhado. São dois valores curtos; cabem na linha. */
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  gap: 0 0.5rem;
  padding-top: 0.1rem;
}
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] > div {
  min-width: auto;
  white-space: nowrap;
}
/* "DATA / HORA" e "CATEGORIA / CÂMERA" em maiúscula minúscula eram mais
   texto que o dado que rotulavam. */
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] > div > div:first-child { display: none; }
/* `inline` não é detalhe: o "·" é um ::before inline e o valor é um <div>
   BLOCO — bloco depois de inline começa linha nova, e era isso que deixava o
   separador órfão no fim da linha e o valor caído embaixo. */
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] > div > div {
  display: inline;
  margin-top: 0;
}
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] > div {
  font-size: 0.72rem;
  color: rgba(255, 255, 255, 0.62);
}
body[data-i3vc] article.videos-card [data-i3vc-parte="meta"] > div + div::before {
  content: "·";
  margin-right: 0.5rem;
  color: rgba(255, 255, 255, 0.3);
}

/* ---- histórico: quem foi ---- */
/* Fica só o motorista, que já traz a confiança entre parênteses. */
body[data-i3vc] article.videos-card [data-i3vc-parte="selos"] > .videos-badge:not(.videos-badge--info) { display: none; }

/* Severidade só na miniatura. */
body[data-i3vc] article.videos-card [data-i3vc-parte="severidade"] { display: none; }

/* ---- histórico: ações ---- */
/* Abrir e Baixar continuam do tamanho de botão. O resto — copiar link,
   destacar, marcar visto — é ação ocasional: some do peso visual e volta ao
   passar o mouse no cartão. Assim seis cartões deixam de ser trinta botões. */
body[data-i3vc] article.videos-card [data-i3vc-parte="acoes"] > div + div {
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.15s ease, max-height 0.15s ease;
}
body[data-i3vc] article.videos-card:hover [data-i3vc-parte="acoes"] > div + div,
body[data-i3vc] article.videos-card:focus-within [data-i3vc-parte="acoes"] > div + div {
  opacity: 1;
  max-height: 4rem;
}

/* ======================= LIVE: o cartão da câmera =======================
   O DEFEITO DE DESENHO: o player — a única razão da tela existir — era o
   elemento com MENOS presença. Um retângulo preto, sem moldura, sem dizer que
   a câmera está fechada e sem convidar a abrir. Em volta dele, dois blocos de
   rótulos em maiúscula miúda (STATUS, RECONHECIMENTO, IMAGEM, VEL, SESSAO),
   um ACIMA e outro ABAIXO, espremendo o vídeo no meio. E o cartão se
   contradizia: selo "Fechada" e, dois centímetros abaixo, "Status: Ao vivo".

   O DESENHO NOVO: nome da câmera e estado no alto; o player logo em seguida,
   em 16:9, com moldura e com o estado escrito DENTRO dele quando está fechada;
   e uma faixa única embaixo, em linha, só com o que tem valor. O olho desce
   uma vez: que câmera é, o que está acontecendo, o que fazer.

   Tudo por `order` — o cartão já é `flex-col`, então reordenar não move nó
   nenhum. Nenhum texto foi reescrito: "câmera fechada" é conteúdo gerado pelo
   CSS, e só aparece quando o JS marcou `data-i3vc-estado="fechada"` lendo o
   próprio selo do pacote. */

body[data-i3vc] article.videos-media-card [data-i3vc-parte="vivo-cabeca"] { order: 1; }
body[data-i3vc] article.videos-media-card [data-i3vc-parte="player"] { order: 2; margin-top: 0.85rem; }
body[data-i3vc] article.videos-media-card [data-i3vc-parte="vivo-faixa-a"] { order: 3; }
body[data-i3vc] article.videos-media-card [data-i3vc-parte="vivo-faixa-b"] { order: 4; }

/* ---- cabeçalho: a câmera é o nome da coisa ---- */
body[data-i3vc] [data-i3vc-parte="vivo-cabeca"] > div:first-child {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #fff;
}

/* ---- o player ---- */
body[data-i3vc] [data-i3vc-parte="player"] .videos-media-shell {
  aspect-ratio: 16 / 9;
  min-height: 0;
  border-radius: 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background:
    radial-gradient(120% 120% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 60%),
    #05070c;
  overflow: hidden;
}
/* A altura fixa do pacote brigava com o 16:9. */
body[data-i3vc] [data-i3vc-parte="player"] .videos-media-shell > * { max-height: 100%; }

/* Fechada: o player diz o que é, em vez de ser um buraco preto. `::after` é
   conteúdo do CSS — não encosta no DOM do React. */
body[data-i3vc] article[data-i3vc-estado="fechada"] [data-i3vc-parte="player"] .videos-media-shell::after {
  content: "Câmera fechada — use Abrir para iniciar a transmissão";
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 2rem;
  text-align: center;
  font-size: 0.8rem;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
}

/* ---- a faixa de dados ---- */
/* Duas grades viram uma linha. Rótulo em cima do valor, os dois miúdos, era
   duas alturas de texto para dizer "0 km/h". */
body[data-i3vc] [data-i3vc-parte="vivo-faixa-a"],
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"] {
  min-height: 0;
  margin-top: 0.6rem;
  padding-top: 0;
}
body[data-i3vc] [data-i3vc-parte="vivo-faixa-a"] > .grid,
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"] > .grid {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 1.1rem;
}
/* `:not(...)` não é capricho: sem ele esta regra é MAIS específica que o
   `display:none` lá embaixo e ressuscita justamente os itens que saíram. O
   layout só alcança o que fica. */
body[data-i3vc] [data-i3vc-parte="vivo-faixa-a"] > .grid > div:not([data-i3vc-parte]):not([data-i3vc-vazio]),
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"] > .grid > div:not([data-i3vc-parte]):not([data-i3vc-vazio]) {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  min-width: 0;
}
body[data-i3vc] [data-i3vc-parte="vivo-faixa-a"] > .grid > div > div,
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"] > .grid > div > div { margin-top: 0; }

/* ---- o que não entra ---- */
/* "Status: Ao vivo" contradizia o selo "Fechada" logo acima. */
body[data-i3vc] [data-i3vc-parte="vivo-status"] { display: none; }
/* "Detalhe" repetia palavra por palavra o que "Reconhecimento" diz. */
body[data-i3vc] [data-i3vc-parte="vivo-extra"] { display: none; }
/* Veículo e Câmera já estão no título do cartão e no topo da página. */
body[data-i3vc] [data-i3vc-parte="vivo-repete"] { display: none; }
/* Traço não é dado: só faz o cartão parecer cheio. */
body[data-i3vc] [data-i3vc-vazio] { display: none; }
/* A tela explicando a si mesma. */
body[data-i3vc] [data-i3vc-parte="vivo-explicacao"] { display: none; }
/* Paginação para duas câmeras. */
body[data-i3vc] [data-i3vc-parte="paginador"] { display: none; }

/* ================= §51b — a página deixa de ser um cartão =================
   Pedidos do dono, 08/08/2026. Cada um com o porquê, para quem mexer depois. */

/* 1) A página inteira estava dentro de um cartão, e o conteúdo dela também era
   feito de cartões: caixa dentro de caixa. A página agora é a página. */
body[data-i3vc] [data-i3vc-parte="superficie"] {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
}

/* 2) "Central de videotelemetria" ao lado de "Voltar para a listagem Live":
   o título da tela já está no menu e na própria navegação. */
body[data-i3vc] [data-i3vc-parte="pilula"] { display: none; }

/* 3) UMA GRADE PARA O TOPO INTEIRO.
   O cabeçalho vinha em quatro caixas encaixadas — cabeçalho > linha > coluna
   esquerda > linha do título — e as abas, a busca, os filtros e as datas
   nasciam cada um num nível diferente. Nada disso podia ser movido: é DOM do
   React.
   A saída é `display:contents` em cada caixa que só existe para agrupar. Ela
   deixa de gerar caixa e os filhos sobem para a grade do miolo, onde eu
   escolho linha e coluna de cada um. Nenhum nó muda de lugar no documento —
   só quem desenha caixa muda.

   Resultado, nas duas abas:
     linha 1   [Voltar]  ......  [Atualizar central] [Ao vivo] [Histórico]
     linha 2   SLH9L22 / Volvo • FH 540 • Preto
     linha 3   [De] [Até]  [Buscar] [Todos os tipos] [Todas as cameras]
   A linha 3 só existe no Histórico: na Ao vivo as datas somem (pedido do
   dono — filtrar período não faz sentido em transmissão ao vivo) e não há
   filtros. */
body[data-i3vc] [data-i3vc-parte="miolo"] {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  column-gap: 0.75rem;
  row-gap: 1rem;
}
body[data-i3vc] [data-i3vc-parte="cabecalho"],
body[data-i3vc] [data-i3vc-parte="cab-linha"],
body[data-i3vc] [data-i3vc-parte="cab-esq"],
body[data-i3vc] [data-i3vc-parte="cab-titulo-linha"],
body[data-i3vc] [data-i3vc-parte="abas"] { display: contents; }

body[data-i3vc] [data-i3vc-parte="cab-voltar"]    { grid-column: 1; grid-row: 1; justify-self: start; }
body[data-i3vc] [data-i3vc-parte="cab-atualizar"] { grid-column: 3; grid-row: 1; }
/* filho 1 do bloco de abas = os dois botões de aba */
body[data-i3vc] [data-i3vc-parte="abas"] > :first-child { grid-column: 4; grid-row: 1; justify-self: end; }
body[data-i3vc] [data-i3vc-parte="cab-titulo"]    { grid-column: 1 / -1; grid-row: 2; }
body[data-i3vc] [data-i3vc-parte="datas"]         { grid-column: 1; grid-row: 3; }
/* filho 2 do bloco de abas = busca + filtros; só existe no Histórico.
   `align-self: end` porque o bloco de datas é mais alto (tem rótulo em cima
   do campo) e é ele que define a altura da linha: centralizados, os campos de
   data ficavam 10 px abaixo da busca. Alinhados pela base, as caixas de todos
   ficam na mesma linha. */
body[data-i3vc] [data-i3vc-parte="abas"] > :nth-child(2) {
  grid-column: 2 / -1;
  grid-row: 3;
  align-self: end;
}
body[data-i3vc] [data-i3vc-parte="miolo"] > *:not([data-i3vc-parte]) { grid-column: 1 / -1; }

/* Sem período para filtrar na Ao vivo. */
body[data-i3vc][data-i3vc-aba="live"] [data-i3vc-parte="datas"] { display: none; }

/* 3b) O título da tela era do tamanho do texto comum.
   Não era estilo: o pacote pede `text-[2rem]`, mas essa classe de valor
   arbitrário NÃO EXISTE no CSS congelado — nenhuma regra casava com o
   elemento e ele herdava os 16 px do corpo. Por isso não precisa de
   `!important` aqui: não há com quem disputar.
   A placa é a identidade da tela e passa a ter porte de título; o
   modelo/cor vira legenda logo abaixo, e "Operação live" deixa de ter o
   mesmo tamanho dos botões ao lado. */
body[data-i3vc] [data-i3vc-parte="cab-titulo"] > :first-child {
  font-size: 1.75rem;
  line-height: 1.15;
}
body[data-i3vc] [data-i3vc-parte="cab-titulo"] > :nth-child(2) {
  margin-top: 0.35rem;
  font-size: 1rem;
}
/* "Operação live" saiu da tela por inteiro (pedido do dono): a aba já se
   chama "Ao vivo" e o menu também. No lugar dele ficam os controles, que
   antes moravam presos na borda direita.
   Sai a CAIXA, não só o texto — um bloco vazio continuaria segurando a
   coluna da esquerda. E `justify-content: flex-start` explícito: a fileira é
   `justify-between`, e sobrar um filho só é o tipo de coisa que funciona por
   acidente até alguém acrescentar um botão. */
body[data-i3vc] [data-i3vc-parte="titulo-secao-caixa"] { display: none; }
body[data-i3vc] [data-i3vc-parte="linha-acoes"] { justify-content: flex-start; }

/* Os campos de data ocupavam 228 px cada por não terem largura declarada; na
   linha compartilhada com a busca e dois filtros isso empurrava tudo para
   fora. 170 px cabe "dd/mm/aaaa, --:--" com folga. */
body[data-i3vc] [data-i3vc-parte="datas"] > label { width: 170px; }
body[data-i3vc] [data-i3vc-parte="datas"] input { width: 100%; min-width: 0; }

/* 4) "Live" vira "Ao vivo" sem tocar no DOM: o texto do botão é colapsado com
   `font-size:0` e o rótulo novo entra como conteúdo do CSS. O ícone é um
   <svg> e não se importa com tamanho de fonte. */
/* Duas regras disputavam esse `font-size` e as duas venciam a minha:
   1. a própria página injeta `.live-videos-page .videos-toolbar-button
      { font-size: .82rem }` — mesma especificidade e DEPOIS no documento;
   2. pior, o §36 daqui mesmo tem `main [data-i3t-btn] { font-size: ...
      !important }`, e `!important` não se ganha com especificidade.
   Por isso o seletor de elemento E o `!important`: sem os dois o botão
   mostrava "Live Ao vivo", os dois rótulos. O ::after é imune ao §36 (a regra
   alcança o botão, não o pseudo), mas leva `!important` também para não
   depender dessa sutileza na próxima vez que alguém mexer aqui. */
body[data-i3vc] button[data-i3vc-parte="aba-live"] { font-size: 0 !important; }
body[data-i3vc] button[data-i3vc-parte="aba-live"]::after {
  content: "Ao vivo";
  font-size: 0.82rem !important;
  font-weight: 600;
}

/* 5) Os contadores eram pastilhas de outra família ao lado de dois botões.
   Mesma altura, mesmo raio, mesma borda: a linha vira um grupo só.
   As variáveis são as do próprio pacote, herdadas de .live-videos-page. */
body[data-i3vc] [data-i3vc-parte="contador"] {
  display: inline-flex;
  min-height: 2.45rem;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--videos-soft-border);
  background: var(--videos-soft-bg);
  padding: 0.62rem 0.95rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1;
  text-transform: none;
  color: rgba(255, 255, 255, 0.84);
}

/* 5b) "0/2 ativas" fora: cada cartão já traz o próprio selo (Fechada / Ao
   vivo) e são dois cartões na tela — o contador contava o que estava à
   vista. "0 iniciadas nesta aba" fica: essa é a única que a tela não mostra
   em outro lugar. */
body[data-i3vc] [data-i3vc-parte="contador-ativas"] { display: none; }

/* 6) Cartão da câmera sem moldura: o vídeo é o objeto, a moldura era só
   contorno em volta de contorno. Ela volta ao passar o mouse, para o cartão
   ainda se anunciar como uma unidade quando você vai agir nele. */
body[data-i3vc] article.videos-media-card:has(.videos-live-fullscreen-root) {
  background: none;
  border-color: transparent;
  box-shadow: none;
  transition: background-color 160ms ease, border-color 160ms ease;
}
body[data-i3vc] article.videos-media-card:has(.videos-live-fullscreen-root):hover,
body[data-i3vc] article.videos-media-card:has(.videos-live-fullscreen-root):focus-within {
  background: var(--videos-soft-bg);
  border-color: var(--videos-soft-border);
}

/* 7) Histórico: fora o que não decide nada.
   - "Motorista não cadastrado" é a ausência de dado ocupando uma linha.
   - "Tela cheia" e o selo de severidade cobriam a própria imagem.
   - A fileira de cinco botões virava trinta botões com seis cartões. */
body[data-i3vc] article.videos-card [data-i3vc-parte="selos"],
body[data-i3vc] article.videos-card [data-i3vc-parte="acoes"],
body[data-i3vc] article.videos-card [data-i3vc-parte="selo-telacheia"],
body[data-i3vc] article.videos-card [data-i3vc-parte="selo-severidade"] { display: none; }

/* 8) Sem os botões, o cartão inteiro abre — e precisa parecer clicável. */
body[data-i3vc] article.videos-card:not(:has(.videos-live-fullscreen-root)) {
  cursor: pointer;
  transition: border-color 160ms ease, transform 160ms ease;
}
body[data-i3vc] article.videos-card:not(:has(.videos-live-fullscreen-root)):hover {
  border-color: rgba(255, 255, 255, 0.22);
  transform: translateY(-1px);
}

/* 9) ENDEREÇO no cartão da Ao vivo.
   É o único dado desta tela que o pacote não traz: o cartão dizia onde a
   câmera está apontada, nunca onde o veículo está. O valor chega como
   atributo (i3track-videocentro.js consulta a mesma rota da ficha do
   veículo) e quem escreve é o CSS — `content: attr(...)` não encosta no DOM
   do React.

   Fica em linha própria, e não junto de "Vel 0 km/h", por uma razão de
   medida: endereço é o texto mais longo do cartão e quebraria a linha dos
   outros dados ao meio. Sem endereço o atributo não existe, a regra não
   casa, e a faixa continua exatamente como estava. */
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"][data-i3vc-endereco] {
  display: flex;
  flex-direction: column;
}
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"][data-i3vc-endereco] > .grid { order: 0; }
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"][data-i3vc-endereco]::before {
  order: 1;
  content: "Endereço";
  margin-top: 0.55rem;
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
body[data-i3vc] [data-i3vc-parte="vivo-faixa-b"][data-i3vc-endereco]::after {
  order: 2;
  content: attr(data-i3vc-endereco);
  margin-top: 0.25rem;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.92);
}

/* ================= §52 — Área de Risco: zonas de concentração ==============
   Pedido do dono, 08/08/2026: "o mapa tem que ser no jeito do Resultados,
   concentração, zona — e eu escolho o tipo que quero ver".
   Quem desenha o calor é um <canvas> do i3track-areas-risco.js; aqui fica o
   que é estilo: os botões de tipo e o recuo dos círculos do pacote. */

/* 1) Os círculos do pacote deixam de ser discos chapados e viram contorno.
   Eles continuam ali — é neles que se clica para abrir o detalhe da área e é
   deles que sai o raio exato. O que some é o preenchimento, que competia com
   o calor e, com áreas sobrepostas, virava uma mancha só. */
.risk-area-map path.leaflet-interactive {
  fill-opacity: 0.05;
  stroke-opacity: 0.5;
  stroke-width: 1;
}
.risk-area-map path.leaflet-interactive:hover { stroke-opacity: 0.95; }

/* 2) O filtro. Uma cor por tipo — a MESMA que o pacote usa no círculo, senão
   o botão vira uma legenda que não bate com o mapa. */
.i3risk-filtro {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(12, 16, 24, 0.88);
  backdrop-filter: blur(6px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.i3risk-filtro button {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 172px;
  padding: 6px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  cursor: pointer;
  font: 600 12px/1 var(--i3t-font-body, "Inter", sans-serif);
  color: rgba(255, 255, 255, 0.72);
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.i3risk-filtro button:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.i3risk-filtro button[data-ativo="1"] {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}
/* Tipo sem nenhuma área cadastrada continua na régua, apagado: a lista de
   tipos é fixa, e uma régua que muda de tamanho conforme o cadastro faz o
   cursor errar o botão. */
.i3risk-filtro button[data-vazio="1"] { opacity: 0.42; }
.i3risk-filtro button[data-vazio="1"][data-ativo="1"] { opacity: 1; }
.i3risk-filtro i {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 999px;
}
.i3risk-filtro .i3risk-rot { flex: 1; text-align: left; }
.i3risk-filtro .i3risk-n {
  flex: none;
  min-width: 20px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  color: rgba(255, 255, 255, 0.86);
}
/* O "Todos" não tem bolinha; o vão da bolinha entra como recuo para os
   rótulos ficarem todos na mesma coluna. */
.i3risk-filtro button[data-i3risk-tipo="todos"] { padding-left: 26px; }

/* 2b) O aviso "Nenhuma área cadastrada / Criar primeira área" tapava um
   quarto do mapa para repetir o botão "Nova área" do cabeçalho, dois
   centímetros acima. Quem marca é o JS, pelo texto do botão.
   O seletor NÃO passa por `.risk-area-map`: o cartão é filho de um invólucro
   que envolve o mapa, não do mapa. Quem limita o alcance é o `data-i3risk-sel`
   no <body>, que só existe nesta rota. */
body[data-i3risk-sel] [data-i3risk-vazio] { display: none; }

/* 3) Filtrar é esconder — no mapa e na lista, pelo MESMO atributo no <body>.
   No mapa dá para fazer só com CSS porque a cor do traço já diz o tipo: é a
   tabela de cores do próprio pacote.

   ESCONDE TUDO E DEVOLVE O ESCOLHIDO — e a ordem importa mais que a lógica.
   A primeira versão fazia o contrário (escondia com `:not([...="todos"])` e
   devolvia por tipo), e a regra de esconder era MAIS ESPECÍFICA que a de
   mostrar: o filtro apagava o mapa inteiro em vez de deixar um tipo. Aqui as
   duas famílias têm a mesma especificidade e a que mostra vem depois — que é
   o desempate que o CSS garante. */
body[data-i3risk-sel] .risk-area-map path.leaflet-interactive,
body[data-i3risk-sel] tr[data-i3risk-tipo] { display: none; }

/* Pelo `fill`, não pelo `stroke`: cada área desenha DOIS caminhos — o
   círculo do raio e o ponto do centro — e só o círculo tem o traço na cor do
   tipo; o ponto tem traço escuro. Filtrando por traço, o ponto do tipo
   escolhido sumia junto com os outros. O `fill` é a cor do tipo nos dois. */
body[data-i3risk-sel="todos"]         .risk-area-map path.leaflet-interactive,
body[data-i3risk-sel="robbery"]       .risk-area-map path.leaflet-interactive[fill="#ef4444"],
body[data-i3risk-sel="accident"]      .risk-area-map path.leaflet-interactive[fill="#f97316"],
body[data-i3risk-sel="forbidden"]     .risk-area-map path.leaflet-interactive[fill="#a855f7"],
body[data-i3risk-sel="theft_attempt"] .risk-area-map path.leaflet-interactive[fill="#eab308"],
body[data-i3risk-sel="maintenance"]   .risk-area-map path.leaflet-interactive[fill="#38bdf8"],
body[data-i3risk-sel="other"]         .risk-area-map path.leaflet-interactive[fill="#94a3b8"] { display: inline; }

body[data-i3risk-sel="todos"]         tr[data-i3risk-tipo],
body[data-i3risk-sel="robbery"]       tr[data-i3risk-tipo="robbery"],
body[data-i3risk-sel="accident"]      tr[data-i3risk-tipo="accident"],
body[data-i3risk-sel="forbidden"]     tr[data-i3risk-tipo="forbidden"],
body[data-i3risk-sel="theft_attempt"] tr[data-i3risk-tipo="theft_attempt"],
body[data-i3risk-sel="maintenance"]   tr[data-i3risk-tipo="maintenance"],
body[data-i3risk-sel="other"]         tr[data-i3risk-tipo="other"] { display: table-row; }

/* ============ §53 — Perfil e Configurações saem dos cartões ================
   Pedido do dono, 08/08/2026, com a ficha do motorista como modelo: abas em
   cima, seções na página, campos separados por linha. Quem etiqueta é o
   i3track-conta.js; aqui é só desenho. */

/* ---- a TINTA das telas novas (§53, §54, §56) ----
   Estas três seções nasceram com `rgba(255,255,255,…)` cravado, porque o
   painel abre no escuro. No MODO CLARO isso é texto branco sobre fundo
   branco: a tela some sem erro nenhum, sem aviso nenhum — foi o que a
   medição mostrou na tela de Temas.

   A cura não é duplicar tudo em `[data-theme="light"]`: é apontar para os
   tokens que o próprio tema já troca (`--text`, `--text-2`, `--border`,
   `--field-bg`). Uma regra só serve os dois modos, e o dia em que a paleta
   mudar, muda lá e chega aqui.

   Só dois níveis de tinta porque é o que a paleta tem: para o terceiro
   (a legenda mais fraca) usamos `opacity`, que funciona em qualquer tema. */
:root {
  --i3n-forte: var(--text, #fff);
  --i3n-media: var(--text-2, rgba(255, 255, 255, 0.62));
  --i3n-linha: var(--border, rgba(255, 255, 255, 0.1));
  --i3n-campo: var(--field-bg, rgba(255, 255, 255, 0.04));
  --i3n-hover: var(--surface-2, rgba(255, 255, 255, 0.06));
}

/* ---- comum às duas telas: cartão vira seção ---- */
body[data-i3conta-tela] [data-i3conta-sec],
body[data-i3conta-tela] [data-i3conta="conteudo"] > div,
body[data-i3conta-tela] [data-i3conta="menu"] {
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
}

/* O contêiner vira coluna para as abas poderem subir por `order` — elas
   nascem no fim, que é a única inserção segura na árvore do React. */
body[data-i3conta-tela] [data-i3conta="miolo"] {
  display: flex;
  flex-direction: column;
  gap: 0;
}
body[data-i3conta-tela] [data-i3conta="cabecalho"] { order: 0; }
body[data-i3conta-tela] .i3conta-abas { order: 1; }
body[data-i3conta-tela] [data-i3conta="grade"] { order: 2; }
body[data-i3conta-tela] [data-i3conta-sec] { order: 3; }

/* ---- a faixa de abas ---- */
.i3conta-abas {
  display: flex;
  gap: 0.25rem;
  margin: 0.25rem 0 0.5rem;
  padding-bottom: 0;
  border-bottom: 1px solid var(--i3n-linha);
}
/* `!important` em tudo porque o i3track-ui.js etiqueta TODO botão dentro do
   `main` com `data-i3t-btn`, e o §36 desenha esse atributo como pílula, com
   `!important`. Sem isto, as abas nasciam pílulas — a ativa azul cheia, as
   outras cinza — que é exatamente o que a ficha do motorista não faz. */
/* O seletor das Configurações leva `button[data-i3conta]` — um atributo a
   mais — porque a pílula azul da aba ativa vem de
   `:root[data-theme] .bg-sky-500\/15 { background-color: … !important }`,
   aqui do §12: (0,3,0) contra os (0,2,2) que eu tinha. `!important` dos dois
   lados empata, e aí quem decide é a especificidade — não a ordem.
   Os inativos vinham de outra ainda mais forte —
   `:root[data-theme] main button[class*="border-white/10"]:not([aria-current])`,
   (0,4,2) — e por isso o seletor terminou com `[class]:not([hidden])`: dois
   qualificadores que não mudam o que casa, só o peso. Feio, e é o preço de
   pintar utilitário do Tailwind com `!important` lá atrás. Quem descobriu foi
   o `CSS.getMatchedStylesForNode` do CDP, que lista a regra vencedora em vez
   de deixar a gente adivinhar. */
.i3conta-abas button,
body[data-i3conta-tela="config"] [data-i3conta="menu"] button[data-i3conta][class]:not([hidden]) {
  position: relative;
  height: auto !important;
  min-height: 0 !important;
  padding: 0.65rem 0.15rem !important;
  margin-right: 1.5rem;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  cursor: pointer;
  font-family: var(--i3t-font-body, "Inter", sans-serif) !important;
  font-size: 0.875rem !important;
  font-weight: 600 !important;
  color: var(--i3n-media) !important;
  transition: color 120ms ease;
}
.i3conta-abas button:hover,
body[data-i3conta-tela="config"] [data-i3conta="menu"] button[data-i3conta][class]:not([hidden]):hover { color: var(--i3n-forte) !important; }
/* O sublinhado da aba ativa é `::after` — sem caixa, sem pílula: a aba é o
   texto e a linha embaixo dele, como na ficha do motorista. */
.i3conta-abas button[data-ativo="1"],
body[data-i3conta-tela="config"] [data-i3conta="menu"] button[data-i3conta][class]:not([hidden])[data-i3conta-ativo="1"] { color: var(--i3n-forte) !important; }
.i3conta-abas button[data-ativo="1"]::after,
body[data-i3conta-tela="config"] [data-i3conta="menu"] button[data-i3conta][class]:not([hidden])[data-i3conta-ativo="1"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--i3t-brand-solid, #0052E6);
}

/* ---- só a seção da aba escolhida fica ---- */
body[data-i3conta-tela="perfil"] [data-i3conta-sec] { display: none; }
body[data-i3conta-aba="info"]   [data-i3conta-sec="info"],
body[data-i3conta-aba="senha"]  [data-i3conta-sec="senha"],
body[data-i3conta-aba="idioma"] [data-i3conta-sec="idioma"] { display: block; }

/* A grade de duas colunas deixa de gerar caixa: cada cartão vira uma seção
   independente do contêiner, com sua própria aba. */
body[data-i3conta-tela="perfil"] [data-i3conta="grade"] { display: contents; }

/* ---- o que sai ---- */
body[data-i3conta-tela="perfil"] [data-i3conta="organizacao"] { display: none; }
body[data-i3conta-tela="config"] [data-i3conta="menu-limites"] { display: none; }
body[data-i3conta-tela="config"] [data-i3conta="menu-tolerancia"] { display: none; }
body[data-i3conta-tela="config"] [data-i3conta="menu-titulo"] { display: none; }
body[data-i3conta-limites] [data-i3conta="conteudo"] { display: none; }

/* ---- campos em linha, separados por traço (o pedido "por listras") ---- */
/* A grade de campos vira uma coluna e cada campo vira uma linha rótulo à
   esquerda, controle à direita. É o que faz treze campos caberem numa tela
   sem virar quatro caixas. */
body[data-i3conta-tela="perfil"] [data-i3conta-sec] .grid { display: block; }
/* A LINHA é o `.space-y-2` — o invólucro de UM campo, com o rótulo e o
   controle dentro. Duas tentativas erradas antes desta, e a lição é a mesma
   das outras telas: conferir o DOM em vez de supor o componente.
     1. `.grid > div` pegava também os invólucros aninhados (Telefone e
        Cargo/descrição vêm num `sm:grid-cols-2`), e o invólucro virava uma
        linha com rótulo vazio e dois campos amassados do lado;
     2. `:has(> label)` não pegava NADA: **o rótulo aqui não é <label>, é um
        <div class="text-xs">** — a regra simplesmente não casava e a tela
        ficava igual, sem erro nenhum.
   O `margin: 0` é obrigatório: `space-y-2` põe margem entre irmãos e ela
   somava com o `padding` da linha. */
body[data-i3conta-tela="perfil"] [data-i3conta-sec] .space-y-2 {
  display: grid;
  grid-template-columns: minmax(160px, 240px) minmax(0, 1fr);
  align-items: center;
  gap: 0.25rem 1.5rem;
  margin: 0 !important;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--i3n-linha);
}
body[data-i3conta-tela="perfil"] [data-i3conta-sec] .space-y-2 > :first-child {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--i3n-media);
}
body[data-i3conta-tela="perfil"] [data-i3conta-sec] .space-y-2:last-child { border-bottom: 0; }
/* O título da seção ganha ar depois das abas e o subtítulo vira legenda. */
body[data-i3conta-tela] [data-i3conta-sec] h2 { font-size: 1.05rem; }
/* Ar entre a faixa de abas e o título da seção: sem isto o título encostava
   na linha das abas e a tela parecia amassada. */
body[data-i3conta-tela] [data-i3conta-sec] > div:first-child {
  margin: 1.1rem 0 0.35rem;
}

/* ---- Configurações: menu vira faixa, canais viram linhas ---- */
body[data-i3conta-tela="config"] [data-i3conta="grade"] {
  display: flex;
  flex-direction: column;
  gap: 0;
}
/* O `!important` na borda é para vencer o reset de cartão lá de cima, que
   zera `border` em tudo que era caixa — inclusive nesta faixa, que é a única
   borda que deve sobrar. */
body[data-i3conta-tela="config"] [data-i3conta="menu"] {
  order: 0;
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--i3n-linha) !important;
  margin-bottom: 0.5rem;
}
/* Os botões ficam DOIS níveis abaixo do cartão do menu (`.space-y-3 >
   .space-y-2 > button`), e não um: achatar só o primeiro nível deixava a
   régua vertical do mesmo jeito. */
/* O `:not(...)` não é enfeite: sem ele esta regra é tão específica quanto o
   `display:none` do título e vem DEPOIS no arquivo — ressuscitava justamente
   a faixa "Submenus" que deveria ter sumido. */
body[data-i3conta-tela="config"] [data-i3conta="menu"] > div:not([data-i3conta="menu-titulo"]),
body[data-i3conta-tela="config"] [data-i3conta="menu"] > div > div {
  display: flex;
  gap: 0;
  margin: 0;
}
body[data-i3conta-tela="config"] [data-i3conta="menu"] button[data-i3conta][class]:not([hidden]) {
  width: auto !important;
  white-space: nowrap;
}
/* A legenda de cada item ("Canais e limites de alertas") sai: numa faixa
   horizontal ela dobra a altura para repetir o que o nome já diz. */
body[data-i3conta-tela="config"] [data-i3conta="menu"] button > div:not(:first-child) { display: none; }
body[data-i3conta-tela="config"] [data-i3conta="conteudo"] { order: 1; }
/* Cada canal (E-mail, SMS, WhatsApp) era um cartão; vira uma faixa separada
   por linha, como as seções do Perfil. */
body[data-i3conta-tela="config"] [data-i3conta="conteudo"] .space-y-4 > div {
  border-radius: 0 !important;
  border-width: 0 0 1px 0 !important;
  border-color: var(--i3n-linha) !important;
  background: none !important;
  box-shadow: none !important;
  padding: 1rem 0 !important;
}

/* ============ §54 — Notificações: a caixa de entrada do aplicativo ==========
   A tabela de regras ("Nome | Tipo | Meio | Ativo") não é removida da árvore,
   só some daqui — se o i3track-notificacoes.js sair, ela volta inteira. */
/* `!important` porque o §36 põe `display: inline-flex !important` em todo
   botão etiquetado com `data-i3t-btn` — e um dos alvos aqui é justamente o
   botão "Atualizar" do cabeçalho. Sem isto ele sobrevivia ao `display:none`
   e ficavam dois "Atualizar" na tela, fazendo coisas diferentes. */
body[data-i3not] [data-i3not-antigo] { display: none !important; }

.i3not { display: block; }
.i3not-barra {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.25rem 0 0.85rem;
  border-bottom: 1px solid var(--i3n-linha);
}
.i3not-busca {
  flex: 1 1 260px;
  min-width: 0;
  height: 40px;
  padding: 0 0.9rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 999px;
  background: var(--i3n-campo);
  color: var(--i3n-forte);
  font: 400 0.875rem/1 var(--i3t-font-body, "Inter", sans-serif);
}
.i3not-busca::placeholder { color: var(--i3n-media); opacity: 0.8; }
.i3not-busca:focus { outline: none; border-color: var(--i3t-brand-solid, #0052E6); }

.i3not-filtros { display: flex; gap: 0.35rem; flex-wrap: wrap; }
/* Os mesmos `[class]:not([hidden])` do §53, e pela mesma razão: o §12 repinta
   utilitário do Tailwind com `!important` e o §36 transforma botão em pílula.
   Aqui os botões são meus, mas o `data-i3t-btn` é posto por JS em qualquer
   botão dentro do `main`. */
.i3not-filtros button[data-f] {
  height: 32px !important;
  min-height: 0 !important;
  padding: 0 0.85rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.8rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
.i3not-filtros button[data-f]:hover { color: var(--i3n-forte) !important; background: var(--i3n-hover) !important; }
/* Sobre a cor da marca o texto é branco nos dois modos: quem manda aqui é o
   fundo pintado, não o tema da página. */
.i3not-filtros button[data-f][data-ativo="1"] {
  background: var(--i3t-brand-solid, #0052E6) !important;
  border-color: var(--i3t-brand-solid, #0052E6) !important;
  color: #fff !important;
}
.i3not-atualizar[class] {
  height: 40px !important;
  min-height: 0 !important;
  padding: 0 1.1rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.875rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-forte) !important;
}
.i3not-atualizar[class]:hover { background: var(--i3n-hover) !important; }

/* Uma linha por notificação, separada por traço — o mesmo desenho da ficha do
   motorista e do Perfil. A cor da marca à esquerda é a gravidade do evento,
   que é a informação que faz varrer a lista com o olho. */
.i3not-linha {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.85rem 0.25rem;
  border-bottom: 1px solid var(--i3n-linha);
  cursor: pointer;
  transition: background-color 120ms ease;
}
.i3not-linha:hover { background: var(--i3n-hover); }
.i3not-marca {
  flex: none;
  width: 3px;
  align-self: stretch;
  border-radius: 3px;
  background: var(--i3not-cor, #94a3b8);
}
.i3not-texto { flex: 1; min-width: 0; }
.i3not-msg {
  font: 600 0.875rem/1.3 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-forte);
}
.i3not-veic {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 0.2rem;
  font-size: 0.78rem;
  color: var(--i3n-media);
}
.i3not-placa {
  font-family: var(--i3t-font-mono, ui-monospace, monospace);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--i3n-forte);
}
.i3not-quando { flex: none; text-align: right; }
.i3not-hora {
  font-family: var(--i3t-font-mono, ui-monospace, monospace);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--i3n-forte);
}
.i3not-dia { margin-top: 0.1rem; font-size: 0.72rem; color: var(--i3n-media); opacity: 0.85; }
.i3not-vazio {
  padding: 2.5rem 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--i3n-media);
}

/* ============ §55 — o tema da plataforma chega às peças ====================
   O JS (i3track-brand-tenant.js) só põe `--i3tema-*` na raiz. É AQUI que cada
   variável encontra a peça que pinta — assim, quando o pacote renomear uma
   classe, muda uma linha deste bloco e nenhum JavaScript.

   Peça sem valor não vira variável, e então nenhuma regra daqui casa: a
   plataforma cai sozinha nas cores de fábrica. É o que faz o botão "Padrão"
   funcionar sem ninguém precisar saber quais eram as cores originais. */

/* A cor da ação: botões, abas ativas, links. */
:root[data-i3tema] {
  --i3t-brand-solid: var(--i3tema-marca, #0052E6);
  /* O tom de passar o mouse é do §51.2 e também estava cravado em azul: sem
     ele, o botão da revenda voltava a azul só ao ser apontado. */
  --i3t-brand-solid-hover: color-mix(in srgb, var(--i3tema-marca, #0052E6) 82%, #fff);
  --brand: var(--i3tema-marca, #0052E6);
  --primary: var(--i3tema-marca, #0052E6);
  --accent: var(--i3tema-marca, #0052E6);
  --color-primary: var(--i3tema-marca, #0052E6);
  --brand-primary: var(--i3tema-marca, #0052E6);
  /* A listra da esquerda dos cartões — a primeira da paleta é a da marca; as
     outras (alerta, ok, atenção) são semânticas e não mudam com a revenda. */
  --i3t-kpi-1: var(--i3tema-listra, var(--i3tema-marca, #0052E6));
}

/* O `--primary`, que é o que pinta BOTÃO, exige um parágrafo.
 *
 * O §10.1 lá em cima crava `--primary:#0052E6 !important` de propósito: os
 * chunks de rota do pacote redefinem o token com outro azul, e sem o
 * `!important` a tela mudava de azul conforme a rota. Só que `!important` de
 * folha vence estilo em linha — então a cor da revenda pintava o menu e a
 * listra, e o botão continuava azul. A medição mostrou exatamente isso:
 * `--brand` virava #c2410c e `--primary` ficava #0052E6.
 *
 * A exceção é reaberta só para quem TEM tema. Mesma especificidade do §10.1
 * (0,2,0) e mais abaixo no arquivo — com `!important` dos dois lados, quem
 * decide é a ordem. Plataforma sem tema não casa aqui e continua exatamente
 * como está hoje.
 *
 * Os tons vizinhos saem por `color-mix` em vez de virem do servidor: pedir
 * seis cores para a revenda seria pedir que ela desenhasse uma paleta. Ela
 * escolhe UMA e o resto se deduz. */
:root[data-i3tema] {
  --primary: var(--i3tema-marca, #0052E6) !important;
  --primary-soft: color-mix(in srgb, var(--i3tema-marca, #0052E6) 18%, transparent) !important;
  --focus-ring: color-mix(in srgb, var(--i3tema-marca, #0052E6) 45%, transparent) !important;
  --accent-border: color-mix(in srgb, var(--i3tema-marca, #0052E6) 90%, transparent) !important;
  --accent-border-soft: color-mix(in srgb, var(--i3tema-marca, #0052E6) 42%, transparent) !important;
}
/* O hover clareia no escuro e escurece no claro — o contrário, nos dois
   casos, some com o botão em vez de destacá-lo. */
:root[data-i3tema][data-theme="dark"]  { --primary-hover: color-mix(in srgb, var(--i3tema-marca, #0052E6) 78%, #fff) !important; }
:root[data-i3tema][data-theme="light"] { --primary-hover: color-mix(in srgb, var(--i3tema-marca, #0052E6) 80%, #000) !important; }

/* O menu lateral: faixa de ícones, painel e o texto sobre eles. */
:root[data-i3tema] .i3duo {
  --i3s: var(--i3tema-sidebar, #2563EB);
  --i3s2: var(--i3tema-sidebar2, var(--i3tema-sidebar, #1B49C0));
  --i3stext: var(--i3tema-sidebarTexto, #EAF0FF);
  /* Os dois tons apagados do menu (item inativo, legenda) eram derivados do
     #EAF0FF cravado: com texto escolhido escuro, eles continuavam claros e o
     menu ficava ilegível pela metade. Aqui eles seguem a cor escolhida. */
  --i3smuted: color-mix(in srgb, var(--i3tema-sidebarTexto, #EAF0FF) 64%, transparent);
  --i3sfaint: color-mix(in srgb, var(--i3tema-sidebarTexto, #EAF0FF) 42%, transparent);
}
/* O cartão da conta (AD / Administrador / ADMIN GERAL). Era um véu BRANCO
   sobre o menu — `rgba(255,255,255,.10)` — e véu branco sobre menu claro é
   invisível: com a revenda escolhendo um menu claro, o cartão sumia. Agora é
   peça do tema, e o quadradinho da sigla sai dele por `color-mix` em vez de
   pedir uma sétima cor a quem só quer escolher a marca. */
:root[data-i3tema] .i3duo-acct {
  background: var(--i3tema-conta, rgba(255, 255, 255, 0.10));
  border-color: color-mix(in srgb, var(--i3tema-sidebarTexto, #EAF0FF) 22%, transparent);
}
:root[data-i3tema] .i3duo-acct .a {
  background: color-mix(in srgb, var(--i3tema-conta, #3B74EE) 55%, var(--i3tema-sidebarTexto, #EAF0FF));
  color: var(--i3tema-sidebar2, #1B49C0);
}
:root[data-i3tema] .i3duo-acct .w b { color: var(--i3tema-sidebarTexto, #EAF0FF); }

/* O ITEM SELECIONADO do menu. Era um véu branco (`rgba(255,255,255,.17)`) com
   texto branco por cima — invisível assim que a revenda escolhe um menu
   claro, que é exatamente o caso do modo claro. Vira peça do tema; o texto
   passa a ser o do menu, e a barrinha da esquerda, a cor da marca. */
:root[data-i3tema] .i3duo {
  --i3sactive: var(--i3tema-selecao, rgba(255, 255, 255, 0.17));
  --i3shover: color-mix(in srgb, var(--i3tema-selecao, #ffffff) 55%, transparent);
}
:root[data-i3tema] .i3duo-item.active,
:root[data-i3tema] .i3duo-item:hover,
:root[data-i3tema] .i3duo-ico.active,
:root[data-i3tema] .i3duo-ico:hover { color: var(--i3tema-sidebarTexto, #EAF0FF); }
:root[data-i3tema] .i3duo-item.active::before,
:root[data-i3tema] .i3duo-ico.active::before { background: var(--i3tema-marca, #0052E6); }

/* Símbolo do menu: o ícone de fábrica é monocromático e o §20 o pinta de
   branco (`filter: brightness(0) invert(1)`). A arte da revenda tem cor
   própria — o mesmo filtro a viraria uma silhueta branca. */
:root[data-i3tema-simbolo] .i3duo-logo img { filter: none; }
/* A faixa pintada antes de o menu montar (§20) tem as cores cravadas no
   gradiente; sem esta regra a tela abre azul de fábrica e vira a cor da
   revenda meio segundo depois. */
:root[data-i3tema] .app-shell::before {
  background: linear-gradient(
    to right,
    var(--i3tema-sidebar, #2563EB) 0 76px,
    var(--i3tema-sidebar2, var(--i3tema-sidebar, #1B49C0)) 76px 100%
  );
}

/* A fonte. Lista fechada no servidor; aqui ela só entra na frente da pilha,
   com as de sempre atrás como rede. */
:root[data-i3tema-fonte] body,
:root[data-i3tema-fonte] #root,
:root[data-i3tema-fonte] .i3duo,
:root[data-i3tema-fonte] button,
:root[data-i3tema-fonte] input,
:root[data-i3tema-fonte] select,
:root[data-i3tema-fonte] textarea {
  font-family: var(--i3tema-fonte), "Bricolage Grotesque", "Inter", ui-sans-serif, system-ui, sans-serif;
}

/* ============ §56 — a TELA "Temas" ========================================
   Mesmo desenho do resto de Configurações: sem cartão, subseções em faixa,
   uma linha por ajuste separada por traço. A tinta vem das variáveis do §53,
   então a tela serve os dois modos com uma regra só.

   Virou tela própria em 09/08/2026 (era aba dentro de Configurações). Segue o
   padrão das outras telas injetadas (§32/.i3plat-pg): montada por cima da
   área de conteúdo do React, abaixo da topbar REAL e à direita do menu REAL —
   `left`/`top`/`background` vêm do JS, que os mede. */
.i3tema-pg {
  position: fixed; right: 0; bottom: 0; z-index: 30;
  overflow-y: auto; overflow-x: hidden;
  padding: 20px 24px 40px;
}
body.i3tema-pg-open section.app-shell__content { display: none !important; }

.i3tema-topo { margin-bottom: 0.5rem; }
.i3tema-topo h1 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--i3n-forte); }
.i3tema-topo p { margin: 2px 0 0; font-size: 12px; color: var(--i3n-media); }

.i3tema-sub { display: flex; gap: 1.25rem; margin: 0.35rem 0 0.25rem; }
.i3tema-sub button[data-sub] {
  height: auto !important;
  min-height: 0 !important;
  padding: 0.35rem 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.82rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
.i3tema-sub button[data-sub][data-ativo="1"] {
  color: var(--i3n-forte) !important;
  box-shadow: inset 0 -2px 0 var(--i3t-brand-solid, #0052E6);
}

.i3tema-corpo { display: none; }
.i3tema[data-sub="cores"] .i3tema-cores,
.i3tema[data-sub="logos"] .i3tema-logos { display: block; }

.i3tema-cab {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 1rem 0 0.35rem;
}
.i3tema-cab h3 { margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--i3n-forte); }
.i3tema-cab p { margin: 0.2rem 0 0; font-size: 0.8rem; color: var(--i3n-media); max-width: 62ch; }

.i3tema-modos { display: flex; gap: 0.35rem; }
.i3tema-modos button[data-modo] {
  height: 32px !important;
  min-height: 0 !important;
  padding: 0 0.85rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.78rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
/* Texto branco sobre a cor da marca nos dois modos: o fundo é pintado, não é
   o fundo da página. */
.i3tema-modos button[data-modo][data-ativo="1"] {
  background: var(--i3t-brand-solid, #0052E6) !important;
  border-color: var(--i3t-brand-solid, #0052E6) !important;
  color: #fff !important;
}

.i3tema-linha {
  display: grid;
  grid-template-columns: minmax(180px, 280px) minmax(0, 1fr);
  align-items: center;
  gap: 0.25rem 1.5rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--i3n-linha);
}
.i3tema-rot span { display: block; font-size: 0.875rem; font-weight: 500; color: var(--i3n-forte); }
.i3tema-rot small { display: block; margin-top: 0.15rem; font-size: 0.72rem; color: var(--i3n-media); opacity: 0.85; }
.i3tema-controle { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }

/* O seletor nativo é uma caixa cinza feia em todo navegador; aqui ele vira o
   próprio quadrado de cor, que é o que a pessoa espera clicar. */
.i3tema-controle input[type="color"] {
  width: 42px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: none;
  cursor: pointer;
}
.i3tema-controle input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
.i3tema-controle input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 6px; }
.i3tema-controle input[type="text"] {
  width: 120px;
  height: 32px;
  padding: 0 0.6rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: var(--i3n-campo);
  color: var(--i3n-forte);
  font: 500 0.8rem/1 var(--i3t-font-mono, ui-monospace, monospace);
}
.i3tema-controle input[type="text"]::placeholder { color: var(--i3n-media); opacity: 0.75; }
.i3tema-controle select {
  height: 32px;
  padding: 0 0.6rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: var(--i3n-campo);
  color: var(--i3n-forte);
  font-size: 0.82rem;
}
.i3tema-limpa[data-limpa] {
  height: 30px !important;
  min-height: 0 !important;
  padding: 0 0.7rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.72rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
.i3tema-limpa[data-limpa]:hover { color: var(--i3n-forte) !important; }

.i3tema-img .i3tema-previa {
  display: inline-grid;
  place-items: center;
  min-width: 96px;
  height: 40px;
  padding: 0 0.5rem;
  border: 1px dashed var(--i3n-linha);
  border-radius: 8px;
  font-size: 0.72rem;
  color: var(--i3n-media);
}
.i3tema-img .i3tema-previa img { max-height: 30px; max-width: 150px; object-fit: contain; }
.i3tema-img input[type="file"] { font-size: 0.78rem; color: var(--i3n-media); max-width: 260px; }
/* "herdada do outro modo": a mesma arte aparecendo nos dois modos não é
   defeito, é herança — dizer isso evita a dúvida de achar que o envio falhou. */
.i3tema-img em[data-heranca] {
  font-style: normal;
  font-size: 0.7rem;
  color: var(--i3n-media);
  opacity: 0.85;
}
.i3tema-img button:disabled { opacity: 0.4; cursor: default; }

.i3tema-acoes {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.1rem 0 0;
}
.i3tema-aviso { flex: 1; font-size: 0.8rem; color: var(--i3n-media); }
.i3tema-padrao[class], .i3tema-salvar[class] {
  height: 38px !important;
  min-height: 0 !important;
  padding: 0 1.1rem !important;
  border-radius: 999px !important;
  cursor: pointer;
  font: 600 0.82rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
}
.i3tema-padrao[class] {
  border: 1px solid var(--i3n-linha) !important;
  background: none !important;
  color: var(--i3n-forte) !important;
}
.i3tema-salvar[class] {
  border: 1px solid var(--i3t-brand-solid, #0052E6) !important;
  background: var(--i3t-brand-solid, #0052E6) !important;
  color: #fff !important;
}

/* ============ §57 — Ícones do mapa: a linha da cor =========================
   Uma linha por tipo, no fim do cartão do pacote (inserção no fim é a única
   segura na árvore do React). A tinta vem do §53 — a tela serve os dois
   modos com uma regra só. */
.i3cor-linha {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.15rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--i3n-linha);
}
.i3cor-linha > span {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--i3n-media);
}
.i3cor-linha input[type="color"] {
  width: 38px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: none;
  cursor: pointer;
}
.i3cor-linha input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
.i3cor-linha input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 6px; }
.i3cor-linha input[type="text"] {
  width: 104px;
  height: 28px;
  padding: 0 0.5rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: var(--i3n-campo);
  color: var(--i3n-forte);
  font: 500 0.75rem/1 var(--i3t-font-mono, ui-monospace, monospace);
}
.i3cor-linha input[type="text"]::placeholder { color: var(--i3n-media); opacity: 0.7; }
/* `[class]` dobra a especificidade para vencer o §51.2, que desenha TODO
   botão dentro do `main` como pílula de 40px com `!important` — o mesmo
   tropeço do §56. */
.i3cor-padrao[class] {
  height: 28px !important;
  min-height: 0 !important;
  padding: 0 0.65rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.7rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
.i3cor-padrao[class]:hover { color: var(--i3n-forte) !important; }
.i3cor-linha em[data-i3cor-aviso] {
  flex: 1 1 100%;
  font-style: normal;
  font-size: 0.7rem;
  color: var(--i3n-media);
}

/* ============ §58 — Treinamentos (/trainings) ==============================
   Pedido do dono, 09/08/2026.

   1. Sai a etiqueta "Academia i3track" que ficava acima do título. Era o
      único elemento CIANO da tela — `border-cyan-300/30` — numa paleta que
      não tem ciano, e repetia em miúdo o que o título já diz em corpo 22.
   2. O botão "Buscar" ficava com a borda azulada de realce
      (`rgba(102,163,255,.4)`) enquanto "Nova trilha" e "Atualizar" usavam a
      borda neutra do sistema. Três botões lado a lado, três contornos
      diferentes. Agora ele é o botão SECUNDÁRIO do §51.2, como os outros; o
      primário da tela continua sendo "Nova trilha".

   O recorte por tela vem do `data-i3t-rota` que o i3track-ui.js carimba no
   `<body>` — sem ele, uma regra sobre classe utilitária do Tailwind valeria
   para o app inteiro. */
body[data-i3t-rota="trainings"] main [class*="border-cyan-300/30"] { display: none !important; }
/* O `[class]` no fim não muda o que casa — muda o PESO. Quem pintava a borda
   azulada era `:root[data-theme] .border-cyan-300\/40` do §12, e `:root` é
   pseudo-classe: conta na coluna das classes, não na dos elementos. Ou seja
   (0,3,0) contra os (0,2,2) que eu tinha, com `!important` dos dois lados.
   Quem contou foi o `CSS.getMatchedStylesForNode` do CDP, que lista a regra
   vencedora por último em vez de deixar a gente adivinhar. */
body[data-i3t-rota="trainings"] main [data-i3t-btn="secundario"][class] {
  border-color: var(--border) !important;
}

/* A caixa "Recortar o fundo automaticamente", na aba Logos. */
.i3tema-opcao {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0 0.5rem;
  margin-top: 0.6rem;
  cursor: pointer;
  max-width: 62ch;
}
.i3tema-opcao input { width: 15px; height: 15px; accent-color: var(--i3t-brand-solid, #0052E6); cursor: pointer; }
.i3tema-opcao span { font-size: 0.8rem; color: var(--i3n-forte); }
.i3tema-opcao small { grid-column: 2; font-size: 0.72rem; color: var(--i3n-media); opacity: 0.85; }

/* ============ §59 — a marquinha do cartão de entrada =======================
   Ao lado de "Acesse o <plataforma>" o pacote desenha um <span> com o símbolo
   da i3track. Numa revenda isso é a marca do fornecedor colada no nome do
   cliente, na primeira tela que ele vê.

   POR QUE ISTO É CSS E NÃO `style` no elemento. Foi feito primeiro escrevendo
   `backgroundImage` direto no <span> — e MEDIU-SE que não para em pé: o React
   redesenha o cabeçalho e reescreve o `background-image` dele (volta para
   `/assets/loader-icon.png`), enquanto o `display` que ninguém disputa
   sobrevive. O observador do login vigia `childList`, não atributo, então não
   havia como revidar. Aqui a decisão sai do nó disputado e sobe para o
   <html>: o script só marca `data-i3login-marca` e a variável `--i3login-marca`
   na raiz, que o React nunca toca, e o `!important` fecha a questão. */
html[data-i3login-marca="simbolo"] .eagle-brand-row .eagle-sprite--mark {
  background-image: var(--i3login-marca) !important;
  background-position: center !important;
  background-size: contain !important;
  background-repeat: no-repeat !important;
}
/* Só logo própria: a marquinha some. Espaço vazio é melhor do que marca alheia. */
html[data-i3login-marca="oculto"] .eagle-brand-row .eagle-sprite--mark {
  display: none !important;
}

/* ============ §60 — o diálogo do sistema veste a plataforma ================
   `i3track-dialogo.js` é o `confirm()` do painel, e o botão principal dele
   nasceu com azul cravado (`rgba(37,99,235,…)` / `#66A3FF`) — numa revenda de
   marca verde, a pergunta aparecia azul no meio da tela verde.

   Só o botão PRINCIPAL segue a marca. O de PERIGO continua vermelho: vermelho
   ali é estado, não identidade — a mesma regra do badge de tabela (§54.3).
   Pintar "apagar tudo" com a cor da revenda seria trocar um aviso por uma
   decoração.

   Sem `!important`: `:root[data-i3tema] .i3dlg-b.primario` é (0,3,0) contra
   (0,2,0) da regra original, e vem depois no arquivo. */
:root[data-i3tema] .i3dlg-b.primario {
  background: color-mix(in srgb, var(--i3tema-marca, #0052E6) 16%, transparent);
  border-color: color-mix(in srgb, var(--i3tema-marca, #0052E6) 50%, transparent);
  color: color-mix(in srgb, var(--i3tema-marca, #0052E6) 72%, #fff);
}
:root[data-i3tema] .i3dlg-b.primario:hover {
  border-color: var(--i3tema-marca, #0052E6);
}
/* No modo claro o mesmo tom clareado some no fundo branco: aqui a letra é a
   cor cheia da marca, como o §51.2 já faz com os botões da tela. */
:root[data-theme="light"][data-i3tema] .i3dlg-b.primario {
  background: color-mix(in srgb, var(--i3tema-marca, #0052E6) 10%, transparent);
  color: var(--i3tema-marca, #0052E6);
}

/* ============ §61 — SENSORES: a aba do veículo e a do equipamento =========
   A aba é anexada no fim da barra do React, então ela precisa parecer as
   outras sem herdar classe nenhuma delas: o desenho é feito aqui, e o §51.2
   (que pinta todo botão dentro de `main` como pílula de 40px) é vencido com
   `[data-i3sens-aba]`, que só existe neste botão. */
.i3sens-aba[data-i3sens-aba] {
  appearance: none;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14));
  background: transparent;
  color: var(--i3n-media, rgba(255,255,255,.7));
  border-radius: 10px;
  padding: 7px 14px;
  font-size: .82rem;
  font-weight: 600;
  height: auto;
  cursor: pointer;
}
.i3sens-aba[data-i3sens-aba]:hover { color: var(--i3n-forte, #fff); border-color: var(--primary, #0052E6); }
.i3sens-aba[data-i3sens-aba][data-ativo="1"] {
  background: color-mix(in srgb, var(--primary, #0052E6) 16%, transparent);
  border-color: var(--primary, #0052E6);
  color: var(--i3n-forte, #fff);
}
/* O painel do pacote sai de cena enquanto a nossa aba está aberta — escondido,
   nunca removido: é nó do React. */
[data-i3sens-oculto="1"] { display: none !important; }

.i3sens { display: block; padding: 4px 0 24px; }
/* `display:block` numa classe VENCE o `[hidden]` do navegador, que é só
   `display:none` sem peso nenhum. Sem esta linha o painel nunca sumia: clicar
   numa aba do pacote reexibia a dele e a nossa continuava embaixo, as duas
   juntas na tela. Medido — voltar de Sensores para Geral não voltava. */
.i3sens[hidden] { display: none !important; }
.i3sens-topo { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin: 8px 0 18px; }
.i3sens-topo h3 { margin: 0 0 4px; font-size: 1rem; color: var(--i3n-forte, #fff); }
.i3sens-topo p { margin: 0; font-size: .82rem; line-height: 1.5; color: var(--i3n-media, rgba(255,255,255,.65)); max-width: 68ch; }
.i3sens-novo {
  flex: none; border: 1px solid var(--primary, #0052E6); border-radius: 10px;
  background: color-mix(in srgb, var(--primary, #0052E6) 16%, transparent);
  color: var(--i3n-forte, #fff); padding: 8px 14px; font-size: .82rem; font-weight: 600; cursor: pointer;
}
.i3sens-recado {
  margin: 0 0 14px; padding: 9px 12px; border-radius: 9px; font-size: .8rem;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14));
  background: var(--i3n-hover, rgba(255,255,255,.04)); color: var(--i3n-forte, #fff);
}
.i3sens-nada, .i3sens-nota {
  margin: 10px 0 0; font-size: .82rem; line-height: 1.55;
  color: var(--i3n-media, rgba(255,255,255,.6)); max-width: 74ch;
}

.i3sens-form {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px;
  align-items: start; margin: 0 0 18px; padding: 16px;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14)); border-radius: 12px;
  background: var(--i3n-hover, rgba(255,255,255,.03));
}
.i3sens-form label { display: grid; gap: 6px; }
.i3sens-form label > span { font-size: .72rem; letter-spacing: .04em; text-transform: uppercase; color: var(--i3n-media, rgba(255,255,255,.6)); }
.i3sens-form small { font-size: .72rem; line-height: 1.45; color: var(--i3n-media, rgba(255,255,255,.5)); }
.i3sens-form-acoes { display: flex; gap: 8px; align-self: end; }
.i3sens-form-acoes button, .i3sens-acoes button {
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.16)); border-radius: 9px;
  background: transparent; color: var(--i3n-forte, #fff);
  padding: 7px 12px; font-size: .78rem; font-weight: 600; cursor: pointer; height: auto;
}
.i3sens-form-acoes button[data-confirma] { border-color: var(--primary, #0052E6); background: color-mix(in srgb, var(--primary, #0052E6) 16%, transparent); }
.i3sens-form-acoes button:disabled { opacity: .45; cursor: not-allowed; }

.i3sens input[type="text"], .i3sens select {
  width: 100%; box-sizing: border-box;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.16)); border-radius: 9px;
  background: var(--i3n-campo, rgba(255,255,255,.05)); color: var(--i3n-forte, #fff);
  padding: 8px 10px; font-size: .82rem; height: auto;
}
.i3sens input[type="text"]:focus, .i3sens select:focus { outline: none; border-color: var(--primary, #0052E6); }

.i3sens-tab { width: 100%; border-collapse: collapse; font-size: .82rem; }
.i3sens-tab th {
  text-align: left; font-size: .7rem; letter-spacing: .05em; text-transform: uppercase; font-weight: 600;
  color: var(--i3n-media, rgba(255,255,255,.55));
  padding: 0 12px 8px 0; border-bottom: 1px solid var(--i3n-linha, rgba(255,255,255,.12));
}
.i3sens-tab td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--i3n-linha, rgba(255,255,255,.08)); color: var(--i3n-forte, #fff); vertical-align: middle; }
.i3sens-tab code { font-size: .78rem; padding: 2px 7px; border-radius: 6px; background: var(--i3n-hover, rgba(255,255,255,.07)); }
.i3sens-vazio { color: var(--i3n-media, rgba(255,255,255,.45)); font-style: normal; }
.i3sens-acoes { text-align: right; white-space: nowrap; }
.i3sens-acoes button + button { margin-left: 6px; }
.i3sens-eu td { background: color-mix(in srgb, var(--primary, #0052E6) 8%, transparent); }
.i3sens-eu span { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--primary, #0052E6); }

/* §61.1 — a busca do equipamento no vínculo do sensor.
   Era um `<select>`: numa conta com centenas de aparelhos, escolher por
   rolagem é procurar agulha. Vira busca, como "Buscar chip" e "Buscar modelo"
   já fazem no resto do sistema. */
.i3sens-achados {
  display: grid; gap: 4px; margin-top: 6px;
  max-height: 220px; overflow-y: auto;
}
/* Sem busca digitada não há lista — e caixa vazia não deve reservar espaço. */
.i3sens-achados:empty { display: none; margin: 0; }
.i3sens-achado {
  display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
  border: 1px solid transparent; border-radius: 8px;
  background: transparent; color: var(--i3n-forte, #fff);
  padding: 7px 9px; font-size: .8rem; cursor: pointer; height: auto;
}
.i3sens-achado:hover, .i3sens-achado:focus-visible {
  background: var(--i3n-hover, rgba(255,255,255,.06));
  border-color: color-mix(in srgb, var(--primary, #0052E6) 45%, transparent);
  outline: none;
}
.i3sens-achado b { font-weight: 600; }
.i3sens-achado span { font-size: .72rem; color: var(--i3n-media, rgba(255,255,255,.55)); }
.i3sens-achados .i3sens-vazio { padding: 7px 9px; font-size: .78rem; }

/* Escolhido: some a busca e fica o aparelho, com saída para trocar. */
.i3sens-escolhido {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  border: 1px solid color-mix(in srgb, var(--primary, #0052E6) 45%, transparent);
  border-radius: 9px; padding: 8px 10px;
  background: color-mix(in srgb, var(--primary, #0052E6) 10%, transparent);
}
.i3sens-escolhido b { font-size: .84rem; color: var(--i3n-forte, #fff); }
.i3sens-escolhido span { font-size: .72rem; color: var(--i3n-media, rgba(255,255,255,.6)); }
.i3sens-escolhido button {
  margin-left: auto; border: 1px solid var(--i3n-linha, rgba(255,255,255,.18));
  border-radius: 8px; background: transparent; color: var(--i3n-forte, #fff);
  padding: 5px 10px; font-size: .74rem; font-weight: 600; cursor: pointer; height: auto;
}


/* ============ §62 — ENTREGAS COM DESENHO PRÓPRIO ==========================

   O módulo de Entregas veio pronto de outro fornecedor e trouxe o desenho
   dele: painel de vidro sobre `bg-white/5`, contorno em `border-white/10`,
   número em `text-white`, rótulo em `text-white/70` e um mapa com fundo de
   gradiente radial escuro cravado no JSX. Nada disso lê os tokens da
   plataforma, então a área inteira ignorava o tema escolhido pela revenda em
   Temas — e, no claro, o mapa continuava preto.

   Uma limpeza anterior tirou parte daquilo e não pôs nada no lugar: quando
   esta seção foi escrita, `.delivery-main-panel` estava com fundo TRANSPARENTE,
   raio 0 e contorno na cor do tema claro dentro do tema escuro. O resultado
   era pior que o desenho do fornecedor: painéis sem corpo, mapa sem base.

   O QUE ESTA SEÇÃO FAZ
   --------------------
   Dá a Entregas uma identidade que é da casa e não é a de ninguém mais:

     - painel com corpo (`--surface-card`), contorno de 1px e canto de 16px,
       sem sombra — o mesmo peso visual das outras áreas;
     - cabeçalho de painel com um traço vertical na cor da marca antes do
       rótulo, no lugar do título solto sobre a linha;
     - abas como controle segmentado sobre trilho, e não como pílulas soltas;
     - base do mapa em malha técnica desenhada com os próprios tokens, que
       funciona no claro e no escuro em vez de ser um retângulo preto.

   Os cartões de indicador NÃO são mexidos aqui: eles já são reconhecidos pela
   etiquetagem de `i3track-ui.js` e vestem o §36. O que sobra deles é a cor
   cravada no texto, e é só isso que esta seção desfaz.
   ------------------------------------------------------------------------- */

/* --- painéis ------------------------------------------------------------- */

main .deliveries-page .delivery-main-panel {
  background: var(--surface-card, #242424) !important;
  background-image: none !important;
  border: 1px solid var(--border, #353535) !important;
  border-radius: var(--i3t-radius-lg, 16px) !important;
  box-shadow: none !important;
  padding: var(--i3t-space-4, 16px) !important;
}

/* O cabeçalho do painel ganha o traço da marca. `::before` não cria nó no DOM
   — o React continua dono de tudo que está dentro. */
main .deliveries-page .delivery-main-panel-header,
main .deliveries-page .delivery-main-map-header {
  position: relative !important;
  margin: 0 0 var(--i3t-space-3, 12px) !important;
  padding: 0 0 var(--i3t-space-3, 12px) 12px !important;
  border-bottom: 1px solid var(--border, #353535) !important;
}

/* O fornecedor pôs `border-b` também nos DOIS filhos do cabeçalho (o rótulo à
   esquerda e a contagem à direita). Com a linha do cabeçalho, viravam três
   sublinhados: um contínuo e dois pedaços soltos, um debaixo de cada texto.
   Some com os pedaços e fica a linha inteira. */
main .deliveries-page .delivery-main-panel-header *,
main .deliveries-page .delivery-main-map-header * {
  border-bottom: 0 !important;
  padding-bottom: 0 !important;
}

main .deliveries-page .delivery-main-panel-header::before,
main .deliveries-page .delivery-main-map-header::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  bottom: calc(var(--i3t-space-3, 12px) + 2px);
  width: 3px;
  border-radius: 3px;
  background: var(--primary, #0052E6);
}

/* --- abas como controle segmentado --------------------------------------- */

/* O contêiner das abas vira trilho. É o irmão que segura os botões
   `.delivery-main-tab`; `:has()` evita depender da classe utilitária que o
   empacotador gera. */
main .deliveries-page div:has(> .delivery-main-tab) {
  background: var(--surface-2, #242424) !important;
  border: 1px solid var(--border, #353535) !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  padding: 4px !important;
  gap: 2px !important;
  width: fit-content;
  max-width: 100%;
}

main .deliveries-page .delivery-main-tab {
  border: 0 !important;
  border-radius: var(--i3t-radius-pill, 999px) !important;
  background: transparent !important;
  color: var(--sub, #A1A1A1) !important;
  height: 34px !important;
  padding: 0 16px !important;
  font-family: var(--i3t-font-body, inherit) !important;
  font-size: .8125rem !important;
  font-weight: 600 !important;
  box-shadow: none !important;
  transition: background-color .16s ease, color .16s ease;
}

main .deliveries-page .delivery-main-tab:hover {
  background: var(--field-bg-hover, rgba(255,255,255,.06)) !important;
  color: var(--text, #F7F7F7) !important;
}

/* A aba ativa é a única com fundo cheio.
   O empacotador NÃO marca o estado com `aria-selected` nem com `data-state`:
   ele troca as classes utilitárias. A aba inativa nasce com
   `border-transparent`; a ativa, com um contorno colorido. Por isso a régua é
   a AUSÊNCIA de `border-transparent`, que sobrevive a uma troca de paleta —
   e não o nome da cor, que não sobreviveria.
   Os dois primeiros seletores ficam para o dia em que o componente passar a
   declarar o estado direito. */
main .deliveries-page .delivery-main-tab[aria-selected="true"],
main .deliveries-page .delivery-main-tab[data-state="active"],
main .deliveries-page .delivery-main-tab:not([class*="border-transparent"]) {
  background: var(--primary, #0052E6) !important;
  color: #fff !important;
  border: 0 !important;
}

/* A cor cravada do texto da aba ativa (`text-sky-100`) perde para a linha
   acima; esta regra fecha o caso em que o §12 repinta a utilitária depois. */
main .deliveries-page .delivery-main-tab:not([class*="border-transparent"]) * {
  color: #fff !important;
}

/* --- base do mapa -------------------------------------------------------- */

/* Malha técnica em vez do gradiente preto cravado: as linhas saem do token de
   contorno, então ela clareia junto com o tema em vez de virar um buraco
   escuro no meio de uma tela clara. */
main .deliveries-page .delivery-main-map-shell {
  background-color: var(--surface-2, #242424) !important;
  background-image:
    repeating-linear-gradient(0deg, var(--border, #353535) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(90deg, var(--border, #353535) 0 1px, transparent 1px 40px) !important;
  background-size: 40px 40px !important;
  border: 1px solid var(--border, #353535) !important;
  border-radius: var(--i3t-radius-lg, 16px) !important;
  box-shadow: none !important;
}

/* O mapa de verdade, quando carrega, cobre a malha. Sem isto a malha
   apareceria por baixo dos ladrilhos com transparência. */
main .deliveries-page .delivery-main-map-shell .leaflet-container,
main .deliveries-page .delivery-main-map-shell .mapboxgl-map {
  background: var(--surface-2, #242424) !important;
  border-radius: calc(var(--i3t-radius-lg, 16px) - 1px) !important;
}

/* --- cor cravada nos indicadores ----------------------------------------- */

/* O acento colorido do cartão já diz posição (§36). A cor no NÚMERO era a
   régua do fornecedor para dizer estado, e competia com o acento: dois canais
   dizendo coisas diferentes com a mesma linguagem. Fica o acento; o número
   volta para a cor de texto. */
main .deliveries-page .delivery-main-metric-value {
  color: var(--text, #F7F7F7) !important;
  font-family: var(--i3t-font-display, inherit) !important;
}

main .deliveries-page .delivery-main-metric-label {
  color: var(--sub, #A1A1A1) !important;
}

/* --- paginação e rodapés ------------------------------------------------- */

main .deliveries-page .delivery-main-pagination {
  color: var(--sub, #A1A1A1) !important;
  border-top: 1px solid var(--border, #353535) !important;
  padding-top: var(--i3t-space-3, 12px) !important;
}

/* --- o que o fornecedor pintou de branco --------------------------------- */

/* Varredura final: qualquer resto de `border-white/10` e `bg-white/5` dentro
   de Entregas passa a ler o token. Sem isto, cada painel novo que o
   empacotador gerar volta a nascer com vidro branco por cima do tema. */
main .deliveries-page [class*="border-white/"] {
  border-color: var(--border, #353535) !important;
}

main .deliveries-page [class*="bg-white/"]:not(.delivery-main-metric) {
  background-color: var(--surface-2, #242424) !important;
}

main .deliveries-page [class*="text-white/"] {
  color: var(--sub, #A1A1A1) !important;
}

/* ============================================================
   §63 — ÁRVORE DE PERMISSÕES NO FORMATO DO MENU
   ------------------------------------------------------------
   A árvore que o pacote desenha fica escondida por `style.display:none`
   (aplicado pelo i3track-perms.js) e esta é a que aparece. Ela reaproveita as
   classes do pacote nos quadros e nas linhas, então herda o desenho da gaveta
   de graça; o que falta são as partes que não existiam lá: a nota de "linha sem
   chave", o recuo dos submenus e o cabeçalho da árvore.
   ============================================================ */
main #i3ap-raiz .i3ap-topo {
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--i3t-radius-lg, 12px);
  background: var(--surface-2);
  padding: 12px 14px;
}
main #i3ap-raiz .i3ap-titulo {
  font: var(--i3t-font-titulo, 600 14px/1.3 Inter, system-ui, sans-serif);
  color: var(--text);
  margin: 0;
}
main #i3ap-raiz .i3ap-sub,
main #i3ap-raiz .i3ap-aviso { font-size: 12px; line-height: 1.45; margin: 4px 0 0; }
main #i3ap-raiz .i3ap-sub { color: var(--sub); }
main #i3ap-raiz .i3ap-aviso { color: var(--i3t-warning, #d97706); }

/* Nome da seção com a mesma barra de destaque dos painéis (§62). */
main #i3ap-raiz .i3ap-secao > div:first-child > div:first-child {
  position: relative;
  padding-left: 10px;
}
main #i3ap-raiz .i3ap-secao > div:first-child > div:first-child::before {
  content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 3px; height: 14px; border-radius: 2px; background: var(--primary);
}

/* Submenu recuado e com um fio à esquerda: fica claro que ele depende da linha
   de cima, e não é mais uma tela solta do menu. */
main #i3ap-raiz .i3ap-filhos {
  margin: 6px 0 0 18px;
  padding-left: 12px;
  border-left: 1px solid var(--stroke);
}
main #i3ap-raiz .i3ap-linha.i3ap-filho { padding: 8px 10px; }

/* A nota explica POR QUE a linha não tem interruptor. Sem ela a linha parecia
   defeito da tela. */
main #i3ap-raiz .i3ap-nota {
  margin: 3px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--sub);
  max-width: 52ch;
}
main #i3ap-raiz .i3ap-semchave {
  color: var(--sub);
  border: 1px dashed var(--stroke);
  border-radius: var(--i3t-radius-pill, 999px);
  padding: 2px 10px;
  white-space: nowrap;
}

/* ============================================================
   §64 — COR DO ESTADO DE CONEXÃO
   ------------------------------------------------------------
   O pacote pinta a pastilha pela régua dele (5 min para Online). Quando o
   i3track-conexao.js troca a palavra pela régua do sistema (1h10), a cor
   antiga fica: "Online" saía laranja de alerta, e texto dizendo uma coisa com
   cor dizendo outra é pior que o erro original — o olho acredita na cor.
   `data-i3conexao` é posto no MESMO elemento do texto, então basta pintar ele.
   ============================================================ */
main [data-i3conexao] { font-weight: 600; }
main [data-i3conexao="online"] { color: var(--i3t-success, #16a34a) !important; }
main [data-i3conexao="offline"] { color: var(--i3t-danger, #dc2626) !important; }
main [data-i3conexao="nunca"] { color: var(--sub) !important; }

/* A pastilha do pacote também carrega fundo e borda próprios. Quando o
   elemento do texto é o próprio badge, o fundo tem de acompanhar. */
main [data-i3conexao="online"][class*="bg-"] {
  background: color-mix(in srgb, var(--i3t-success, #16a34a) 14%, transparent) !important;
  border-color: color-mix(in srgb, var(--i3t-success, #16a34a) 38%, transparent) !important;
}
main [data-i3conexao="offline"][class*="bg-"] {
  background: color-mix(in srgb, var(--i3t-danger, #dc2626) 14%, transparent) !important;
  border-color: color-mix(in srgb, var(--i3t-danger, #dc2626) 38%, transparent) !important;
}
main [data-i3conexao="nunca"][class*="bg-"] {
  background: var(--surface-2) !important;
  border-color: var(--stroke) !important;
}

/* A faixa do meio: falou hoje, mas não agora. Nem verde de "tudo certo", nem
   vermelho de "caiu" — âmbar, que é o que ela é: observar. (§64) */
main [data-i3conexao="sem-sinal"] { color: var(--i3t-warning, #d97706) !important; }
main [data-i3conexao="sem-sinal"][class*="bg-"] {
  background: color-mix(in srgb, var(--i3t-warning, #d97706) 14%, transparent) !important;
  border-color: color-mix(in srgb, var(--i3t-warning, #d97706) 38%, transparent) !important;
}

/* A ficha do equipamento pinta o valor com `body.i3veic .i3v-val{color:… !important}`
   — especificidade maior que a do §64. Sem esta linha o Status trocava de
   palavra e continuava cinza, e o operador acredita na cor antes da palavra. */
body.i3veic .i3v-val[data-i3conexao="online"] { color: var(--i3t-success, #16a34a) !important; }
body.i3veic .i3v-val[data-i3conexao="sem-sinal"] { color: var(--i3t-warning, #d97706) !important; }
body.i3veic .i3v-val[data-i3conexao="offline"] { color: var(--i3t-danger, #dc2626) !important; }
body.i3veic .i3v-val[data-i3conexao="nunca"] { color: var(--sub) !important; }

/* ============ §96 — TRANSFERIR EQUIPAMENTO ENTRE PLATAFORMAS ==============
   A aba nova em /devices/:id/edit. Mesmo desenho da aba de Sensores (§61) e
   pelo mesmo motivo: ela é anexada no fim da barra do React sem herdar classe
   nenhuma, então a aparência é feita aqui — e o §51.2, que pinta todo botão
   dentro de `main` como pílula de 40px, é vencido pelo atributo
   `[data-i3transf-aba]`, que só existe neste botão.
   -------------------------------------------------------------------------- */
.i3transf-aba[data-i3transf-aba] {
  appearance: none;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14));
  background: transparent;
  color: var(--i3n-media, rgba(255,255,255,.7));
  border-radius: 10px;
  padding: 7px 14px;
  font-size: .82rem;
  font-weight: 600;
  height: auto;
  cursor: pointer;
}
.i3transf-aba[data-i3transf-aba]:hover { color: var(--i3n-forte, #fff); border-color: var(--primary, #0052E6); }
.i3transf-aba[data-i3transf-aba][data-ativo="1"] {
  background: color-mix(in srgb, var(--primary, #0052E6) 16%, transparent);
  border-color: var(--primary, #0052E6);
  color: var(--i3n-forte, #fff);
}
[data-i3transf-oculto="1"] { display: none !important; }

/* `display:block` numa classe VENCE o `[hidden]` do navegador, que é só
   `display:none` sem peso nenhum — sem isto o painel nunca sumiria ao voltar
   para uma aba do pacote, e as duas ficariam na tela juntas (medido no §61). */
.i3transf { display: block; padding: 4px 0 24px; max-width: 720px; }
.i3transf[hidden] { display: none; }

.i3transf-topo h3 { margin: 0 0 6px; font-size: 1rem; color: var(--i3n-forte, #fff); }
.i3transf-nota { margin: 0 0 18px; font-size: .85rem; line-height: 1.5; color: var(--i3n-media, rgba(255,255,255,.7)); }
.i3transf-vazio { margin-top: 12px; }

.i3transf-cartao {
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14));
  border-radius: 12px;
  padding: 4px 16px;
  margin-bottom: 18px;
}
.i3transf-linha {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  font-size: .86rem;
  border-bottom: 1px solid var(--i3n-linha, rgba(255,255,255,.08));
}
.i3transf-linha:last-child { border-bottom: 0; }
.i3transf-linha span { color: var(--i3n-media, rgba(255,255,255,.7)); }
.i3transf-linha b { color: var(--i3n-forte, #fff); font-weight: 600; text-align: right; }

.i3transf-campo { display: block; margin-bottom: 16px; }
.i3transf-campo span {
  display: block;
  margin-bottom: 6px;
  font-size: .8rem;
  font-weight: 600;
  color: var(--i3n-media, rgba(255,255,255,.7));
}
.i3transf-campo select {
  width: 100%;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--i3n-linha, rgba(255,255,255,.14));
  background: var(--i3n-fundo2, rgba(255,255,255,.04));
  color: var(--i3n-forte, #fff);
  font-size: .88rem;
}

/* Os avisos são o que NÃO vai junto. Ficam antes do botão de propósito: quem
   descobre depois que o chip ficou para trás descobriu tarde. */
.i3transf-avisos {
  margin: 0 0 20px;
  padding-left: 18px;
  font-size: .82rem;
  line-height: 1.6;
  color: var(--i3n-media, rgba(255,255,255,.7));
}
.i3transf-avisos b { color: var(--i3n-forte, #fff); }

.i3transf-acoes { display: flex; gap: 10px; }
.i3transf-ok[data-i3transf-enviar], .i3transf-ok[data-i3transf-voltar] {
  appearance: none;
  border: 0;
  border-radius: 10px;
  padding: 10px 20px;
  font-size: .86rem;
  font-weight: 600;
  color: #fff;
  background: var(--primary, #0052E6);
  cursor: pointer;
  height: auto;
}
.i3transf-ok[disabled] { opacity: .45; cursor: not-allowed; }

.i3transf-erro {
  margin: 14px 0 0;
  font-size: .84rem;
  color: var(--i3t-danger, #dc2626);
}

/* --- 96.1 — O AVISO FLUTUANTE (o mesmo de todo erro do sistema) -----------
   Medido em 13/08/2026 na recusa de IMEI já cadastrado em outra plataforma: a
   caixa vinha com `bg-red-500/20` na classe e `rgba(0,0,0,0)` de verdade — uma
   das regras que repintam utilitária com `!important` apagava o fundo — e com
   1187px de largura, porque nada limitava. O resultado era o texto atravessar o
   título da tela e os botões Cancelar/Salvar, legível pela metade.

   Aviso que não se lê não avisa.

   A GEOMETRIA vale para qualquer cor, inclusive uma que venha a existir depois.
   O FUNDO é escrito só para o vermelho porque, conferido no bundle por busca
   literal, `bg-red-500/20` é a ÚNICA variante deste aviso — não existe versão de
   sucesso nem de alerta. Regra para variante que não existe é uma afirmação
   falsa sobre a tela, deixada no arquivo para o próximo leitor tropeçar.
   -------------------------------------------------------------------------- */
[class*="z-\[12000\]"].fixed {
  width: max-content !important;
  max-width: min(560px, calc(100vw - 32px)) !important;
  white-space: normal !important;
  line-height: 1.45 !important;
  backdrop-filter: blur(6px);
}
[class*="z-\[12000\]"].fixed[class*="bg-red-"] {
  background-color: #7f1d1d !important;
  border-color: rgba(239, 68, 68, .55) !important;
  color: #fee2e2 !important;
}

/* ============ §97 — O ícone do tipo no mapa =================================
   Pedido do dono, 15/08/2026: "a cor do próprio ícone mesmo... o utilitário
   quando tá com a ig ligada ele fica cinza, não muda igual o do carro".

   O anel do marcador sempre mudou de cor com a ignição; o desenho de dentro,
   não — e a diferença entre um tipo e outro não era escolha nenhuma, era o
   FORMATO em que o desenho chegava. Quem caía no desenho embutido da tela
   (feito com `currentColor`) ficava verde; quem tinha um arquivo `.svg`
   virava `<img>`, e `<img>` não obedece cor: o cinza `#7C8899` está escrito
   dentro do arquivo.

   `mask` resolve sem buscar o arquivo e sem mexer no DOM depois: o desenho
   entra como MOLDE e quem pinta é `background-color: currentColor`. Vale para
   os 40 desenhos de fábrica de uma vez.

   Foto enviada pelo usuário continua `<img>` de propósito (arte dele, não
   molde), e emoji continua emoji — figura colorida não veste cor de estado. */
.i3-marca .glifo.molde {
  display: block;
  background-color: currentColor;
  -webkit-mask: var(--i3molde) center / contain no-repeat;
  mask: var(--i3molde) center / contain no-repeat;
}

/* As duas cores de ignição passam a ser da PLATAFORMA (peças `igLigada` e
   `igDesligada` do tema, como `marca` e `sidebar`). Sem tema escolhido, os
   valores de fábrica são os mesmos de antes — nada muda para quem não mexeu.
   O `box-shadow` sai duas vezes: a primeira linha é o que todo navegador
   entende, a segunda só vale onde `color-mix` existe. */
.i3-marca[data-estado="ligada"] { color: var(--i3tema-igLigada, #22C55E); }
.i3-marca[data-estado="desligada"] { color: var(--i3tema-igDesligada, #EF4444); }
.i3-marca[data-estado="ligada"] .anel {
  border-color: var(--i3tema-igLigada, #22C55E);
  box-shadow: 0 0 0 3px rgba(34, 197, 94, .22);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--i3tema-igLigada, #22C55E) 22%, transparent);
}
.i3-marca[data-estado="desligada"] .anel {
  border-color: var(--i3tema-igDesligada, #EF4444);
  box-shadow: 0 0 0 3px rgba(239, 68, 68, .20);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--i3tema-igDesligada, #EF4444) 20%, transparent);
}

/* ---- §97.1 — a faixa das duas cores, em Configurações › Ícones do mapa ----
   Fica ao lado de "Salvar ícones", que é onde a pessoa já está quando pensa
   no assunto. Grava sozinha ao escolher: são duas cores, não vale um segundo
   botão de salvar ao lado de um botão de salvar. */
.i3est-faixa {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin: 0.9rem 0 0;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 14px;
  background: var(--i3n-campo);
}
.i3est-faixa > h4 {
  margin: 0;
  font: 600 0.78rem/1.3 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-forte);
}
.i3est-faixa > h4 small {
  display: block;
  font-weight: 400;
  font-size: 0.7rem;
  color: var(--i3n-media);
}
.i3est-par { display: flex; align-items: center; gap: 0.45rem; }
.i3est-par > label {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--i3n-media);
}
.i3est-par input[type="color"] {
  width: 38px; height: 28px; padding: 0;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: none;
  cursor: pointer;
}
.i3est-par input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
.i3est-par input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 6px; }
.i3est-par input[type="text"] {
  width: 96px; height: 28px; padding: 0 0.5rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 8px;
  background: var(--i3n-fundo);
  color: var(--i3n-forte);
  font: 500 0.75rem/1 var(--i3t-font-mono, ui-monospace, monospace);
}
/* a prévia usa o MESMO desenho do mapa (`.i3-marca`), em miniatura */
.i3est-previa { display: flex; align-items: center; gap: 0.6rem; margin-left: auto; }
.i3est-previa .i3-marca { position: relative; }
.i3est-aviso {
  flex: 1 1 100%;
  margin: 0;
  font-size: 0.7rem;
  color: var(--i3n-media);
}
/* `[class]` dobra a especificidade contra o §51.2, que faz de TODO botão
   dentro do `main` uma pílula de 40px com `!important`. */
.i3est-padrao[class] {
  height: 28px !important;
  min-height: 0 !important;
  padding: 0 0.7rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.7rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-media) !important;
}
.i3est-padrao[class]:hover { color: var(--i3n-forte) !important; }

/* ---- §97.2 — o botão "Observação" e o que ele abre ------------------------
   A receita do ícone novo. Vai ao lado de "Salvar ícones" porque é ali que a
   dúvida aparece: a pessoa acabou de mandar um PNG de 1024px com fundo branco
   e vai descobrir no mapa que ficou um quadrado. */
.i3obs-b[class] {
  height: 40px;
  min-height: 0;
  padding: 0 1rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 999px;
  background: none;
  cursor: pointer;
  font: 600 0.8rem/1 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-forte);
}
.i3obs-b[class]:hover { border-color: var(--i3t-brand-solid, #0052E6); }
/* O corpo rola, não o diálogo: com o texto inteiro solto o painel passava de
   980px de altura e o título saía por cima da tela. Rolando aqui, título e
   botão ficam sempre visíveis. */
.i3obs-corpo {
  display: grid;
  gap: 0.9rem;
  margin: 0.2rem 0 0.4rem;
  max-height: 58vh;
  overflow-y: auto;
  padding-right: 0.35rem;
}
.i3obs-corpo h3 {
  margin: 0 0 0.3rem;
  font: 600 0.82rem/1.3 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-forte);
}
.i3obs-corpo ul { margin: 0; padding-left: 1.05rem; display: grid; gap: 0.28rem; }
.i3obs-corpo li { font-size: 0.8rem; line-height: 1.45; color: var(--i3n-media); }
.i3obs-corpo li b { color: var(--i3n-forte); font-weight: 600; }
.i3obs-prompt {
  margin: 0;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 10px;
  background: var(--i3n-campo);
  color: var(--i3n-forte);
  font: 400 0.74rem/1.5 var(--i3t-font-mono, ui-monospace, monospace);
  white-space: pre-wrap;
}
.i3obs-copiar[class] {
  justify-self: start;
  height: 30px !important;
  min-height: 0 !important;
  padding: 0 0.8rem !important;
  border: 1px solid var(--i3n-linha) !important;
  border-radius: 999px !important;
  background: none !important;
  cursor: pointer;
  font: 600 0.72rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
  color: var(--i3n-forte) !important;
}

/* ---- §97.3 — a cor de ignição DESTE tipo, dentro do cartão ----------------
   Pedido do dono, 15/08/2026: as duas cores também em cada ícone, "quando
   tiver como mudar; ícone que não, não precisa".

   Só existe no tipo cujo desenho é molde (`/assets/tipos/*.svg`). Em emoji e
   em foto a linha some — ali a cor é da figura, não do sistema, e um seletor
   que não muda nada na tela é pior do que seletor nenhum. */
.i3est-tipo {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-top: 0.15rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--i3n-linha);
}
.i3est-tipo > span {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--i3n-media);
}
.i3est-tipo .i3est-par > label { font-size: 0.7rem; }
.i3est-tipo .i3est-previa { gap: 0.4rem; }
.i3est-tipo em[data-i3est-tipo-aviso] {
  flex: 1 1 100%;
  font-style: normal;
  font-size: 0.7rem;
  color: var(--i3n-media);
}

/* ============ §98 — O aviso de progresso ===================================
   Pedido do dono, 15/08/2026. O recado do pacote fica numa caixa em fluxo
   normal, medida a 885px do topo, no meio de uma lista de 40 tipos: quem não
   rola não vê. Dois arquivos enviados por ele nesse dia ficaram no disco e
   fora da configuração exatamente por isso.

   Fica no ALTO e no meio, porque é onde o olho já está depois de clicar, e
   acima de tudo (o aviso do pacote é `z-[12000]`). Não é modal: não trava a
   tela nem escurece o fundo — o trabalho continua atrás dele. */
.i3prog {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translate(-50%, -14px);
  z-index: 12100;
  width: min(460px, calc(100vw - 32px));
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.i3prog.aberto { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.i3prog-painel {
  padding: 0.85rem 1rem 0.9rem;
  border: 1px solid var(--i3n-linha);
  border-radius: 14px;
  background: var(--i3n-cartao, #11161f);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .45);
  backdrop-filter: blur(8px);
}
.i3prog-topo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.i3prog-topo strong {
  font: 600 0.86rem/1.3 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-forte);
}
.i3prog-pct {
  font: 600 0.78rem/1 var(--i3t-font-mono, ui-monospace, monospace);
  color: var(--i3n-media);
  font-variant-numeric: tabular-nums;
}
.i3prog-barra {
  margin: 0.6rem 0 0.55rem;
  height: 6px;
  border-radius: 999px;
  background: rgba(148, 163, 184, .22);
  overflow: hidden;
}
.i3prog-barra > i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--i3t-brand-solid, #0052E6);
  transition: width .2s ease;
}
/* A fase sem número: o servidor está tirando o fundo e não há o que medir.
   Listra andando diz "estou vivo" sem fingir uma porcentagem. */
.i3prog-barra > i.indefinida {
  background-image: linear-gradient(115deg,
    rgba(255, 255, 255, .32) 25%, transparent 25%, transparent 50%,
    rgba(255, 255, 255, .32) 50%, rgba(255, 255, 255, .32) 75%, transparent 75%);
  background-size: 18px 18px;
  animation: i3prog-anda .7s linear infinite;
  transition: none;
}
@keyframes i3prog-anda { from { background-position: 0 0; } to { background-position: 18px 0; } }
.i3prog.pronto .i3prog-barra > i { background-color: #22c55e; }
.i3prog.erro .i3prog-barra > i { background-color: #ef4444; }
.i3prog-msg {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--i3n-media);
}
.i3prog-msg:empty { display: none; }
.i3prog-acoes { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.i3prog-acoes:empty { display: none; }
.i3prog-acoes { margin-top: 0.7rem; }
/* `[class]` para vencer o §51.2, que faz de todo botão da página uma pílula
   de 40px com `!important`. */
.i3prog-b[class] {
  height: 32px !important;
  min-height: 0 !important;
  padding: 0 0.9rem !important;
  border-radius: 999px !important;
  border: 1px solid var(--i3t-brand-solid, #0052E6) !important;
  background: var(--i3t-brand-solid, #0052E6) !important;
  color: #fff !important;
  cursor: pointer;
  font: 600 0.75rem/1 var(--i3t-font-body, "Inter", sans-serif) !important;
}
.i3prog-b.discreto[class] {
  border-color: var(--i3n-linha) !important;
  background: none !important;
  color: var(--i3n-media) !important;
}

/* §98.1 — o aviso de tipo herdado, no cartão do tipo */
.i3herda {
  flex: 1 1 100%;
  margin: 0.55rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--i3n-linha);
  font-size: 0.7rem;
  line-height: 1.45;
  color: var(--i3n-media);
}

/* §97.4 — "Usar a cor original da imagem", ao lado de Excluir tipo/Remover.
   Pedido do dono, 15/08/2026. O sistema decide se o desenho SERVE de molde;
   isto decide se ele DEVE ser usado como molde — e essa é decisão de quem
   desenhou o ícone. Fica na mesma fileira das outras decisões sobre o tipo. */
.i3orig {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0 0.2rem;
  cursor: pointer;
  font: 500 0.73rem/1.2 var(--i3t-font-body, "Inter", sans-serif);
  color: var(--i3n-media);
  user-select: none;
}
.i3orig:hover { color: var(--i3n-forte); }
.i3orig input[type="checkbox"] {
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--i3t-brand-solid, #0052E6);
  cursor: pointer;
}
.i3orig input:disabled { opacity: .5; cursor: progress; }
.i3orig[hidden] { display: none; }

/* ============ §99 — O PERFIL QUE NÃO SE APAGA =============================
   Em /users › Grupos de permissões existe um perfil que é o PADRÃO: é ele que
   as plataformas leem como perfil global, e é dele que sai o acesso de quem
   está nele — em todas as bases de uma vez. O servidor recusa apagá-lo; aqui a
   linha dele para de OFERECER o que não vai acontecer.

   A linha é marcada por `web/assets/i3track-perms.js`, que lê a marca do
   registro (`attributes.padrao` / `somenteLeitura`) — nunca o nome, que o dono
   troca quando quiser.

   `padrao`  = o perfil padrão desta instalação.
   `externo` = perfil do ADMIN GERAL visto de dentro de uma plataforma: lá ele é
               só leitura, quem edita é a casa.

   O `!important` é o mesmo motivo de sempre: o CSS do pacote entra depois. */
tr[data-i3t-grupo-padrao] button.text-red-300{ display:none !important; }

tr[data-i3t-grupo-padrao] td:first-child > div::after{
  display:inline-flex; align-items:center;
  border-radius:9999px;
  border:1px solid var(--stroke);
  background:var(--surface-2);
  color:var(--sub);
  padding:2px 8px;
  font-size:10px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  white-space:nowrap;
}
tr[data-i3t-grupo-padrao="padrao"] td:first-child > div::after{ content:"Padrão"; }
tr[data-i3t-grupo-padrao="externo"] td:first-child > div::after{ content:"Admin geral"; }

/* ============ §100 — TROCAR O CLIENTE DO VEÍCULO =========================
   O botão fica logo abaixo do campo "Cliente *" do Editar, dentro da mesma
   célula da grade — é onde a pergunta nasce ("este carro é de quem?"), e não
   numa barra de ações no topo, longe do campo que a responde.

   Discreto de propósito: é uma ação rara e que move cadastro de uma empresa
   para outra. Botão grande e colorido ao lado de um campo obrigatório convida
   ao clique distraído. */
.i3v-troca-cliente{
  margin-top:6px;
  align-self:flex-start;
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--stroke);
  border-radius:9999px;
  background:transparent;
  color:var(--sub);
  padding:3px 10px;
  font-size:11px; font-weight:600; letter-spacing:.02em;
  cursor:pointer;
  transition:color .15s, border-color .15s, background .15s;
}
.i3v-troca-cliente:hover{
  color:var(--text);
  border-color:var(--primary);
  background:color-mix(in srgb, var(--primary) 10%, transparent);
}
/* O seletor dentro do diálogo de confirmação. */
.i3v-troca-corpo{ margin:2px 0 10px; }
.i3v-troca-select{
  width:100%;
  border:1px solid var(--stroke);
  border-radius:10px;
  background:var(--surface-2);
  color:var(--text);
  padding:9px 12px;
  font-size:13px;
}
.i3v-troca-select:focus{ outline:none; border-color:var(--primary); }

/* ============ §101 — A PLACA DA PLATAFORMA (revenda) =====================
   Mesma forma da pílula PLATAFORMA do administrador geral, sem a seta e sem
   o cursor de clique: aqui não há o que escolher, a revenda tem uma
   plataforma só. É uma placa, não um seletor. */
.i3gp-btn--fixo{
  cursor:default;
  padding-right:14px;
}
.i3gp-btn--fixo:hover{ border-color: var(--border, rgba(255,255,255,.14)); }

/* ============ §102 — CAMPO QUE VEIO DA CONSULTA DA PLACA =================
   Na tela Novo veículo, o que a consulta nacional preencheu fica trancado
   enquanto aquela placa estiver no campo (i3track-veiculo-novo.js). Um campo
   que não aceita digitação e parece igual aos outros é um campo quebrado:
   aqui ele mostra que está trancado, e o título diz por quê. */
.i3nv-daplaca{
  cursor:not-allowed;
  border-color:rgba(56,189,248,.35) !important;
  background:rgba(56,189,248,.08) !important;
  color:rgba(255,255,255,.82);
}
.i3nv-daplaca:focus{ outline:none; box-shadow:none; }

/* ============ §103 — LOGO POR ARQUIVO NA CRIAÇÃO DA PLATAFORMA ===========
   Era um campo pedindo URL: quem cria a plataforma tem o arquivo da marca na
   mão, não um endereço na internet. Agora é o mesmo gesto da tela de Temas —
   escolher arquivo, ver a prévia, tirar se errou (i3track-plataformas-pagina.js).
   O `input[type=file]` fica escondido: a etiqueta é o botão. */
.i3pp-arq{ display:flex; align-items:center; gap:9px; min-height:38px; flex-wrap:wrap; }
.i3pp-arq-b{
  background:var(--surface-2); color:var(--text); border:1px solid var(--border);
  border-radius:8px; padding:9px 12px; font-size:13px; cursor:pointer; white-space:nowrap;
}
.i3pp-arq-b:hover{ border-color:var(--sub); }
.i3pp-arq-prev{
  width:38px; height:38px; object-fit:contain; border-radius:8px;
  border:1px solid var(--border); background:var(--surface-2); padding:3px;
}
.i3pp-arq-prev[hidden]{ display:none; }
.i3pp-arq-nome{
  font-size:12px; color:var(--sub); overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; max-width:180px;
}
.i3pp-arq-x{
  background:none; border:none; color:var(--sub); cursor:pointer;
  font-size:14px; line-height:1; padding:4px 6px; border-radius:6px;
}
.i3pp-arq-x:hover{ color:#F87171; }
.i3pp-arq-x[hidden]{ display:none; }

/* ============ §104 — ALERTA SONORO (i3track-alerta-som.js) ===============
   O interruptor na barra da tela de Notificações e a faixa que aparece junto
   com o som. A faixa não é decoração: som sem nada escrito deixa a pessoa
   procurando o que apitou. Ela é clicável e leva para as notificações. */
.i3not-som{
  display:flex; align-items:center; gap:.5rem;
  height:40px; padding:0 .95rem;
  border:1px solid var(--i3n-linha); border-radius:999px;
  font:600 .875rem/1 var(--i3t-font-body, "Inter", sans-serif);
  color:var(--i3n-texto, var(--text)); cursor:pointer; user-select:none;
  margin-left:auto;
}
.i3not-som:hover{ background:var(--i3n-hover); }
.i3not-som input{ width:15px; height:15px; accent-color:var(--primary,#2563eb); cursor:pointer; }
.i3not-som[hidden]{ display:none; }

/* Sobe acima da bolha do chat de suporte, que mora no canto de baixo. */
.i3som-faixa{
  position:fixed; right:18px; bottom:92px; z-index:99998;
  display:flex; align-items:center; gap:.6rem;
  max-width:min(380px, calc(100vw - 36px));
  padding:12px 16px; border-radius:12px; cursor:pointer;
  background:var(--surface-2, #1c1c1c); color:var(--text, #fff);
  border:1px solid rgba(239,68,68,.45);
  box-shadow:0 10px 30px rgba(0,0,0,.35);
  font:600 13px/1.35 var(--i3t-font-body, "Inter", sans-serif);
  animation:i3som-entra .18s ease-out;
}
.i3som-faixa:hover{ border-color:rgba(239,68,68,.8); }
.i3som-ico{ font-size:16px; line-height:1; }
@keyframes i3som-entra{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
