/* =====================================================================
   PRISMA — Design System
   Missão 04 / Etapa 9.2 — Rebranding, Identidade Visual e Redesign UX/UI

   Extraído do <style> inline de templates/base.html (Etapas 1-9) para
   um arquivo estático versionável. Nenhuma regra de layout estrutural
   (app-body/sidebar/dash-drawer/etc. das Etapas 9/9.1) foi removida —
   só reorganizada, retematizada com os tokens PRISMA (seção 4 da
   missão) e estendida com os novos componentes desta etapa. Nenhum id
   ou seletor usado pelo JavaScript foi renomeado.

   Risco avaliado (seção 11 da missão): extrair CSS para um arquivo
   estático é de baixo risco (STATICFILES_DIRS já configurado, sem
   lógica/efeitos colaterais — só aparência). Extrair o <script>
   também NÃO foi feito agora: envolve ordem de execução, closures e o
   contrato window.__rgbPanel, com risco bem maior para o ganho — fica
   documentado como proposta para uma etapa futura, não implementado
   aqui (ver relatório final).
   ===================================================================== */

/* =========================================================
   1) TOKENS — paleta oficial, superfícies, tipografia, espaçamento,
   raios, sombras, estados de interação (seções 4 e 5 da missão)
   ========================================================= */
:root{
  /* --- Paleta oficial PRISMA (seção 4) --- */
  --prisma-deep-blue: #18253D;
  --prisma-blue:       #3456D1;
  --prisma-violet:     #6552D9;
  --prisma-cyan:        #19A8BC;
  --prisma-coral:      #F18B57;
  --prisma-light:      #F4F7FB;

  /* --- Papéis semânticos (nunca distribuir as 6 cores igualmente —
     cada uma tem um papel específico, ver seção 4 "Distribuição") --- */
  --color-bg:            var(--prisma-light);
  --color-surface:       #FFFFFF;
  --color-surface-alt:   #EEF2FA;
  --color-header:        var(--prisma-deep-blue);
  --color-header-contrast: #FFFFFF;

  --color-primary:          var(--prisma-blue);
  --color-primary-strong:   #2946A5;
  --color-primary-contrast: #FFFFFF;
  --color-primary-soft:     rgba(52, 86, 209, 0.12);

  --color-accent-violet:      var(--prisma-violet);
  --color-accent-violet-soft: rgba(101, 82, 217, 0.12);
  --color-accent-cyan:        var(--prisma-cyan);
  --color-accent-cyan-soft:   rgba(25, 168, 188, 0.12);
  --color-accent-coral:       var(--prisma-coral);
  --color-accent-coral-soft:  rgba(241, 139, 87, 0.14);

  --color-text:        #121B2E;
  --color-text-muted:  #5B6B85;
  --color-text-faint:  #8795AC;
  --color-text-inverse: #F4F7FB;

  --color-border:        rgba(18, 27, 46, 0.10);
  --color-border-strong: rgba(18, 27, 46, 0.18);

  /* --- Estados independentes da marca (seção 4, obrigatório) --- */
  --color-success:      #1C9A6C;
  --color-success-soft: rgba(28, 154, 108, 0.12);
  --color-warning:      #B9790A;
  --color-warning-soft: rgba(185, 121, 10, 0.12);
  --color-danger:       #D1403D;
  --color-danger-soft:  rgba(209, 64, 61, 0.12);
  --color-info:         var(--prisma-cyan);
  --color-info-soft:    var(--color-accent-cyan-soft);

  /* --- Tipografia --- */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --fs-2xs: 10.5px;
  --fs-xs:  11.5px;
  --fs-sm:  12.5px;
  --fs-base: 13.5px;
  --fs-md:  15px;
  --fs-lg:  17px;
  --fs-xl:  21px;
  --fs-2xl: 26px;
  --fs-brand: 23px; /* Etapa 9.3 — wordmark PRISMA no header, maior presença */
  --fw-regular: 400;
  --fw-medium:  600;
  --fw-bold:    700;
  --fw-black:   800;

  /* --- Espaçamento --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* --- Raios --- */
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-pill: 999px;

  /* --- Sombras --- */
  --shadow-sm: 0 2px 8px rgba(18, 27, 46, 0.06);
  --shadow-md: 0 8px 20px rgba(18, 27, 46, 0.10);
  --shadow-lg: 0 18px 44px rgba(18, 27, 46, 0.18);

  /* --- Alturas de componentes / casco do app ---
     Etapa 9.3: --nav-h 60→68px (presença da marca; controles à direita
     NÃO mudam de tamanho, só recentralizam automaticamente — ver seção
     3 do CSS). --sidebar-w 304→320px: a referência pedida (280-300px)
     já era menor que o valor anterior, então só alargar não resolvia a
     compressão real — o problema era o padding duplicado (rail +
     card). Resolvido alargando moderadamente E reduzindo esse padding
     (ver .sidebar-scroll/.sidebar-section mais abaixo). */
  --control-h: 38px;
  --nav-h: 68px;
  --sidebar-w: 320px;
  --sidebar-w-collapsed: 48px;

  /* --- Transições --- */
  --transition-fast: .12s ease;
  --transition-base: .18s ease;
}

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================
   2) BASE
   ========================================================= */
