:root {
  color-scheme: light;
  --bg: #eef2f6;
  --panel: #ffffff;
  --panel-alt: #f8fafc;
  --ink: #111827;
  --muted: #64748b;
  --line: #cbd5e1;
  --primary: #1d4ed8;
  --primary-dark: #1e3a8a;
  --success: #047857;
  --warning: #b45309;
  --danger: #b42318;
  --shadow: 0 10px 24px rgba(15, 23, 42, 0.08);
}

* {
  box-sizing: border-box;
}

html {
  /* Reserva o espaco da barra de rolagem vertical sempre, mesmo em abas
     cujo conteudo nao chega a precisar de scroll — sem isso, o cabecalho
     (logos/titulo, que ocupa 100% da largura) fica ~17px mais largo nas
     abas curtas do que nas abas altas (onde a barra classica do Windows
     consome esses pixels), fazendo os logos parecerem se deslocar ao
     trocar de aba. */
  scrollbar-gutter: stable;
}

[v-cloak] {
  display: none;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  background: var(--bg);
  font-family: "Segoe UI", Arial, Helvetica, sans-serif;
  font-size: 15px;
  line-height: 1.45;
}

button,
input,
select,
textarea {
  font: inherit;
}

.topbar {
  display: grid;
  grid-template-columns: 190px 1fr 240px;
  align-items: center;
  gap: 16px;
  min-height: 108px;
  padding: 10px 26px;
  color: var(--ink);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.brand-logo {
  width: 92px;
  height: 92px;
  object-fit: contain;
}

.topbar-end {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-self: end;
  gap: 4px;
}

.user-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  min-height: 0;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--line);
  color: #64748b;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.icon-button:hover {
  background: var(--panel-alt);
}

.user-badge-wrap {
  position: relative;
}

.user-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  min-height: 0;
  background: none;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

.user-badge:hover {
  background: var(--panel-alt);
}

.user-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  flex: 0 0 auto;
}

.user-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 110px;
  line-height: 1.25;
}

.user-name,
.user-role {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}

.user-role {
  font-size: 11px;
  color: #64748b;
}

.user-chevron {
  width: 16px;
  height: 16px;
  color: #94a3b8;
  flex: 0 0 auto;
  transition: transform 0.15s ease;
}

.user-chevron-open {
  transform: rotate(180deg);
}

.auth-panel {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 20;
  width: 220px;
  margin-top: 8px;
  padding: 14px;
  display: grid;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  text-align: left;
}

.auth-panel .subtabs {
  margin: 0 0 4px;
}

.auth-panel-name {
  font-weight: 700;
  color: var(--ink);
}

.auth-panel-username {
  margin-top: -6px;
  font-size: 12px;
}

.brand-title {
  min-width: 0;
  text-align: center;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

.brand-title h1 {
  margin-bottom: 2px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display", "Segoe UI", Roboto, Arial, Helvetica, sans-serif;
  font-size: 32px;
  font-weight: 800;
  letter-spacing: -0.02em;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6), 0 2px 6px rgba(15, 23, 42, 0.25);
}

/* Duas cores batendo com o proprio wordmark do logo (misc/powerlab_icon.png
   e as artes de origem) — "Power" no azul da marca, "Lab" no laranja
   amostrado direto do PNG original (#f07903), em vez de inventar uma nova
   paleta pro texto. */
.brand-word-power {
  color: var(--primary-dark);
}

.brand-word-lab {
  color: #f07903;
}

.brand-tagline {
  margin-bottom: 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Traço de "pulso" (referencia a oscilografia/sinal — familiar pra quem
   trabalha com sistemas de potencia) sob o slogan, nas mesmas 3 cores do
   anel do icone (azul/verde/laranja). Puramente decorativo (aria-hidden). */
.brand-pulse {
  display: block;
  width: 200px;
  height: 14px;
  margin: 6px auto 0;
}

.brand-pulse-line {
  fill: none;
  stroke: url(#brandPulseGradient);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.statusbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  min-height: 32px;
  padding: 6px 22px;
  color: #fff;
  background: var(--primary-dark);
  font-size: 14px;
}

.statusbar.ok {
  background: var(--success);
}

.statusbar.error {
  background: var(--danger);
}

.status-text {
  flex: 1 1 auto;
}

/* Farol de convergencia do caso em memoria -- ponto colorido com anel
   branco fixo (nao usa a cor de fundo da statusbar) para continuar legivel
   nos tres estados de statusKind (neutro/ok/error), que ja usam azul/verde/
   vermelho pra outra coisa (resultado da ultima acao, nao da convergencia). */
.convergence-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

.convergence-dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55);
}

.convergence-badge.pending .convergence-dot {
  background: #f5b301;
}

.convergence-badge.converged .convergence-dot {
  background: #16a34a;
}

.convergence-badge.diverged .convergence-dot {
  background: #dc2626;
}

/* "Alteracoes pendentes" -- o usuario alternou o estado de um circuito no
   Explorador de Dados com o caso ja convergido (ver hasPendingCircuitStateChanges/
   convergenceStatus em app.js). Cor de atencao distinta de "pending" (nunca
   executado) para nao confundir os dois estados. */
.convergence-badge.stale .convergence-dot {
  background: var(--warning);
}

/* Celula clicavel "Estado" do Explorador de Dados > Circuitos (ver
   renderCircuitStateCell/toggleCircuitState em app.js) -- unica coluna
   editavel do Explorador. Pilula com ponto colorido, no mesmo espirito do
   farol de convergencia (.convergence-badge) acima, mas como botao. */
.circuit-state-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  line-height: 1.4;
}

.circuit-state-badge:hover {
  filter: brightness(0.96);
}

.circuit-state-dot {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
}

.circuit-state-badge.on {
  background: #dcfce7;
  color: var(--success);
}

.circuit-state-badge.on .circuit-state-dot {
  background: var(--success);
}

.circuit-state-badge.off {
  background: #f1f5f9;
  color: var(--muted);
}

.circuit-state-badge.off .circuit-state-dot {
  background: var(--muted);
}

/* Override staged ainda nao recalculado (ver isCircuitStateModified) --
   mesmo proposito visual do asterisco/borda usado em isConstantModified,
   mas como anel colorido pra nao competir com o texto da pilula. */
.circuit-state-badge.modified {
  border-color: var(--warning);
  box-shadow: 0 0 0 1px var(--warning);
}

