/* HRD Sphere - design system compartilhado entre paginas.
   Redesign CMP (set/2026): paleta, glass e fontes vindos de
   docs/referencia/cmp-dashboard-teste2.html. Os tokens "novos" (--azure,
   --cyan, --glass...) sao a fonte da verdade; os tokens antigos (--bg,
   --surface, --accent...) continuam existindo, mas agora apontam pra eles -
   assim /finops e o resto do CSS herdam o visual novo sem reescrita. */
:root{
  color-scheme: dark;

  /* --- tokens do redesign CMP --- */
  --cmp-bg: #050816;
  --cmp-bg-2: #070C22;
  --glass: rgba(16,24,58,.55);
  --glass-hi: rgba(26,38,86,.6);
  --line: rgba(96,140,255,.18);
  --line-hi: rgba(96,165,255,.45);
  --text: #EAF0FF;
  --text-2: #9BA8D4;
  --text-3: #65729F;
  --azure: #3B9CFF;
  --cyan: #2BE3FF;
  --violet: #9D7BFF;
  --green: #34F5B0;
  --amber: #FFBE4D;
  --red: #FF4F7B;
  --pink: #FF5FD2;
  --r: 16px;
  --r-lg: 20px;
  --f-d: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --f-b: 'Inter Tight', ui-sans-serif, system-ui, sans-serif;
  --f-m: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  --glow-azure: 0 0 24px -6px rgba(59,156,255,.7);
  --glow-cyan: 0 0 12px var(--cyan);
  --shadow-glass: 0 1px 0 rgba(255,255,255,.06) inset, 0 0 0 1px rgba(0,0,0,.2), 0 24px 50px -28px rgba(0,0,0,.9);

  /* --- tokens antigos, remapeados pra paleta nova --- */
  --bg: var(--cmp-bg);
  --bg-plane: var(--cmp-bg);
  --surface: var(--glass);
  --surface-2: rgba(40,56,120,.35);
  --surface-hover: var(--glass-hi);
  --border: var(--line);
  --border-strong: var(--line-hi);
  --text-primary: var(--text);
  --text-secondary: var(--text-2);
  --text-muted: var(--text-3);
  --accent: var(--azure);
  --accent-ink: #031026;
  --accent-dim: rgba(59,156,255,.16);

  --good: var(--green);
  --warning: var(--amber);
  --serious: #FF8A5B;
  --critical: var(--red);

  --series-1: var(--azure);
  --series-2: var(--cyan);
  --series-3: var(--violet);
  --series-4: var(--amber);
  --series-5: var(--pink);
  --series-6: var(--green);

  --chart-grid: rgba(96,140,255,.08);
  --chart-axis: rgba(96,140,255,.22);

  --radius-s: 10px;
  --radius-m: var(--r);
  --radius-l: var(--r-lg);
  --font-display: var(--f-d);
  --font-body: var(--f-b);
  --font-mono: var(--f-m);

  --ease: cubic-bezier(.2,.8,.2,1);
  --shadow-card: var(--shadow-glass);
  --shadow-card-hover: var(--shadow-glass), 0 0 40px -24px rgba(59,156,255,.9);
  --shadow-glow-accent: var(--glow-azure);
}