html, body { height: 100%; margin: 0; }
body{
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  -webkit-font-smoothing: antialiased;
}
button, input, select, textarea{ font-family: inherit; }

/* foco visível e consistente (acessibilidade — seção 5) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
[tabindex]:focus-visible{
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* =========================================================
   3) HEADER PRISMA (seção 6.1)
   ========================================================= */
.agro-navbar{
  background: var(--color-header);
  box-shadow: 0 4px 16px rgba(18, 27, 46, 0.25);
}
.prisma-header-inner{
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
}
.prisma-brand{
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 0 0 auto;
}
/* Etapa 9.3 (seção 2.2): símbolo e wordmark maiores — mesma geometria/
   cores SVG do logo aprovado, só a área de exibição cresceu. */
.prisma-brand__mark{
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  display: block;
}
.prisma-brand__wordmark{
  font-size: var(--fs-brand);
  font-weight: var(--fw-black);
  letter-spacing: .3px;
  color: var(--color-header-contrast);
  line-height: 1;
}
.prisma-brand__divider{
  width: 1px;
  height: 28px;
  background: rgba(255,255,255,0.18);
  flex: 0 0 auto;
}
/* Etapa 9.3 (seção 2.3): módulo com mais contraste/leitura, mas ainda
   claramente subordinado à marca (peso/tamanho menores que o wordmark). */
.prisma-module{
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
.prisma-module__name{
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: rgba(244,247,251,1);
}
.prisma-module__tagline{
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: rgba(244,247,251,0.62);
  letter-spacing: .2px;
}
@media (max-width: 1200px){
  .prisma-module__tagline{ display: none; }
}
@media (max-width: 860px){
  .prisma-brand__divider, .prisma-module{ display: none; }
  /* Etapa 9.3 (seção 2.5): evita sobreposição com o seletor de ambiente
     em telas estreitas — volta ao tamanho compacto só aqui. */
  .prisma-brand__mark{ width: 30px; height: 30px; }
  .prisma-brand__wordmark{ font-size: var(--fs-lg); }
}

/* usuário */
.user-pill{
  background: rgba(255,255,255,0.10);
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--color-header-contrast);
  gap: 6px;
}
.user-pill i{ font-size: 1.15rem; opacity: 0.9; }

/* =========================================================
   4) SELETOR DE AMBIENTE (seção 6.1 / 7)
   ========================================================= */
