/* ============================================================================
   Portal VP-Corporate · camada de responsividade, tipografia e navegação
   Versão 2.30.0 · 2 de Setembro de 2026

   ADITIVA de propósito: carrega DEPOIS de styles.css e só sobrepõe o que precisa.
   A identidade visual do capítulo 6 — cores, logótipo, estrutura — fica intacta
   em styles.css. Remover este ficheiro do index.html devolve o portal ao estado
   anterior sem mais nenhuma alteração.

   Tipografia: pilha de sistema. Em Mac, iPhone e iPad resolve para San Francisco,
   que é a letra do apple.com; em Windows para Segoe UI e em Android para Roboto.
   Não se carrega tipo de letra externo de propósito — evita dependência de CDN,
   respeita a política de conteúdos da aplicação e não atrasa o primeiro desenho.
   ========================================================================== */

:root {
  --ui-font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
             "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ui-ease: cubic-bezier(.32, .72, 0, 1);      /* curva de animação da Apple */
  --ui-fast: .18s;
  --ui-slow: .38s;
  --ui-radius: 12px;
  --ui-sidebar: 236px;
  --ui-topbar: 52px;
  --ui-shadow-1: 0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --ui-shadow-2: 0 4px 12px rgba(16,24,40,.08), 0 2px 4px rgba(16,24,40,.04);
  --ui-shadow-3: 0 24px 48px -12px rgba(16,24,40,.18);
}

/* ---------------------------------------------------------------- tipografia */
body, button, input, select, textarea, .btn {
  font-family: var(--ui-font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body { font-size: clamp(14px, 0.9rem + .1vw, 15px); line-height: 1.47; letter-spacing: -.006em; }

h1, h2, h3, h4 { font-weight: 600; letter-spacing: -.022em; line-height: 1.16; }
h1 { font-size: clamp(24px, 1.4rem + 1vw, 34px); letter-spacing: -.028em; }
h2 { font-size: clamp(19px, 1.15rem + .5vw, 25px); }
h3 { font-size: clamp(16px, 1rem + .25vw, 19px); }

/* Números grandes: tabulares, para as colunas alinharem e não dançarem */
.kpi-value, .d2-k .v, table.grid td, .table td, .num, .mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.kpi-value, .d2-k .v { letter-spacing: -.03em; font-weight: 600; }
.kpi-label { letter-spacing: .01em; }

/* ------------------------------------------------------------ barra de topo */
header.topbar {
  height: var(--ui-topbar);
  padding-left: max(18px, env(safe-area-inset-left));
  padding-right: max(18px, env(safe-area-inset-right));
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  background: color-mix(in srgb, var(--ac-navy) 94%, transparent);
  transition: box-shadow var(--ui-fast) var(--ui-ease);
}
body.ui-scrolled header.topbar { box-shadow: 0 6px 20px rgba(0,0,0,.22); }
@supports not (backdrop-filter: blur(1px)) {
  header.topbar { background: var(--ac-navy); }
}

/* --------------------------------------------------------------- navegação
   A barra lateral é navy por decisão de identidade (styles.css, v1.0.4), com a
   barra cyan à esquerda no item activo. Não se toca nisso: aqui só se acrescenta
   o que falta — conforto de toque, transições e as famílias colapsáveis. Os
   selectores repetem «nav.sidebar» porque é essa a especificidade do original;
   sem isso as regras não pegam.                                              */
nav.sidebar {
  scrollbar-width: thin;
  padding-bottom: max(12px, env(safe-area-inset-bottom));
}
nav.sidebar .nav-item {
  transition: background var(--ui-fast) var(--ui-ease),
              border-left-color var(--ui-fast) var(--ui-ease),
              color var(--ui-fast) var(--ui-ease);
}
nav.sidebar .nav-item:active { background: rgba(255,255,255,.12); }

/* Famílias colapsáveis — o comportamento vive em ui.js */
nav.sidebar .nav-fam { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 6px; }
nav.sidebar .nav-fam::after {
  content: "\203A"; margin-left: auto; font-size: 15px; line-height: 1;
  transform: rotate(90deg); transition: transform var(--ui-fast) var(--ui-ease); opacity: .8;
}
nav.sidebar .nav-fam.collapsed::after { transform: rotate(0deg); }
nav.sidebar .nav-item.ui-hidden { display: none; }

/* --------------------------------------------------- gaveta em ecrã pequeno */
@media (max-width: 860px) {
  nav.sidebar {
    width: min(84vw, 300px);
    left: calc(-1 * min(84vw, 300px));
    top: var(--ui-topbar);
    padding-top: 6px;
    transition: left var(--ui-slow) var(--ui-ease), box-shadow var(--ui-slow) var(--ui-ease);
    box-shadow: none;
  }
  nav.sidebar.open { left: 0; box-shadow: var(--ui-shadow-3); }
  nav.sidebar .nav-item { padding: 13px 16px; font-size: 15px; }  /* alvo de toque ≥ 44px */
  nav.sidebar .nav-fam { padding: 14px 18px 8px; }
  main.content { padding: 14px 16px 90px; }
  header.topbar { gap: 10px; }
  .brand-product { font-size: 14px; }
  .brand-version { display: none; }
}
/* Fundo escurecido por trás da gaveta */
#ui-backdrop {
  position: fixed; inset: var(--ui-topbar) 0 0 0; z-index: 35;
  background: rgba(10,14,30,.42);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--ui-slow) var(--ui-ease);
}
body.ui-drawer #ui-backdrop { opacity: 1; pointer-events: auto; }
body.ui-drawer { overflow: hidden; }
#menu-toggle {
  border-radius: 9px; min-width: 40px; min-height: 34px; font-size: 16px; line-height: 1;
  transition: background var(--ui-fast) var(--ui-ease), transform var(--ui-fast) var(--ui-ease);
}
#menu-toggle:hover { background: rgba(255,255,255,.14); }
#menu-toggle:active { transform: scale(.94); }