*{box-sizing:border-box}
html,body{height:100%}
html{scroll-behavior:smooth}
body{margin:0; background:var(--cmp-bg); color:var(--text-primary); font:500 14px/1.5 var(--font-body); -webkit-font-smoothing:antialiased; overflow-x:hidden}
/* Fundo do redesign: gradientes radiais + grid sutil, fixos atras de tudo */
body::before{content:""; position:fixed; inset:0; z-index:-2; pointer-events:none;
  background:
    radial-gradient(1000px 600px at 55% 20%, rgba(43,120,255,.18), transparent 60%),
    radial-gradient(700px 500px at 0% 100%, rgba(157,123,255,.12), transparent 60%),
    radial-gradient(600px 400px at 100% 90%, rgba(43,227,255,.08), transparent 60%),
    linear-gradient(180deg, #050816, #040611)}
body::after{content:""; position:fixed; inset:0; z-index:-1; pointer-events:none; opacity:.35;
  background-image:linear-gradient(rgba(96,140,255,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(96,140,255,.06) 1px, transparent 1px);
  background-size:40px 40px;
  -webkit-mask-image:radial-gradient(circle at 50% 30%, #000 30%, transparent 80%); mask-image:radial-gradient(circle at 50% 30%, #000 30%, transparent 80%)}
/* TESTE (out/2026): imagem de fundo no app inteiro - body.bg-photo, ligado
   por ?fundo=imagem e desligado por ?fundo=padrao (app.js lembra a escolha). */
body.bg-photo::before{background:linear-gradient(rgba(4,6,18,.8), rgba(4,6,18,.86)), url(/assets/bg-sphere.webp?v=3) center/cover no-repeat, #040611}
body.bg-photo::after{display:none}
a{color:inherit; text-decoration:none}
h1,h2,h3{font-family:var(--font-display); margin:0; text-wrap:balance; line-height:1.18; letter-spacing:-.01em}
p{margin:0}
.mono{font-family:var(--font-mono); font-variant-numeric: tabular-nums}
button{font-family:inherit; cursor:pointer}
:focus-visible{outline:2px solid var(--cyan); outline-offset:2px; border-radius:4px}
[hidden]{display:none!important}

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.01ms!important; animation-iteration-count:1!important;
    transition-duration:.01ms!important; scroll-behavior:auto!important;
  }
}

/* Scrollbar discreta, coerente com o tema escuro */
*{scrollbar-width:thin; scrollbar-color:var(--surface-2) transparent}
*::-webkit-scrollbar{width:9px; height:9px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--surface-2); border-radius:20px; border:2px solid var(--bg-plane)}
*::-webkit-scrollbar-thumb:hover{background:var(--surface-hover)}

@keyframes viewIn{ from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:translateY(0)} }
@keyframes growFromZero{ from{transform:scaleX(0)} to{transform:scaleX(1)} }
@keyframes drawLine{ from{stroke-dashoffset:1} to{stroke-dashoffset:0} }
@keyframes fadeIn{ from{opacity:0} to{opacity:1} }
.chart-line{stroke-dasharray:1; stroke-dashoffset:1; animation:drawLine .8s var(--ease) .05s both}
.chart-area{opacity:0; animation:fadeIn .6s var(--ease) .35s both}
.chart-dot{opacity:0; animation:fadeIn .3s var(--ease) .75s both}

/* ---------- Shell: sidebar + topbar (redesign CMP) ---------- */
#app{display:grid; grid-template-columns:240px minmax(0,1fr); min-height:100vh}
.side{position:sticky; top:0; height:100vh; overflow-y:auto; display:flex; flex-direction:column; gap:22px; padding:22px 14px; z-index:30;
  background:linear-gradient(180deg, rgba(10,16,44,.75), rgba(5,8,22,.85)); border-right:1px solid var(--line); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px)}
.brand{display:flex; align-items:center; gap:11px; padding:0 8px}
.brand-mark{width:36px; height:36px; border-radius:12px; flex:none; overflow:hidden; box-shadow:0 0 22px rgba(43,160,255,.55)}
.brand-mark img{width:100%; height:100%; object-fit:cover; display:block}
.brand-name{font:700 16px/1 var(--f-d); letter-spacing:-.01em}
.brand-sub{margin-top:4px; color:var(--text-3); font:500 9.5px var(--f-m); white-space:nowrap; letter-spacing:-.01em} /* "Cloud Management Platform" numa linha so */
/* logo do produto no topo da barra lateral (arte "Cloud Management Platform", 08/10/2026), centralizado */
.brand-logo{justify-content:center; padding:0 8px; margin-top:16px; margin-bottom:34px} /* folga do topo da tela e ate o menu (Dashboard, FinOps...) */
.brand-logo img{display:block; width:140px; height:auto; filter:drop-shadow(0 0 14px rgba(43,140,255,.35))}
/* marca em TEXTO (08/10/2026): "CLOUD / MANAGEMENT / linha de luz / PLATFORM"
   desenhado pelo navegador - nitido em qualquer resolucao (imagem nao chegava nisso
   no 4K). Fonte Exo 2 (quadrada/futurista como a arte de referencia); uma versao em
   Michroma (estilo Eurostile) foi testada e descartada - ficou so a linha de luz. */
.brand-word{flex-direction:column; align-items:center; gap:3px; text-align:center; line-height:1; user-select:none}
.brand-word span{display:block; font-family:'Exo 2', var(--f-d); text-shadow:0 0 14px rgba(70,150,255,.45)}
.brand-word .bw-1{font-weight:700; font-size:34px; letter-spacing:.06em; color:#F4F7FF}
.brand-word .bw-2{font-weight:700; font-size:18.5px; letter-spacing:.03em; color:#F4F7FF}
.brand-word .bw-line{width:140px; height:2px; margin:6px 0 3px; border-radius:2px; text-shadow:none;
  background:linear-gradient(90deg, transparent, rgba(60,140,255,.7) 25%, #BFE6FF 50%, rgba(60,140,255,.7) 75%, transparent);
  box-shadow:0 0 8px rgba(80,160,255,.8)}
.brand-word .bw-3{margin-top:2px; font-weight:500; font-size:12.5px; letter-spacing:.42em; padding-left:.42em; color:#9CCBFF}

.menu{list-style:none; margin:0; padding:0; display:grid; gap:3px}
.menu a{display:flex; align-items:center; gap:12px; padding:9px 12px; border-radius:12px; color:var(--text-2); font-weight:600; position:relative; transition:color .2s, background .2s}
.menu a svg{width:18px; height:18px; flex:none; color:var(--c)}
.menu a:not(.disabled):hover{color:var(--text); background:rgba(59,156,255,.07)}
.menu a.on{color:#fff; background:linear-gradient(90deg, rgba(59,156,255,.28), rgba(59,156,255,.04)); box-shadow:inset 0 0 0 1px rgba(59,156,255,.4), var(--glow-azure)}
.menu a.on::before{content:""; position:absolute; left:-14px; top:9px; bottom:9px; width:3px; border-radius:2px; background:var(--cyan); box-shadow:var(--glow-cyan)}
.menu a.on svg{filter:drop-shadow(0 0 6px var(--c))}
/* Modulo ainda nao implementado: visivel, mas apagado e nao navegavel */
.menu a.disabled{opacity:.45; cursor:not-allowed}
/* Nome dos modulos com mais destaque (20/10/2026): com os icones de nuvem maiores embaixo,
   o titulo (FinOps, Monitor...) tinha ficado apagado */
.menu > li > a:not(.prov){font-size:15px; font-weight:500; color:#E3E9FA}
.menu > li > a:not(.prov) svg{width:20px; height:20px}
.menu > li > a.on:not(.prov){color:#fff}
/* submenu (12/10/2026): FinOps com Azure / Google Cloud. Desde 15/10/2026 sempre aberto
   (pedido do Charles) - sem setinha; o pai navega pro FinOps Azure.
   Nas paginas de FinOps o pai fica em .on-parent e o item da pagina em .on */
.menu .sub-toggle .chev{display:none}
.menu .sub-toggle.on-parent{color:#fff}
.submenu{list-style:none; margin:2px 0 4px; padding:0 0 0 24px; display:none; gap:2px}
.has-sub.open > .submenu{display:grid}
.menu .submenu a{padding:7px 12px; gap:10px; font-size:13px}
.menu .submenu a.on::before{left:-38px}
/* logo do provedor no lugar da bolinha (15/10/2026): assets/icons/azure.svg e gcp.svg */
/* Linha de nuvens embaixo de cada modulo (20/10/2026, pedido do Charles): as 3 linhas
   Azure / Google Cloud / AWS do FinOps viraram 1 linha de icones, e todo modulo ganhou a
   sua. Habilitado = <a class="prov">; ainda sem pagina naquela nuvem = <span class="prov off">;
   nuvem da pagina atual = .on */
/* sempre visivel embaixo de cada modulo (pedido do Charles, 20/10/2026 - antes so aparecia com o mouse) */
.prov-row{display:flex; gap:4px; margin:0 0 6px 34px}
/* .menu a (padding, fundo e moldura do item ativo) nao vale aqui: icone puro, centralizado */
.menu .prov, .prov{display:grid; place-items:center; width:38px; height:32px; padding:0; border-radius:8px; background:none; box-shadow:none; position:relative; transition:background .15s, opacity .15s}
.prov img{width:24px; height:24px; display:block}
/* Google Cloud e AWS sao desenhos largos e baixos: um pouco maiores pra ter o mesmo peso visual do Azure */
.prov img[src*="gcp"], .prov img[src*="aws"]{width:28px; height:28px}
.menu .prov{transition:opacity .18s, filter .18s, transform .18s}
.menu .prov img{transition:filter .18s}
.menu a.prov:not(.on){opacity:.8}
/* nuvem da pagina atual: brilho em volta do icone (sem moldura nem sublinhado) */
.menu a.prov.on{opacity:1; background:radial-gradient(closest-side, rgba(90,170,255,.28), transparent); box-shadow:none}
.menu a.prov.on::before{display:none}
.menu a.prov.on img{filter:drop-shadow(0 0 5px rgba(120,190,255,.9)) drop-shadow(0 0 12px rgba(59,156,255,.55))}
/* mouse em cima de um icone: ele acende e cresce (os outros ficam como estao) */
.menu a.prov:hover{opacity:1; filter:none; transform:scale(1.12); background:radial-gradient(closest-side, rgba(255,255,255,.12), transparent)}
.menu a.prov:hover img{filter:drop-shadow(0 0 6px rgba(255,255,255,.45))}
.prov.off{opacity:.25; filter:grayscale(1); cursor:not-allowed}
.sub-logo{width:16px; height:16px; flex:none; display:block; filter:drop-shadow(0 0 4px rgba(120,160,255,.35))}

.side-foot{margin-top:auto; padding:14px; border-radius:16px; font-size:12px; color:var(--text-3); --glow-c:#9D7BFF}
.side-foot b{display:flex; align-items:center; gap:8px; color:var(--text-2); font:600 13px var(--f-d); margin-bottom:3px}
.side-foot b svg{width:16px; height:16px; color:var(--violet)}
/* usuario logado (app.js -> loadUser) */
.side-foot .user-name{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.side-foot .user-mail{display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.side-foot .user-logout{display:inline-flex; align-items:center; gap:6px; margin-top:10px; padding:5px 12px 5px 10px; border-radius:999px;
  color:#FFB3C7; font-weight:600; font-size:12px; text-decoration:none; background:rgba(255,79,123,.08); border:1px solid rgba(255,79,123,.35);
  transition:background .15s, border-color .15s, color .15s, box-shadow .15s}
.side-foot .user-logout:hover{color:#fff; background:rgba(255,79,123,.22); border-color:rgba(255,120,150,.7); box-shadow:0 0 12px rgba(255,79,123,.35)}
.side-foot .user-logout:hover svg{transform:translateX(2px)}
.side-foot .user-logout svg{transition:transform .15s}
.side-foot .user-logout:focus-visible{outline:2px solid #FF8FAB; outline-offset:2px}

.main-col{min-width:0}
.top{display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:20px 24px 0}
.top-title{min-width:0}
.crumb{font:600 11px var(--f-m); color:var(--text-3); text-transform:uppercase; letter-spacing:.08em}
.top h1{margin:2px 0 0; font:600 24px/1.1 var(--f-d); letter-spacing:-.02em}
.grow{flex:1}
.search{display:flex; align-items:center; gap:8px; height:38px; padding:0 12px; border-radius:12px; min-width:240px; color:var(--text-3); background:rgba(10,16,44,.6); border:1px solid var(--line); font-size:13px; cursor:default}
.search svg{width:16px; height:16px; flex:none}
.search kbd{margin-left:auto; font:600 11px var(--f-m); padding:2px 6px; border-radius:6px; border:1px solid var(--line); color:var(--text-2)}
.menu-btn{display:none}
.scrim{display:none}

main{padding:18px 24px 22px; max-width:1680px} /* 22px embaixo = mesmo respiro da sidebar (.side padding): fundo dos cards alinhado com a caixa do usuario */
.view{display:flex; flex-direction:column; gap:16px; animation:viewIn .4s var(--ease) both}
.lede{color:var(--text-secondary); font-size:14px; max-width:62ch; margin-top:4px; line-height:1.55}

.ring{--pct:50; --ring-color:var(--accent); aspect-ratio:1; border-radius:50%; background:conic-gradient(var(--ring-color) calc(var(--pct)*1%), var(--surface-2) 0); display:flex; align-items:center; justify-content:center; flex:none; filter:drop-shadow(0 0 5px color-mix(in srgb, var(--ring-color) 55%, transparent)) drop-shadow(0 0 13px color-mix(in srgb, var(--ring-color) 32%, transparent))}
.ring-inner{background:var(--bg); border-radius:50%; width:70%; height:70%; display:flex; align-items:center; justify-content:center}

.grid{display:grid; gap:14px}
/* 1a coluna (Custo do mes) um pouco mais larga que as outras 5: "R$
   241.273,00" e mais longo que "91/100"/"34"/etc, entao precisa de mais
   espaco pra caber no mesmo tamanho de fonte sem quebrar linha - em vez
   de diminuir só esse valor (o que deixava ele menor que os outros),
   da mais espaco pra coluna dele. O minmax(189px,...) garante essa
   largura minima mesmo em telas mais estreitas (perto do breakpoint de
   980px, onde o grid-6 vira grid-3/2 - ver media queries abaixo). */
.grid-6{grid-template-columns:minmax(189px,1.35fr) repeat(5,minmax(0,1fr))}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-2{grid-template-columns:2fr 1fr}
.card{position:relative; background:linear-gradient(160deg, var(--glass-hi), var(--glass) 55%, rgba(8,12,34,.6)); border:1px solid var(--border); border-radius:var(--radius-l); padding:14px 18px; box-shadow:var(--shadow-card); backdrop-filter:blur(18px) saturate(140%); -webkit-backdrop-filter:blur(18px) saturate(140%); transition:transform .18s var(--ease), box-shadow .18s var(--ease), border-color .15s var(--ease), background .15s var(--ease)}
.card-title{font-size:12px; color:var(--text-muted); text-transform:uppercase; letter-spacing:.07em; display:flex; align-items:center; justify-content:space-between; gap:8px}

/* ---------- Componentes do redesign CMP (reutilizaveis por qualquer pagina) ---------- */
/* .glass: painel de vidro com borda em gradiente. --glow-c muda a cor da
   borda, --glow a cor do brilho externo. */
.glass{position:relative; background:linear-gradient(160deg, var(--glass-hi), var(--glass) 55%, rgba(8,12,34,.6));
  border:1px solid var(--line); border-radius:var(--r-lg); backdrop-filter:blur(18px) saturate(140%); -webkit-backdrop-filter:blur(18px) saturate(140%);
  box-shadow:var(--shadow-glass), 0 0 40px -30px var(--glow, rgba(59,156,255,.9))}
.glass::before{content:""; position:absolute; inset:-1px; border-radius:inherit; padding:1px; pointer-events:none;
  background:linear-gradient(135deg, color-mix(in srgb, var(--glow-c, #3B9CFF) 70%, transparent), transparent 35%, transparent 65%, color-mix(in srgb, var(--glow-c, #3B9CFF) 40%, transparent));
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite:xor; mask-composite:exclude; opacity:.8}
/* .ico: quadradinho de icone com a cor do modulo (--c) */
.ico{width:32px; height:32px; flex:none; border-radius:10px; display:grid; place-items:center; color:var(--c, var(--azure));
  background:radial-gradient(circle at 30% 25%, color-mix(in srgb, var(--c, var(--azure)) 40%, transparent), color-mix(in srgb, var(--c, var(--azure)) 10%, transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--c, var(--azure)) 45%, transparent), 0 0 18px -4px var(--c, var(--azure))}
.ico svg{width:17px; height:17px}
.pill{display:inline-flex; align-items:center; gap:7px; height:32px; padding:0 12px; border-radius:10px; background:rgba(5,8,22,.7); border:1px solid var(--line); font-size:12px; color:var(--text-2); backdrop-filter:blur(8px)}
.pill b{color:var(--text); font-family:var(--f-m)}
.pill svg{width:14px; height:14px}
/* Selo "dados de exemplo" da topbar (mesma regra do .source-badge.mock) */
.tag-demo{height:28px; display:inline-flex; align-items:center; gap:6px; padding:0 10px; border-radius:9px; font:600 11.5px var(--f-m); color:var(--amber); background:rgba(255,190,77,.1); border:1px solid rgba(255,190,77,.35); white-space:nowrap}
.tag-demo svg{width:13px; height:13px}
.ibtn{width:38px; height:38px; flex:none; border-radius:12px; display:grid; place-items:center; background:rgba(10,16,44,.6); border:1px solid var(--line); position:relative; color:var(--text-2); transition:color .15s var(--ease), border-color .15s var(--ease)}
.ibtn:hover{color:var(--text); border-color:var(--line-hi)}
.ibtn svg{width:18px; height:18px}
.ibtn .dot{position:absolute; top:-4px; right:-4px; min-width:18px; width:auto; height:18px; padding:0 4px; border-radius:9px; background:var(--red); color:#fff; font:700 10px/18px var(--f-m); text-align:center; box-shadow:0 0 12px var(--red)}
.num{font-family:var(--f-m); font-variant-numeric:tabular-nums}
.up{color:var(--green)} .dn{color:var(--red)} .fl{color:var(--text-3)}
.card.clickable{cursor:pointer}
.card.clickable:hover{border-color:var(--border-strong); background:var(--surface-hover); transform:translateY(-2px); box-shadow:var(--shadow-card-hover), inset 0 1px 0 rgba(255,255,255,.04)}
.card.clickable:active{transform:translateY(0); box-shadow:var(--shadow-card), inset 0 1px 0 rgba(255,255,255,.03)}

/* justify-content:flex-start (com gap fixo) em vez de space-between OU
   center: os 6 KPIs tem sub-textos de tamanhos bem diferentes ("Custo do
   mes" vs "Recursos ociosos · R$ 34.272/mes de economia", que quebra
   linha) - space-between empurrava o valor pra baixo quando o bloco de
   texto era curto, e center piorou porque cada card tem altura de
   conteudo diferente (mais ou menos linhas quebradas), entao cada um
   centralizava num ponto vertical diferente. Fixando icone+valor no
   topo com gap fixo, os 6 ficam alinhados na mesma linha nao importa
   quanto o sub-texto quebre embaixo. */
/* min-width:0 e essencial aqui: sem isso, o grid-6 usa o min-content de
   cada card (o texto "R$ 241.273,00" com white-space:nowrap) como piso
   da coluna, deixando a 1a coluna mais larga que as outras 5 - foi por
   isso que o icone/valor do card de custo ficavam fora de linha com o
   resto (a coluna dele tinha outra largura, nao era so vertical). */
.kpi{display:flex; flex-direction:column; gap:16px; min-height:108px; justify-content:flex-start; min-width:0}
.kpi-top{display:flex; align-items:center; justify-content:space-between}
.kpi-ic{font-size:15px}
.kpi-val{font-family:var(--font-mono); font-size:18.5px; font-weight:600; letter-spacing:-.005em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.kpi-sub{font-size:11.5px; color:var(--text-secondary)}
.delta{font-size:11px; font-family:var(--font-mono); padding:1px 6px; border-radius:20px; font-weight:600}
.delta.up-bad{color:var(--critical); background:rgba(255,79,123,.14)}
.delta.up-good{color:var(--good); background:rgba(52,245,176,.14)}
.delta.down-good{color:var(--good); background:rgba(52,245,176,.14)}

.hero{display:flex; align-items:center; gap:30px; padding:18px 30px; background:radial-gradient(120% 160% at 0% 0%, rgba(59,156,255,.10), transparent 60%), var(--surface); border:1px solid var(--border); border-radius:var(--radius-l); box-shadow:0 0 44px -14px rgba(59,156,255,.28), var(--shadow-card); flex-wrap:wrap}

/* Cloud Score em destaque, como foco visual do hero (anel grande + variação) */
.hero-score{display:flex; flex-direction:column; align-items:center; gap:7px; flex:none; padding-right:30px; border-right:1px solid var(--border); text-align:center}
.hero-score .ring{width:150px; height:150px}
.hero-score .ring-inner{flex-direction:column}
.hero-score-num{font-family:var(--font-display); font-size:38px; font-weight:800; line-height:1}
.hero-score-grade{font-size:11.5px; color:var(--good); font-weight:600}
.hero-score-delta{font-size:11px; color:var(--text-muted)}
.hero-score-delta strong{color:var(--good); font-weight:600}

/* Painel "Sobre o Cloud Score": explicação + os 6 pilares como barras (troca as
   mini-rings com sparkline por algo mais legível ao lado de um anel grande). */
.hero-panel{flex:1; min-width:260px}
.hero-panel-title{font-size:15px; font-weight:700}
.hero-panel-desc{color:var(--text-secondary); font-size:13px; max-width:56ch; margin-top:4px; line-height:1.55}
.hero-pillars{display:flex; flex-direction:column; gap:7px; margin-top:12px}
.hero-pillar{display:flex; align-items:center; gap:12px}
.hero-pillar-lbl{width:96px; flex:none; font-size:12px; color:var(--text-secondary)}
.hero-pillar-bar{flex:1; height:6px; border-radius:4px; background:var(--surface-2); overflow:hidden}
.hero-pillar-fill{height:100%; border-radius:4px; transition:width .6s var(--ease)}
.hero-pillar-val{width:44px; flex:none; text-align:right; font-family:var(--font-mono); font-size:12px; color:var(--text-secondary)}

/* Barra de acoes rapidas */
.quick-actions{display:flex; gap:10px; flex-wrap:wrap}
.qa-btn{display:flex; align-items:center; gap:8px; font-size:12.5px; font-weight:500; padding:9px 15px; border-radius:20px; background:var(--surface); border:1px solid var(--border-strong); color:var(--text-primary); text-decoration:none; transition:background .15s var(--ease), border-color .15s var(--ease), transform .15s var(--ease), box-shadow .15s var(--ease)}
.qa-btn:hover{background:var(--surface-hover); border-color:var(--accent); transform:translateY(-1px); box-shadow:0 6px 16px -8px rgba(0,0,0,.5)}
.qa-btn:active{transform:translateY(0)}
.qa-btn .ic{font-size:13px; color:var(--accent)}

/* Lista ranqueada (top recursos por custo) */
.rank-list{display:flex; flex-direction:column}
.rank-row{display:grid; grid-template-columns:20px 1fr 82px; align-items:center; gap:10px; padding:8px 2px}
.rank-num{font-family:var(--font-mono); font-size:11px; color:var(--text-muted); text-align:center}
.rank-main{min-width:0}
.rank-name{font-size:12.5px; color:var(--text-secondary); margin-bottom:4px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.rank-track{background:var(--surface-2); border-radius:6px; height:7px; overflow:hidden}
.rank-fill{height:100%; border-radius:6px; transform-origin:left; animation:growFromZero .6s var(--ease) both}
.rank-val{font-family:var(--font-mono); font-size:12px; text-align:right; color:var(--text-primary)}

/* Recursos com maior alta de custo: lista com variação percentual vs.
   período anterior (ilustrativo — ver comentário em mock.js) */
.delta-list{display:flex; flex-direction:column}
.delta-row{display:flex; align-items:center; gap:10px; padding:8px 2px; border-top:1px solid var(--border)}
.delta-row:first-child{border-top:none; padding-top:0}
.delta-name{flex:1; min-width:0; font-size:12.5px; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.delta-val{font-family:var(--font-mono); font-size:11.5px; color:var(--text-muted); flex:none}
.delta-pct{font-family:var(--font-mono); font-size:11.5px; font-weight:600; flex:none; width:58px; text-align:right}
.delta-pct.up{color:var(--warning)}
.delta-pct.down{color:var(--good)}

/* Seletor de período do gráfico de tendência diária de custos */
.period-pills{display:flex; gap:4px; flex:none}
.period-pill{font-family:var(--font-mono); font-size:10.5px; font-weight:600; padding:4px 10px; border-radius:20px; border:1px solid var(--border); background:none; color:var(--text-muted); transition:background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease)}
.period-pill:hover{border-color:var(--border-strong); color:var(--text-secondary)}
.period-pill.active{color:var(--accent); background:var(--accent-dim); border-color:rgba(59,156,255,.28)}

/* Disponibilidade / alertas */
.alert-list{display:flex; flex-direction:column}
.alert-row{display:flex; align-items:flex-start; gap:10px; padding:9px 2px; border-bottom:1px solid var(--border)}
.alert-row:last-child{border-bottom:none}
.alert-row .dot{margin-top:5px}
.alert-main{flex:1; min-width:0}
.alert-title{font-size:12.5px; font-weight:500; display:flex; align-items:center; gap:6px; flex-wrap:wrap}
.alert-desc{font-size:11.5px; color:var(--text-secondary); margin-top:2px; line-height:1.45}
.alert-src{font-size:9px; text-transform:uppercase; letter-spacing:.04em; padding:1px 6px; border-radius:20px; background:var(--surface-2); color:var(--text-muted); font-weight:600}
.alert-time{font-size:11px; color:var(--text-muted); font-family:var(--font-mono); white-space:nowrap; margin-left:6px}

.plist{display:flex; flex-direction:column}
.prow{display:flex; align-items:center; gap:10px; padding:10px 4px; border-bottom:1px solid var(--border); font-size:13px; transition:background .15s var(--ease)}
.prow:last-child{border-bottom:none}
a.prow:hover, .prow.clickable:hover{background:var(--surface-2); border-radius:var(--radius-s)}
.dot{width:8px; height:8px; border-radius:50%; flex:none}
.dot.critical{background:var(--critical); box-shadow:0 0 6px -1px var(--critical)} .dot.warning{background:var(--warning); box-shadow:0 0 6px -1px var(--warning)} .dot.good{background:var(--good); box-shadow:0 0 6px -1px var(--good)}
.prow .tag{margin-left:auto; font-size:10.5px; color:var(--text-muted); font-family:var(--font-mono)}

.chart-wrap{width:100%}
.chart-wrap svg{width:100%; height:auto; display:block; overflow:visible}

.hbars{display:flex; flex-direction:column} /* mesmo espaçamento das linhas do "Custo por assinatura" (.sub-row) */
.hbar-row{display:grid; grid-template-columns:120px 1fr 104px; align-items:center; gap:10px; font-size:12.5px; padding:7px 2px; border-bottom:1px solid transparent}
.hbar-label{color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.hbar-track{background:var(--surface-2); border-radius:6px; height:10px; overflow:hidden}
.hbar-fill{height:100%; border-radius:6px; transform-origin:left; animation:growFromZero .6s var(--ease) both}
.hbar-val{font-family:var(--font-mono); text-align:right; color:var(--text-primary); white-space:nowrap} /* "R$ 48.980,96" numa linha só */

.flist{display:flex; flex-direction:column}
.frow{display:flex; align-items:flex-start; gap:12px; padding:12px 2px; border-bottom:1px solid var(--border)}
.frow:last-child{border-bottom:none}
.frow .ficon{width:28px; height:28px; border-radius:8px; flex:none; display:flex; align-items:center; justify-content:center; font-size:13px; background:var(--surface-2)}
.frow-main{flex:1; min-width:0}
.frow-title{font-size:13px; font-weight:500}
.frow-desc{font-size:12px; color:var(--text-secondary); margin-top:2px; line-height:1.45}
.frow-save{font-family:var(--font-mono); font-size:12.5px; color:var(--good); white-space:nowrap}

.status-word{font-size:10.5px; padding:2px 8px; border-radius:20px; font-weight:600; text-transform:uppercase; letter-spacing:.03em}

/* Fonte dos dados - selo que diz se o bloco e real ou de exemplo */
/* Selo de origem do dado: so uma bolinha - verde (real, com brilho) ou cinza
   (exemplo). O texto fica no title/aria-label (ver SourceBadge.jsx / sourceBadge()). */
.source-badge{display:inline-flex; align-items:center; flex:none; padding:0; cursor:help}
.source-badge svg{display:block; width:26px; height:26px}
/* sempre no canto superior direito do cabecalho do card, mesmo quando vem
   embrulhado num <span title> (ex.: Service Health, Azure Monitor) */
.ph > span:has(> .source-badge){margin-left:auto; display:inline-flex}

.sub-list{display:flex; flex-direction:column}
.sub-row{display:flex; align-items:center; gap:9px; padding:7px 2px; border-bottom:1px solid var(--border); font-size:12.5px}
.sub-row:last-child{border-bottom:none}
.sub-row.unmonitored{opacity:.6}
.sub-row.failed .sub-cost{color:var(--critical)}
.sub-key{flex:none}
.sub-key-ok{color:#FFBE4D} /* mesma cor do icone do card "Custo por assinatura" */
.sub-key-unmonitored{color:var(--text-muted)}
.sub-key-failed{color:var(--critical)}
.sub-name{flex:1; min-width:0; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sub-cost{font-family:var(--font-mono); color:var(--text-primary); white-space:nowrap; flex:none; min-width:92px; text-align:right}

.inc-list{display:flex; flex-direction:column}
/* "+ N outros — ver todos" / "ver menos" no fim de uma lista .inc-list (ex.: FinOps "Novos no mes") */
.inc-more{display:block; margin:10px auto 0; padding:4px 2px; background:none; border:0; cursor:pointer; color:var(--text-3); font:500 12.5px var(--f-b); text-decoration:underline; text-underline-offset:3px}
.inc-more:hover{color:var(--text)}
.inc-row{display:flex; align-items:flex-start; gap:12px; padding:7px 2px; border-bottom:1px solid var(--border)}
.inc-row:last-child{border-bottom:none}
.inc-rank{width:20px; flex:none; font-family:var(--font-mono); font-size:12px; color:var(--text-muted); padding-top:1px}
.inc-main{flex:1; min-width:0}
.inc-name{font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.inc-desc{font-size:12px; color:var(--text-secondary); margin-top:1px; line-height:1.35}
.inc-domain{display:flex; align-items:center; gap:5px; font-size:11px; color:var(--text-muted); margin-top:1px}
.inc-domain svg{flex:none}
.inc-value{font-family:var(--font-mono); font-size:12.5px; color:var(--critical); white-space:nowrap; flex:none; text-align:right; padding-top:1px}
/* lista em 2 colunas e compacta (FinOps "Top 10 maiores aumentos"): 1-5 a esquerda,
   6-10 a direita - metade da altura, pra pagina caber na tela sem rolagem */
.inc-list-2col{display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); grid-auto-flow:column; grid-template-rows:repeat(5, auto); column-gap:44px; position:relative}
.inc-list-2col .inc-row{padding:7px 2px; align-items:baseline}
.inc-list-2col .inc-row:nth-child(5){border-bottom:none}
/* divisor vertical entre as 2 colunas (pedido do Charles, 09/10/2026): solto no
   meio do vão, sem encostar nas linhas horizontais, com degradê e brilho leve */
.inc-list-2col::before{content:""; position:absolute; top:4px; bottom:4px; left:50%; width:2px; transform:translateX(-50%); border-radius:2px;
  background:linear-gradient(180deg, transparent, var(--line-hi) 18%, var(--azure) 50%, var(--line-hi) 82%, transparent);
  box-shadow:0 0 8px rgba(59,156,255,.45); pointer-events:none}
.inc-list-2col .inc-main{display:flex; align-items:baseline; gap:8px}
.inc-list-2col .inc-name{flex:0 1 auto; max-width:48%; font-size:12.5px}
.inc-list-2col .inc-desc{flex:1 1 0; min-width:0; margin-top:0; font-size:11.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.inc-list-2col .inc-domain{display:none}
@media (max-width: 900px){ .inc-list-2col{grid-template-columns:minmax(0,1fr); grid-auto-flow:row; grid-template-rows:none} .inc-list-2col .inc-row:nth-child(5){border-bottom:1px solid var(--border)} .inc-list-2col::before{display:none} }
.api-banner{display:flex; gap:10px; align-items:flex-start; padding:12px 14px; border-radius:var(--radius-s); background:rgba(255,79,123,.10); border:1px solid rgba(255,79,123,.3); font-size:12.5px; color:var(--text-secondary); margin-bottom:14px}
.api-banner.warning{background:rgba(255,190,77,.10); border-color:rgba(255,190,77,.35)}
.api-banner b{color:var(--text-primary)}
.api-banner code{font-family:var(--font-mono); font-size:11px; background:var(--surface-2); padding:1px 5px; border-radius:4px}

footer.foot{padding:26px 22px 40px; text-align:center; color:var(--text-muted); font-size:11.5px}

/* Layout do Sumario Executivo — reagrupado por "peso visual" (cards
   parecidos na mesma linha), em vez de colunas paralelas com quantidades
   de card bem diferentes: aquilo sempre deixava vao vazio embaixo da
   coluna mais curta, nao importa o hack de CSS (o vao so mudava de
   coluna).
   Linha que sobrou montada hoje:
   - grid-copilot-row: Copilot AI | Alertas | Acoes rapidas
   (As linhas "Custo/Tendencia diaria/Distribuicao" -grid-exec-charts-,
   "Recursos em alta/Alertas prioritarios/Disponibilidade" -grid-exec-lists-,
   "Vulnerabilidades/Certificados/Backup&DR/Copilot/Recomendacoes"
   -grid-bottom- e "Ambientes/Mapa de recursos" -grid-env-map- foram
   removidas do Sumario Executivo a pedido do Charles; os componentes
   continuam no repo, so nao sao mais montados aqui. As classes seguem
   definidas abaixo caso alguma delas volte pra outra pagina.) */
.grid-exec-charts{grid-template-columns:1fr 1.3fr 1fr}
.grid-copilot-row{grid-template-columns:1fr 1fr .9fr}
.grid-bottom{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:14px}
.grid-env-map{grid-template-columns:1fr 1fr}

/* Ambientes: visao geral compacta (Produção/DR reaproveitam os mesmos
   numeros de `islands`; Homologação/Desenvolvimento sao ilustrativos ate
   o produto ler a tag de ambiente dos recursos no Azure). */
.env-grid{display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-top:10px}
.env-tile{display:flex; flex-direction:column; gap:3px; padding:12px; border:1px solid var(--border); border-radius:var(--radius-s); background:var(--bg-plane)}
.env-tile-ic{width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--border-strong); margin-bottom:2px}
.env-tile-name{font-size:12.5px; font-weight:600; color:var(--text-primary)}
.env-tile-sub{font-size:11px; color:var(--text-muted)}
.env-tile-status{font-size:11px; font-weight:600}

/* Link "ver mais" ao pe de um card - .disabled marca que a pagina de
   destino ainda nao existe (mesmo padrao visual dos itens "em breve" do
   menu lateral), pra nao fingir um link que nao leva a lugar nenhum. */
.card-more-link{display:inline-flex; align-items:center; gap:6px; margin-top:10px; font-size:12px; font-weight:600; color:var(--accent); text-decoration:none}
.card-more-link:hover{text-decoration:underline}
.card-more-link.disabled{opacity:.55; pointer-events:none; color:var(--text-secondary)}
.card-more-link .count{font-size:10px; font-weight:600; font-family:var(--font-mono); color:var(--text-muted); background:var(--surface-2); border-radius:20px; padding:1px 7px}

/* Distribuicao de Custos: donut + legenda (mesma categoria de custo do
   FinOps real, sem inventar numeros novos) */
.cost-dist{display:flex; align-items:center; gap:18px; margin-top:8px}
.cost-dist-legend{display:flex; flex-direction:column; gap:7px; flex:1; min-width:0}
.cost-dist-row{display:flex; align-items:center; gap:8px; font-size:12px}
.cost-dist-dot{width:9px; height:9px; border-radius:50%; flex:none}
.cost-dist-lbl{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-secondary)}
.cost-dist-val{font-family:var(--font-mono); color:var(--text-secondary); flex:none}

/* Mapa de Recursos: so as regioes Azure realmente em uso (Brazil South +
   East US do DR) sobre uma textura de pontos abstrata - nao e um
   mapa-mundi geografico real, entao nao finge presenca em regioes onde
   nao ha nada. */
.resource-map{position:relative; height:140px; border-radius:var(--radius-m); overflow:hidden; border:1px solid var(--border);
  background-image:radial-gradient(rgba(255,255,255,0.055) 1px, transparent 1.4px);
  background-size:15px 15px; background-color:var(--bg-plane)}
.resource-map-pin{position:absolute; transform:translate(-50%,-6px); display:flex; flex-direction:column; align-items:center; gap:5px}
.resource-map-dot{width:9px; height:9px; border-radius:50%; background:currentColor; box-shadow:0 0 0 5px color-mix(in srgb, currentColor 20%, transparent), 0 0 12px 1px currentColor}

/* Tendência diária de custos — ocupa a mesma posição/coluna que era do
   Digital Twin 3D no grid-exec3. As colunas dos lados variam de altura
   (a esquerda tem 4 cards, a direita 3) e qual delas é a mais alta muda
   conforme o conteúdo - então, ao inves de deixar esse card com altura
   fixa (o que só move o vão vazio pra baixo dele quando ele vira a coluna
   mais curta), ele acompanha a altura da coluna mais alta como as outras,
   e o espaço extra vira respiro centralizado ao redor do gráfico, dentro
   do próprio card - nunca um vão solto fora de qualquer moldura.
   Nem "height:auto" nem a propriedade aspect-ratio no <svg> mantiveram a
   proporção de forma confiável dentro do flex (o SVG esticava verticalmente
   e distorcia o gráfico) - por isso a proporção 620x170 é forçada via
   padding-bottom (%), que é sempre relativo à LARGURA do próprio elemento e
   não depende do navegador calcular altura automática de um SVG. */
.daily-trend-card{display:flex; flex-direction:column}
.daily-trend-card .chart-wrap{flex:1; min-height:110px; display:flex; align-items:center; justify-content:center}
.daily-trend-card .chart-ratio-box{position:relative; width:100%; max-width:620px; padding-bottom:27.42%; height:0; overflow:hidden}
.daily-trend-card .chart-ratio-box svg{position:absolute; top:0; left:0; width:100%; height:100%}

/* Cloud Digital Twin 3D (Three.js) — os componentes seguem no repo
   (não são mais montados no Sumário Executivo, ver ExecutiveSummary.jsx) */
.digital-twin-card{display:flex; flex-direction:column}
.digital-twin-canvas{
  position:relative; width:100%; aspect-ratio:1/1; max-height:620px; margin-top:10px;
  background:radial-gradient(120% 120% at 50% 15%, rgba(57,135,229,0.12), transparent 60%), var(--bg-plane);
  border:1px solid var(--border); border-radius:var(--radius-m); overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04), inset 0 0 60px -30px rgba(57,135,229,.4);
}
.digital-twin-canvas canvas{width:100%!important; height:100%!important; display:block}
.twin-fallback{display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; color:var(--text-muted); font-size:12.5px; text-align:center; padding:20px; gap:8px}
.twin-fallback ul{list-style:none; margin:0; padding:0; columns:2; gap:14px; text-align:left; font-size:11.5px; color:var(--text-secondary)}
.twin-fallback li{padding:3px 0}

/* Mini stat cards: Recursos ociosos, Certificados, Backup & DR */
.mini-stat-val{font-family:var(--font-mono); font-size:22px; font-weight:600}
.mini-stat-sub{font-size:11px; color:var(--text-muted); margin-top:2px}
.mini-stat-list{list-style:none; margin:10px 0 0; padding:0; display:flex; flex-direction:column; gap:6px}
.mini-stat-list li{display:flex; justify-content:space-between; gap:10px; font-size:11.5px; color:var(--text-secondary); border-top:1px solid var(--border); padding-top:6px}
.mini-stat-list li:first-child{border-top:none; padding-top:0}
.mini-stat-list li b{font-family:var(--font-mono); color:var(--text-primary); font-weight:600; white-space:nowrap}

/* Selo do provedor no cabecalho do card do Digital Twin (marca local + texto) */
.twin-provider{display:inline-flex; align-items:center; gap:5px}

/* Labels do Cloud Digital Twin 3D, renderizados como HTML real via drei/Html
   (nao mais texto desenhado em canvas) - mesma linguagem visual de "chip neon". */
.twin-chip{
  background:rgba(6,10,30,.72); border:1.5px solid; border-radius:10px;
  padding:5px 11px; text-align:center; white-space:nowrap;
  backdrop-filter:blur(2px); box-shadow:0 0 16px -4px currentColor;
}
.twin-chip-title{font-family:var(--font-display); font-weight:600; font-size:12.5px; color:#f2f4fb; line-height:1.3}
.twin-chip-sub{font-family:var(--font-mono); font-size:10.5px; margin-top:1px}
.twin-chip-center .twin-chip-title{font-size:14px; letter-spacing:.02em}
.twin-chip-center{padding:7px 16px}

/* Copilot Insights teaser */
.insight-row{display:flex; gap:12px; align-items:flex-start}
.insight-orb{width:40px; height:40px; border-radius:50%; background:var(--surface-2); border:1px solid var(--border-strong); display:flex; align-items:center; justify-content:center; flex:none; box-shadow:0 0 14px -2px rgba(59,156,255,.5)}
.insight-count{font-family:var(--font-mono); font-weight:700; font-size:19px}
.insight-count span{font-family:var(--font-body); font-weight:400; font-size:10.5px; color:var(--text-muted); margin-left:4px}
.insight-list{margin:6px 0 0; padding-left:15px; font-size:11px; color:var(--text-secondary); display:flex; flex-direction:column; gap:2px}

/* Lista de recomendacoes do Copilot AI - mesmo espirito do alert-row
   (linha com borda superior), so com um selo de impacto a direita em vez
   de dot+hora. */
.reco-list{display:flex; flex-direction:column; margin-top:12px}
.reco-row{display:flex; align-items:flex-start; justify-content:space-between; gap:10px; padding:9px 2px; border-top:1px solid var(--border)}
.reco-row:first-child{border-top:none; padding-top:0}
.reco-title{font-size:12.5px; font-weight:500; color:var(--text-primary)}
.reco-sub{font-size:11px; color:var(--text-secondary); margin-top:2px}
.impact-badge{font-size:10px; font-weight:600; padding:2px 8px; border-radius:20px; white-space:nowrap; flex:none; margin-top:1px}
.impact-badge.high{color:var(--critical); background:rgba(255,79,123,.14)}
.impact-badge.medium{color:var(--warning); background:rgba(255,190,77,.14)}

/* Acoes rapidas (card de baixo) - grade 2 colunas de atalhos, .disabled no
   mesmo padrao visual do menu lateral (opacidade + selo "em breve" +
   pointer-events off), pra nao fingir link pra pagina que nao existe. */
.qa-grid{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:10px}
.qa-grid-btn{display:flex; align-items:center; gap:9px; padding:10px 12px; border-radius:var(--radius-s); border:1px solid var(--border); background:var(--bg-plane); color:var(--text-primary); font-size:12px; font-weight:500; text-decoration:none; transition:background .15s var(--ease), border-color .15s var(--ease)}
.qa-grid-btn:hover{background:var(--surface-2); border-color:var(--border-strong)}
.qa-grid-btn .ic{display:flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:50%; background:var(--surface-2); color:var(--accent); flex:none}
.qa-grid-btn .count{margin-left:auto}
.qa-grid-btn.disabled{opacity:.5; pointer-events:none}

/* Ambiente multicloud — mesma linguagem visual do Mapa de Recursos
   (resource-map-pin/twin-chip), so que como grafo: centro = visao geral,
   pontas = provedores. So Azure e On-Premises puxam linha ate o centro
   (conexao real, mesmos numeros de resourceRegions/islands); AWS/Google
   Cloud ficam esmaecidos, com 0 recursos e sem linha - mostram que o
   produto ja nasceu pronto pra multicloud sem fingir uma integracao que
   ainda nao existe. */
.multicloud-card{display:flex; flex-direction:column}
.mc-viz{position:relative; height:232px; margin-top:8px; border-radius:var(--radius-m); overflow:hidden; border:1px solid var(--border);
  background-image:radial-gradient(rgba(255,255,255,0.05) 1px, transparent 1.4px);
  background-size:16px 16px; background-color:var(--bg-plane)}
.mc-lines{position:absolute; inset:0; width:100%; height:100%}
.mc-lines line{stroke:var(--border-strong); stroke-width:.5}
/* AWS/Google Cloud: linha so pra mostrar que fazem parte do mapa
   multicloud (o produto ja nasceu pronto pra eles) - tracejada e mais
   apagada que a linha solida de Azure/On-Premises, pra nao parecer uma
   conexao de dados real que ainda nao existe (o chip continua dizendo
   "0 recursos - nao conectado"). */
.mc-lines line.mc-line-off{stroke:var(--border); stroke-dasharray:2 2}
.mc-center{transform:translate(-50%,-50%)}
/* Nos da linha de baixo (AWS/GCP, y>50%): o pin padrao cresce PRA BAIXO a
   partir do ponto ancorado (bom pra linha de cima) - na linha de baixo isso
   empurrava o hex pra fora da caixa (cortado pelo overflow:hidden do
   .mc-viz). Aqui inverte: ancora a base da coluna no ponto, crescendo pra
   CIMA, e a ordem dos filhos no JSX tambem inverte (hex primeiro, chip por
   ultimo) pra manter o chip perto do ponto, como na linha de cima. */
.mc-node-bottom{transform:translate(-50%, calc(-100% + 6px))}
/* Desconectado (AWS/GCP): o logo em si fica com a cor de marca normal —
   só o texto/moldura em volta (chip tracejado, borda do hex) usa a cor
   neutra de "0 recursos", pra sinalizar status sem apagar o logo. */
.mc-node-off .twin-chip{opacity:.6; border-style:dashed}
.mc-node-off .resource-map-dot{box-shadow:none}
.mc-hex{display:flex; filter:drop-shadow(0 0 8px color-mix(in srgb, currentColor 45%, transparent))}
.mc-note{margin:10px 2px 0; font-size:11px; color:var(--text-muted); line-height:1.5}


@media (max-width: 980px){
  .grid-6{grid-template-columns:repeat(3,1fr)}
  .grid-3{grid-template-columns:repeat(3,1fr)}
  .grid-2{grid-template-columns:1fr}
  .grid-exec-charts{grid-template-columns:1fr}
  .grid-copilot-row{grid-template-columns:1fr}
  .grid-env-map{grid-template-columns:1fr}
  .mc-viz{height:340px}
}
/* Abaixo de 1024px a sidebar vira drawer (botao ☰ + scrim), controlado
   por body.nav-open em assets/app.js */
@media (max-width: 1023px){
  #app{grid-template-columns:minmax(0,1fr)}
  .side{position:fixed; left:0; top:0; bottom:0; width:260px; height:100%; transform:translateX(-105%); visibility:hidden; transition:transform .3s var(--ease), visibility 0s .3s}
  body.nav-open .side{transform:none; visibility:visible; transition:transform .3s var(--ease)}
  body.nav-open .scrim{display:block; position:fixed; inset:0; z-index:25; background:rgba(2,4,12,.6); backdrop-filter:blur(2px)}
  body.nav-open{overflow:hidden}
  .menu-btn{display:grid}
  .search{display:none}
  .top{padding:14px 14px 0}
  main{padding:14px 14px 30px}
}
@media (max-width: 720px){
  .top{gap:10px}
  .top h1{font-size:20px}
}
/* Telas estreitas: o selo "dados de exemplo" desce pra linha de baixo
   (continua visivel) pra titulo + botoes caberem numa linha so */
@media (max-width: 560px){
  .top-title{flex:1; min-width:0}
  .top h1{white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
  .top .grow{display:none}
  .tag-demo{order:5; margin-left:48px}
}
@media (max-width: 720px){
  .grid-6{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:1fr}
  .digital-twin-canvas{max-height:360px}
  .hero{padding:18px; gap:18px}
  .hero-score{width:100%; padding-right:0; border-right:none; border-bottom:1px solid var(--border); padding-bottom:16px}
  .hero-score .ring{width:96px; height:96px; margin:0 auto}
  .hero-score-num{font-size:26px}
  .hero-pillar-lbl{width:76px}
}

/* ---------- Sumario Executivo (redesign CMP) ----------
   Linha de 6 KPIs em glass -> holograma + alertas -> 5 cards embaixo.
   Os grids usam minmax(0,...) em tudo pra nunca gerar scroll horizontal. */
.exec{gap:16px}
/* TODA pagina ocupa a altura da tela: a ultima linha de cards estica ate o fim,
   alinhada com a caixa do usuario no rodape da sidebar (ambos a 22px do fim - padding
   de baixo do main = da .side). Vale pra paginas novas do _modelo.html sem fazer nada.
   flex 1 0 auto: nunca encolhe abaixo do conteudo - pagina mais alta que a tela rola
   normal e o alinhamento acontece no fim da rolagem. */
.main-col{display:flex; flex-direction:column; min-height:100vh}
.main-col > main{flex:1 0 auto; display:flex; flex-direction:column; box-sizing:border-box}
#execRoot{flex:1 0 auto; display:flex; flex-direction:column}
main > .view, #execRoot > .view{flex:1 0 auto}
.view > :last-child{flex:1 0 auto}
/* 8 cards numa linha em tela larga (HRD Score + 7 pilares, out/2026); 4 por
   linha abaixo de 1440px e 2 no celular (media queries mais abaixo) */
.kpis{display:grid; grid-template-columns:minmax(0,1.25fr) repeat(7,minmax(0,1fr)); gap:12px}
.kpi-g{padding:12px 12px 10px; overflow:hidden; min-width:0; display:flex; flex-direction:column; color:inherit; animation:kpiIn .6s var(--ease) both; container-type:inline-size}

a.kpi-g{transition:transform .18s var(--ease)}
a.kpi-g:hover{transform:translateY(-2px)}
/* Linhas e titulos que abrem o portal (pagina Security): mesma aparencia, so ganha hover */
a.kpi-g{color:inherit; text-decoration:none}
a.inc-row, a.hd-row{color:inherit; text-decoration:none; cursor:pointer}
a.inc-row:hover .inc-name, a.hd-row:hover .hd-name{color:var(--cyan); text-decoration:underline}
.ph h3 a.ph-link{color:inherit; text-decoration:none}
.ph h3 a.ph-link:hover{color:var(--cyan); text-decoration:underline}
@keyframes kpiIn{from{opacity:0; transform:translateY(10px)}}
.kpi-h{display:flex; align-items:center; gap:8px; color:var(--text-2); font-size:12.5px; font-weight:600; min-width:0}
/* titulo do card com "..." quando nao cabe (cards mais estreitos com 8 na linha) */
.kpi-h .kpi-label{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kpi-h .ico, .kpi-h .kpi-note, .kpi-h .more{flex:none}
.kpi-h .more{margin-left:auto; color:var(--text-3)}
.kpi-v{display:flex; align-items:baseline; gap:8px; margin-top:10px; min-width:0}
.kpi-v b{font:700 24px/1 var(--f-d); letter-spacing:-.03em; white-space:nowrap}
.kpi-v span{font:600 11.5px var(--f-m); white-space:nowrap}
.kpi-v b .kpi-amt{font:inherit; letter-spacing:inherit} /* valor colorido dentro do numero (Resultado do FinOps): mesma fonte/tamanho */
/* variação numa linha própria, embaixo do valor (ex.: FinOps "R$ 1.730,87 melhor · 10%") */
/* "i" ao lado do titulo do KPI: passa o mouse pra ver como o numero e calculado */
.kpi-note{display:inline-flex; color:var(--text-3); cursor:help}
.kpi-note:hover{color:var(--text)}
/* rotulo acima do valor (ex.: FinOps "Custo atual (01 a 04/10)") */
.kpi-g small.kpi-caption{margin-top:10px}
.kpi-g small.kpi-caption + .kpi-v{margin-top:4px}
/* valor secundario, abaixo da nota (ex.: FinOps "R$ 31.068,58" embaixo de "88/100") */
.kpi-v.kpi-v-2 b{font-size:18px}
/* Caixinha de explicacao do KPI ao passar o mouse (ou focar pelo teclado):
   fica DENTRO do card (o .kpi-g tem overflow:hidden), cobrindo a parte de
   baixo, e some ao tirar o mouse. Teste no High Availability (out/2026). */
.kpi-tip{position:absolute; left:8px; right:8px; bottom:8px; z-index:5; padding:9px 11px; border-radius:11px;
  background:rgba(8,12,34,.94); border:1px solid color-mix(in srgb, var(--glow-c, #2BE3FF) 45%, transparent);
  box-shadow:0 8px 24px -8px rgba(0,0,0,.7); color:var(--text-2); font-size:11.5px; font-weight:500; line-height:1.4;
  opacity:0; transform:translateY(6px); pointer-events:none; transition:opacity .18s var(--ease), transform .18s var(--ease)}
.kpi-g:hover .kpi-tip, .kpi-g:focus-visible .kpi-tip{opacity:1; transform:none}
@media (prefers-reduced-motion: reduce){ .kpi-tip{transition:none} }
/* Caixa FIXA de explicacao dentro do card (mesmo visual da .kpi-tip, mas
   sempre visivel e no fluxo normal) - ex.: Security, "e o alarme da casa..." */
.kpi-desc{margin-top:8px; padding:8px 10px; border-radius:11px; background:rgba(8,12,34,.6);
  border:1px solid color-mix(in srgb, var(--glow-c, #2BE3FF) 45%, transparent);
  color:var(--text-2); font-size:11.5px; font-weight:500; line-height:1.4}
/* linhas de apoio clicaveis (ex.: Security "Severidade Alta: 294" -> Defender
   no portal): mesma cor do texto de apoio, so o numero colorido por severidade */
.kpi-g small.kpi-line a{color:inherit; text-decoration:none}
.kpi-g small.kpi-line a:hover{color:var(--text); text-decoration:underline}
.kpi-line b{font-weight:700}
/* respiro entre a nota (ex.: 38/100) e a 1a linha de apoio (Severidade Alta) */
.kpi-g .kpi-v + small.kpi-line{margin-top:14px}
.kpi-line b.sev-high{color:#FF4F5E}
.kpi-line b.sev-med{color:#FFD84D}
.kpi-line b.sev-low{color:#3B9CFF}
/* variacao do Cloud Score no mes: mesma cor/tamanho/fonte do texto de apoio
   dos pilares (.kpi-g small), so o numero colorido (verde sobe, vermelho cai) */
.ks-month{margin-top:6px; font-size:11.5px; color:var(--text-3); white-space:nowrap}
.ks-month b{font-weight:700}
/* variacao em linhas proprias embaixo do valor (ex.: FinOps "R$ 5.649,87 melhor setembro" / "15%");
   pode quebrar linha em vez de cortar, porque o texto em R$ e longo pro card */
.kpi-below{display:grid; gap:2px; margin-top:6px}
.kpi-below span{font-size:11.5px; font-weight:500; color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.kpi-below b{font:700 12.5px var(--f-d); font-variant-numeric:tabular-nums; letter-spacing:.01em} /* fonte dos numeros grandes: na mono pequena o 0 (com ponto dentro) parecia 8 */
/* "comparado com setembro" embaixo da economia - mesmo cinza do texto de apoio */
.kpi-g .kpi-below small.kpi-delta-note{margin-top:0}
/* previsao do mes no KPI FinOps (o "Forecast" do portal): marca listrada roxa a esquerda, como no portal */
.kpi-forecast{display:grid; gap:1px; margin-top:10px; padding-left:9px; position:relative}
.kpi-forecast::before{content:""; position:absolute; left:0; top:1px; bottom:1px; width:3px; border-radius:2px; background:repeating-linear-gradient(135deg, var(--violet) 0 3px, rgba(157,123,255,.35) 3px 6px)}
.kpi-g .kpi-forecast small{margin:0; font-size:11px; color:var(--text-3)}
.kpi-forecast b{font:700 15px/1.15 var(--f-d); letter-spacing:-.01em; color:var(--text); white-space:nowrap}
/* numero do dia embaixo do grafico do KPI (ex.: FinOps 01 05 10 ... 04) -
   cada rotulo centralizado no x do ponto; o 1o e o ultimo alinhados a borda */
.spark-days{position:relative; height:11px; margin-top:2px; font:500 8.5px/1 var(--f-m); color:var(--text-3); opacity:.8}
.spark-days span{position:absolute; top:0; transform:translateX(-50%)}
.spark-days span:first-child{transform:none}
.spark-days span:last-child:not(:first-child){transform:translateX(-100%)}
.kpi-g small{display:block; color:var(--text-3); font-size:11.5px; margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.kpi-g .spark-area{display:block; width:100%; height:34px; margin-top:8px}
/* grafico sempre no fundo do card: todas as linhas na mesma altura */
.kpi-g .kpi-spark{margin-top:auto}
/* descricao do pilar (ex.: "todos os 59 recursos monitorados disponiveis"):
   ate 3 linhas, e "..." so se passar disso */
.kpi-g small.kpi-sub{white-space:normal; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; line-clamp:3; overflow:hidden; line-height:1.35}
/* (fica DEPOIS das regras basicas do card: mesma especificidade, a ultima vence) */
/* Card estreito (ex.: notebook 4K com escala 200%: ~1900px uteis -> 8 cards de
   ~175px): em vez de cortar com "...", titulo e textos do FinOps quebram linha,
   a setinha some e a nota diminui um pouco. Tela larga: nada muda. */
@container (max-width: 210px){
  .kpi-h .kpi-label{white-space:normal; line-height:1.15; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2}
  .kpi-h .more{display:none}
  .kpi-g small.kpi-caption{white-space:normal; line-height:1.3}
  .kpi-below span{white-space:normal; line-height:1.3}
  .kpi-v{gap:5px}
  .kpi-v b{font-size:21px}
  .kpi-v.kpi-v-2 b{font-size:16.5px}
  .kpi-v span{font-size:10.5px}
}.kpi-score{display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:12px}
/* CLOUD Score em destaque: --sc = cor da nota (A verde, B amarelo, C laranja, D
   vermelho - ver KpiRow.jsx). Fundo, borda, brilho e anel seguem essa cor,
   pro estado do ambiente ficar visivel de longe. */
.kpi-score.graded{--sc:#2BE3FF; border-color:color-mix(in srgb, var(--sc) 45%, transparent);
  background:radial-gradient(120% 140% at 0% 0%, color-mix(in srgb, var(--sc) 26%, transparent), transparent 60%), linear-gradient(160deg, rgba(20,28,70,.75), rgba(10,14,40,.6));
  box-shadow:0 0 0 1px color-mix(in srgb, var(--sc) 18%, transparent) inset, 0 10px 40px -14px color-mix(in srgb, var(--sc) 60%, transparent)}
.kpi-score.graded .score-ring{width:110px; height:110px}
.kpi-score.graded .score-ring svg{filter:drop-shadow(0 0 10px color-mix(in srgb, var(--sc) 75%, transparent))}
.kpi-score.graded .score-ring b{font-size:38px; color:#fff; text-shadow:0 0 14px color-mix(in srgb, var(--sc) 60%, transparent)}
.kpi-score.graded .kpi-h{font:700 18px var(--f-d); color:var(--sc); letter-spacing:.01em; white-space:nowrap}
.kpi-score .grade{justify-self:start; padding:3px 9px; border-radius:999px; font:600 11.5px var(--f-m);
  color:var(--sc); background:color-mix(in srgb, var(--sc) 14%, transparent); border:1px solid color-mix(in srgb, var(--sc) 40%, transparent); white-space:nowrap}
/* Layout do CLOUD Score pela largura do PROPRIO card (container query), nao
   da tela: largo = anel a esquerda, titulo + nota a direita; estreito (a
   linha de 6 KPIs em telas ~1400-1600px deixa o card com ~190px) = anel
   menor ao lado do titulo e a nota numa linha propria, sem cortar texto. */
.kpi-score:has(.kpi-score-in){display:block; container-type:inline-size}
.kpi-score-in{display:grid; grid-template-columns:auto minmax(0,1fr); grid-template-areas:"ring head" "ring grade"; align-items:center; column-gap:12px; row-gap:8px; height:100%}
.kpi-score-in .ks-ring{grid-area:ring}
.kpi-score-in .ks-head{grid-area:head; align-self:end; min-width:0}
.kpi-score-in .grade{grid-area:grade; align-self:start}
@container (max-width: 250px){
  .kpi-score-in{grid-template-areas:"ring head" "grade grade"; column-gap:10px}
  .kpi-score-in .ks-head{align-self:center}
  .kpi-score.graded .score-ring{width:86px; height:86px}
  .kpi-score.graded .score-ring b{font-size:38px}
}
/* bem estreito (notebook Full HD com escala 125%: cards de ~140px): nota menor pro "100/100 0 pts" caber */
@container (max-width: 150px){
  .kpi-v b{font-size:18px}
  .kpi-v span{font-size:10px}
}
/* HRD Score com velocimetro (gauge() em charts.js), empilhado:
   titulo + variacao do mes -> velocimetro -> numero + "Nota <faixa>".
   --sc = cor do segmento onde o ponteiro esta (scoreBand). */
.kpi-score:has(.kpi-gauge-in){display:block}
.kpi-gauge-in{display:flex; flex-direction:column; height:100%}
.kpi-gauge-in .ks-head{display:flex; align-items:baseline; justify-content:space-between; gap:8px; min-width:0}
.kpi-gauge-in .ks-head .ks-month{margin-top:0}
.kpi-gauge-in .ks-gauge{margin:10px auto 0; width:100%; max-width:190px}
.kpi-gauge-in .gauge{display:block; width:100%; height:auto}
.kpi-gauge-in .ks-foot{flex:1; display:flex; flex-direction:column; align-items:center; margin-top:4px}
/* etiqueta "Status: Otimo" numa linha propria, centralizada embaixo do numero:
   contorno e "Status:" em branco, so o nome da faixa na cor dela */
/* margem auto em cima e embaixo: a etiqueta fica centralizada na sobra entre o numero e a borda de baixo */
.kpi-gauge-in .ks-foot .grade{margin:auto 0; justify-self:auto; padding:4px 12px; font-size:13.5px; color:#fff; border-color:rgba(255,255,255,.75); background:rgba(255,255,255,.06)}
.kpi-gauge-in .ks-foot .grade b{color:var(--sc); font:inherit; font-weight:700}
.kpi-gauge-in .ks-foot > b{font:700 46px/1 var(--f-d); color:var(--sc); text-shadow:0 0 14px color-mix(in srgb, var(--sc) 60%, transparent)}

.score-ring{position:relative; width:86px; height:86px}
.score-ring svg{width:100%; height:100%; transform:rotate(-90deg); filter:drop-shadow(0 0 8px rgba(43,227,255,.7))}
.score-ring b{position:absolute; inset:0; display:grid; place-items:center; font:700 26px var(--f-d)}

.exec-mid{display:grid; grid-template-columns:minmax(0,1fr) 360px; gap:16px}
/* Tela larga: linha do holograma com altura fixa (antes 500px+ e esticava
   com a lista de alertas, ~570px) - a lista de alertas rola por dentro do
   card quando nao cabe, em vez de esticar a linha. Abaixo de 1180px os dois
   empilham e voltam a altura natural (ver media query mais abaixo). */
@media (min-width: 1181px){
  .exec-mid{grid-template-rows:420px}
  .exec-mid .holo{min-height:0}
  .exec-mid .panel{min-height:0}
  .exec-mid .panel .alerts{overflow-y:auto; min-height:0; padding-right:4px; scrollbar-width:thin}
}
/* 3 cards de Service Health + Copilot Insights (um pouco mais largo) */
.exec-bot{display:grid; grid-template-columns:minmax(0,1.15fr) repeat(3,minmax(0,1fr)) 360px; gap:16px} /* Monitor (+largo) + 3 Service Health na largura do holograma; coluna Azure/DevOps Status com os mesmos 360px dos Alertas prioritarios (bordas alinhadas com a linha de cima) */
/* ultima coluna dividida ao meio: Azure Status em cima, DevOps Status embaixo, mesma altura */
.exec-stack{display:grid; grid-template-rows:1fr 1fr; gap:16px; min-width:0}
.exec-stack > .bc{min-height:0; overflow:hidden}

/* Cabecalho de painel: .ico + titulo + acao/selo a direita */
.ph{display:flex; align-items:center; gap:10px; margin-bottom:14px; min-width:0}
.ph h3{margin:0; font:600 15px var(--f-d); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
/* titulo + frase curta embaixo dele (CardHead com subtitle) */
.ph .ph-titles{display:flex; flex-direction:column; gap:2px; min-width:0}
.ph .ph-sub{color:var(--text-3); font-size:11.5px; line-height:1.3;
  /* frase inteira (ate 3 linhas, antes cortava em 2 - pedido do Charles, 19/10/2026) e
     sempre a altura de 3 linhas: cards lado a lado com frases de tamanhos diferentes
     ficam com o numero grande na mesma altura, um pouco mais abaixo */
  min-height:calc(3 * 1.3em); display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; line-clamp:3; overflow:hidden}
/* meia altura (Azure Status / DevOps Status empilhados): sem a reserva de 3 linhas */
.exec-stack .ph .ph-sub{min-height:0}
.ph .more{margin-left:auto; font-size:12px; color:var(--text-3); font-weight:600; white-space:nowrap}
.ph a.more:hover{color:var(--cyan)}
.ph .source-badge{margin-left:auto}

.panel{padding:18px; display:flex; flex-direction:column; --glow-c:#FF4F7B; --glow:rgba(255,79,123,.8)}
.alerts{list-style:none; margin:0; padding:0; display:grid; gap:9px}
.alerts li > *{display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:11px; padding:11px 11px 11px 14px; border-radius:14px;
  background:rgba(255,255,255,.025); border:1px solid rgba(255,255,255,.05); position:relative; overflow:hidden; color:inherit; transition:border-color .2s, background .2s}
.alerts li > a:hover{border-color:color-mix(in srgb, var(--c) 45%, transparent); background:rgba(255,255,255,.04)}
.alerts li > *::before{content:""; position:absolute; left:0; top:10px; bottom:10px; width:3px; border-radius:2px; background:var(--c); box-shadow:0 0 10px var(--c)}
.alerts p{margin:0; font-weight:600; font-size:13px; line-height:1.35}
.alerts .meta{display:flex; align-items:center; gap:8px; margin-top:5px; color:var(--text-3); font-size:11.5px}
.alerts .go{color:var(--text-3)}
.sev{font:700 10px var(--f-m); padding:2px 7px; border-radius:6px; color:var(--c); background:color-mix(in srgb, var(--c) 15%, transparent)}

.bc{padding:16px; display:flex; flex-direction:column; gap:10px; min-width:0; color:inherit}
.bc .ph{margin:0}
a.bc{transition:transform .18s var(--ease)}
a.bc:hover{transform:translateY(-2px)}
.bc .big{font:700 24px/1 var(--f-d); letter-spacing:-.02em}
.bc .sub{color:var(--text-3); font-size:12px; margin-top:4px}
.bc .row{display:flex; justify-content:space-between; align-items:center; gap:10px; font-size:12.5px; color:var(--text-2)}
.bc .row b{color:var(--text); font:600 12px var(--f-m); white-space:nowrap}
.bc .row b.dn{color:var(--red)}
.copilot{--glow-c:#9D7BFF; --glow:rgba(157,123,255,.9); background:linear-gradient(160deg, rgba(60,40,140,.45), rgba(16,24,58,.55) 60%)}
.ins{padding:10px 11px; border-radius:12px; background:rgba(5,8,22,.45); border:1px solid rgba(157,123,255,.25); font-size:12.5px; line-height:1.45; color:var(--text-2)}
.ins b{color:var(--text)}
/* Card Azure Monitor (MonitorCard.jsx): linha de severidades + aviso de ruido */
.mon-sev{display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:4px; text-align:center}
.mon-sev span, .mon-sev a{padding:5px 0; border-radius:9px; background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.05); color:inherit; text-decoration:none}
/* cada severidade e link pro portal (consulta dos alertas abertos dela) */
.mon-sev a{transition:border-color .15s, background .15s}
.mon-sev a:hover{border-color:rgba(255,255,255,.25); background:rgba(255,255,255,.07)}
.mon-sev small{display:block; font:600 9.5px var(--f-m); color:var(--text-3); letter-spacing:.03em}
.mon-sev b{font:700 12px var(--f-m)}
.mon-noise{display:flex; gap:7px; align-items:flex-start; padding:8px 10px; border-radius:11px; font-size:11.5px; line-height:1.4; color:var(--text-2);
  background:rgba(255,176,32,.07); border:1px solid rgba(255,176,32,.25)}
.mon-noise b{color:var(--text)}
/* Evento do Azure Service Health (HealthEventsCard) */
.hev{padding:9px 11px; border-radius:12px; background:rgba(255,255,255,.025); border:1px solid rgba(255,255,255,.05); display:grid; gap:4px}
/* titulo do evento em no maximo 2 linhas, com "..." - os titulos da Azure
   sao longos (ate 4 linhas) e faziam a pagina rolar; o completo fica no
   title (passar o mouse) */
.hev-t{font-weight:600; font-size:12.5px; line-height:1.35; color:var(--text);
/* etiqueta do nivel do evento (Health Advisories): Critical vermelho, Warning amarelo, Info cinza */
.hev-lvl{display:inline-block; margin-right:6px; padding:1px 6px; border-radius:999px; font:600 9.5px/1.4 var(--f-m); font-style:normal; letter-spacing:.04em; text-transform:uppercase; vertical-align:1px}
.hev-lvl.lvl-critical{color:#FF6B7F; background:rgba(255,79,123,.14); border:1px solid rgba(255,79,123,.45)}
.hev-lvl.lvl-warning{color:#FFD66B; background:rgba(255,190,77,.12); border:1px solid rgba(255,190,77,.45)}
.hev-lvl.lvl-info{color:var(--text-3); background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.18)}
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-clamp:2; overflow:hidden}
.hev .row{font-size:11.5px; color:var(--text-3)}

@media (max-width: 1440px){
  .kpis{grid-template-columns:repeat(4,minmax(0,1fr))}
  .exec-bot{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width: 1180px){
  .exec-mid{grid-template-columns:minmax(0,1fr)}
  .panel .alerts{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width: 760px){
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kpi-score{grid-column:1/-1}
  .exec-bot{grid-template-columns:minmax(0,1fr)}
  .panel .alerts{grid-template-columns:minmax(0,1fr)}
}
@media (prefers-reduced-motion: reduce){ .kpi-g{animation:none} }

/* Card do holograma: o <canvas> do R3F ocupa o card inteiro, cabecalho e
   rodape ficam por cima (pointer-events:none pra nao atrapalhar o arraste) */
.holo{min-height:500px; overflow:hidden; padding:0; --glow-c:#2BE3FF; --glow:rgba(43,227,255,.9)}
.holo-canvas{position:absolute; inset:0; border-radius:inherit; overflow:hidden}
.holo-canvas canvas{display:block; width:100%!important; height:100%!important; touch-action:pan-y}
.holo-h{position:absolute; z-index:3; top:16px; left:18px; right:18px; display:flex; align-items:flex-start; gap:12px; pointer-events:none}
.holo-h h2{margin:0; font:600 17px var(--f-d)}
.holo-h p{margin:3px 0 0; color:var(--text-2); font-size:12.5px}
.holo-h .source-badge{margin-left:auto}
.holo-f{position:absolute; z-index:3; left:18px; right:18px; bottom:16px; display:flex; gap:10px; flex-wrap:wrap; pointer-events:none}
@media (max-width: 760px){ .holo{min-height:460px} }

/* Etiquetas dos provedores no holograma (HTML real via drei/Html).
   .off = provedor nao conectado: apagado, borda tracejada, sem numeros. */
.holo-lbl{transform:translate(var(--dx,0px), calc(-60% + var(--dy,0px))); padding:9px 12px; border-radius:13px; min-width:132px; white-space:nowrap;
  background:rgba(6,10,30,.72); border:1px solid color-mix(in srgb, var(--c) 55%, transparent); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  box-shadow:0 0 24px -6px var(--c), inset 0 1px 0 rgba(255,255,255,.06); font-family:var(--f-b); color:var(--text)}
.holo-lbl b{display:flex; align-items:center; gap:7px; font:600 13px var(--f-d)}
.holo-lbl b img{width:20px; height:20px; object-fit:contain; filter:drop-shadow(0 0 6px var(--c))}
.holo-lbl div{display:flex; justify-content:space-between; gap:12px; margin-top:4px; color:var(--text-2); font-size:11.5px}
.holo-lbl div span:last-child{color:var(--text); font-family:var(--f-m)}
.holo-lbl.off{opacity:.62; border-style:dashed; box-shadow:none; min-width:0}
.holo-lbl .nc{font:600 10.5px var(--f-m); color:var(--text-3); text-transform:uppercase; letter-spacing:.04em}
@media (max-width: 760px){
  .holo-lbl{padding:6px 9px; min-width:0; background:rgba(6,10,30,.9)}
  .holo-lbl b{font-size:12px}
  .holo-lbl div{font-size:10.5px}
  .holo-lbl div:nth-of-type(n+3){display:none} /* "Regiões" fica no rodapé do card */
}

/* ---------- Molde das paginas de modulo (mesmo do Sumario Executivo) ----------
   Estrutura: <div class="view exec"> -> banners .api-banner -> linha de KPIs
   (.kpis, ou .kpis-3 pra 3 caixas) -> .page-grid de cards .glass.bc com
   cabecalho .ph. Ver static/_modelo.html. */
.kpis-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.kpis-3 .kpi-h > span:not(.ico){min-width:0}
/* resumo do mes (16/10/2026, pedido do Charles): as 3 caixas de cima se destacam das
   listas de baixo - fundo tingido com a cor da caixa (--glow-c), borda e brilho mais
   fortes e uma faixa colorida no topo */
.kpis-3 .kpi-g{background:linear-gradient(150deg, color-mix(in srgb, var(--glow-c, #3B9CFF) 24%, var(--glass-hi)), color-mix(in srgb, var(--glow-c, #3B9CFF) 9%, var(--glass)) 60%, rgba(8,12,34,.6));
  border-color:color-mix(in srgb, var(--glow-c, #3B9CFF) 45%, transparent);
  box-shadow:var(--shadow-glass), 0 0 28px -10px color-mix(in srgb, var(--glow-c, #3B9CFF) 75%, transparent)}
.kpis-3 .kpi-g::after{content:""; position:absolute; left:16px; right:16px; top:0; height:3px; border-radius:0 0 3px 3px; pointer-events:none;
  background:linear-gradient(90deg, transparent, var(--glow-c, #3B9CFF), transparent); box-shadow:0 0 12px var(--glow-c, #3B9CFF)}
.ph .ph-end{margin-left:auto; flex:none}
.ph .ph-end:empty{display:none}
.kpi-h .ph-end{margin-left:auto; flex:none}
.page-grid{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px}
.page-grid > .span-2{grid-column:1/-1}
/* Variante com 3 cards lado a lado (ex.: FinOps assinatura/categoria/novos) */
.page-grid.page-grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}
/* 4 cards lado a lado (FinOps Azure, 15/10/2026: Top 10 aumentos, assinatura,
   categoria, novos) - caixas estreitas, entao listas compactas e barras embaixo do nome */
.page-grid.page-grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}
.page-grid-4 .hbar-row{grid-template-columns:minmax(0,1fr) auto; row-gap:3px; padding:4px 2px}
.page-grid-4 .hbar-track{grid-column:1/-1; grid-row:2; height:6px}
.page-grid-4 .hbar-val{font-size:12px}
.page-grid-4 .sub-cost{white-space:nowrap}
/* lista compacta: nome e detalhe em 1 linha cada (corta com ...; o texto todo fica no title) */
.inc-list-compact .inc-row{padding:3px 2px; gap:8px}
.inc-list-compact .inc-main{min-width:0}
.inc-list-compact .inc-name{font-size:12.5px; line-height:1.35; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.inc-list-compact .inc-desc{font-size:11px; line-height:1.3; margin-top:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.inc-list-compact .inc-domain{display:none}
.inc-list-compact .inc-value{font-size:12px; white-space:nowrap}
.bc .chart-wrap, .bc .hbars, .bc .flist, .bc .sub-list, .bc .inc-list{margin-top:2px}
.api-banner{border-radius:var(--r); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px); margin-bottom:0}
@media (max-width: 1180px){
  .page-grid, .page-grid.page-grid-3{grid-template-columns:minmax(0,1fr)}
}
@media (min-width: 761px) and (max-width: 1400px){
  .page-grid.page-grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width: 760px){
  .page-grid.page-grid-4{grid-template-columns:minmax(0,1fr)}
}
@media (max-width: 760px){
  .kpis-3{grid-template-columns:minmax(0,1fr)}
}
/* Telas estreitas: titulo do card quebra linha em vez de cortar com "…" */
@media (max-width: 560px){ .ph h3{white-space:normal; overflow:visible; line-height:1.25} }

/* Destaque rapido de um card quando o usuario chega nele por um atalho
   (ex.: sino da topbar -> Alertas prioritarios, ver assets/app.js). */
@keyframes cardFlash{0%,100%{box-shadow:none} 30%{box-shadow:0 0 0 2px var(--red), 0 0 34px -4px var(--red)}}
.flash{animation:cardFlash 1.4s var(--ease) 2}
@media (prefers-reduced-motion: reduce){ .flash{animation:none; outline:2px solid var(--red); outline-offset:2px} }

/* ===================== Tela de login (static/login.html) =====================
   Visual "futurista" (referencia do Charles, out/2026): ceu estrelado, globo
   digital pontilhado no centro com orbitas e nos de servicos, plataforma com
   aneis pulsando na base, cartao de vidro com o login a direita, cards de
   modulos embaixo. Prefixo lg- (evita colidir com .ring/.orbit do app).
   Abaixo de 1180px: palco some e o cartao vem logo depois do texto;
   abaixo de 760px: tudo em 1 coluna. Reduced-motion: nada se mexe. */
.lg-body{margin:0; min-height:100vh; background:#02040F; color:#EAF0FF; font-family:var(--f-b); overflow-x:hidden}
.lg-bg{position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden;
  background:radial-gradient(1100px 720px at 50% 40%, rgba(110,50,255,.34), transparent 70%), radial-gradient(900px 600px at 12% 92%, rgba(90,40,210,.22), transparent 70%), #04020F}
.lg-stars{position:absolute; inset:-50%; background-image:
  radial-gradient(1px 1px at 20px 30px, rgba(255,255,255,.7), transparent), radial-gradient(1px 1px at 120px 80px, rgba(160,200,255,.6), transparent),
  radial-gradient(1.5px 1.5px at 200px 160px, rgba(255,255,255,.5), transparent), radial-gradient(1px 1px at 310px 40px, rgba(180,210,255,.55), transparent),
  radial-gradient(1px 1px at 400px 210px, rgba(255,255,255,.45), transparent);
  background-size:420px 260px; animation:lgStars 160s linear infinite; opacity:.7}
.lg-planet{position:absolute; width:900px; height:900px; left:50%; top:-560px; transform:translateX(-30%); border-radius:50%;
  background:radial-gradient(circle at 60% 85%, rgba(140,90,255,.35), rgba(40,14,120,.25) 45%, transparent 70%); box-shadow:0 40px 140px rgba(110,60,255,.25)}
.lg-glow{position:absolute; left:28%; right:28%; bottom:18%; height:220px; background:radial-gradient(ellipse at center, rgba(60,130,255,.35), transparent 70%); filter:blur(30px)}
@keyframes lgStars{to{transform:translate(420px,260px)}}
.lg-body > *:not(.lg-bg){position:relative; z-index:1}

/* topo */
.lg-top{display:grid; grid-template-columns:1fr auto auto; gap:40px; align-items:start; max-width:1640px; margin:0 auto; padding:26px 40px 0; box-sizing:border-box}
.lg-brand{display:flex; align-items:center; gap:14px}
.lg-brand img{width:62px; height:62px; object-fit:contain; filter:drop-shadow(0 0 14px rgba(59,156,255,.6))}
.lg-word{font:300 32px/1 var(--f-d); letter-spacing:.02em}
.lg-word b{font-weight:700}
.lg-tag{margin-top:6px; font:400 15px var(--f-b); color:#B9C6EE}
.lg-brand.sm img{width:36px; height:36px}
.lg-brand.sm .lg-word{font-size:18px}
.lg-brand.sm .lg-tag{font-size:11px; margin-top:3px}
.lg-kicker{font:500 10.5px var(--f-m); letter-spacing:.32em; color:#5FA8FF; line-height:1.9; padding-top:8px}
.lg-kicker .dim{color:#4A6BB8; letter-spacing:.22em}
.lg-motto{font:500 10px var(--f-m); letter-spacing:.3em; color:#7E8FC4; line-height:1.9; border-left:1px solid rgba(96,140,255,.3); padding-left:16px}

/* corpo em 3 colunas */
.lg-main{display:grid; grid-template-columns:310px minmax(0,1fr) 390px; gap:24px; align-items:center; max-width:1640px; margin:0 auto; padding:10px 40px 0; box-sizing:border-box}
.lg-left h1{margin:0 0 16px; font:500 32px/1.15 var(--f-d); letter-spacing:-.01em}
.lg-left h1 em{font-style:normal; font-weight:700; color:#2BB4FF; text-shadow:0 0 22px rgba(43,180,255,.55)}
.lg-lead{margin:0 0 26px; color:#AFC0EA; font-size:14.5px; line-height:1.55}
.lg-feats{list-style:none; margin:0; padding:0; display:grid; gap:16px}
.lg-feats li{display:flex; gap:14px; align-items:center}
.lg-feats svg{width:30px; height:30px; flex:none; fill:none; stroke:#4FB0FF; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; filter:drop-shadow(0 0 6px rgba(79,176,255,.6))}
.lg-feats b{display:block; font:600 14.5px var(--f-b)}
.lg-feats span{display:block; margin-top:2px; font-size:12.5px; color:#8696C6}

/* palco central: cena SVG flutuante (globo pontilhado, orbitas e 8 nos a cada 45 graus,
   mesmo tamanho e brilho, fundo transparente) - vetorial, nitida em qualquer largura. Os
   continentes deslizam dentro do globo (lg-land) pra parecer que ele gira. */
.lg-stage{position:relative; width:100%; margin:0 auto}
.lg-scene{display:block; width:100%; height:auto; overflow:visible}
.lg-t1{font:700 44px var(--f-d); fill:#fff}
.lg-t2{font:300 40px var(--f-d); fill:#CDBBFF; letter-spacing:.04em}
.lg-t3{font:600 8.5px var(--f-m); fill:#E4DAFF; letter-spacing:.16em}
.lg-nl{font:600 13px var(--f-b); fill:#F3EEFF}
.lg-land{animation:lgLand 60s linear infinite}
.lg-ring-spin{transform-box:fill-box; transform-origin:center; animation:lgSpinSvg 120s linear infinite}
.lg-nf{animation:lgFloat 6s ease-in-out infinite}
@keyframes lgLand{to{transform:translateX(300px)}}
@keyframes lgSpinSvg{to{transform:rotate(360deg)}}
@keyframes lgFloat{50%{transform:translateY(-5px)}}

/* cartao de login */
.lg-card{padding:34px 34px 30px; border-radius:22px; background:linear-gradient(165deg, rgba(14,28,84,.82), rgba(6,12,44,.88));
  border:1.5px solid rgba(70,140,255,.7); box-shadow:0 0 0 1px rgba(40,90,255,.25) inset, 0 0 40px rgba(40,110,255,.45), 0 30px 80px -30px rgba(0,0,0,.9);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px)}
.lg-welcome{font:500 13px var(--f-b); letter-spacing:.12em; color:#B9C6EE}
.lg-card h2{margin:8px 0 4px; font:300 36px/1 var(--f-d); letter-spacing:.02em}
.lg-card h2 b{font-weight:700}
.lg-card-tag{font-size:15px; color:#B9C6EE}
.lg-card-txt{margin:18px 0 22px; font-size:14.5px; line-height:1.5; color:#D5DEF7}
.lg-msg{margin:0 0 16px; padding:11px 13px; border-radius:12px; font-size:13px; line-height:1.45}
.lg-msg.ok{color:#B6FFE4; background:rgba(52,245,176,.1); border:1px solid rgba(52,245,176,.35)}
.lg-msg.warn{color:#FFE2A8; background:rgba(255,190,77,.1); border:1px solid rgba(255,190,77,.4)}
.lg-msg.err{color:#FFC2D1; background:rgba(255,79,123,.1); border:1px solid rgba(255,79,123,.4)}
.lg-field{display:flex; align-items:center; gap:12px; padding:0 14px; height:50px; border-radius:10px; background:rgba(4,10,36,.7); border:1px solid rgba(110,150,255,.35)}
.lg-field:focus-within{border-color:#4FA8FF; box-shadow:0 0 0 3px rgba(79,168,255,.2)}
.lg-field svg{width:20px; height:20px; flex:none; fill:none; stroke:#9BB0E6; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
.lg-field input{flex:1; min-width:0; background:none; border:0; outline:0; color:#EAF0FF; font:400 16px var(--f-b)}
.lg-field input::placeholder{color:#7F8DB8}
.lg-primary{margin-top:16px; width:100%; height:54px; border:0; border-radius:10px; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:10px;
  font:600 16px var(--f-b); color:#fff; background:linear-gradient(90deg, #1E6BFF, #4B3BFF 55%, #7A3BFF); box-shadow:0 10px 30px -8px rgba(70,90,255,.8);
  transition:transform .15s var(--ease), box-shadow .15s var(--ease)}
.lg-primary:hover{transform:translateY(-1px); box-shadow:0 14px 36px -8px rgba(90,100,255,.95)}
.lg-primary svg{width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round}
.lg-note{margin:10px 0 0; font-size:11.5px; color:#7F8DB8; text-align:center}
.lg-or{display:flex; align-items:center; gap:12px; margin:18px 0; font:500 12px var(--f-b); color:#9BA8D4}
.lg-or::before, .lg-or::after{content:""; flex:1; height:1px; background:rgba(110,150,255,.3)}
.lg-ms{display:flex; align-items:center; justify-content:center; gap:14px; height:54px; border-radius:10px; text-decoration:none;
  font:600 15px var(--f-b); color:#EAF0FF; background:rgba(4,10,36,.55); border:1px solid rgba(200,215,255,.55); transition:background .15s, border-color .15s}
.lg-ms:hover{background:rgba(30,50,120,.6); border-color:#fff}
.lg-ms-logo{width:24px; height:24px}
.lg-primary:focus-visible, .lg-ms:focus-visible{outline:3px solid #2BE3FF; outline-offset:3px}

/* modulos embaixo */
.lg-mods{display:grid; grid-template-columns:repeat(5,minmax(0,1fr)) minmax(0,1.6fr); gap:14px; max-width:1640px; margin:26px auto 0; padding:0 40px; box-sizing:border-box}
.lg-mods article{padding:16px; border-radius:12px; background:rgba(8,16,52,.7); border:1px solid rgba(80,130,255,.28)}
.lg-mods article > span{display:inline-grid; place-items:center; width:38px; height:38px; border-radius:10px; vertical-align:middle; margin-right:10px;
  background:color-mix(in srgb, var(--c) 14%, transparent); border:1px solid color-mix(in srgb, var(--c) 55%, transparent)}
.lg-mods article > span svg{width:20px; height:20px; fill:none; stroke:var(--c); stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round}
.lg-mods article > b{display:inline-block; vertical-align:middle; font:600 13px/1.25 var(--f-b)}
.lg-mods article p{margin:12px 0 0; font-size:12px; line-height:1.45; color:#9BA8D4}
.lg-mods .lg-360{background:linear-gradient(160deg, rgba(30,40,120,.6), rgba(10,16,52,.75)); border-color:rgba(110,150,255,.45)}
.lg-360-head{display:flex; align-items:center; gap:10px; font:600 15px var(--f-d)}
.lg-360-head svg{width:24px; height:24px; fill:none; stroke:#4FB0FF; stroke-width:1.8; stroke-linecap:round}
.lg-mods .lg-360 p{margin:10px 0 12px}
.lg-360-logos{display:flex; gap:10px}
.lg-360-logos img{width:30px; height:30px; object-fit:contain; padding:5px; border-radius:8px; background:rgba(255,255,255,.06); border:1px solid rgba(110,150,255,.3)}
.lg-360-logos img.off{opacity:.35; filter:grayscale(1)}

/* rodape */
.lg-foot{display:flex; align-items:center; justify-content:space-between; gap:20px; max-width:1640px; margin:26px auto 0; padding:18px 40px 26px; box-sizing:border-box; border-top:1px solid rgba(80,130,255,.18)}
.lg-slogan{font:500 10.5px var(--f-m); letter-spacing:.24em; color:#4A6BB8}
.lg-slogan b{color:#4FB0FF}

/* TESTE (out/2026): imagem pronta assets/bg-sphere.webp no login, ligada por
   ?visual=palco ou ?visual=fundo (script do login.html poe body.lg-photo +
   lg-v-palco/lg-v-fundo). Sem parametro, fica o globo SVG. */
/* imagem inteira (contain, nenhum no cortado). Onde sobra tela (em cima/embaixo
   ou nas laterais, conforme a proporcao), o fundo e a MESMA cor do espaco da
   imagem (#020613, medido nas bordas dela) + as estrelas da pagina, e as bordas
   da imagem somem num degrade - assim nao aparece faixa nem emenda. */
.lg-photo .lg-bg{background:#020613}
/* a camada tem o tamanho exato da imagem (3:2, o maior que cabe na tela). Da
   imagem so aproveitamos o GLOBO (centro 766,496 px, raio 296 - medido): o ::before
   recorta um circulo com borda suave e apaga os icones originais dela. Por cima
   vai o anel .lg-ring (SVG no login.html, mesmo sistema de coordenadas da imagem)
   com os pilares do dashboard - cores e icones iguais aos cards do Sumario. */
.lg-photo .lg-glow{left:50%; top:50%; right:auto; bottom:auto; width:min(100vw, 150vh); height:auto; aspect-ratio:3/2; transform:translate(-50%,-50%); filter:none; background:none}
.lg-photo .lg-glow::before{content:""; position:absolute; inset:0; background:url(/assets/bg-sphere.webp?v=3) center/100% 100% no-repeat;
  -webkit-mask-image:radial-gradient(ellipse 19.4% 29.1% at 49.87% 48.44%, #000 95%, transparent 100%);
          mask-image:radial-gradient(ellipse 19.4% 29.1% at 49.87% 48.44%, #000 95%, transparent 100%)}
.lg-ring{display:none}
.lg-photo .lg-ring{display:block; position:absolute; inset:0; width:100%; height:100%; overflow:visible}
.lg-rn{font:600 22px var(--f-b); fill:#F2F6FF}
.lg-photo .lg-planet{display:none}
.lg-photo .lg-stars{opacity:.45}
/* palco: so marca no topo + cartao no centro, por cima do globo da imagem */
.lg-v-palco .lg-left, .lg-v-palco .lg-stage, .lg-v-palco .lg-mods, .lg-v-palco .lg-kicker,
.lg-v-palco .lg-motto, .lg-v-palco .lg-foot{display:none}
.lg-v-palco .lg-main{grid-template-columns:minmax(0,380px); justify-content:center; min-height:calc(100vh - 120px); padding-bottom:40px}
.lg-v-palco .lg-card{background:rgba(6,12,44,.5); backdrop-filter:blur(10px) saturate(1.2); -webkit-backdrop-filter:blur(10px) saturate(1.2)}
/* fundo: layout atual, globo SVG some e o da imagem aparece no meio; bordas
   escurecidas pra ler o texto da esquerda e o cartao */
.lg-v-fundo .lg-bg::after{content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(2,4,15,.88) 0, rgba(2,4,15,.45) 26%, rgba(2,4,15,.1) 45%, rgba(2,4,15,.1) 58%, rgba(2,4,15,.5) 72%, rgba(2,4,15,.88) 100%)}
.lg-v-fundo .lg-stage{visibility:hidden}
/* imagem menor no formato fundo (72% da largura), pra os nos das laterais nao
   ficarem por baixo do texto da esquerda, do cartao e do slogan do rodape */
.lg-v-fundo .lg-glow{width:min(72vw, 108vh)}
/* sem os cards de modulos nem o rodape (pedido do Charles): o anel ja mostra os
   pilares e a linha/slogan do rodape ficavam por cima da imagem */
.lg-v-fundo .lg-mods, .lg-v-fundo .lg-foot{display:none}

@media (max-width: 1180px){
  .lg-main{grid-template-columns:minmax(0,1fr) 400px}
  .lg-stage{display:none}
  .lg-mods{grid-template-columns:repeat(3,minmax(0,1fr))}
  .lg-motto{display:none}
}
@media (max-width: 760px){
  .lg-top{grid-template-columns:1fr; padding:20px 16px 0}
  .lg-kicker{display:none}
  .lg-main{grid-template-columns:minmax(0,1fr); padding:16px 16px 0}
  .lg-card{order:-1; padding:26px 22px}
  .lg-left h1{font-size:26px}
  .lg-mods{grid-template-columns:minmax(0,1fr); padding:0 16px}
  .lg-foot{flex-direction:column; align-items:flex-start; padding:18px 16px}
}
@media (prefers-reduced-motion: reduce){
  .lg-stars, .lg-land, .lg-ring-spin, .lg-nf{animation:none}
}

/* ===================== Tela de login (imagem) (static/login.html) =====================
   A tela e a arte pronta assets/login-v2.webp (3:2). .li-stage tem a proporcao
   dela e o maior tamanho que cabe na janela, centralizada; a sobra e da cor da
   borda da imagem (#020D3C) e as bordas dela somem num degrade curto. Por cima:
   .li-card (cartao de login de verdade, no lugar do desenhado que foi apagado
   da arte). Unidades cqw = % da largura da
   imagem, pra tudo crescer junto com ela. Abaixo de 900px / tela em pe: .li-mobile. */
/* Desde 08/10/2026 a arte fica num PAINEL arredondado, menor e centralizado (como
   uma moldura), sobre um fundo de espaco com estrelas - a borda do painel e
   intencional, entao nao ha mais sobra/emenda nas bordas da tela. */
.li-body{margin:0; min-height:100vh; display:grid; place-items:center; color:#EAF0FF; font-family:var(--f-b); overflow-x:hidden;
  background:radial-gradient(1200px 700px at 50% 45%, rgba(110,70,255,.32), transparent 70%), radial-gradient(800px 500px at 85% 10%, rgba(60,90,255,.22), transparent 70%), linear-gradient(180deg, #1A1550, #0D0A33 60%, #090725)}
/* estrelas: pontinhos em 3 camadas, sobre o fundo padrao do tema */
.li-body::before{z-index:0; background-image:
  radial-gradient(1.2px 1.2px at 20px 30px, rgba(255,255,255,.75), transparent), radial-gradient(1px 1px at 140px 90px, rgba(190,200,255,.6), transparent),
  radial-gradient(1.6px 1.6px at 230px 170px, rgba(255,255,255,.55), transparent), radial-gradient(1px 1px at 330px 50px, rgba(200,190,255,.6), transparent),
  radial-gradient(1.3px 1.3px at 410px 220px, rgba(255,255,255,.5), transparent);
  background-size:440px 260px; opacity:.8}
.li-body::after{display:none}
.li-sr{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
/* painel: 3:2, ate 1080px / 76% da largura / altura da tela - 180px (folga em volta) */
.li-stage{position:relative; z-index:1; width:min(76vw, 1080px, calc((100vh - 180px) * 1.5)); aspect-ratio:3/2; margin:32px auto; container-type:inline-size;
  border-radius:18px; overflow:hidden; border:1px solid rgba(160,140,255,.35);
  box-shadow:0 0 0 1px rgba(90,70,200,.25), 0 30px 90px -20px rgba(0,0,0,.75), 0 0 80px rgba(100,70,255,.25)}
.li-img{display:block; width:100%; height:100%; user-select:none; -webkit-user-drag:none}
/* Cartao de login em HTML (09/10/2026): TODO o texto do cartao foi apagado da arte
   (login-v2-card*.webp; interior x 1088-1484, y 206-806 de 1536x1024) e e desenhado
   aqui - nitido em qualquer tela (o texto da imagem ficava nublado no 4K), com
   tamanho minimo maior nos textos pequenos. Desde 09/10/2026 a moldura tambem e HTML
   (cartao apagado da arte): x 1082-1490, y 236-832 px - cobre a area onde ficava o
   cartao antigo (sem cidade por tras), conteudo distribuido na altura.
   1cqw = 1% da largura da arte. Em painel pequeno some o texto de apoio. */
.lc{position:absolute; left:70.44%; top:23%; height:58.2%; width:26.56%; box-sizing:border-box; padding:2.4cqw 2.2cqw; display:flex; flex-direction:column; justify-content:space-evenly; gap:1cqw;
  border-radius:1.15cqw; background:linear-gradient(170deg, rgba(48,52,150,.62), rgba(26,24,96,.7)); border:1.5px solid rgba(160,195,255,.85);
  box-shadow:0 0 1.6cqw rgba(90,150,255,.55), inset 0 0 1.4cqw rgba(140,185,255,.18); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  font-family:var(--f-b); color:#EAF0FF; -webkit-font-smoothing:antialiased}
.lc-brand-text{font:700 2.3cqw/1 'Space Grotesk', var(--f-d); letter-spacing:-.01em; color:#fff}
.lc-brand-text span{background:linear-gradient(90deg, #4F8BFF, #9B6BFF); -webkit-background-clip:text; background-clip:text; color:transparent}
.lc-brand-img{display:block; width:14.5cqw; height:auto; margin:0 0 .5cqw}
.lc-sub{margin:.4cqw 0 0; font-size:max(13px, 1.08cqw); color:#E2E8FF}
.lc-title{margin:0 0 1.3cqw; font:600 max(16px, 1.5cqw) var(--f-b); color:#fff}
.lc-txt{margin:0 0 1.1cqw; font-size:max(12px, .9cqw); line-height:1.45; color:#C9D3F2}
.lc form{margin:0; display:flex; flex-direction:column; gap:1cqw}
.li-field{display:flex; align-items:center; gap:.8cqw; height:3.1cqw; min-height:33px; padding:0 .9cqw; box-sizing:border-box; border-radius:.45cqw;
  background:rgba(10,14,50,.6); border:1px solid rgba(150,170,255,.38); transition:border-color .15s, box-shadow .15s}
.li-field:focus-within{border-color:#5FC8FF; box-shadow:0 0 0 .2cqw rgba(95,200,255,.22)}
.li-field svg{width:1.3cqw; height:1.3cqw; min-width:15px; min-height:15px; flex:none; fill:none; stroke:#B7C4EE; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round}
.li-field input{flex:1; min-width:0; background:none; border:0; outline:0; color:#EAF0FF; font:400 max(12.5px, .95cqw) var(--f-b)}
.li-field input::placeholder{color:#A3B0DA}
.li-go{display:flex; align-items:center; justify-content:center; gap:.6cqw; height:3.2cqw; min-height:34px; border:0; border-radius:.45cqw; cursor:pointer; color:#fff;
  font:600 max(12.5px, .95cqw) var(--f-b); background:linear-gradient(90deg, #17C6F4, #4A7BFF 55%, #8A3BFF);
  box-shadow:0 .5cqw 1.6cqw -.5cqw rgba(80,120,255,.8); transition:filter .15s, box-shadow .15s}
.li-go:hover{filter:brightness(1.1)}
.li-go:focus-visible, .lc-ms:focus-visible{outline:.2cqw solid #2BE3FF; outline-offset:.25cqw}
.li-go svg, .lc-ms .lc-arrow{width:1.2cqw; height:1.2cqw; min-width:14px; min-height:14px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round}
.li-msg{margin:0; font-size:max(12.5px, .88cqw); padding:.5cqw .7cqw; border-radius:.45cqw}
.lc-or{display:flex; align-items:center; gap:.9cqw; margin:1.5cqw 0; font:500 max(11px, .78cqw) var(--f-b); color:#AFBBE0}
.lc-or::before, .lc-or::after{content:""; flex:1; height:1px; background:rgba(150,170,255,.3)}
.lc-ms{display:flex; align-items:center; justify-content:center; gap:.8cqw; height:3.2cqw; min-height:34px; border-radius:.45cqw; text-decoration:none;
  font:600 max(12.5px, .92cqw) var(--f-b); color:#fff; background:rgba(8,14,56,.55); border:1px solid rgba(200,215,255,.6); transition:background .15s, border-color .15s}
.lc-ms:hover{background:rgba(30,50,130,.6); border-color:#fff}
.lc-ms .lc-mslogo{width:1.5cqw; height:1.5cqw; min-width:18px; min-height:18px}
.lc-safe{display:flex; align-items:center; gap:.8cqw; margin-top:1.8cqw}
.lc-safe svg{flex:none; width:1.6cqw; height:1.6cqw; min-width:18px; min-height:18px; fill:none; stroke:#C9D6FF; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round}
.lc-safe small{display:block; font-size:max(11.5px, .85cqw); color:#C9D3F2}
@container (max-width: 820px){ .lc-txt{display:none} .lc-title{margin-top:1.2cqw} }
/* com mensagem (?msg=), ela ocupa o lugar do texto de apoio */
/* textos de FORA do cartao em HTML (09/10/2026) - apagados da arte, nitidos em
   qualquer tela. .la = paragrafo + lista da esquerda (x 66, y 390 px); .lb = barra
   de baixo, caixa HTML de x 46 a 1490, y 868-962 (moldura da arte apagada); o rodape saiu. */
.la{position:absolute; left:4.3%; top:41%; width:24.5%; display:flex; flex-direction:column; gap:1.25cqw; color:#EAF0FF; font-family:var(--f-b); -webkit-font-smoothing:antialiased}
.la-item{display:flex; align-items:center; gap:1.1cqw}
.la-ico{flex:none; width:3.3cqw; height:3.3cqw; min-width:38px; min-height:38px; border-radius:50%; display:grid; place-items:center; box-sizing:border-box;
  border:2px solid transparent; background:linear-gradient(#0B1240, #0B1240) padding-box, linear-gradient(135deg, #2BE3FF, #9B5CFF) border-box; box-shadow:0 0 .9cqw rgba(90,140,255,.45)}
.la-ico svg, .lb-i > svg{width:55%; height:55%; fill:none; stroke:url(#laGrad); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
.la-item b{display:block; font:600 max(14px, 1.08cqw) var(--f-b); color:#fff}
.la-item small{display:block; margin-top:.15cqw; font-size:max(12.5px, .88cqw); color:#BCC7EA}
/* bloco do canto superior direito (x 1073-1478, y 78-152 px), apagado da arte */
.lt{position:absolute; right:3.8%; top:7.6%; height:7.4%; display:flex; align-items:center; justify-content:flex-end; gap:1.4cqw;
  font-family:var(--f-b); -webkit-font-smoothing:antialiased}
.lt p{margin:0}
.lt-a{font:600 max(9.5px, .74cqw)/1.6 var(--f-b); letter-spacing:.16em; text-transform:uppercase; color:#EAF0FF; white-space:nowrap}
.lt i{align-self:stretch; width:1px; background:rgba(200,215,255,.45)}
.lt-b{font-size:max(10.5px, .84cqw); line-height:1.45; color:#8FBCFF; white-space:nowrap}
.lb{position:absolute; left:3%; top:86.3%; width:94%; height:9.2%; box-sizing:border-box; display:grid; grid-template-columns:repeat(5, minmax(0,1fr)); align-items:center;
  border-radius:.9cqw; background:rgba(8,12,42,.78); border:1px solid rgba(140,160,255,.32); box-shadow:inset 0 0 1.5cqw rgba(90,120,255,.12);
  color:#EAF0FF; font-family:var(--f-b); -webkit-font-smoothing:antialiased}
.lb-i{display:flex; align-items:center; gap:.9cqw; padding:0 1cqw; min-width:0}
.lb-i + .lb-i{border-left:1px solid rgba(140,160,255,.25)}
.lb-i > svg{flex:none; width:2.4cqw; height:2.4cqw; min-width:24px; min-height:24px}
.lb-i > div{min-width:0}
.lb-i b, .lb-i small{display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.lb-i b{font:600 max(13.5px, 1.02cqw) var(--f-b); color:#fff}
.lb-i small{margin-top:.2cqw; font-size:max(12px, .84cqw); color:#BCC7EA}

/* telas estreitas ou em pe: a imagem ficaria minuscula - cartao simples */
.li-mobile{display:none; position:relative; z-index:1}
@media (max-width: 900px), (max-aspect-ratio: 1/1){
  /* fundo no tom da arte (bordas do recorte do globo ~ #0A1943, medido): marinho
     atras do globo, escurecendo ate quase preto nas laterais e embaixo (vinheta) */
  .li-body{display:block; background:radial-gradient(ellipse 85% 45% at 50% 22%, #0C1D4E 0%, #0A1943 45%, #060E2C 75%, #03061A 100%), #03061A}
  .li-body::before{opacity:.45}
  .li-stage{display:none}
  .li-mobile{display:flex; flex-direction:column; justify-content:center; min-height:100vh; min-height:100dvh; box-sizing:border-box; max-width:400px; margin:0 auto; padding:14px 16px 20px}
  .li-m-name{font:700 32px/1 var(--f-d)}
  .li-m-name span{background:linear-gradient(90deg, #3D7BFF, #4FC3FF); -webkit-background-clip:text; background-clip:text; color:transparent}
  .li-m-sub{margin:6px 0 4px; font-size:13px; color:#D5DEF7}
  /* recorte da arte: globo + anel de provedores (assets/login-v2-globe.webp, 2.5x
     da regiao x 395-1075, y 92-700 px - com folga em volta). As bordas somem por
     completo nos 4 lados (degrade de 16%), pra o azul da arte se misturar ao roxo
     do fundo sem aparecer o retangulo; o cartao comeca abaixo, sem sobrepor. */
  .li-m-hero{display:block; width:calc(100% + 32px); height:auto; margin:0 -16px 40px;
    -webkit-mask-image:linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent), linear-gradient(transparent, #000 14%, #000 86%, transparent);
    -webkit-mask-composite:source-in; mask-image:linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent), linear-gradient(transparent, #000 14%, #000 86%, transparent); mask-composite:intersect}
  .li-m-card{position:relative}
  .li-m-card{width:100%; max-width:310px; margin:0 auto; box-sizing:border-box; padding:16px 15px; border-radius:12px; background:rgba(6,12,52,.85); border:1.5px solid rgba(90,120,255,.85); box-shadow:0 0 28px rgba(70,90,255,.5)}
  .li-m-card h2{margin:0 0 4px; font:600 18px var(--f-d)}
  .li-m-card p{margin:0 0 12px; font-size:12.5px; color:#C9D3F2; line-height:1.4}
  .li-m-btn{display:flex; align-items:center; gap:10px; height:40px; padding:0 12px; border-radius:8px; text-decoration:none; color:#fff; font:500 13.5px var(--f-b);
    border:1.5px solid #3D7BFF; box-shadow:0 0 16px rgba(61,123,255,.55)}
  .li-m-btn svg{width:18px; height:18px; flex:none}
  .li-m-btn:focus-visible{outline:3px solid #2BE3FF; outline-offset:3px}
  .li-m-card .li-m-safe{margin:10px 0 0; font-size:11px; color:#AAB6DA}
  .li-m-form{display:grid; gap:8px}
  .li-m-input{height:40px; padding:0 11px; border-radius:8px; border:1px solid rgba(150,170,255,.4); background:rgba(10,14,50,.6); color:#EAF0FF; font:400 16px var(--f-b)}
  .li-m-go{height:40px; border:0; border-radius:8px; color:#fff; font:500 13.5px var(--f-b); cursor:pointer; background:linear-gradient(90deg, #17C6F4, #4A7BFF 55%, #8A3BFF)}
  .li-m-or{display:flex; align-items:center; gap:10px; margin:10px 0; font-size:11px; color:#9FB0DA}
  .li-m-or::before, .li-m-or::after{content:""; flex:1; height:1px; background:rgba(150,170,255,.3)}
}
@media (prefers-reduced-motion: reduce){ .lc-ms, .li-go, .li-field{transition:none} }
/* Custo por categoria (FinOps Azure, 16/10/2026): clicar numa categoria abre embaixo os
   recursos que mais custaram nela (.hbar-detail, montado em finops.html) */
.hbar-row.hbar-click{cursor:pointer; border-radius:8px; transition:background .15s}
.hbar-row.hbar-click:hover, .hbar-row.hbar-click.open{background:rgba(59,156,255,.08)}
.hbar-row.hbar-click:focus-visible{outline:2px solid var(--cyan); outline-offset:1px}
.hbar-detail{margin:2px 0 8px 6px; padding:6px 10px; border-left:2px solid var(--line-hi); border-radius:0 8px 8px 0; background:rgba(10,16,48,.45); display:grid; grid-template-columns:minmax(0,1fr); gap:1px; min-width:0} /* minmax(0,...): nome longo corta com ... em vez de empurrar o valor pra fora */
.hd-row{display:flex; justify-content:space-between; gap:10px; padding:3px 0; font-size:12px; min-width:0}
.hd-name{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-2)}
.hd-val{flex:none; font-family:var(--f-m); white-space:nowrap; color:var(--text)}
.hd-more{padding-top:2px; font-size:11px; color:var(--text-3)}
/* Busca da topbar (16/10/2026, app.js setupSearch): o campo vira botao e abre uma caixa no meio da tela */
.search[role="button"]{cursor:pointer; transition:border-color .15s, color .15s}
.search[role="button"]:hover, .search[role="button"]:focus-visible{border-color:var(--line-hi); color:var(--text-2); outline:none}
.sr-scrim{position:fixed; inset:0; z-index:200; background:rgba(4,6,20,.6); backdrop-filter:blur(3px); display:flex; justify-content:center; align-items:flex-start; padding:12vh 16px 16px}
.sr-scrim[hidden]{display:none}
.sr-box{width:min(640px, 100%); max-height:70vh; display:flex; flex-direction:column; padding:10px; --glow-c:#2BE3FF}
.sr-input{display:flex; align-items:center; gap:10px; padding:6px 10px 10px; border-bottom:1px solid var(--line); color:var(--text-2)}
.sr-input input{flex:1; min-width:0; background:none; border:0; outline:0; color:var(--text); font:500 15px var(--f-b)}
.sr-input kbd{font:600 11px var(--f-m); padding:2px 6px; border-radius:6px; border:1px solid var(--line); color:var(--text-3)}
.sr-list{list-style:none; margin:6px 0 0; padding:0; overflow:auto}
.sr-group{padding:10px 10px 4px; font:600 10.5px var(--f-m); letter-spacing:.08em; text-transform:uppercase; color:var(--text-3)}
.sr-item{display:grid; gap:1px; padding:8px 10px; border-radius:10px; cursor:pointer}
.sr-item b{font-weight:600; font-size:13.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sr-item small{font-size:11.5px; color:var(--text-3); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.sr-item.on{background:rgba(59,156,255,.14)}
.sr-item.sr-nolink{cursor:default}
.sr-status{margin:6px 10px 2px; font-size:12px; color:var(--text-3)}
.sr-status:empty{display:none}
/* lista aberta separada por tipo de recurso (ex.: Storage = discos + storage accounts) */
.hd-group{display:flex; justify-content:space-between; gap:10px; min-width:0; margin-top:6px; padding:4px 0 3px; border-bottom:1px solid var(--line); font:600 11px var(--f-b); letter-spacing:.02em; color:var(--cyan)}
.hd-group:first-child{margin-top:0}
.hd-group > span:first-child{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* Pagina Monitor (16/10/2026): caixa do Azure Monitor + caixas "nao conectado" das ferramentas */
.mon-big{font:700 44px/1 var(--f-d); margin-top:4px}
.mon-cap{display:block; margin:4px 0 12px; font-size:12px; color:var(--text-3)}
.mon-sevs{display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:6px; margin-bottom:12px}
.mon-sevs > div{display:grid; gap:2px; padding:6px; border-radius:10px; border:1px solid var(--line); background:rgba(10,16,48,.45); text-align:center}
.mon-sevs small{font:600 10.5px var(--f-m); color:var(--text-3)}
.mon-sevs b{font:700 16px var(--f-m)}
.mon-foot{margin:10px 0 0; font-size:12px; color:var(--text-3)}
.mon-foot a{color:var(--cyan)}
.mon-off{display:grid; gap:6px; padding:4px 2px}
.mon-off b{font-size:13px; color:var(--text-2)}
.mon-off p{margin:0; font-size:12.5px; line-height:1.5; color:var(--text-3)}
.mon-off .mon-need{color:var(--text-2)}
.mon-states{grid-template-columns:repeat(3,minmax(0,1fr))}
/* Custo do AKS (FinOps Azure, 17/10/2026): seletor de cluster + total + barras por peca */
.aks-pick{width:100%; margin:2px 0 10px; padding:7px 10px; border-radius:10px; border:1px solid var(--line); background:rgba(10,16,48,.7); color:var(--text); font:500 12.5px var(--f-b); cursor:pointer}
.aks-pick:focus-visible{outline:2px solid var(--cyan); outline-offset:1px}
.aks-total{display:grid; gap:2px; margin-bottom:8px}
.aks-total b{font:700 22px/1.1 var(--f-d)}
.aks-total small{font-size:11.5px; color:var(--text-3)}
/* Monitor como painel (18/10/2026): 4 KPIs com anel, mapa + tabela de alertas, graficos */
.mon-kpis{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px}
.mon-kpi-body{display:flex; align-items:center; gap:14px; margin-top:10px; min-height:66px}
.mon-kpi-body > div:not(.ring){display:grid; gap:3px; min-width:0}
.mon-kpi-body small{font-size:11.5px; color:var(--text-3)}
.mon-kpi-num{font:700 22px/1 var(--f-d)}
.mon-kpi-num small{font:600 14px var(--f-d); color:var(--text-3)}
.mon-kpi-big{font:700 38px/1 var(--f-d)}
.mon-kpi-load{font-size:12px; color:var(--text-3)}
.mon-kpi .ring-inner b{font:700 15px var(--f-d)}
#kVms{flex-wrap:wrap}
.mon-kpi-body > div.mon-vm-off{flex-basis:100%; display:flex; flex-wrap:wrap; align-items:center; gap:4px 8px; margin-top:2px; font-size:11.5px}
.mon-vm-off small{color:var(--text-3)}
.mon-vm-off a, .mon-vm-off span{color:var(--text-2); text-decoration:none; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.mon-vm-off a:hover{color:var(--cyan); text-decoration:underline}
.mon-mini{display:flex; flex-wrap:wrap; gap:4px 10px; font:600 11px var(--f-m)}
.mon-mini b{font-weight:700}
.mon-row2{display:grid; grid-template-columns:minmax(0,1.9fr) minmax(0,1fr); gap:16px; flex:0 0 auto}
/* mapa-mundi (worldMap em charts.js) */
.world-map{display:block; width:100%; height:auto}
.wm-land{fill:rgba(96,140,255,.16); stroke:rgba(120,160,255,.35); stroke-width:.6}
.wm-dot{fill:var(--c); stroke:#fff; stroke-width:1.2}
.wm-halo{fill:var(--c); opacity:.18; animation:wmPulse 2.4s ease-in-out infinite}
.wm-label{fill:var(--text); font:600 12px var(--f-b); paint-order:stroke; stroke:rgba(5,8,22,.85); stroke-width:3px}
@keyframes wmPulse{0%,100%{opacity:.12}50%{opacity:.32}}
@media (prefers-reduced-motion: reduce){.wm-halo{animation:none}}
.wm-legend{display:flex; flex-wrap:wrap; gap:14px; margin-top:6px; font-size:11.5px; color:var(--text-3)}
.wm-legend span::before{content:""; display:inline-block; width:9px; height:9px; margin-right:6px; border-radius:50%; background:var(--c); vertical-align:middle}
/* tabela de alertas */
.mon-table{display:grid; gap:4px; max-height:430px; overflow:auto; padding-right:2px}
.mt-row{display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:10px; padding:6px 8px; border-radius:10px; border-left:3px solid var(--c); background:color-mix(in srgb, var(--c) 8%, rgba(10,16,48,.5))}
.mt-sev{font:700 10.5px var(--f-m); color:var(--c)}
.mt-main{display:grid; min-width:0}
.mt-main b{font-size:12.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.mt-main small, .mt-time small{font-size:11px; color:var(--text-3); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.mt-time{display:grid; justify-items:end; font:600 12px var(--f-m)}
/* donut de alertas por servico */
.mon-donut{display:flex; align-items:center; gap:16px; flex-wrap:wrap}
.mon-donut-leg{display:grid; gap:6px; flex:1; min-width:140px}
.mon-donut-leg > div{display:flex; align-items:center; gap:8px; font-size:12px}
.mon-donut-leg i{width:10px; height:10px; border-radius:3px; flex:none}
.mon-donut-leg span{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-2)}
.mon-donut-leg b{font:600 12px var(--f-m)}
@media (max-width: 1180px){ .mon-kpis{grid-template-columns:repeat(2,minmax(0,1fr))} .mon-row2{grid-template-columns:minmax(0,1fr)} }
@media (max-width: 760px){ .mon-kpis{grid-template-columns:minmax(0,1fr)} }
.mon-allok{padding:10px 2px; font-size:13px; color:var(--green)}