/* Aviso + atalho para recalcular, logo abaixo do Explorador de Circuitos,
   quando ha' overrides de estado pendentes (ver modifiedCircuitStatesCount
   em app.js). */
.circuit-state-pending-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
  padding: 8px 12px;
  border-radius: 8px;
  background: #fffbeb;
  border: 1px solid var(--warning);
  color: var(--warning);
  font-size: 13px;
  font-weight: 600;
}

/* Farol de ocupacao do servidor (ver /api/health, serverLoadKind em app.js) --
   mesmo padrao visual do farol de convergencia acima (ponto + anel branco). */
.server-load-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

.server-load-dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55);
}

.server-load-badge.idle .server-load-dot {
  background: #16a34a;
}

.server-load-badge.busy .server-load-dot {
  background: #f5b301;
}

.server-load-badge.queued .server-load-dot {
  background: #dc2626;
}

.workspace-tabs {
  display: flex;
  gap: 4px;
  padding: 10px 16px 0;
  background: #dde5ee;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}

/* Fica sempre por ultimo na nav (margin-left:auto empurra pra direita),
   fora do fluxo de rolagem horizontal das abas — troca de idioma da
   interface web (ver PPLI18N em i18n-web.js), independente do idioma do
   processo Python (PYPOWERLAB_LANG, so' usado pela GUI desktop). */
.lang-switch {
  display: flex;
  gap: 2px;
  margin-left: auto;
  padding: 2px;
  align-self: center;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.lang-switch button {
  display: flex;
  align-items: center;
  gap: 5px;
  min-height: 28px;
  padding: 4px 10px;
  color: #334155;
  background: transparent;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.02em;
}

.lang-flag {
  width: 18px;
  height: 13px;
  border-radius: 2px;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
}

.lang-switch button.active {
  color: #fff;
  background: var(--primary);
}

.workspace-tabs button,
.subtabs button {
  min-height: 40px;
  padding: 8px 15px;
  color: #334155;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-bottom-color: #b9c4d0;
  border-radius: 6px 6px 0 0;
  cursor: pointer;
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
}

.workspace-tabs button.active,
.subtabs button.active {
  color: #fff;
  background: var(--primary);
  border-color: var(--primary);
}

.workspace {
  max-width: 1500px;
  margin: 0 auto;
  padding: 16px;
}

/* Diagrama Unifilar: fluxo de potencia ativa da esquerda para a direita
   (ver leftNeighbors/rightNeighbors em drawDiagram, app.js) usa muito mais
   espaco horizontal que as demais abas — libera o teto de largura so
   nessa aba em vez de mexer no limite geral do workspace. */
.workspace-wide {
  max-width: 2400px;
}

.page-grid {
  display: grid;
  gap: 16px;
}

.input-grid {
  grid-template-columns: minmax(360px, 1.25fr) minmax(320px, 0.75fr);
}

.flow-grid {
  grid-template-columns: 1fr;
}

.page-stack {
  display: grid;
  gap: 16px;
}

.about-page { gap: 16px; max-width: 980px; margin: 0 auto; }
.panel.about-hero {
  padding: 30px 34px;
  background: linear-gradient(135deg, #fff 0%, #eff6ff 100%);
}
/* :not(.welcome-panel) -- about-hero tambem e' reaproveitada pelo card "Nenhum
   caso carregado" (welcome-panel, ver index.html), que so' tem h2/p/button
   soltos (sem o wrapper .about-hero-text) -- virar flex row ali empurraria
   esses filhos lado a lado em vez de empilhados. */
.panel.about-hero:not(.welcome-panel) {
  display: flex;
  align-items: center;
  gap: 28px;
}
.about-hero-logo {
  flex: 0 0 auto;
  width: 260px;
  height: 260px;
  object-fit: contain;
  border-radius: 12px;
}
.about-hero-text { flex: 1 1 auto; min-width: 0; }
@media (max-width: 700px) {
  .panel.about-hero:not(.welcome-panel) { flex-direction: column; text-align: center; }
}
.about-hero h2 { margin-bottom: 8px; color: var(--primary-dark); font-size: 30px; }
.eyebrow { margin-bottom: 8px; color: var(--primary); font-size: 12px; font-weight: 800; letter-spacing: .12em; }
.about-lead { max-width: 720px; margin-bottom: 16px; font-size: 18px; }
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.about-list { margin: 0; padding-left: 22px; }
.about-list li + li { margin-top: 10px; }
.feedback-panel { display: flex; flex-direction: column; align-items: flex-start; }
.feedback-button { display: inline-block; margin-top: auto; padding: 10px 16px; color: #fff; background: var(--primary); border-radius: 6px; font-weight: 700; text-decoration: none; }
.feedback-button:hover { background: var(--primary-dark); }
/* Link de e-mail dentro do texto do painel de feedback -- sem underline por
   default porque o "_" do endereco (powerlab_project@...) fica colado no
   underline padrao do navegador e confunde visualmente; underline so aparece
   no hover, como sinal de interatividade. */
.feedback-panel .muted a { text-decoration: none; font-weight: 600; }
.feedback-panel .muted a:hover { text-decoration: underline; }
.about-version-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: fit-content;
  margin: 4px auto 0;
  padding: 10px 22px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  box-shadow: var(--shadow);
}
.about-version-badge-label {
  color: rgba(255, 255, 255, .82);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.about-version-badge-value {
  color: #fff;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .02em;
  font-family: ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
}
.about-version-badge-date {
  color: rgba(255, 255, 255, .82);
  font-size: 13px;
  font-weight: 600;
  padding-left: 10px;
  border-left: 1px solid rgba(255, 255, 255, .35);
}
.about-version-history summary { cursor: pointer; list-style-position: inside; }
.about-version-history summary h2 { display: inline; margin: 0; }
.about-version-note { margin: 8px 0 0; font-size: 13px; font-style: italic; color: var(--muted); }
.about-release { margin-top: 18px; }
.about-release h3 { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 0 0 6px; font-size: 16px; }
.about-release h4 { margin: 10px 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted, #667085); }
.about-release .about-list li + li { margin-top: 4px; }
.about-release-current {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: var(--primary);
}

.panel,
.mini-panel {
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.panel {
  padding: 16px;
  background: var(--panel);
}

.mini-panel {
  padding: 12px;
  box-shadow: none;
}

.panel-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.panel h2,
.mini-panel h3 {
  margin-bottom: 12px;
}

.panel h2 {
  font-size: 17px;
}

.mini-panel h3 {
  font-size: 15px;
}

.field {
  display: grid;
  gap: 6px;
  margin-bottom: 12px;
}

.field span,
.command-box span,
.summary-list span,
.muted {
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
}

.ai-remember-key {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: -6px 0 10px;
  color: var(--muted);
  font-size: 13px;
}

.ai-remember-key input[type="checkbox"] {
  width: auto;
}

.ai-key-help {
  margin: -2px 0 14px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.ai-key-help a {
  color: var(--accent);
  font-weight: 700;
}

input,
select,
textarea {
  width: 100%;
  min-height: 38px;
  padding: 8px 10px;
  color: var(--ink);
  background: #fbfcfd;
  border: 1px solid var(--line);
  border-radius: 6px;
}

select[size] {
  min-height: 360px;
}

textarea {
  min-height: 110px;
  resize: vertical;
}

button,
.file-button {
  min-height: 38px;
  padding: 8px 13px;
  color: var(--primary-dark);
  background: #fff;
  border: 1px solid var(--primary);
  border-radius: 6px;
  cursor: pointer;
  font-weight: 700;
  font-size: 14px;
}

button:hover,
.file-button:hover {
  background: #eff6ff;
}

button:disabled,
input:disabled,
select:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.primary {
  min-width: 170px;
  color: #fff;
  background: var(--primary);
}

.small-primary {
  min-width: 120px;
}

.primary:hover {
  background: var(--primary-dark);
}

.toolbar,
.upload-row {
  display: flex;
  align-items: end;
  gap: 10px;
  margin-bottom: 12px;
}

.toolbar-title {
  align-self: center;
  min-width: 54px;
  color: var(--ink);
}

.grow {
  flex: 1 1 auto;
}

.compact {
  width: 130px;
}

.file-button input {
  display: none;
}

.selected-file {
  min-height: 46px;
  margin: 0 0 18px;
  padding: 12px;
  overflow-wrap: anywhere;
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-weight: 700;
}

.summary-list {
  display: grid;
  gap: 8px;
  margin-top: 18px;
}

.summary-list div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}

/* Chip de severidade (ver severityClass em app.js) -- "Sem violações" em verde, contagem
   por categoria em vermelho. */
.severity-ok {
  color: var(--success);
}

.severity-alert {
  color: var(--danger);
}

.dashboard-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 20px;
  margin: 10px 0 14px;
}

.dashboard-dropdown {
  position: relative;
}

.dashboard-dropdown-toggle {
  min-width: 150px;
}

.dashboard-dropdown-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 46ch: "Área NN - " (~10 caracteres) + até 36 caracteres do campo Nome do DARE
     (colunas 19-54, ver formatodosdadosderea.htm) -- cabe o nome inteiro sem quebrar
     linha no meio da palavra. */
  min-width: 46ch;
  max-width: min(46ch, 90vw);
  max-height: 260px;
  overflow: auto;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow);
}

.dashboard-check {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  color: var(--ink);
  font-weight: 700;
  font-size: 13px;
}

.dashboard-check input {
  width: auto;
  min-height: auto;
}

.dashboard-chart {
  height: 380px;
  margin-bottom: 24px;
}

/* Espaço extra pro range slider (ver renderConvergenceChart) sem espremer demais a
   área de plotagem -- mesmo motivo do .pv-chart (560px) ter mais altura que os
   gráficos de área/agregador, que não têm dataZoom. */
.dashboard-chart-with-zoom {
  height: 440px;
}

/* Resumo formal exibido apos a acao "Carregar Caso" (POST /api/load, ver
   loadCase em app.js): titulo do PWF (codigo TITU) sempre visivel, contagens
   de dados e, se a leitura emitiu algo (ver leitura.py), a lista de avisos. */
.case-summary {
  margin: 0 0 18px;
  padding: 12px;
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.case-summary-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.case-summary-title strong {
  color: var(--primary-dark);
  font-size: 15px;
}

.case-warnings {
  padding-top: 12px;
  margin-top: 12px;
  border-top: 1px solid var(--line);
}

.case-warnings ul {
  margin: 6px 0 0;
  padding-left: 18px;
  color: var(--danger);
  font-size: 13px;
}

.case-warnings li + li {
  margin-top: 4px;
}

.grid {
  display: grid;
  gap: 12px;
}

.grid.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.command-box {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
  padding: 12px;
  background: #eff6ff;
  border-left: 4px solid var(--primary);
  border-radius: 6px;
}

.command-box div {
  display: grid;
  gap: 4px;
}


.command-box strong {
  overflow-wrap: anywhere;
  color: var(--primary-dark);
}

.subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 12px 0;
  border-bottom: 1px solid var(--line);
}

/* Empurra a aba "Visão Geral" pro lado direito da janela de resultados, separada das
   demais (Visualizador/Exploradores/Curvas/Log), que ficam agrupadas à esquerda. */
.subtabs button.subtab-right {
  margin-left: auto;
}

.flow-options,
.reports-options {
  display: grid;
  grid-template-columns: minmax(260px, 0.7fr) minmax(420px, 1.3fr);
  gap: 12px;
}

.reports-options {
  grid-template-columns: repeat(3, minmax(240px, 1fr));
}

.wide-mini {
  grid-column: 1 / -1;
}

.check-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(190px, 1fr));
  gap: 7px 12px;
}

.check-grid.controls {
  grid-template-columns: repeat(3, minmax(210px, 1fr));
}

.compact-grid {
  grid-template-columns: repeat(2, minmax(190px, 1fr));
}

.check-row,
.radio-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  color: #1f2937;
  line-height: 1.25;
}