/* --------------------------------------------------------- cartões e grelhas */
.card { border-radius: var(--ui-radius); box-shadow: var(--ui-shadow-1);
  transition: box-shadow var(--ui-fast) var(--ui-ease), transform var(--ui-fast) var(--ui-ease); }
.card:hover { box-shadow: var(--ui-shadow-2); }
/* NÃO mexer nas colunas de .kpi-grid nem de .chart-grid. O styles.css fixa
   340px de mínimo nos gráficos e 200px nos indicadores, e não é arbitrário: as
   caixas de gráfico têm altura fixa com o canvas em position:absolute, e apertar
   a coluna abaixo do que o Chart.js desenhou faz o canvas sair da caixa e
   sobrepor-se ao que está ao lado. As duas grelhas já são responsivas com
   auto-fit e auto-fill — não precisavam de ajuda nenhuma. */
@media (max-width: 640px) { .card { border-radius: 10px; } }

/* ------------------------------------------------------------------ tabelas */
.table-wrap { -webkit-overflow-scrolling: touch; border-radius: 10px; }
@media (max-width: 860px) {
  .table-wrap { max-height: none; }
  table.grid, .table { font-size: 13px; }
  table.grid th, table.grid td, .table th, .table td { white-space: nowrap; }
}
/* Sinal de que a tabela continua para o lado */
.table-wrap { background:
  linear-gradient(90deg, #fff 30%, rgba(255,255,255,0)) left / 28px 100% no-repeat,
  linear-gradient(90deg, rgba(255,255,255,0), #fff 70%) right / 28px 100% no-repeat,
  radial-gradient(farthest-side at 0 50%, rgba(16,24,40,.12), transparent) left / 12px 100% no-repeat,
  radial-gradient(farthest-side at 100% 50%, rgba(16,24,40,.12), transparent) right / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll; }

/* -------------------------------------------------------- botões e formulários */
button, .btn { border-radius: 9px; font-weight: 500; letter-spacing: -.01em;
  transition: filter var(--ui-fast) var(--ui-ease), transform var(--ui-fast) var(--ui-ease),
              box-shadow var(--ui-fast) var(--ui-ease); }
button:hover, .btn:hover { filter: brightness(1.06); }
button:active, .btn:active { transform: scale(.97); }
input, select, textarea { border-radius: 9px; font-size: 15px; }   /* 15px evita o zoom no iOS */
@media (min-width: 861px) { input, select, textarea { font-size: 13.5px; } }

/* ---------------------------------------------------------------- acessível */
:focus-visible { outline: 2px solid var(--ac-cyan); outline-offset: 2px; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ------------------------------------- ausência de dados, em vez de inventar */
.sem-dados {
  display: inline-block; font-size: 12.5px; font-weight: 500; letter-spacing: -.01em;
  color: #6b7280; background: #f3f4f6; border: 1px solid #e5e7eb;
  border-radius: 999px; padding: 3px 10px; white-space: nowrap;
}
.fonte-referencia {
  display: inline-block; margin-left: 6px; font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
  color: var(--st-yellow-tx); background: #fff8e1; border: 1px solid #ffe6a0;
  border-radius: 4px; padding: 1px 5px; vertical-align: middle;
}

/* ------------------------------------------------------------ ecrãs grandes */
@media (min-width: 1600px) { main.content { padding-left: 40px; padding-right: 40px; } }
@media print {
  header.topbar, nav.sidebar, .footer, #ui-backdrop, #menu-toggle { display: none !important; }
  main.content { padding: 0; overflow: visible; height: auto; }
  .card { box-shadow: none; border: 1px solid #ddd; break-inside: avoid; }
}

/* ------------------------------------------------- cascata da receita
   Uma peça só: quatro parcelas encadeadas na escala do target, seguidas das
   métricas de leitura e do detalhe fechado por omissão. Cada parcela arranca
   onde a anterior acabou, pelo que a barra vazia à direita da última é
   exactamente o que falta originar.

   Sem SVG com texto: o bloco tem de encolher para 320px de largura sem que a
   tipografia encolha com ele, e texto dentro de um viewBox escalado faz
   precisamente isso. Barras em CSS, números em HTML. */
/* --- a cascata em colunas ---
   Uma coluna por parcela, a arrancar onde a anterior acabou. O traço no topo
   de cada coluna prolonga-se pelo intervalo até à seguinte — é o mesmo nível,
   e é isso que faz a peça ler-se como cascata. */
.cv-wrap { margin-top: 12px; --cv-gap: 10px; }
.cv-row { display: flex; align-items: stretch; gap: var(--cv-gap); }
.cv-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
.cv-plot { position: relative; height: var(--cv-alt, 168px); width: 84%; margin: 0 auto; }
.cv-seg { position: absolute; left: 0; right: 0; border-radius: 3px;
  transform-origin: bottom center; }
/* o prolongamento até à coluna seguinte */
.cv-col:not(:last-child) .cv-seg::after { content: ""; position: absolute;
  left: 100%; top: 0; width: calc(19% + var(--cv-gap)); border-top: 1px dashed #B7C0D4; }
.cv-seg.marcada { box-shadow: inset 0 0 0 2px #E89C3C; }
.cv-seg.alvo { background: transparent; border: 1.5px dashed #B7C0D4; }
.cv-col.alvo .cv-seg::after { display: none; }
.cv-val { position: absolute; left: 0; right: 0; margin-bottom: 4px; text-align: center;
  font-size: 12.5px; font-weight: 800; color: #001D6C; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.cv-rot { flex: 0 0 auto; padding-top: 7px; text-align: center; font-size: 10.5px;
  font-weight: 700; color: #001D6C; line-height: 1.25; }
.cv-rot small { display: block; font-weight: 500; font-size: 9.5px; color: #8C96AB;
  margin-top: 1px; }
.casc-leitura { font-size: 11.5px; color: #5B6478; margin: 9px 0 0; }

.cv-seg { transition: transform .6s var(--ui-ease, cubic-bezier(.32,.72,0,1))
  calc(var(--i, 0) * 70ms); }
.cv-val { transition: opacity .4s ease calc(var(--i, 0) * 70ms + .2s); }
.g-pre .cv-seg { transform: scaleY(0); }
.g-pre .cv-val { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .cv-seg, .cv-val { transition: none; } }
@media (max-width: 460px) {
  .cv-wrap { --cv-gap: 6px; }
  .cv-val { font-size: 9px; }
  .cv-rot { font-size: 9px; }
  .cv-rot small { font-size: 8px; }
}

.casc-aviso { background: #FFF9F0; border-left: 3px solid #E89C3C;
  border-radius: 0 8px 8px 0; padding: 8px 12px 9px; margin: 10px 0 0; }
.ca-l { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 11px; color: #8A5A12; }
.ca-l b { font-weight: 800; color: #6E4610; font-variant-numeric: tabular-nums;
  margin-left: 4px; }
.ca-l .falta b { color: #C2762A; }
.casc-aviso p { margin: 4px 0 0; font-size: 10.5px; line-height: 1.45; color: #A07840; }

.casc-metricas { display: grid; margin-top: 12px; gap: 9px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 128px), 1fr)); }
.casc-m { border: 1px solid #E3E8F2; border-radius: 10px; padding: 9px 11px; }
.casc-m.anelm { display: flex; align-items: center; gap: 11px; }
.casc-anel { flex: none; }
.casc-ml { font-size: 9.5px; font-weight: 800; letter-spacing: .5px; color: #5B6478; }
.casc-mv { font-size: 20px; font-weight: 800; color: #001D6C;
  font-variant-numeric: tabular-nums; }
.casc-mn { font-size: 10.5px; color: #7A8396; }

.casc-det { margin-top: 11px; border-top: 1px solid #EDF0F6; padding-top: 9px; }
.casc-det > summary { cursor: pointer; font-size: 12.5px; font-weight: 700; color: #00B5CC;
  list-style: none; -webkit-tap-highlight-color: transparent;
  min-height: 30px; display: flex; align-items: center; }
.casc-det > summary::-webkit-details-marker { display: none; }
.casc-det > summary::before { content: "\25B8"; margin-right: 6px; }
.casc-det[open] > summary::before { content: "\25BE"; }
.casc-pills { display: grid; gap: 8px; margin-top: 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 162px), 1fr)); }
.casc-pill { border: 1px solid #E3E8F2; border-radius: 10px; padding: 9px 11px;
  background: #fff; }
.casc-pill.clic { cursor: pointer; }
.casc-pill.clic:hover { border-color: #00B5CC; }
.casc-pl { font-size: 9.5px; font-weight: 800; letter-spacing: .4px; color: #5B6478; }
.casc-pv { font-size: 16px; font-weight: 700; color: #001D6C;
  font-variant-numeric: tabular-nums; }
.casc-pn { font-size: 10px; color: #7A8396; margin-top: 1px; }

@media (max-width: 520px) {
  .casc-rh { grid-template-columns: 1fr; row-gap: 1px; }
  .casc-rv { font-size: 18px; }
}

/* ============================ gramática de gráficos ====================
   Os tipos do relatório do T-Muxima, nas cores da casa. Regra que atravessa
   tudo o que está abaixo: nenhuma medida de texto depende da largura do
   cartão. Barras e colunas escalam; os números não. */

.g-vazio { font-size: 11.5px; color: #7A8396; margin: 8px 0 0; }
.g-rank, .g-pares { margin-top: 8px; }

.g-linha, .g-par { display: grid; align-items: center; column-gap: 10px;
  padding: 4px 0; grid-template-columns: minmax(60px, 27%) 1fr; }
.g-par { grid-template-columns: minmax(60px, 24%) 1fr auto; }
.g-linha.clic { cursor: pointer; border-radius: 6px; }
.g-linha.clic:hover { background: #F6F9FC; }
.g-linha.clic:hover .g-fill { filter: brightness(1.12); }

.g-rot { font-size: 11.5px; font-weight: 700; color: #101828; text-align: right;
  line-height: 1.25; overflow-wrap: anywhere; }
.g-track { display: flex; align-items: center; gap: 7px; min-width: 0; }
/* A barra escala sobre a largura da pista menos o espaço reservado ao
   rótulo, para a mais comprida acabar dentro do cartão e não por baixo do
   número. --g-res vem do bloco, calculado sobre o rótulo mais longo. */
.g-fill { height: 17px; border-radius: 3px; flex: none; min-width: 2px;
  width: calc((100% - var(--g-res, 90px)) * var(--pc, 0) / 100); }
.g-val { font-size: 10.5px; font-weight: 700; color: #101828; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.g-val small { font-weight: 500; color: #7A8396; }

.g-duplo { display: grid; row-gap: 3px; position: relative; min-width: 0; }
.g-duplo .g-fill { height: 13px; }
/* A referência de pró-rata: onde a barra devia estar a esta altura do ano. */
.g-duplo::before { content: ""; position: absolute; top: -2px; bottom: -2px;
  left: calc((100% - var(--g-res, 90px)) * var(--g-marca, -999) / 100);
  border-left: 1.5px dashed #C0392B; }
.g-delta { font-size: 11px; font-weight: 800; color: #2E7D46; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.g-delta.neg { color: #C0392B; }

.g-leg { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px;
  font-size: 11px; color: #5B6478; }
.g-leg i { display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: 5px; vertical-align: -1px; }

/* --- área e colunas partilham o mesmo plano de fundo --- */
.g-cols, .g-area { margin-top: 10px; }
.g-plot { position: relative; height: var(--g-alt, 168px); --g-gut: 34px; }
.g-plot > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.g-grade { position: absolute; left: 0; right: 0; border-top: 1px solid #EDF1F8; }
.g-grade > span { position: absolute; left: 0; top: 2px; font-size: 9.5px;
  color: #8C96AB; line-height: 1; }
.g-ref { position: absolute; left: 0; right: 0; border-top: 2px dashed #B7791F; }
.g-ref > span { position: absolute; right: 0; bottom: 3px; font-size: 10px;
  font-weight: 700; color: #B7791F; background: #fff; padding: 0 3px; }

.g-colrow { position: absolute; inset: 0 0 0 var(--g-gut, 34px); display: flex;
  align-items: flex-end; gap: 3px; }
.g-mm { position: absolute; inset: 0 0 0 var(--g-gut, 34px); width: auto;
  height: 100%; pointer-events: none; }
.g-col { flex: 1 1 0; min-width: 0; height: 100%; position: relative;
  display: flex; align-items: flex-end; }
.g-col-f { width: 88%; max-width: 40px; margin: 0 auto; border-radius: 3px 3px 0 0; }
.g-col-f.prev { background: transparent; border: 1.5px dashed #C7D0E4;
  border-bottom: 0; border-radius: 3px 3px 0 0; box-sizing: border-box; }
/* O número acompanha o topo da sua coluna — a altura vem no atributo, porque
   é a coluna que a conhece. Ancorado ao topo da caixa dava sempre o mesmo
   sítio, longe da barra baixa e por cima da alta. */
.g-col-v { position: absolute; left: 50%; transform: translateX(-50%);
  margin-bottom: 3px; font-size: 9.5px; font-weight: 800; color: #101828;
  white-space: nowrap; }
.g-colrot { display: flex; gap: 3px; margin-top: 5px; padding-left: var(--g-gut, 34px); }
.g-colrot > span { flex: 1 1 0; min-width: 0; font-size: 9px; color: #8C96AB;
  text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.g-eixo { position: relative; height: 14px; margin-top: 2px; }
.g-eixo > span { position: absolute; transform: translateX(-50%); font-size: 9.5px;
  color: #8C96AB; white-space: nowrap; }
.g-pin { position: absolute; transform: translate(-50%, 0); margin-bottom: 7px; }
.g-pin > span { font-size: 10px; font-weight: 800; color: #101828; white-space: nowrap; }

/* --- a entrada -------------------------------------------------------
   Uma vez, escalonada, e nula para quem pediu ao sistema menos movimento. */
.g-fill, .g-col-f { transform-origin: left center;
  transition: transform .65s var(--ui-ease, cubic-bezier(.32,.72,0,1))
    calc(var(--i, 0) * 45ms); }
.g-col-f { transform-origin: bottom center; }
.g-pre .g-fill { transform: scaleX(0); }
.g-pre .g-col-f { transform: scaleY(0); }
.g-val, .g-col-v, .g-pin { transition: opacity .4s ease calc(var(--i, 0) * 45ms + .22s); }
.g-pre .g-val, .g-pre .g-col-v, .g-pre .g-pin { opacity: 0; }
.g-traco { transition: stroke-dashoffset 1.05s var(--ui-ease, cubic-bezier(.32,.72,0,1)); }

@media (prefers-reduced-motion: reduce) {
  .g-fill, .g-col-f, .g-val, .g-col-v, .g-pin, .g-traco { transition: none; }
}
@media (max-width: 480px) {
  .g-linha { grid-template-columns: 1fr; row-gap: 1px; }
  .g-par { grid-template-columns: 1fr auto; }
  .g-rot { text-align: left; }
  .g-par .g-rot { grid-column: 1 / -1; }
  .g-col-r { font-size: 8px; }
}

/* --- cartões de indicador -------------------------------------------- */
#vp-numeros, #vp-sd-kpi { display: grid; gap: 9px; margin-top: 9px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 146px), 1fr)); }
.g-kpi { border: 1px solid #E3E8F2; border-radius: 10px; padding: 9px 11px 10px;
  background: #fff; }
.g-kpi-l { font-size: 9.5px; font-weight: 800; letter-spacing: .7px; color: #5B6478;
  text-transform: uppercase; display: flex; align-items: center; }
.g-kpi-l i { width: 7px; height: 7px; border-radius: 2px; margin-right: 6px;
  flex: none; }
.g-kpi-v { font-size: 21px; font-weight: 800; color: #001D6C; letter-spacing: -.5px;
  margin: 2px 0 0; font-variant-numeric: tabular-nums; line-height: 1.15; }
.g-kpi-s { font-size: 10.5px; color: #7A8396; }

/* --------------------------------------- a fila dos dois gráficos verticais
   A cascata e a receita mensal partilham a fila enquanto houver largura para
   as duas. Cada uma com metade do cartão, as colunas ficam juntas em vez de
   espalhadas — que era o que fazia a fila anterior gastar dois ecrãs para
   mostrar duas séries curtas. Abaixo de 900px empilham. */
.deck-graf { display: grid; gap: 14px; margin-bottom: 14px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }

/* ------------------------------- target dentro do cartão de indicador
   As duas linhas do painel de referência: contra o quê se mede, e quanto já
   lá vai. Só aparecem onde existe target carregado. */
.g-kpi-alvo { margin-top: 8px; padding-top: 7px; border-top: 1px solid #EDF0F6; }
.g-kpi-r { display: flex; justify-content: space-between; align-items: baseline;
  font-size: 10.5px; color: #5B6478; line-height: 1.7; }
.g-kpi-r b { font-weight: 800; color: #101828; font-variant-numeric: tabular-nums; }
.g-kpi-r b.ok { color: #2E7D46; }
.g-kpi-r b.off { color: #C2762A; }

/* --- colunas emparelhadas e pontos das linhas --- */
.g-col.g-duo { display: flex; align-items: flex-end; gap: 2px; }
.g-col.g-duo .g-col-f { width: 46%; max-width: 20px; margin: 0; }
.g-comb .g-plot { --g-gut: 34px; padding-right: 38px; }
.g-comb .g-colrow, .g-comb .g-mm, .g-comb .g-dots { right: 38px; }
.g-comb .g-colrot { padding-right: 38px; }
.g-grade > b { position: absolute; right: 0; top: 2px; font-size: 9.5px;
  font-weight: 600; color: #8C96AB; line-height: 1; }
.g-dots { position: absolute; inset: 0 0 0 var(--g-gut, 34px); pointer-events: none; }
.g-dots.g-dots-l { left: 0; }
.g-dot { position: absolute; width: 7px; height: 7px; border-radius: 50%;
  transform: translate(-50%, 50%); box-shadow: 0 0 0 2px #fff;
  pointer-events: auto; }
.g-pre .g-dot { opacity: 0; }
.g-dot { transition: opacity .35s ease calc(var(--i, 0) * 40ms + .35s); }

/* --- equipas, uma a uma --- */
.g-eqs { display: grid; gap: 10px; margin-top: 9px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 208px), 1fr)); }
.g-eq { border: 1px solid #E3E8F2; border-radius: 11px; padding: 12px 13px;
  background: #fff; }
.g-eq-h { display: flex; align-items: center; font-size: 10px; font-weight: 800;
  letter-spacing: .6px; text-transform: uppercase; color: #5B6478; }
.g-eq-h i { width: 8px; height: 8px; border-radius: 2px; margin-right: 6px; flex: none; }
.g-eq-v { font-size: 26px; font-weight: 800; color: #001D6C; letter-spacing: -.5px;
  margin: 4px 0 8px; font-variant-numeric: tabular-nums; }
.g-eq-v small { display: block; font-size: 10px; font-weight: 500; color: #8C96AB;
  letter-spacing: 0; margin-top: -2px; }
.g-eq-r { display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11px; color: #5B6478; line-height: 1.85;
  border-top: 1px solid #F2F5FA; }
.g-eq-r:first-of-type { border-top: 0; }
.g-eq-r b { font-weight: 700; color: #101828; font-variant-numeric: tabular-nums; }
.g-eq-r b.ok { color: #2E7D46; }
.g-eq-r b.off { color: #C0392B; }
.g-eq { transition: opacity .4s ease calc(var(--i, 0) * 55ms),
  transform .5s var(--ui-ease, cubic-bezier(.32,.72,0,1)) calc(var(--i, 0) * 55ms); }
.g-pre .g-eq { opacity: 0; transform: translateY(6px); }
@media (prefers-reduced-motion: reduce) { .g-eq, .g-dot { transition: none; } }

/* ------------------------------------------- as camadas do Dashboard
   Um dashboard de gestão não é uma colecção de gráficos: é uma sequência de
   perguntas. Cada cabeçalho abre a camada que responde a uma delas. */
.sec-t { display: grid; grid-template-columns: auto 1fr; gap: 12px;
  align-items: start; margin: 26px 0 12px; }
.sec-t:first-child { margin-top: 4px; }
.sec-n { font-size: 11.5px; font-weight: 800; color: #fff; background: #001D6C;
  border-radius: 8px; width: 27px; height: 27px; display: flex; flex: none;
  align-items: center; justify-content: center; }
.sec-t h3 { font-size: 17px; color: #001D6C; margin: 1px 0 2px; font-weight: 800;
  letter-spacing: -.2px; }
.sec-t p { margin: 0; color: #5B6478; font-size: 12.5px; line-height: 1.55;
  max-width: 78ch; }
@media (max-width: 520px) { .sec-t h3 { font-size: 15.5px; } }

/* --------------------------------------------------- abas do Dashboard
   Uma página que se estende sem fim obriga a percorrer tudo para chegar ao
   que interessa. Três abas: o resumo executivo abre por omissão, o negócio
   e a entrega ficam a um clique. Nada é redesenhado ao trocar — tudo já foi
   montado na primeira carga. */
.dash-tabs { display: flex; gap: 4px; margin: 2px 0 16px; padding: 4px;
  background: #EDF1F8; border-radius: 11px; overflow-x: auto;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.dash-tabs::-webkit-scrollbar { display: none; }
.dash-tab { flex: 1 1 auto; min-height: 38px; padding: 0 18px; border: 0;
  border-radius: 8px; background: transparent; color: #5B6478; cursor: pointer;
  font: inherit; font-size: 13.5px; font-weight: 700; white-space: nowrap;
  transition: background .18s ease, color .18s ease;
  -webkit-tap-highlight-color: transparent; }
.dash-tab:hover { color: #001D6C; }
.dash-tab.activo { background: #fff; color: #001D6C;
  box-shadow: 0 1px 2px rgba(16,24,40,.08), 0 1px 3px rgba(16,24,40,.06); }
.dash-tab:focus-visible { outline: 2px solid #00B5CC; outline-offset: 1px; }
.aba > .sec-t:first-child { margin-top: 2px; }
@media (max-width: 480px) { .dash-tab { padding: 0 13px; font-size: 12.5px; } }

/* --------------------------------- o número com direcção e com referência
   Duas linhas de texto obrigavam a ler dois números e a dividi-los de
   cabeça. A barra diz o mesmo de relance; o risco marca onde ela devia
   estar a esta altura do ano. E a linha fina sob o número dá-lhe direcção,
   que é o que um número sozinho nunca tem. */
.g-kpi-spark { height: 16px; margin: 5px 0 0; opacity: .85; }
.g-kpi-spark svg { display: block; width: 100%; height: 100%; }
.g-kpi-bar { position: relative; height: 7px; border-radius: 4px; background: #EEF1F7;
  overflow: hidden; margin-bottom: 6px; }
.g-kpi-bar i { display: block; height: 100%; border-radius: 4px;
  transform-origin: left center;
  transition: transform .7s var(--ui-ease, cubic-bezier(.32,.72,0,1)) .25s; }
.g-kpi-bar u { position: absolute; top: -2px; bottom: -2px; width: 0;
  border-left: 1.5px dashed #5B6478; }
.g-pre .g-kpi-bar i { transform: scaleX(0); }
.g-kpi-alvo { margin-top: 7px; padding-top: 6px; border-top: 1px solid #EDF0F6; }

/* --- equipas: a proporção antes dos números --- */
.g-eq-bar { display: flex; height: 9px; border-radius: 4px; overflow: hidden;
  background: #EEF1F7; margin: 2px 0 7px; }
.g-eq-bar i { display: block; height: 100%; }
.g-eq-leg { display: flex; flex-wrap: wrap; gap: 3px 11px; font-size: 10.5px;
  color: #5B6478; margin-bottom: 9px; }
.g-eq-leg i { display: inline-block; width: 7px; height: 7px; border-radius: 2px;
  margin-right: 4px; vertical-align: -1px; }
.g-eq-v small { font-size: 9.5px; }
@media (prefers-reduced-motion: reduce) { .g-kpi-bar i { transition: none; } }

/* ----------------------------------------------- o que exige acção
   Uma lista por ordem de escrita punha um risco de $2k por cima de um de
   $200k. Cada acção traz o que está em jogo, anualizado, e a barra diz o
   peso de relance. A ordem é gravidade primeiro, dinheiro depois. */
.vpa-tot { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  padding: 0 0 11px; margin-bottom: 4px; border-bottom: 1px solid #EDF0F6; }
.vpa-tot b { font-size: 25px; font-weight: 800; color: #001D6C; letter-spacing: -.5px;
  font-variant-numeric: tabular-nums; }
.vpa-tot span { font-size: 11.5px; color: #7A8396; }
/* display explícito: o styles.css define .vpa como flex, e a marcação nova
   é de blocos. */
.vpa { display: block; padding: 8px 0 7px; border: 0; border-top: 1px solid #F2F5FA;
  border-radius: 0; background: none; }
.vpa:first-of-type { border-top: 0; padding-top: 4px; }
.vpa.clic { cursor: pointer; }
.vpa.clic:hover .vpa-t { color: #001D6C; }
.vpa.clic:hover .vpa-b i { filter: brightness(1.12); }
.vpa-h { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: baseline; }
.vpa-t { font-size: 12.5px; font-weight: 700; color: #101828; min-width: 0;
  display: block; margin: 0; line-height: 1.35; }
.vpa-t small { font-weight: 500; color: #8C96AB; font-size: 10.5px; margin-left: 6px;
  line-height: 1.35; }
.vpa-v { font-size: 12.5px; font-weight: 800; color: #001D6C; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.vpa-b { height: 5px; border-radius: 3px; background: #EEF1F7; overflow: hidden;
  margin: 5px 0 0; }
.vpa-b i { display: block; height: 100%; border-radius: 3px; transform-origin: left center;
  transition: transform .65s var(--ui-ease, cubic-bezier(.32,.72,0,1))
    calc(var(--i, 0) * 60ms); }
.g-pre .vpa-b i { transform: scaleX(0); }
.vpa-tot { padding-bottom: 9px; }
.vpa-tot b { font-size: 22px; }
.vpa-ok { font-size: 12.5px; color: #2E7D46; margin: 6px 0 0; }
.casc-metricas.topo { margin: 10px 0 4px; }
@media (prefers-reduced-motion: reduce) { .vpa-b i { transition: none; } }

/* ----------------------------- a fila da acção, em paralelo e alinhada
   Três cartões lado a lado só se lêem em paralelo se as linhas de cada um
   ficarem à altura das do vizinho. O cabeçalho de todos ocupa a mesma
   altura, mesmo quando um título parte em duas linhas, e o corpo arranca
   sempre no mesmo sítio. */
.deck-acao { display: grid; gap: 14px; margin-bottom: 14px; align-items: stretch;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }
.deck-acao > .card { display: flex; flex-direction: column; }
.deck-acao > .card > .eyebrow { display: block; min-height: 15px; }
.deck-acao > .card > .sub-muted { min-height: 32px; }
.deck-acao > .card > .sub-muted:empty { min-height: 32px; }

/* ================================================= o mosaico do Resumo
   Os gráficos à esquerda e uma coluna de indicadores navegáveis à direita,
   como nos painéis de referência. Abaixo de 1080px a coluna passa para
   baixo — nunca se espreme, porque espremida deixa de se ler. */
.mosaico { display: grid; gap: 14px; margin-bottom: 14px; align-items: start;
  grid-template-columns: minmax(0, 1fr) 296px; }
.mos-main { min-width: 0; }
.mos-rail { min-width: 0; }
@media (max-width: 1080px) { .mosaico { grid-template-columns: minmax(0, 1fr); } }
/* Os dois gráficos empilham-se sempre dentro da coluna esquerda. Lado a
   lado, o da receita mensal é bem mais baixo do que a cascata e deixava um
   rasgo branco no meio da página — que é o defeito que mais se nota num
   mosaico. Empilhados, cada um ocupa a largura toda e não sobra nada. */
.mosaico .deck-graf { grid-template-columns: minmax(0, 1fr); margin-bottom: 0;
  align-content: start; }
.mos-rail { position: sticky; top: 12px; }
@media (max-width: 1080px) { .mos-rail { position: static; } }

/* --- o funil: uma linha por estado, clicável --- */
/* O funil vive por baixo dos indicadores e na mesma grelha: é a decomposição
   deles, estado a estado, e não uma segunda contagem. Em coluna deixava a
   dúvida de serem números diferentes; alinhado, a relação é evidente. */
.fun-tit { margin: 15px 0 2px; padding-top: 13px; border-top: 1px solid #EDF0F6;
  font-size: 10px; font-weight: 800; letter-spacing: .8px; text-transform: uppercase;
  color: #5B6478; }
.fun-tit span { display: block; margin-top: 3px; font-size: 11px; font-weight: 500;
  letter-spacing: 0; text-transform: none; color: #8C96AB; }
.fun { display: grid; gap: 2px; margin-top: 8px; }
.fun-l { display: grid; grid-template-columns: auto 1fr auto; column-gap: 8px;
  align-items: center; width: 100%; text-align: left; background: none; border: 0;
  font: inherit; cursor: pointer; padding: 6px 8px 7px; border-radius: 9px;
  -webkit-tap-highlight-color: transparent;
  transition: background .16s ease, box-shadow .16s ease; }
.fun-l:hover { background: #F6F9FC; }
.fun-l.activo { background: #EEF6FB; box-shadow: inset 0 0 0 1px #7FCDE6; }
.fun-l:focus-visible { outline: 2px solid #00B5CC; outline-offset: -2px; }
.fun-p { width: 9px; height: 9px; border-radius: 3px; }
.fun-t { font-size: 12.5px; font-weight: 700; color: #101828; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fun-v { font-size: 12.5px; font-weight: 800; color: #001D6C; white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.fun-b { grid-column: 2 / -1; height: 5px; border-radius: 3px; background: #EEF1F7;
  overflow: hidden; margin-top: 4px; }
.fun-b i { display: block; height: 100%; border-radius: 3px; transform-origin: left center;
  transition: transform .6s var(--ui-ease, cubic-bezier(.32,.72,0,1))
    calc(var(--i, 0) * 55ms); }
.g-pre .fun-b i { transform: scaleX(0); }
.fun-q { grid-column: 2 / -1; font-size: 10px; color: #8C96AB; margin-top: 3px; }

/* --- o detalhe, ao lado dos gráficos e não noutro ecrã --- */
.inl-h { display: grid; grid-template-columns: 1fr auto; gap: 12px;
  align-items: start; padding-bottom: 8px; border-bottom: 1px solid #EDF0F6; }
.inl-a { display: flex; gap: 14px; align-items: baseline; white-space: nowrap; }
.inl-a a { font-size: 11.5px; font-weight: 700; color: #00B5CC; cursor: pointer;
  text-decoration: none; }
.inl-a a.fecha { color: #8C96AB; font-weight: 600; }
.inl-a a:hover { text-decoration: underline; }
@media (max-width: 520px) {
  .inl-h { grid-template-columns: 1fr; }
  .fun-t { font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) { .fun-b i { transition: none; } }

/* --- variação face ao mês anterior, no cartão de indicador --- */
.g-kpi-d { display: inline-flex; align-items: baseline; gap: 3px; margin-top: 5px;
  font-size: 10.5px; font-weight: 800; font-variant-numeric: tabular-nums;
  padding: 2px 7px; border-radius: 99px; }
.g-kpi-d i { font-style: normal; font-size: 8.5px; }
.g-kpi-d span { font-weight: 500; color: inherit; opacity: .72; }
.g-kpi-d.sobe { color: #1E6B38; background: #E9F6EE; }
.g-kpi-d.desce { color: #A5342A; background: #FCEDEB; }

/* --- taxas de conversão do funil --- */
.conv { display: grid; gap: 9px; margin-top: 9px; }
.conv-h { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: baseline; }
.conv-t { font-size: 12px; font-weight: 700; color: #101828; }
.conv-v { font-size: 12px; font-weight: 800; color: #001D6C;
  font-variant-numeric: tabular-nums; }
.conv-b { height: 7px; border-radius: 3px; background: #EEF1F7; overflow: hidden;
  margin-top: 5px; }
.conv-b i { display: block; height: 100%; border-radius: 3px; transform-origin: left center;
  transition: transform .6s var(--ui-ease, cubic-bezier(.32,.72,0,1))
    calc(var(--i, 0) * 70ms); }
.g-pre .conv-b i { transform: scaleX(0); }
.conv-r { font-size: 10.5px; color: #8C96AB; margin-top: 4px; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.conv-r.sobe { color: #C2762A; }
.conv-al { font-size: 11px; line-height: 1.5; color: #8A5A12; background: #FFF9F0;
  border-left: 3px solid #E89C3C; border-radius: 0 8px 8px 0; padding: 8px 11px;
  margin: 11px 0 0; }
.conv-nota { font-size: 10px; line-height: 1.45; color: #A0A8BA; margin: 9px 0 0; }
@media (prefers-reduced-motion: reduce) { .conv-b i { transition: none; } }

/* ------------------------------- a banda encostada, e o resumo à direita
   Os indicadores ocupavam a largura toda e sobrava-lhes espaço em branco à
   direita. Passam a três colunas encostadas à esquerda, e o que sobra leva
   resumos que dizem coisa nova — o risco em jogo e a relação entre fases —,
   nunca uma segunda contagem do que os cartões já dizem. */
/* O funil encosta ao canto superior direito e sobe até ao topo da página: o
   cabeçalho da camada fica dentro da coluna esquerda, não por cima das
   duas. É o canto onde os painéis de referência põem a barra de estados, e
   é o sítio para onde o olho vai a seguir aos números. */
.topo { display: grid; gap: 14px; margin-bottom: 14px; align-items: stretch;
  grid-template-columns: minmax(0, 1fr) 300px; }
/* As duas colunas crescem à mesma altura: o branco que sobra fica dentro do
   cartão mais curto, e não como um rasgo entre eles. */
.topo-esq { min-width: 0; display: flex; flex-direction: column; }
.topo-esq > .sec-t { margin-top: 2px; flex: 0 0 auto; }
.topo-esq > .card { flex: 1 1 auto; }
.topo-lado { min-width: 0; display: flex; flex-direction: column; }
.topo-lado > .card { flex: 1 1 auto; }
.topo #vp-numeros { align-content: start; }
@media (max-width: 1080px) { .topo { grid-template-columns: minmax(0, 1fr); } }
.topo #vp-numeros { grid-template-columns: repeat(auto-fit, minmax(min(100%, 158px), 1fr));
  gap: 8px; }

/* --- o caminho para o módulo, em cada cartão --- */
.g-kpi.clic { cursor: pointer; transition: border-color .16s ease, background .16s ease; }
.g-kpi.clic:hover { border-color: #BFE4F2; background: #FBFDFE; }
.g-kpi-l b { margin-left: auto; font-size: 14px; color: #B7C0D4; font-weight: 700;
  line-height: 1; }
.g-kpi.clic:hover .g-kpi-l b { color: #00B5CC; }
.card-ir { float: right; font-size: 10.5px; font-weight: 700; color: #00B5CC;
  cursor: pointer; text-decoration: none; letter-spacing: 0; text-transform: none;
  margin-left: 10px; }
.card-ir:hover { text-decoration: underline; }

/* --------------------------- estrutura da carteira e do ciclo de entrega
   Seis indicadores que não se lêem do total de receita. Enchem o espaço que
   sobrava à esquerda do funil: em vez de branco, informação que faltava. */
.crts { display: grid; gap: 9px; margin-top: 9px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); }
.crt { border: 1px solid #E3E8F2; border-radius: 10px; padding: 9px 11px 10px;
  background: #fff; }
.crt-l { font-size: 9px; font-weight: 800; letter-spacing: .6px; color: #5B6478;
  text-transform: uppercase; }
.crt-v { font-size: 19px; font-weight: 800; color: #001D6C; letter-spacing: -.4px;
  margin: 2px 0 1px; font-variant-numeric: tabular-nums; line-height: 1.15; }
.crt-n { font-size: 10px; color: #8C96AB; line-height: 1.4; }

/* --------------------------------- gráficos de módulo, na mesma gramática
   Cada módulo mostra até três distribuições e a evolução mensal. Eram
   canvas em caixas de altura fixa; passam a barras ordenadas e colunas, e
   cada barra filtra a lista que está por baixo. */
.mod-graf { display: grid; gap: 14px; margin: 8px 0 14px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); }

/* ============================================ dinâmica de interacção
   O portal respondia sem sinal: clicar num cartão, num botão ou num item de
   menu não devolvia nada até a página mudar. Estas regras dão resposta
   imediata ao toque — nada decorativo, só a confirmação de que o gesto foi
   registado. Tudo cai por terra para quem pediu menos movimento. */
:root { --ui-t: .16s; }

/* --- cartões: elevam-se ao passar, afundam ao carregar --- */
.card { transition: box-shadow var(--ui-t) ease, border-color var(--ui-t) ease,
  transform var(--ui-t) ease; }
.g-kpi.clic:active, .crt:active { transform: scale(.988); }
.g-kpi.clic, .fun-l, .vpa.clic, .g-linha.clic, .g-pill, .casc-pill.clic {
  transition: background var(--ui-t) ease, border-color var(--ui-t) ease,
    box-shadow var(--ui-t) ease, transform .1s ease; }
.fun-l:active, .vpa.clic:active, .g-linha.clic:active { transform: scale(.99); }

/* --- botões: resposta ao passar e ao carregar --- */
button, .btn, input[type="submit"] {
  transition: filter var(--ui-t) ease, box-shadow var(--ui-t) ease,
    transform .1s ease, background var(--ui-t) ease; }
button:not(:disabled):hover, .btn:not(:disabled):hover { filter: brightness(1.06); }
button:not(:disabled):active, .btn:not(:disabled):active { transform: scale(.975); }
button:disabled { opacity: .55; cursor: not-allowed; }
button:focus-visible, .btn:focus-visible, a:focus-visible,
.dash-tab:focus-visible, .fun-l:focus-visible {
  outline: 2px solid #00B5CC; outline-offset: 2px; border-radius: 6px; }

/* --- campos de pesquisa e filtros --- */
input, select, textarea { transition: border-color var(--ui-t) ease,
  box-shadow var(--ui-t) ease, background var(--ui-t) ease; }
input:hover:not(:focus), select:hover:not(:focus) { border-color: #CFDCEA; }
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: #00B5CC;
  box-shadow: 0 0 0 3px rgba(0,181,204,.16); }
/* Um campo de pesquisa com texto dentro tem de se distinguir de um vazio:
   é a diferença entre ver tudo e ver uma parte. */
input:not(:placeholder-shown) { border-color: #7FCDE6; background: #FBFEFF; }

/* --- menu: o item activo e o que se percorre --- */
nav.sidebar .nav-item { transition: background var(--ui-t) ease,
  color var(--ui-t) ease, padding-left var(--ui-t) ease; }
nav.sidebar .nav-item:hover:not(.active) { padding-left: 20px; }
nav.sidebar .nav-item:active { transform: none; }

/* --- as linhas da tabela respondem ao percorrer --- */
tbody tr { transition: background var(--ui-t) ease; }
tbody tr:hover { background: #F6F9FC; }

/* --- a entrada de cada vista, uma vez --- */
@keyframes vpEntra { from { opacity: 0; transform: translateY(5px); } }
main.content > * { animation: vpEntra .3s var(--ui-ease, cubic-bezier(.32,.72,0,1)) both; }

@media (prefers-reduced-motion: reduce) {
  .card, button, .btn, input, select, textarea, .g-kpi.clic, .fun-l,
  .vpa.clic, .g-linha.clic, nav.sidebar .nav-item, tbody tr { transition: none; }
  main.content > * { animation: none; }
  .g-kpi.clic:active, .crt:active, button:active, .btn:active,
  .fun-l:active, .vpa.clic:active, .g-linha.clic:active { transform: none; }
  nav.sidebar .nav-item:hover:not(.active) { padding-left: inherit; }
}