.env-switcher{
  display: inline-flex;
  gap: 4px;
  background: rgba(255,255,255,0.08);
  border-radius: var(--radius-pill);
  padding: 3px;
}
.env-switch-btn{
  border: none;
  background: transparent;
  color: rgba(244,247,251,0.72);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all var(--transition-fast);
}
.env-switch-btn:hover{ color: #fff; }
.env-switch-btn.active{
  background: var(--color-surface);
  color: var(--color-header);
  box-shadow: var(--shadow-sm);
}
/* ponto de identidade discreto por ambiente — nunca a única forma de
   diferenciar (texto do botão já diferencia), só reforço visual */
.env-switch-btn[data-env="banco"] .env-switch-dot{ background: var(--color-primary); }
.env-switch-btn[data-env="nova"] .env-switch-dot{ background: var(--color-accent-violet); }
.env-switch-dot{
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: 0 0 auto;
}
@media (max-width: 992px){
  .env-switch-btn span.env-switch-label{ display:none; }
}

/* =========================================================
   5) CASCO DO APP — sidebar + mapa (Etapa 9, retematizado)
   ========================================================= */
.app-body{
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}

.sidebar{
  width: var(--sidebar-w);
  flex: 0 0 auto;
  background: var(--color-bg);
  border-right: 1px solid var(--color-border);
  position: relative;
  transition: width var(--transition-base);
  display: flex;
  flex-direction: column;
}
.sidebar.collapsed{ width: var(--sidebar-w-collapsed); }
.sidebar.collapsed .sidebar-scroll{ display: none; }
.sidebar-scroll{
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  min-height: 0;
  /* Etapa 9.3: menos padding no "rail" (os cards já têm o seu próprio
     padding interno — ver .sidebar-section) para não duplicar o
     espaço perdido nas duas camadas e deixar mais largura útil para
     inputs/botões. Etapa 9.3.1: padding vertical também reduzido —
     ver diagnóstico no relatório da etapa sobre altura acumulada. */
  padding: var(--space-2) var(--space-2) var(--space-3);
}
/* Etapa 9.3 (seção 5): scrollbar discreta, coerente com o design
   system, em vez da scrollbar genérica do sistema operacional. */
.sidebar-scroll{ scrollbar-width: thin; scrollbar-color: var(--color-border-strong) transparent; }
.sidebar-scroll::-webkit-scrollbar{ width: 8px; }
.sidebar-scroll::-webkit-scrollbar-track{ background: transparent; }
.sidebar-scroll::-webkit-scrollbar-thumb{
  background: var(--color-border-strong);
  border-radius: var(--radius-pill);
}
.sidebar-scroll::-webkit-scrollbar-thumb:hover{ background: var(--color-text-faint); }
.sidebar-collapse-btn{
  position: absolute;
  top: 10px;
  right: -14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 5;
  color: var(--color-text-muted);
}
.sidebar-collapse-btn:hover{ color: var(--color-primary); }

/* --- Grupos conceituais da sidebar: EXPLORAR / VISUALIZAR / ANALISAR
   (seção 6.2) --- */
.sidebar-group{ margin-bottom: var(--space-1); }
.sidebar-group__title{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-black);
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--color-text-faint);
  padding: var(--space-2) var(--space-1) var(--space-1);
}
.sidebar-group__title::after{
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}
/* primeiro grupo logo no topo não precisa do respiro extra de cima */
.sidebar-group__title:first-child{ padding-top: 0; }

.sidebar-section{
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-2);
}
/* Etapa 9.3.1 (seção 2/7 do relatório): EXPLORAR e VISUALIZAR (seções
   data-env="shared") não precisam da casca de card — o título do grupo
   já dá a separação visual necessária, e remover borda/sombra/padding
   duplicados é o maior fator isolado de redução de altura. ANALISAR
   mantém o card: é o único contexto que de fato alterna (Banco de
   Dados ↔ Análise Sentinel-2) e se beneficia de um limite visual
   claro. */
.sidebar-section--flat{
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0 var(--space-1);
  margin-bottom: var(--space-3);
}
.sidebar-section__h{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}
.sidebar-section__h i{ color: var(--color-primary); font-size: 1rem; }
.sidebar-section__sub{
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: var(--color-text-faint);
  margin-top: -6px;
  margin-bottom: var(--space-2);
}
.source-badge{
  margin-left: auto;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  text-transform: none;
  letter-spacing: 0;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}
.source-badge.source-badge--banco{ background: var(--color-primary-soft); color: var(--color-primary-strong); }
.source-badge.source-badge--nova{ background: var(--color-accent-violet-soft); color: var(--color-accent-violet); }

.sidebar-form .field,
.sidebar-section .field{ margin-bottom: var(--space-2); }
.sidebar-section .field:last-child{ margin-bottom: 0; }

/* Etapa 9.3.1 (seção 2 do relatório): Cidade + Fazenda lado a lado em
   vez de empilhados — uma das duas maiores reduções de altura do
   grupo EXPLORAR. Talhão continua em largura cheia abaixo. */