.check-row input,
.radio-row input {
  width: 16px;
  min-height: 16px;
  flex: 0 0 auto;
}

.radio-line {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.radio-row.inline {
  min-width: 190px;
}

/* Componente reutilizável <anarede-set-selector>/<anarede-clause> (ver
   app.js) — padronizado para qualquer tela que precise da linguagem de
   seleção de conjuntos (hoje: editor DINC do fluxo de potência
   continuado). */
.anarede-set-selector {
  margin-bottom: 16px;
}

.anarede-set-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: 12px;
}

.anarede-clause {
  min-width: 0;
  padding: 12px;
  margin: 0;
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 8px;
  transition: opacity 0.15s ease;
}

.anarede-clause:disabled {
  opacity: 0.5;
}

.anarede-clause legend {
  padding: 0 4px;
  color: var(--primary-dark);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
}

.anarede-clause-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 10px;
}

.anarede-clause-row:last-child {
  margin-bottom: 0;
}

.anarede-clause-row .field {
  min-width: 110px;
  flex: 1 1 110px;
  margin-bottom: 0;
}

/* Destaque para a Condição (A/E) que fica entre os dois elementos da
   cláusula — mesmo destaque visual da coluna "C" na figura da linguagem de
   seleção. */
.anarede-field-condition {
  min-width: 130px;
  flex: 0 0 130px;
  padding: 6px;
  background: #eef2f6;
  border-radius: 6px;
}

.anarede-clause-summary {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  color: var(--ink);
  font-size: 13px;
}

.anarede-clause-summary strong {
  color: var(--primary-dark);
}

.anarede-principal {
  display: flex;
  align-self: center;
  justify-content: center;
  min-width: 160px;
  padding-top: 22px;
}

.anarede-principal .field {
  width: 100%;
  margin-bottom: 0;
}

.anarede-set-preview {
  margin: 10px 0 0;
  padding: 8px 12px;
  color: var(--primary-dark);
  background: #eff6ff;
  border-left: 4px solid var(--primary);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 700;
  overflow-wrap: anywhere;
}

@media (max-width: 760px) {
  .anarede-set-grid {
    grid-template-columns: 1fr;
  }

  .anarede-principal {
    padding-top: 0;
  }
}

.dinc-percent-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
}

/* Campos de titulo de eixo (texto livre) precisam de mais espaco que os
   campos de min/max (numeros curtos) com quem dividem a linha — sem isso
   o titulo digitado fica cortado no input. */
.dinc-percent-row .field.axis-title {
  flex: 2 1 220px;
}

.dinc-actions-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.dinc-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 120px;
}

.dinc-list {
  flex: 1 1 320px;
  min-height: 120px;
  max-height: 260px;
  overflow-y: auto;
  padding: 6px;
  background: #fbfcfd;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.dinc-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 1px 10px;
  border-radius: 6px;
  cursor: pointer;
}

.dinc-list-item:hover {
  background: var(--panel-alt);
}

.dinc-list-item.active {
  background: #eff6ff;
  border: 1px solid var(--primary);
}

.dinc-list-item span {
  overflow-wrap: anywhere;
}

.dinc-list-item .dinc-entry-code {
  overflow-wrap: normal;
  overflow-x: auto;
  color: var(--primary-dark);
  font-family: "Consolas", "Courier New", monospace;
  font-size: 12px;
  line-height: 1.3;
  white-space: pre;
}

/* Linhas "DINC" / regua de colunas / "99999" que emolduram a lista de
   selecoes, reproduzindo o bloco exato que sera gravado no .pwf — mesma
   fonte/tamanho do .dinc-entry-code, alinhadas nas mesmas colunas. Padding
   e line-height enxutos de proposito: e pra parecer uma unica peca de
   codigo compacta, nao uma lista "arejada" de itens separados. */
.dinc-code-static {
  padding: 1px 10px;
  overflow-x: auto;
  color: var(--muted);
  font-family: "Consolas", "Courier New", monospace;
  font-size: 12px;
  line-height: 1.3;
  white-space: pre;
}

/* Guia vertical ligando "DINC" a "99999", como um bloco recolhivel de
   editor de codigo — da identidade visual de "um unico bloco" pras linhas
   soltas (cabecalho estatico + entradas + rodape estatico). */
.dinc-code-block {
  border-left: 3px solid var(--line);
  margin-left: 4px;
}

.dinc-keyword {
  color: var(--primary);
  font-weight: 700;
}

.dinc-comment {
  color: var(--muted);
  font-style: italic;
}

.dinc-seg-prefix {
  color: var(--ink);
  font-weight: 700;
}

.dinc-seg-suffix {
  color: var(--primary-dark);
}

.dinc-list-item button {
  flex: 0 0 auto;
  min-height: 0;
  padding: 0 8px;
  border: none;
  font-size: 11px;
  line-height: 15.6px;
}

.viewer-frame {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  overflow: hidden;
}

.viewer-title {
  padding: 8px 12px;
  color: var(--ink);
  background: var(--panel-alt);
  border-bottom: 1px solid var(--line);
  font-weight: 700;
}

.report-toolbar {
  align-items: end;
  margin: 0;
  padding: 8px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.search-mode {
  width: 126px;
  flex: 0 0 126px;
}

.search-status {
  align-self: center;
  min-width: 112px;
  color: var(--muted);
  font-size: 13px;
  white-space: nowrap;
}

.report-output {
  width: 100%;
  min-height: 430px;
  max-height: 68vh;
  margin: 0;
  padding: 14px;
  overflow: auto;
  color: #e5e7eb;
  background: #0f172a;
  border: 0;
  border-radius: 0;
  font-family: Consolas, "Courier New", monospace;
  font-size: 14px;
  line-height: 1.45;
  white-space: pre;
}

mark {
  padding: 0 2px;
  color: #111827;
  background: #f59e0b;
  border-radius: 3px;
}

mark.current-match {
  color: #052e16;
  background: #22c55e;
}

.table-wrap {
  max-height: 68vh;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
}

table {
  width: max-content;
  min-width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}

th,
td {
  min-width: 92px;
  padding: 7px 10px;
  border-right: 1px solid #d8e0e6;
  border-bottom: 1px solid #d8e0e6;
  text-align: center;
  white-space: nowrap;
}

th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #edf3f5;
}

th.sortable {
  cursor: pointer;
  user-select: none;
}

th.sortable:hover,
th.sorted {
  color: var(--primary-dark);
  background: #dbeafe;
}

.left {
  min-width: 220px;
  text-align: left;
}

.table-status {
  margin-top: 8px;
  color: var(--muted);
  font-size: 13px;
}

/* Coluna de ações da aba Administração (ver renderAdminUserActionsCell em
   app.js) -- dois botões nativos lado a lado dentro da célula do Tabulator. */
.admin-users-actions {
  display: flex;
  gap: 6px;
}

/* Explorador (aba Resultados > Explorador) — grid do Tabulator
   (vendor/tabulator.min.js). tabulator.min.css traz o tema padrao da lib
   (cinza/azul genérico); as regras abaixo sobrescrevem só o necessário pra
   casar com a paleta do resto do app (--primary/--line/--muted etc.) em vez
   de reescrever o tema inteiro. */
.explorer-table {
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  font-size: 14px;
}

.explorer-table .tabulator {
  background: var(--panel);
  border: none;
  font-family: "Segoe UI", Arial, Helvetica, sans-serif;
}