.sidebar-row-2{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.sidebar-row-2 .field{ margin-bottom: 0; }

/* Etapa 9.3.1: "Carregar GeoJSON" + "Remover" numa única linha
   compacta (antes: campo de upload + botão largo de 38px numa linha
   própria abaixo — a ação de remover passa a ser um ícone associado
   ao arquivo carregado, como sugerido na missão). */
.sidebar-upload-row{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.sidebar-upload-row .form-control{ flex: 1; }

/* Etapa 9.4 (Fase 2): gatilho de upload com identidade PRISMA — o
   <input type="file"> real fica sobreposto (overlay transparente),
   garantindo clique/teclado/foco 100% nativos; só a aparência é
   substituída. */
.sidebar-upload-trigger{
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.sidebar-upload-trigger:hover{ border-color: var(--color-primary); }
.sidebar-upload-trigger:focus-within{
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.sidebar-upload-trigger i{ font-size: 1rem; flex: 0 0 auto; color: var(--color-text-faint); }
.sidebar-upload-trigger__text{
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
}
/* estado "arquivo carregado": leve destaque azul, nunca verde/sucesso —
   carregar não é em si uma validação de conteúdo. */
.sidebar-upload-trigger.has-file{ border-color: var(--color-primary); background: var(--color-primary-soft); }
.sidebar-upload-trigger.has-file i{ color: var(--color-primary-strong); }
.sidebar-upload-trigger.has-file .sidebar-upload-trigger__text{ color: var(--color-primary-strong); font-weight: var(--fw-bold); }
.sidebar-upload-input{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}
.sidebar-icon-btn{
  flex: 0 0 auto;
  width: var(--control-h);
  height: var(--control-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: all var(--transition-fast);
}
.sidebar-icon-btn:hover{ background: var(--color-danger-soft); border-color: rgba(209,64,61,0.35); color: var(--color-danger); }
.sidebar-icon-btn i{ font-size: 1rem; }

/* Etapa 9.4 (Fase 3): dica de estado vazio — uma linha discreta dentro
   da própria sidebar, nunca um modal/painel sobre o mapa. */
.sidebar-empty-hint{
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--color-text-faint);
  line-height: 1.5;
}
.sidebar-empty-hint i{ margin-top: 1px; flex: 0 0 auto; }

/* Etapa 9.3.1 (seção 3 — navegação progressiva): disclosure para
   ações secundárias (ex.: Dashboard/Comparação), colapsadas por
   padrão mas sempre identificadas por um rótulo visível — nunca uma
   ação escondida sem indicação de que existe. */
.sidebar-disclosure-toggle{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  cursor: pointer;
  margin-top: var(--space-2);
  text-decoration: none;
}
.sidebar-disclosure-toggle:hover{ background: var(--color-primary-soft); color: var(--color-primary-strong); }
.sidebar-disclosure-toggle i.bi-chevron-down{
  margin-left: auto;
  transition: transform var(--transition-fast);
  font-size: .85rem;
}
.sidebar-disclosure-toggle[aria-expanded="true"] i.bi-chevron-down{ transform: rotate(180deg); }
.sidebar-disclosure-body{ padding-top: var(--space-2); }
.sidebar-form .form-label,
.sidebar-section .form-label{
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  margin-bottom: 4px;
  color: var(--color-text-muted);
  display: block;
}
.sidebar-form .form-select,
.sidebar-form .form-control,
.sidebar-section .form-select,
.sidebar-section .form-control,
.sidebar-section input[type="date"]{
  font-size: var(--fs-base);
  height: var(--control-h);
  width: 100%;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.sidebar-form .form-select:focus,
.sidebar-form .form-control:focus,
.sidebar-section .form-select:focus,
.sidebar-section .form-control:focus,
.sidebar-section input[type="date"]:focus{
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.sidebar-btn-row{ display: flex; gap: var(--space-2); margin-top: var(--space-1); }
.sidebar-btn-row .btn-app{ flex: 1; }

/* painel Sentinel-2 (ver initRgbPanel) reaproveitado dentro do grupo
   ANALISAR — some apenas a casca de card flutuante, nunca a
   lógica/ids internos. */
#rgbPanelMount .rgb-panel-control{
  width: 100%;
  box-shadow: none;
  border: none;
  padding: 0;
  border-radius: 0;
  background: transparent;
}

/* =========================================================
   6) CONTROLES — pills, botões, inputs (seção 5 "Componentes")
   ========================================================= */
.pill-group{ display: inline-flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; margin-bottom: var(--space-2); }
/* Etapa 9.3.1: índices em UMA linha compacta (a grade 2x2 da Etapa 9.3
   gastava uma linha extra de altura). Os três ainda não disponíveis
   (EVI/PSRI/SIPI) ficam visualmente menores — são apenas rótulos
   desabilitados ("ainda não disponível"), então reduzir o peso visual
   deles é proporcional à sua relevância, sem removê-los da interface. */
.pill-btn.offline{ padding: 5px 8px; font-size: var(--fs-2xs); }
.pill-btn.offline i{ font-size: .9rem; }
.pill-btn{
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  padding: 7px 12px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  user-select: none;
  transition: all var(--transition-fast);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  box-shadow: var(--shadow-sm);
}
.pill-btn i{ font-size: 1.0rem; line-height: 1; opacity: .85; }
.pill-btn:hover{ background: var(--color-surface-alt); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.pill-btn:active{ transform: translateY(0); box-shadow: var(--shadow-sm); }

/* Active padrão (azul PRISMA) */
.pill-btn.active{
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
  color: var(--color-primary-strong);
}
/* Índice aplicado: mantém semântica própria (sucesso/vegetação), não a
   cor de marca — "as escalas cromáticas de índices devem preservar seu
   significado analítico" (seção 4) */
.pill-btn.index-btn.active{
  border-color: var(--color-success);
  background: var(--color-success-soft);
  color: var(--color-success);
}
.pill-btn.base-btn.active{
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
  color: var(--color-primary-strong);
}
.pill-btn.offline{ opacity: 0.45; cursor: not-allowed; filter: grayscale(1); box-shadow: none; }
.pill-btn.offline:hover{ transform: none; box-shadow: none; background: var(--color-surface); }
.pill-btn.offline i{ opacity: 0.6; }

/* Botões principais (estilo unificado) */
.btn-app{
  height: var(--control-h);
  border-radius: var(--radius-sm);
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  letter-spacing: .1px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 12px;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border-strong);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast), border-color var(--transition-fast);
}
.btn-app:hover{ transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-app:active{ transform: translateY(0); box-shadow: var(--shadow-sm); }
.btn-app i{ font-size: 1.05rem; line-height: 1; }
.btn-app.btn-primary{ background: var(--color-primary); border-color: var(--color-primary); }
.btn-app.btn-primary:hover{ background: var(--color-primary-strong); border-color: var(--color-primary-strong); }
.btn-app.btn-dark{ background: var(--color-header); border-color: var(--color-header); }
.btn-app.btn-danger{ border-color: rgba(209,64,61,0.35); }
/* Etapa 9.3 (seção 6, "Ação Remover GeoJSON"): ações destrutivas em
   estilo ghost — neutras em repouso, o vermelho aparece só no ícone
   e no hover, nunca como a cor dominante do botão em repouso.
   Aplica-se a toda .btn-outline-danger (Remover GeoJSON e Limpar
   Índice), por consistência do design system. */
.btn-app.btn-outline-danger{
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text-muted);
  box-shadow: none;
}
.btn-app.btn-outline-danger i{ color: var(--color-danger); }
.btn-app.btn-outline-danger:hover{
  background: var(--color-danger-soft);
  border-color: rgba(209,64,61,0.35);
  color: var(--color-danger);
}
.btn-app.btn-outline-danger:hover i{ color: var(--color-danger); }

/* =========================================================
   7) MAPA (seção 6.3)
   ========================================================= */
.map-wrapper{
  flex: 1;
  min-height: 0;
  padding: var(--space-3) var(--space-4) var(--space-4) var(--space-4);
  background: var(--color-bg);
  position: relative;
}
#map{
  height: 100%;
  width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  background: #DFE6EE;
}
/* Etapa 11.1 (Fase 6.4): fundo neutro enquanto a comparação temporal
   está ativa — nenhum mapa-base por trás de pixels mascarados/
   transparentes, evitando confundir imagem de outra data com a cena
   analisada. Aplicado/removido só por enterCompareMode()/endCompare(). */
#map.compare-neutral-bg{ background: var(--color-surface-alt); }

.loading-overlay{
  position:absolute;
  inset: 0;
  display:none;
  align-items:center;
  justify-content:center;
  background: rgba(244,247,251,0.72);
  z-index: 998;
  border-radius: var(--radius-lg);
}
.loading-overlay .card{
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  box-shadow: var(--shadow-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.loading-overlay .spinner-border{ color: var(--color-primary); }

/* Card flutuante no mapa (Leaflet control) — metadados Esri */
.esri-meta-control{
  background: rgba(255,255,255,0.97);
  padding: 10px 12px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  border: 1px solid var(--color-border);
  font-family: var(--font-sans);
  min-width: 220px;
}
.esri-meta-control .title{
  font-size: var(--fs-xs);
  font-weight: var(--fw-black);
  color: var(--color-text);
  opacity: 0.75;
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: .4px;
}
.esri-meta-control .line{ font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--color-text); }
.esri-meta-control .sub{ margin-top: 2px; font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--color-text-muted); }

/* =========================================================
   8) PAINÉIS CONTEXTUAIS — dashboard histórico + Sentinel-2
   (seção 6.4: identificação → indicadores → gráficos →
   estatísticas → proveniência → detalhes técnicos recolhíveis)
   ========================================================= */
.dash-scrim{ position: fixed; inset: 0; background: rgba(18,27,46,0.72); z-index: 3000; display: none; }
.dash-drawer{
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: min(520px, 92vw);
  background: var(--color-surface);
  z-index: 3001;
  transform: translateX(110%);
  transition: transform .22s ease;
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
}
.dash-drawer.open{ transform: translateX(0); }
.dash-header{
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap: var(--space-3);
  background: var(--color-surface-alt);
}
.dash-title{ font-weight: var(--fw-black); font-size: var(--fs-md); color: var(--color-text); line-height: 1.25; }
.dash-sub{ font-size: var(--fs-sm); color: var(--color-text-muted); margin-top: 4px; }
.dash-source-tag{
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .3px;
  margin-top: 6px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
}
.dash-source-tag--banco{ background: var(--color-primary-soft); color: var(--color-primary-strong); }
.dash-source-tag--nova{ background: var(--color-accent-violet-soft); color: var(--color-accent-violet); }
.dash-body{ padding: var(--space-4); overflow: auto; flex: 1; }

.kpi-grid{ display:grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.kpi{ border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: var(--space-3); background: var(--color-surface); }
.kpi .label{ font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--color-text-muted); }
.kpi .value{ font-size: var(--fs-xl); font-weight: var(--fw-black); color: var(--color-text); margin-top: 2px; }
.kpi .hint{ font-size: var(--fs-xs); color: var(--color-text-faint); margin-top: 2px; }

.dash-section{ margin-top: var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-surface); }
.dash-section .sec-h{
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  display:flex;
  justify-content:space-between;
  align-items:center;
}
.dash-section .sec-b{ padding: var(--space-3); }
.kv{ display:grid; grid-template-columns: 140px 1fr; gap: 7px 10px; font-size: var(--fs-sm); }
.kv .k{ color: var(--color-text-muted); font-weight: var(--fw-bold); }
.kv .v{ color: var(--color-text); font-weight: var(--fw-medium); }

/* detalhes técnicos recolhíveis (seção 6.4, item 6) */
.tech-details-toggle{
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--color-text-muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.tech-details-toggle:hover{ color: var(--color-primary); }
.tech-details-toggle i{ transition: transform var(--transition-fast); font-size: .85rem; }
.tech-details-toggle[aria-expanded="true"] i{ transform: rotate(180deg); }
.tech-details-body{
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  line-height: 1.6;
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
}
.tech-details-body div{ margin-bottom: 2px; }

/* ===== FIX histórico (Etapa 8): trava altura do gráfico ===== */
.chart-wrap{ height: 220px; width: 100%; position: relative; }
#ndviChart{ width: 100% !important; height: 100% !important; display: block; }

/* =========================================================
   9) ESTADOS — vazio, carregando, erro, aviso (seção 8)
   ========================================================= */
.status-pill{
  display: inline-flex;
  align-items: flex-start;
  gap: 7px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.5;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
  width: 100%;
}
.status-pill i{ margin-top: 2px; flex: 0 0 auto; }
.status-pill--info{ background: var(--color-info-soft); color: #0E6E7D; }
.status-pill--success{ background: var(--color-success-soft); color: var(--color-success); }
.status-pill--warning{ background: var(--color-warning-soft); color: var(--color-warning); }
.status-pill--danger{ background: var(--color-danger-soft); color: var(--color-danger); }

/* =========================================================
   9.1) POPUP DE TALHÃO — ação "Ver análise do talhão" (Etapa 10)
   ========================================================= */
.talhao-popup{ font-size: var(--fs-sm); line-height: 1.5; }
.talhao-popup__actions{ margin-top: var(--space-2); }
.talhao-popup__btn{
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 10px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--color-primary-contrast);
  background: var(--color-primary);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}
.talhao-popup__btn:hover{ background: var(--color-primary-strong); }
.talhao-popup__btn:focus-visible{ outline: 2px solid var(--color-primary-strong); outline-offset: 2px; }

/* =========================================================
   10) COMPARAÇÃO (Modal)
   ========================================================= */
.cmp-map{ height: 380px; width: 100%; border-radius: var(--radius-lg); overflow: hidden; background: #DFE6EE; border: 1px solid var(--color-border); box-shadow: var(--shadow-md); }
.cmp-badge{ font-size: var(--fs-sm); font-weight: var(--fw-black); padding: 6px 10px; border-radius: var(--radius-pill); background: var(--color-primary-soft); color: var(--color-primary-strong); border: 1px solid var(--color-border); }

/* =========================================================
   12) COMPARADOR TEMPORAL SENTINEL-2 — Missão 04 / Etapa 11
   Divisor vertical arrastável diretamente sobre o mapa (nunca um
   slider HTML externo). Elementos são filhos diretos de
   map.getContainer() (ver initRgbPanel/ensureCompareDividerDom no
   script), por isso as regras aqui usam seletores de classe simples,
   sem acoplamento a nenhum componente de painel.
   ========================================================= */
.compare-divider{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 0;
  z-index: 650; /* acima de todas as panes do Leaflet (tilePane 200,
                   rgbPane 350, overlayPane 400 — contornos do GeoJSON
                   continuam visíveis por estarem numa pane abaixo
                   deste nível), abaixo de popups (700) e controles. */
  pointer-events: none; /* só o controle circular dentro dela é interativo */
}
.compare-divider[hidden]{ display: none; }
.compare-divider__line{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--color-surface);
  box-shadow: 0 0 0 1px rgba(18,27,46,0.35), 0 2px 10px rgba(18,27,46,0.35);
}
.compare-divider__thumb{
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-surface);
  border: 2px solid var(--color-primary);
  box-shadow: var(--shadow-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  color: var(--color-primary);
  font-size: 13px;
  cursor: ew-resize;
  pointer-events: auto;
  touch-action: none; /* evita rolagem/scroll da página durante o arraste por toque */
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
}
.compare-divider__thumb:hover{ box-shadow: 0 0 0 6px var(--color-primary-soft), var(--shadow-lg); }
.compare-divider__thumb:focus-visible{
  outline: none;
  box-shadow: 0 0 0 4px var(--color-primary-soft), var(--shadow-lg);
}
.compare-divider__thumb.dragging{
  transform: translate(-50%, -50%) scale(1.08);
  box-shadow: 0 0 0 8px var(--color-primary-soft), var(--shadow-lg);
}

.compare-labels{
  position: absolute;
  top: var(--space-3);
  left: 0;
  right: 0;
  z-index: 640;
  /* Missão 04 / Etapa 11.2.B1.1 (Fase 4.2): 3 colunas (anterior /
     variação / recente) em vez do antigo flex de 2 pontas — a coluna
     central nunca cobre a bolinha do divisor (que fica mais abaixo,
     verticalmente centrada) nem a área de interesse. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  pointer-events: none; /* nunca bloqueia o arraste do divisor nem os controles do Leaflet */
}
.compare-labels[hidden]{ display: none; }
.compare-label{
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: 1.5;
  padding: 5px 10px;
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.94);
  color: var(--color-text);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border);
}
.compare-label--left{ border-color: var(--color-border-strong); justify-self: start; }
.compare-label--right{ border-color: var(--color-accent-violet); color: var(--color-accent-violet); justify-self: end; text-align: right; }

/* Missão 04 / Etapa 11.2.B1.1 (Fase 4.2): bloco central de variação —
   só aparece com NDVI e as duas estatísticas disponíveis (ver
   updateCompareLabels no script); nunca equipara "variação das médias
   individuais" a "variação na área comum válida" — a segunda, quando
   indisponível, é documentada como limitação, nunca fabricada. */
.compare-variation{
  justify-self: center;
  text-align: center;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: 1.5;
  padding: 5px 10px;
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.94);
  color: var(--color-text);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--color-border);
  max-width: 260px;
}
.compare-variation[hidden]{ display: none; }
.compare-variation__limitation{
  margin-top: 2px;
  font-size: 9.5px;
  font-weight: var(--fw-regular, 400);
  color: var(--color-text-muted);
}