.explorer-table .tabulator-header {
  background: #edf3f5;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}

.explorer-table .tabulator-col {
  background: transparent;
  border-right: 1px solid #d8e0e6;
}

/* Mesma especificidade da regra padrao do Tabulator
   (.tabulator .tabulator-header .tabulator-col, 3 classes) — sem bater essa
   especificidade a nossa regra perderia mesmo vindo depois no CSS. O
   Tabulator alinha o conteudo do cabecalho ao topo por padrao
   (justify-content:flex-start). Com largura padronizada por coluna (ver
   explorerColumns em app.js) alguns rotulos quebram em duas linhas e
   outros cabem numa só — alinhados ao topo, os de uma linha só ficavam
   "flutuando" perto da borda superior enquanto os de duas linhas
   preenchiam a celula inteira, parecendo desalinhados entre si. Centralizar
   verticalmente faz o bloco de texto (1 ou 2 linhas) ficar sempre no meio
   da mesma altura de linha, entao todas as colunas alinham entre si. */
.explorer-table .tabulator-header .tabulator-col {
  justify-content: center;
}

/* A quebra em si vem de headerWordWrap:true na definição da coluna
   (app.js — adiciona a classe tabulator-col-title-wrap que o próprio
   Tabulator já sabe estilizar); aqui só ajustamos entrelinha/alinhamento
   pra ficar compacto e centralizado com a largura padronizada por coluna. */
.explorer-table .tabulator-col-title {
  line-height: 1.25;
  text-align: center;
}

.explorer-table .tabulator-col.tabulator-sortable:hover,
.explorer-table .tabulator-col.tabulator-col-sorter-element:hover {
  background: #dbeafe;
}

.explorer-table .tabulator-row {
  background: var(--panel);
  border-bottom: 1px solid #d8e0e6;
}

.explorer-table .tabulator-row.tabulator-row-even {
  background: var(--panel-alt);
}

.explorer-table .tabulator-row:hover {
  background: #e0edff;
}

.explorer-table .tabulator-cell {
  border-right: 1px solid #d8e0e6;
  padding: 7px 10px;
}

/* O tema padrao do Tabulator marca TODA coluna fixa (ver frozen:true em
   explorerColumns/circuitExplorerColumns, app.js) com uma borda grossa
   (2px, cinza escuro) — inclusive entre colunas fixas vizinhas (ex.
   De/Para/Circuito no Explorador de Circuitos), o que parecia "varias
   colunas marcadas" em vez de só indicar onde a area fixa termina.
   Uniformiza pra mesma borda fina (1px, #d8e0e6) usada em todas as outras
   celulas — a coluna continua fixa ao rolar, so' para de ter destaque
   visual proprio. */
.explorer-table .tabulator-frozen.tabulator-frozen-left,
.explorer-table .tabulator-frozen.tabulator-frozen-right {
  border-right: 1px solid #d8e0e6;
  border-left: 1px solid #d8e0e6;
}

/* Titulo de coluna com icone de filtro (estilo Excel/planilha — ver
   renderExplorerColumnTitle em app.js): o filtro em si só some/aparece num
   popover ao clicar no funil, em vez de ocupar uma linha inteira sempre
   visível abaixo de cada coluna (era o que deixava o cabeçalho alto e
   "pesado" antes). Colunas sem filtro (ver EXPLORER_NO_FILTER_COLUMNS) nem
   recebem esse wrapper, só o texto puro do Tabulator.
   Tentativa anterior posicionava o icone com position:absolute pra nao
   disputar espaço com o texto — mas isso empilhava padding-right proprio
   em cima do padding-right:25px que o Tabulator ja reserva pra seta de
   ordenacao (.tabulator-sortable .tabulator-col-title), sobrando so ~30px
   pro texto em colunas estreitas e cortando o rotulo quase por completo.
   Voltou pro layout inline-flex (texto + icone lado a lado, sem padding
   extra) — a largura de cada coluna (ver explorerColumns em app.js) e que
   garante espaço suficiente pros dois. */
.explorer-col-title {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
}

.explorer-filter-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex: 0 0 auto;
}

.explorer-filter-toggle:hover {
  background: rgba(29, 78, 216, 0.12);
  color: var(--primary-dark);
}

.explorer-filter-toggle.active {
  background: var(--primary);
  color: #fff;
}

/* Popover anexado no <body> (ver openExplorerFilterPopover em app.js), por
   isso o estilo é auto-contido em vez de depender de nada do Tabulator. */
.explorer-filter-popover {
  position: absolute;
  z-index: 50;
  min-width: 190px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 10px;
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.explorer-filter-popover input[type="text"],
.explorer-filter-popover input[type="number"] {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 5px 7px;
  font-size: 13px;
  width: 100%;
  box-sizing: border-box;
}

.explorer-filter-numeric-row {
  display: flex;
  gap: 6px;
}

.explorer-filter-numeric-row select {
  flex: 0 0 auto;
  width: 58px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 13px;
}

.explorer-filter-numeric-row input {
  flex: 1 1 auto;
  min-width: 0;
}

.explorer-filter-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 220px;
  overflow-y: auto;
}

.explorer-filter-list button {
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 4px;
  padding: 6px 8px;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}

.explorer-filter-list button:hover {
  background: var(--panel-alt);
}

.explorer-filter-list button.active {
  background: #dbeafe;
  color: var(--primary-dark);
  font-weight: 600;
}

.explorer-filter-clear {
  align-self: flex-start;
  background: transparent;
  border: none;
  color: var(--primary);
  font-size: 12px;
  padding: 2px 0;
  cursor: pointer;
}

.explorer-filter-clear:hover {
  text-decoration: underline;
}

.explorer-columns-popover {
  min-width: 260px;
  max-width: 320px;
}

.explorer-columns-title {
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.explorer-columns-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
}

.explorer-columns-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 4px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}

.explorer-columns-item:hover {
  background: var(--panel-alt);
}

/* Sem isso a checkbox herda a regra global "input { width:100%; min-height:
   38px; ... }" (ver topo do arquivo) — pensada pra campos de texto/numero,
   nao pra checkbox — e vira uma caixa gigante que empurra o rotulo/descricao
   pra fora da largura do popover (daí a barra de rolagem horizontal e o
   texto "sumindo"). */
.explorer-columns-item input {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  min-height: 0;
  padding: 0;
  margin: 2px 0 0;
}

.explorer-columns-item-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.explorer-columns-item-label {
  font-weight: 500;
}

.explorer-columns-item-desc {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.3;
}

/* Violacao de limite operacional (tensao vs. vmin/vmax, Q gerado vs.
   qmin/qmax — ver EXPLORER_LIMIT_HIGHLIGHT_FIELDS/buildExplorerColumns em
   app.js): cor de fundo + texto colorido e em negrito, nao so uma das duas,
   pra ficar identificavel mesmo pra quem tem dificuldade de distinguir
   azul/vermelho por contraste/peso, nao so matiz. */
.explorer-table .tabulator-cell.explorer-limit-low {
  background: #dbeafe;
  color: var(--primary-dark);
  font-weight: 700;
}

.explorer-table .tabulator-cell.explorer-limit-high {
  background: #fee2e2;
  color: var(--danger);
  font-weight: 700;
}

/* Carregamento de circuito acima do limite normal mas ainda dentro do de
   emergencia (ver formatter da coluna "carregamento" em
   buildCircuitExplorerColumns, app.js) — terceiro patamar, entre "normal"
   (sem destaque) e "acima da emergencia" (.explorer-limit-high, vermelho). */
.explorer-table .tabulator-cell.explorer-limit-warning {
  background: #fef3c7;
  color: var(--warning);
  font-weight: 700;
}

/* Celula que difere entre as duas solucoes comparadas (aba "Comparar
   Soluções", ver compareBusRows/compareCircuitRows em app.js) -- mesmo
   proposito visual de explorer-limit-*, mas pra "mudou de A pra B" em vez de
   "violou limite operacional". */
.compare-table td.explorer-diff {
  background: #fef3c7;
  color: var(--warning);
  font-weight: 700;
}

/* Comparador de Casos (aba workspaceTab === 'compareCases', ver app.js) --
   reaproveita .compare-table/.explorer-diff acima (mesma tag <td>, mesmo
   seletor), mas .explorer-limit-warning/-high NÃO servem aqui: essas regras
   são escopadas a ".explorer-table .tabulator-cell" (celulas do Tabulator,
   ver Explorador de Barras/Circuitos) -- esta aba usa <table> simples, sem
   Tabulator, então precisa da mesma cor com um seletor próprio. */
.compare-table td.explorer-limit-warning {
  background: #fef3c7;
  color: var(--warning);
  font-weight: 700;
}

.compare-table td.explorer-limit-high {
  background: #fee2e2;
  color: var(--danger);
  font-weight: 700;
}

.compare-watchlist-textarea {
  font-family: Consolas, "Courier New", monospace;
  resize: vertical;
}

/* Aba "Diff de Texto (.pwf)" do Comparador de Casos (compareCasesTab ===
   'text', ver runCompareText em app.js e text_diff.py no backend) --
   linha inteira tingida por tag (igual/inserida/removida/modificada) e,
   dentro de uma linha modificada, span por palavra via
   textdiff-seg-delete/-insert (ver _inline_segments em text_diff.py).
   Reaproveita as MESMAS cores de --success/--warning/--danger que
   .explorer-diff/.explorer-limit-* já usam no restante do app, por
   consistência visual (verde=inserido, âmbar=modificado, vermelho=removido). */
.textdiff-table {
  font-family: Consolas, "Courier New", monospace;
  font-size: 12px;
}

.textdiff-table .textdiff-lineno {
  width: 1%;
  white-space: nowrap;
  color: var(--muted);
  text-align: right;
  user-select: none;
}

.textdiff-table .textdiff-cell {
  white-space: pre-wrap;
  word-break: break-all;
}

.textdiff-row-insert td {
  background: #ecfdf5;
}

.textdiff-row-delete td {
  background: #fef2f2;
}

.textdiff-row-replace td {
  background: #fffbeb;
}

.textdiff-seg-delete {
  background: #fecaca;
  color: var(--danger);
  text-decoration: line-through;
}

.textdiff-seg-insert {
  background: #bbf7d0;
  color: var(--success);
  font-weight: 700;
}

.table-status.error {
  color: var(--danger);
}

.mono {
  font-family: Consolas, "Courier New", monospace;
}

.explorer-legend {
  display: flex;
  gap: 16px;
  margin: 6px 0;
  font-size: 12px;
  color: var(--muted);
}

.explorer-legend-item {
  position: relative;
  padding-left: 16px;
}

.explorer-legend-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  transform: translateY(-50%);
}

.explorer-legend-low::before {
  background: #dbeafe;
  border: 1px solid var(--primary-dark);
}

.explorer-legend-high::before {
  background: #fee2e2;
  border: 1px solid var(--danger);
}

.explorer-legend-warning::before {
  background: #fef3c7;
  border: 1px solid var(--warning);
}

/* Barra de rolagem horizontal "espelho", fixa no rodape da tela (ver
   updateStickyHScroll em app.js) — a tabela do Tabulator (altura fixa em
   68vh) pode ficar mais abaixo do que a viewport visivel dependendo de
   quanto a pagina foi rolada verticalmente, empurrando a rolagem horizontal
   nativa dela pra fora de vista. Este elemento fica sempre alcancavel no
   rodape e sincroniza scrollLeft nos dois sentidos com a tabela ativa —
   left/width sao calculados em JS (getBoundingClientRect da tabela ativa),
   nao dá pra fixar via CSS puro porque dependem de qual coluna/aba esta
   visivel no momento. */
.sticky-hscroll {
  position: fixed;
  bottom: 0;
  height: 16px;
  overflow-x: auto;
  overflow-y: hidden;
  background: var(--panel);
  border-top: 1px solid var(--line);
  box-shadow: 0 -2px 6px rgba(15, 23, 42, 0.08);
  z-index: 40;
}

.sticky-hscroll-spacer {
  height: 1px;
}

.constants-caption {
  margin: -6px 0 0;
  text-transform: none;
}

.constants-actions {
  display: flex;
  gap: 8px;
}

.constants-search {
  max-width: 420px;
}

.constants-table-wrap {
  max-height: 62vh;
}

.constants-table input {
  min-width: 130px;
  text-align: right;
}

.constants-table tr.modified td {
  background: #fff7ed;
}

.empty,
.empty-message {
  height: 120px;
  color: var(--muted);
  text-align: center;
}

.log-output pre {
  min-height: 360px;
  margin: 0;
  padding: 14px;
  overflow: auto;
  background: #0f172a;
  color: #e2e8f0;
  border-radius: 6px;
  font-family: Consolas, "Courier New", monospace;
  font-size: 14px;
}