/* =========================================================
   13) CARTÃO FLUTUANTE "NDVI — RESUMO" (Missão 04 / Etapa 11.2.B1.1,
   Fase 4.1) — visualização INDIVIDUAL (nunca durante a comparação,
   que tem suas próprias etiquetas acima). Filho direto do container
   do mapa, no canto inferior-esquerdo — o mesmo canto que o painel
   Sentinel-2 ocupava antes de ser realocado para a sidebar (Etapa 9),
   hoje livre.
   ========================================================= */
.ndvi-quickinfo{
  position: absolute;
  left: var(--space-3);
  bottom: var(--space-3);
  z-index: 620; /* acima das panes (até 400), abaixo do divisor/controles do comparador (640/650) — nunca aparecem ao mesmo tempo */
  width: 240px;
  background: rgba(255,255,255,0.96);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3);
  font-size: var(--fs-xs);
  color: var(--color-text);
}
.ndvi-quickinfo[hidden]{ display: none; }
.ndvi-quickinfo__date{
  font-size: var(--fs-sm);
  font-weight: var(--fw-black);
  margin-bottom: 4px;
}
.ndvi-quickinfo__stats{ line-height: 1.6; margin-bottom: 6px; }
.ndvi-quickinfo__legend{ margin-bottom: 6px; }
.ndvi-quickinfo__nodata{
  font-size: 10.5px;
  color: var(--color-text-muted);
  line-height: 1.4;
  margin-bottom: 8px;
}
.ndvi-quickinfo__btn{
  width: 100%;
  border: 1px solid var(--color-primary);
  background: var(--color-primary-soft);
  color: var(--color-primary-strong);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  border-radius: var(--radius-md);
  padding: 6px 8px;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}