.diagram-canvas {
  display: block;
  cursor: grab;
  width: 100%;
  /* max-height sozinho corta so a altura e deixa a largura em 100%, o que
     distorce o desenho (circulos viram elipses). Convertendo o limite de
     altura (70vh) num limite de largura equivalente, largura e altura
     encolhem juntas e a proporcao do canvas (ver diagramLogicalSize() em
     app.js) e sempre mantida. */
  max-width: calc(70vh * 3600 / 1600);
  aspect-ratio: 3600 / 1600;
  min-height: 360px;
  max-height: 70vh;
  margin: 0 auto;
  background: #fbfcfd;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.diagram-canvas.dragging {
  cursor: grabbing;
}

.diagram-caption {
  margin: -6px 0 0;
  text-transform: none;
}

.diagram-toolbar {
  display: flex;
  align-items: end;
  gap: 18px;
  margin-bottom: 12px;
}

.diagram-toolbar .field {
  max-width: 620px;
  margin-bottom: 0;
}

.diagram-bus-search {
  position: relative;
  max-width: 220px;
}

.diagram-bus-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  width: 100%;
  min-width: 260px;
  max-height: 240px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow);
}

.diagram-bus-suggestions li + li {
  margin-top: 2px;
}

.diagram-bus-suggestions button {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 4px;
  padding: 6px 8px;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}

.diagram-bus-suggestions button:hover {
  background: var(--panel-alt);
}

.diagram-zoom-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 9px;
}

.diagram-zoom-controls button {
  min-width: 34px;
  padding: 4px 8px;
  line-height: 1;
}

.diagram-zoom-level {
  min-width: 46px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.diagram-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding-bottom: 9px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.diagram-legend span::before {
  display: inline-block;
  width: 18px;
  height: 4px;
  margin-right: 5px;
  vertical-align: middle;
  content: '';
}

.legend-normal::before { background: var(--success); }
.legend-warning::before { background: var(--warning); }
.legend-danger::before { background: var(--danger); }
.legend-off::before { background: #94a3b8; }

.diagram-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
  margin: -4px 0 12px;
}

.diagram-breadcrumb-item {
  padding: 3px 9px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--primary);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}

.diagram-breadcrumb-item:hover:not(:disabled) {
  background: var(--panel-alt);
  text-decoration: underline;
}

.diagram-breadcrumb-item + .diagram-breadcrumb-item::before {
  margin-right: 4px;
  color: var(--line);
  content: '›';
}

.diagram-breadcrumb-item.current {
  color: var(--ink);
  background: var(--panel-alt);
  cursor: default;
}

.diagram-planarity {
  margin: -4px 0 12px;
  font-size: 13px;
}

.diagram-planarity.ok {
  color: var(--success);
}

.diagram-planarity.warn {
  color: var(--warning);
}

.diagram-selection-panel {
  max-width: 420px;
  margin: 12px auto 0;
  padding: 10px 14px;
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.diagram-selection-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: var(--ink);
}

.diagram-selection-close {
  min-width: 26px;
  padding: 0 6px;
  line-height: 1.6;
  font-size: 15px;
  color: var(--muted);
  background: transparent;
  border: none;
}

.diagram-selection-lines {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 4px;
  font-size: 13px;
  color: var(--ink);
}

/* Menu de contexto (botao direito) sobre um circuito do diagrama unifilar
   -- ver diagramContextMenu/selectDiagramBusOnRightClick em app.js.
   position:fixed porque as coordenadas vem de event.clientX/clientY
   (viewport), diferente do .diagram-selection-panel (fluxo normal, abaixo
   do canvas). */
.diagram-context-menu {
  position: fixed;
  z-index: 200;
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 6px;
  font-size: 13px;
}

.diagram-context-menu-title {
  padding: 4px 8px 6px;
  color: var(--muted);
  font-size: 12px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
  white-space: nowrap;
}

.diagram-context-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 7px 8px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}

.diagram-context-menu-item:hover {
  background: var(--panel-alt);
}

.chat-log {
  display: grid;
  gap: 10px;
  min-height: 180px;
  max-height: 42vh;
  margin: 12px 0;
  padding: 12px;
  overflow: auto;
  background: #fbfcfd;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.maps-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 18px;
  margin-bottom: 12px;
}

.maps-toolbar .field {
  max-width: 420px;
  margin-bottom: 0;
}

.maps-page-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 9px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
}

.maps-page-controls button {
  min-width: 34px;
  padding: 4px 8px;
  line-height: 1;
}

.maps-page-controls input[type="number"] {
  width: 64px;
  min-height: 30px;
  padding: 4px 6px;
  text-align: center;
}

.maps-body {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 16px;
  align-items: start;
}

.maps-search-panel .field {
  margin-bottom: 10px;
}

.maps-search-results {
  display: grid;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  max-height: 50vh;
  overflow: auto;
}

.maps-search-result {
  display: block;
  width: 100%;
  padding: 8px 10px;
  text-align: left;
  font-weight: 400;
  background: #fbfcfd;
}

.maps-search-result strong {
  display: block;
  margin-bottom: 2px;
  color: var(--primary-dark);
  font-size: 12px;
}

.maps-search-result span {
  color: var(--ink);
  font-size: 13px;
  line-height: 1.4;
}

.maps-canvas-wrap {
  overflow: auto;
  max-height: 78vh;
  padding: 12px;
  background: #525659;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: grab;
}

.maps-canvas-wrap.dragging {
  cursor: grabbing;
}

.maps-canvas {
  display: block;
  margin: 0 auto;
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.35);
  /* Arrastar (ver startMapsDrag/onMapsDragMove) faz scroll do wrap enquanto
     o mouse ainda esta sobre o canvas -- sem isso, o navegador tenta
     selecionar o canvas/pagina no meio do arrasto (cursor de texto,
     "fantasma" de selecao), o que atrapalha o gesto de pan. */
  user-select: none;
}

@media (max-width: 900px) {
  .maps-body {
    grid-template-columns: 1fr;
  }
}

.sin-topology-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px 14px;
  margin-bottom: 14px;
}

.sin-topology-search {
  position: relative;
  flex: 1 1 240px;
  min-width: 240px;
  max-width: 360px;
}

.sin-topology-search-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  /* 1101: acima dos panes internos do Leaflet (tile/overlay/marker/popup vao
     ate' 700, controles de zoom em 1000) -- .leaflet-container so' tem
     position:relative sem z-index proprio, entao nao cria um stacking
     context que contenha esses panes, e eles vazam por cima de qualquer
     elemento irmao com z-index mais baixo (ver .dashboard-dropdown-panel
     abaixo, que sofria do mesmo problema aqui dentro do mapa). */
  z-index: 1101;
  width: 100%;
  min-width: 280px;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow);
}

.sin-topology-search-suggestions li + li {
  margin-top: 2px;
}

.sin-topology-search-suggestions button {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 4px;
  padding: 6px 8px;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}

.sin-topology-search-suggestions button:hover {
  background: var(--panel-alt);
}

.sin-topology-search-suggestions button span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
}

.sin-topology-search-empty {
  padding: 6px 8px;
  color: var(--muted);
  font-size: 13px;
}

.dashboard-dropdown-panel-wide {
  min-width: 320px;
  max-width: min(360px, 90vw);
  max-height: 320px;
}

/* Mesmo motivo do z-index em .sin-topology-search-suggestions: dentro da
   Topologia SIN, o dropdown (z-index:20, ver .dashboard-dropdown-panel)
   fica atras dos panes internos do Leaflet quando os dois se sobrepoem
   (o mapa vem depois no DOM e o container do Leaflet nao cria stacking
   context proprio pra' conter esses panes). So' escopado pro toolbar da
   Topologia SIN -- o uso original em "Resumo" (aba Fluxo de Potencia) nao
   tem mapa por baixo e nao precisa disso. */
.sin-topology-toolbar .dashboard-dropdown-panel {
  z-index: 1101;
}

.dashboard-dropdown-panel-wide .dashboard-check {
  white-space: normal;
}

.dashboard-dropdown-search {
  min-height: 32px;
  margin-bottom: 6px;
  padding: 6px 8px;
  font-weight: 400;
  text-transform: none;
}

.dashboard-dropdown-hint {
  margin: 0 0 4px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
}

.sin-topology-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

/* Checkbox "chip" (fundo + cantos arredondados + accent-color no lugar do
   checkbox padrao do SO) em vez da lista de checkboxes cru anterior --
   mesmo principio visual de filtro usado em painéis de camada de software
   de mapa moderno (ex.: QGIS, Google Maps). accent-color e' suportado por
   todos os browsers relevantes hoje (Chrome/Edge/Firefox/Safari) e evita
   ter que desenhar um checkbox customizado em SVG so' pra isso. */
.sin-topology-legend-item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px 6px 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.sin-topology-legend-item:hover {
  background: #eef2f5;
  border-color: var(--primary);
}

.sin-topology-legend-item input[type="checkbox"] {
  width: auto;
  min-height: auto;
  margin: 0;
  accent-color: var(--primary);
}

.sin-topology-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.sin-topology-map-wrap {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
}

.sin-topology-map {
  flex: 1 1 auto;
  min-width: 0;
  height: 640px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #eef2f5;
}

.message {
  max-width: 960px;
  padding: 10px 12px;
  background: #f4f8f9;
  border-left: 4px solid var(--line);
  border-radius: 6px;
}

.message.user {
  margin-left: auto;
  background: #eef6ff;
  border-left-color: var(--primary);
}

.message.assistant {
  background: #ecfdf5;
  border-left-color: var(--success);
}

.message.system {
  max-width: 100%;
  background: transparent;
  border-left-color: var(--line);
  color: var(--muted);
  font-size: 12px;
  padding: 6px 12px;
}

.message p {
  margin: 6px 0 0;
  white-space: pre-wrap;
}

.plot-image {
  display: block;
  width: 100%;
  max-width: 100%;
  height: 420px;
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
}

.curves-panel {
  padding: 14px 0;
}

.curves-panel .empty {
  height: auto;
  padding: 40px 0;
}

.curves-panel a.file-button {
  display: inline-block;
  text-decoration: none;
}

.pv-layout {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.pv-bus-list {
  flex: 0 0 300px;
  max-height: 520px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
}

.pv-bus-row {
  padding: 4px 0;
  border-bottom: 1px solid #f1f5f9;
}

.pv-bus-row:last-child {
  border-bottom: none;
}

.pv-bus-row-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pv-bus-row-header button {
  min-height: 26px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 400;
}

.pv-style-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0;
}

.pv-style-controls input[type="color"] {
  width: 32px;
  min-height: 26px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}

.pv-style-controls input[type="number"] {
  width: 56px;
  min-height: 26px;
  padding: 2px 4px;
  font-size: 13px;
}

.pv-style-controls select {
  min-height: 26px;
  padding: 2px 4px;
  font-size: 12px;
}

.pv-chart-col {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: column;
  gap: 8px;
}

.pv-chart-toolbar {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.pv-chart-toolbar button {
  min-height: 30px;
  padding: 4px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
}

.pv-chart-wrap {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
}

/* Em tela cheia o wrap vira o proprio elemento :fullscreen — da um respiro
   nas bordas e deixa o grafico ocupar a altura real da tela, em vez da
   altura fixa de 560px usada no layout normal. */
.pv-chart-wrap:fullscreen {
  align-items: stretch;
  padding: 20px;
  background: var(--panel);
}

.pv-chart-wrap:fullscreen .pv-chart {
  height: 100%;
}

.pv-chart {
  flex: 1 1 auto;
  min-width: 0;
  height: 560px;
}

@media (max-width: 1100px) {
  .input-grid,
  .flow-options,
  .reports-options,
  .grid.two,
  .grid.three {
    grid-template-columns: 1fr;
  }

  .check-grid,
  .check-grid.controls,
  .compact-grid {
    grid-template-columns: repeat(2, minmax(180px, 1fr));
  }
}

@media (max-width: 700px) {
  .toolbar,
  .upload-row,
  .panel-title,
  .constants-actions,
  .diagram-toolbar,
  .maps-toolbar {
    align-items: stretch;
    flex-direction: column;
  }

  .topbar {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 8px;
    padding: 10px 14px;
  }

  .brand-logo {
    width: 72px;
    height: 72px;
  }

  .topbar-end {
    justify-self: center;
    align-items: center;
  }

  .statusbar,
  .compact,
  .primary {
    width: 100%;
    min-width: 0;
    text-align: left;
  }

  .workspace {
    padding: 10px;
  }

  .check-grid,
  .check-grid.controls,
  .compact-grid {
    grid-template-columns: 1fr;
  }
}