.ndvi-quickinfo__btn:hover{ background: var(--color-primary-soft); filter: brightness(0.97); }
.ndvi-quickinfo__btn:focus-visible{ outline: 2px solid var(--color-primary-strong); outline-offset: 2px; }

/* bloco de configuração dentro do painel Sentinel-2 (sidebar) —
   reaproveita .pill-group/.pill-btn/.form-select já existentes */
.compare-config{
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed rgba(15,23,42,0.14);
}
.compare-field-label{
  display: block;
  font-size: 10.5px;
  font-weight: 800;
  color: #64748b;
  margin-bottom: 3px;
}
#rgbBtnCompareToggle.active{
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
  color: var(--color-primary-strong);
}

/* =========================================================
   11) RESPONSIVO (seção 9)
   ========================================================= */
@media (max-width: 992px) {
  .sidebar{ width: 268px; }
  .map-wrapper{ padding: var(--space-2); }
  #map{ border-radius: var(--radius-md); }
  .kpi-grid{ grid-template-columns: 1fr; }
  .kv{ grid-template-columns: 120px 1fr; }
  .cmp-map{ height: 320px; }
  .chart-wrap{ height: 200px; }
  .compare-labels{ padding: 0 var(--space-2); }
  .compare-label{ font-size: 9.5px; padding: 4px 8px; }
  .compare-variation{ font-size: 9.5px; padding: 4px 8px; max-width: 160px; }
  .ndvi-quickinfo{ width: 200px; }
}
