/* ============================================================================
   border-ds-dataviz.css — DATA VIZ (cap.5) do DS da border ltd.
   Camada de visualização de dados: gráficos e indicadores.
   Depende de border-ds.css (paleta --viz-* já vive lá) + border-ds-base.css.
   Ordem: border-ds.css → border-ds-base.css → border-ds-components.css → border-ds-dataviz.css

   Os tokens de viz (--viz-categorical-*, --viz-sequential-*, --viz-positive/
   negative/neutral, --viz-grid, --viz-axis) estão em border-ds.css.
   As classes dos 15 charts (Area, Bar, Line, Donut, KPI card, Heatmap…) entram
   aqui conforme forem codadas. Charts são card + plot FILL + SVG com constraints.
   ============================================================================ */

/* Scaffold canônico de chart (codifica os padrões já provados no BOARD/financeiro:
   card .viz-card + legenda .chart-legend + barra .hbar). NÃO substitui os charts
   bespoke desses apps (SVG tunado + presos no CSS de impressão e JÁ consumindo --viz-*);
   serve charts NOVOS e os demos do site do DS. SVG real continua gerado em JS. */

/* ── Card do chart ─────────────────────────────────────────────────────────── */
.ds-chart {
  display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px);
  background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-border); border-radius: var(--radius-large, 8px);
  padding: var(--spacing-inset-sm, 24px);
}
.ds-chart__head { font-family: var(--font-family-overline); font-weight: var(--font-weight-bold);
  font-size: var(--font-size-xs); line-height: 1.3; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-text-helper); margin: 0; }
.ds-chart__note { margin: 0; font-family: var(--font-family-caption); font-weight: var(--font-weight-regular);
  font-size: var(--font-size-xs); line-height: 1.45; color: var(--color-text-helper); }
/* área do plot (SVG/canvas FILL, centralizado) */
.ds-chart__plot { flex: 1 1 auto; min-height: 0; align-content: center; }
.ds-chart__plot svg { display: block; max-width: 100%; height: auto; }

/* ── Legenda ───────────────────────────────────────────────────────────────── */
.ds-chart__legend { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.ds-chart__legend--col { flex-direction: column; gap: 10px; align-items: stretch; width: 100%; }
.ds-chart__legend-item { display: inline-flex; align-items: center; gap: 8px; min-width: 0;
  font-family: var(--font-family-sans); font-size: var(--font-size-sm); }
.ds-chart__legend--col .ds-chart__legend-item { display: flex; }
.ds-chart__legend-dot { width: 10px; height: 10px; border-radius: var(--radius-small, 2px); flex: 0 0 auto;
  background: var(--viz-categorical-1); }
.ds-chart__legend-label { color: var(--color-text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds-chart__legend--col .ds-chart__legend-label { flex: 1 1 auto; }
.ds-chart__legend-value { margin-left: auto; padding-left: 14px; flex: 0 0 auto;
  font-family: var(--font-family-mono); font-size: var(--font-size-xs); color: var(--color-text-sub); font-variant-numeric: tabular-nums; }

/* ── Barras horizontais (chart 100% CSS — sem SVG) ───────────────────────────
   row = [rótulo | trilho | valor]. fill aceita --viz-* via style/override. */
.ds-bar { display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px); }
.ds-bar__row { display: grid; grid-template-columns: 160px 1fr 64px; align-items: center; gap: var(--spacing-stack-xxxs, 16px); }
.ds-bar__label { font-family: var(--font-family-sans); font-size: var(--font-size-sm); color: var(--color-text-sub);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ds-bar__track { height: 16px; min-width: 0; background: var(--color-bg-muted); border-radius: var(--radius-small, 2px); overflow: hidden; }
.ds-bar__fill { display: block; height: 100%; border-radius: var(--radius-small, 2px); background: var(--viz-sequential-3); }
.ds-bar__value { font-family: var(--font-family-mono); font-size: var(--font-size-xs); text-align: right;
  color: var(--color-text); font-variant-numeric: tabular-nums; }

/* ── Eixos / grade (para SVG: usar como stroke via currentColor ou os tokens) ── */
.ds-chart__axis { stroke: var(--viz-axis); }
.ds-chart__grid { stroke: var(--viz-grid); }

/* Título de gráfico (cap.5 usa título Bold 16, ≠ do __head overline do scaffold) */
.ds-chart__title { margin: 0; font-family: var(--font-family-headings); font-weight: var(--font-weight-bold); font-size: var(--font-size-md); line-height: 1.25; color: var(--color-text); }

/* ===========================================================================
   CHARTS RENDERÁVEIS EM CSS (cap.5). Cada um é o PLOT — vive dentro de um card
   .ds-chart (título + plot). Os charts de série pura (Line/Area/Stacked area/
   Scatter/Radar/Sankey) NÃO ganham CSS próprio: usam o card .ds-chart + os tokens
   --viz-*/.ds-chart__axis/__grid, com o SVG gerado em JS. KPI card = .ds-stat.
   Valores (largura/altura/%, stops do conic) vêm por style inline / JS.
   =========================================================================== */

/* ── METER (1312:2) — barra de progresso rotulada ──────────────────────────── */
.ds-meter { display: flex; flex-direction: column; gap: var(--spacing-stack-nano, 8px); }
.ds-meter__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ds-meter__label { font-family: var(--font-family-sans); font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); color: var(--color-text-sub); }
.ds-meter__value { font-family: var(--font-family-sans); font-weight: var(--font-weight-bold); font-size: var(--font-size-md); color: var(--color-text); }
.ds-meter__track { height: 12px; border-radius: var(--radius-pill, 999px); background: var(--color-bg-muted); overflow: hidden; }
.ds-meter__fill { height: 100%; border-radius: var(--radius-pill, 999px); background: var(--viz-positive); }
.ds-meter--warning .ds-meter__fill { background: var(--viz-categorical-5); }
.ds-meter--danger  .ds-meter__fill { background: var(--viz-negative); }
.ds-meter__scale { display: flex; align-items: baseline; justify-content: space-between; font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }

/* ── BULLET (1336:2) — medida vs faixas qualitativas + alvo ────────────────── */
.ds-bullet { display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px); }
.ds-bullet__row { display: flex; flex-direction: column; gap: var(--spacing-stack-quarck, 4px); }
.ds-bullet__head { display: flex; align-items: baseline; justify-content: space-between; font-family: var(--font-family-sans); font-size: var(--font-size-xs); }
.ds-bullet__name { color: var(--color-text-sub); }
.ds-bullet__num { font-weight: var(--font-weight-bold); color: var(--color-text); }
.ds-bullet__track { position: relative; height: 18px; border-radius: var(--radius-small, 2px); background: var(--color-bg-muted); overflow: hidden; }
/* faixas qualitativas (claro→escuro), empilhadas da maior pra menor (largura inline) */
.ds-bullet__band { position: absolute; inset: 0 auto 0 0; height: 100%; }
.ds-bullet__band--1 { background: var(--color-bg-muted); }
.ds-bullet__band--2 { background: var(--color-border); }
.ds-bullet__band--3 { background: var(--color-border-strong); }
/* medida (barra fina central) + alvo (marcador vertical) — posição inline */
.ds-bullet__measure { position: absolute; top: 50%; left: 0; transform: translateY(-50%); height: 8px; border-radius: var(--radius-pill, 999px); background: var(--viz-positive); }
.ds-bullet__target { position: absolute; top: 0; width: 2px; height: 100%; background: var(--color-text); }

/* ── GAUGE (1315:2) — arco semicircular 100% CSS (conic + máscara radial) ─────
   --val = 0..100 (define o ângulo: 100 = 180°). Three-quarter = --sweep 270. */
.ds-gauge { display: flex; flex-direction: column; align-items: center; gap: var(--spacing-stack-quarck, 4px); }
.ds-gauge__dial {
  --val: 68; position: relative; width: 200px; height: 100px;
  background: conic-gradient(from -90deg at 50% 100%, var(--viz-positive) calc(var(--val) * 1.8deg), var(--color-bg-muted) 0deg);
  border-radius: 200px 200px 0 0;
  -webkit-mask: radial-gradient(circle at 50% 100%, transparent 0 56%, #000 56.5%);
          mask: radial-gradient(circle at 50% 100%, transparent 0 56%, #000 56.5%);
}
.ds-gauge__readout { display: flex; flex-direction: column; align-items: center; margin-top: -28px; }
.ds-gauge__value { font-family: var(--font-family-headings); font-weight: var(--font-weight-bold); font-size: var(--font-size-2xl); line-height: 1; color: var(--color-text); }
.ds-gauge__caption { font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }
.ds-gauge__ends { display: flex; justify-content: space-between; width: 200px; font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }

/* ── DONUT / PIE / PROGRESS (1279:19) — anel 100% CSS (conic + máscara) ──────
   Os stops do conic vêm por style inline (data-driven). Pie = sem máscara.    */
.ds-donut { display: flex; flex-direction: column; align-items: center; gap: var(--spacing-stack-xxxs, 16px); }
.ds-donut__ring {
  position: relative; width: 150px; height: 150px; border-radius: 50%;
  background: conic-gradient(var(--viz-categorical-1) 0 40%, var(--viz-categorical-2) 40% 75%, var(--viz-categorical-3) 75% 100%);
}
.ds-donut__ring::after {
  content: ''; position: absolute; inset: 22%; border-radius: 50%; background: var(--color-bg);
}
.ds-donut--pie .ds-donut__ring::after { display: none; }
/* Versão SVG (vizDonut): 1 <circle> por fatia → tooltip + realce no hover */
.ds-donut__svg-wrap { position: relative; width: var(--ds-donut-size, 150px); height: var(--ds-donut-size, 150px); }
.ds-donut__svg { display: block; width: 100%; height: 100%; }
.ds-donut__slice { transition: opacity .12s ease; }
.ds-donut__svg:has(.ds-donut__slice:hover) .ds-donut__slice { opacity: .45; }
.ds-donut__svg .ds-donut__slice:hover { opacity: 1; }
/* pointer-events:none — senão o centro (inset:0) tampa as fatias e mata o tooltip no hover */
.ds-donut__center { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; pointer-events: none; }
.ds-donut__total { font-family: var(--font-family-headings); font-weight: var(--font-weight-bold); font-size: var(--font-size-lg); line-height: 1; color: var(--color-text); }
.ds-donut__caption { font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }

/* ── DISTRIBUTION (1327:2) — histograma 100% CSS ─────────────────────────────
   Barras com altura por valor (inline). Boxplot é variante SVG (fica no chrome). */
.ds-distribution { display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px); }
.ds-distribution__plot { display: flex; align-items: flex-end; gap: 3px; height: 200px; }
.ds-distribution__bar { flex: 1 1 0; min-width: 0; background: var(--viz-positive); border-radius: 2px 2px 0 0; }
.ds-distribution__axis { display: flex; align-items: baseline; justify-content: space-between; font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }

/* ── HEATMAP (1324:2) — grade de células 100% CSS ────────────────────────────
   --cols define as colunas. Intensidade por classe --1..5 (sequencial) ou bg inline. */
.ds-heatmap { display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px); }
.ds-heatmap__grid { display: grid; grid-template-columns: repeat(var(--cols, 7), 1fr); gap: 5px; }
.ds-heatmap__cell { aspect-ratio: 1 / 1; border-radius: 3px; background: var(--viz-sequential-3); }
.ds-heatmap__cell--1 { background: var(--viz-sequential-1); }
.ds-heatmap__cell--2 { background: var(--viz-sequential-2); }
.ds-heatmap__cell--3 { background: var(--viz-sequential-3); }
.ds-heatmap__cell--4 { background: var(--viz-sequential-4); }
.ds-heatmap__cell--5 { background: var(--viz-sequential-5); }
.ds-heatmap__axis { display: grid; grid-template-columns: repeat(var(--cols, 7), 1fr); gap: 5px; text-align: center; font-family: var(--font-family-sans); font-size: var(--font-size-xs); color: var(--color-text-helper); }

/* ── TREEMAP (1330:2) — aproximação flex (tiles dimensionados por valor inline) ─
   Treemap real precisa de algoritmo (JS); aqui é scaffold flex. Mono = sequencial,
   Categorical = paleta categórica (cor por tile via classe/inline).            */
.ds-treemap { display: flex; flex-direction: column; gap: var(--spacing-stack-xxxs, 16px); }
.ds-treemap__plot { display: flex; flex-wrap: wrap; gap: 4px; height: 260px; align-content: stretch; }
.ds-treemap__tile { position: relative; display: flex; flex-direction: column; justify-content: flex-start; gap: 2px; padding: 10px; border-radius: 4px; overflow: hidden; background: var(--viz-sequential-3); color: var(--color-text-inverse); }
.ds-treemap__tile-label { font-family: var(--font-family-sans); font-size: var(--font-size-xs); line-height: 1.2; opacity: 0.9; }
.ds-treemap__tile-value { font-family: var(--font-family-sans); font-weight: var(--font-weight-bold); font-size: var(--font-size-xs); line-height: 1.2; }

/* ===========================================================================
   INTERATIVIDADE — crosshair + tooltip no hover.
   (Movido do bloco inline do SITES/DS/index.html p/ a folha canônica, pra que
   TODOS os sites — inclusive o financeiro — herdem o estilo do tooltip.)
   =========================================================================== */
.ds-chart__plot { position: relative; }
.vz-band { pointer-events: all; cursor: crosshair; }
.vz-cross { stroke: var(--color-text); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0; transition: opacity .1s ease; pointer-events: none; }
.vz-dot { cursor: pointer; transition: r .1s ease; }
.ds-heatmap__cell[data-viztip], .ds-treemap__tile[data-viztip] { cursor: pointer; }
.vz-tip { position: absolute; top: 6px; left: 0; transform: translateX(-50%); pointer-events: none; z-index: 6; background: var(--color-text); color: var(--color-bg); font-family: var(--font-family-sans); font-size: 11px; line-height: 1.45; padding: 6px 9px; border-radius: 4px; white-space: nowrap; box-shadow: var(--shadow-medium, 0 4px 12px rgba(0,0,0,.16)); }
.vz-tip__h { font-weight: 700; margin-bottom: 3px; }
.vz-tip__r { display: flex; align-items: center; gap: 7px; }
.vz-tip__dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.vz-tip__l { opacity: .85; }
.vz-tip__v { margin-left: auto; padding-left: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── Donut/anel: track de fundo (anel de progresso) ──────────────────────────── */
.ds-donut__track { stroke: var(--bg3, var(--color-border)); }

/* ── Barras (ramo de valor do vizBars: o.bars): linha do zero, rótulos e sub ──── */
.ds-bar-axis { stroke: var(--viz-axis); stroke-width: 1; }
.ds-bar-rect { transition: height .5s var(--ease, ease), y .5s var(--ease, ease); }
.ds-bar-val { font-family: var(--font-family-mono); font-weight: var(--font-weight-bold); font-size: var(--font-size-xs); fill: var(--color-text); }
.ds-bar-lbl { font-family: var(--font-family-sans); font-weight: var(--font-weight-medium); font-size: var(--font-size-xs); fill: var(--color-text-sub); }
.ds-bar-sub { font-family: var(--font-family-mono); font-size: 9.5px; fill: var(--color-text-helper); }

/* ===========================================================================
   ENTRANCE MOTION LAYER (cap.5) — animação de entrada dos charts com a sensação
   do Framer Motion (mola/stagger/desenho). Disparada ao entrar na viewport pelo
   vzAnimate() (border-ds-dataviz.js), que adiciona .vz-armed no .ds-chart__plot e
   .vz-in quando intersecta. Progressive enhancement: sem JS não há .vz-armed →
   charts estáticos (estado final). --vz-i (índice) escalona o delay.
   =========================================================================== */
.ds-chart__plot, .vz-growx, .ds-gauge, .ds-distribution, .ds-bullet {
  --vz-dur: 1s; --vz-draw-dur: 1.6s; --vz-stagger: 100ms;
  --vz-ease-out: cubic-bezier(.16, 1, .3, 1);
  --vz-ease-spring: cubic-bezier(.16, 1, .3, 1);
}
/* estado ARMADO (pré-animação) — só sob .vz-armed (adicionado pelo JS) */
.vz-armed .vz-bar, .vz-armed .ds-bar-rect {
  transform: scaleY(0); transform-box: fill-box; transform-origin: bottom; opacity: .001;
}
.vz-armed .vz-line, .vz-armed .vz-spark { stroke-dasharray: 1; stroke-dashoffset: 1; }
.vz-armed .vz-area { opacity: 0; }
.vz-armed .vz-mk, .vz-armed .vz-dot {
  transform: scale(0); transform-box: fill-box; transform-origin: center; opacity: 0;
}
.vz-armed .vz-poly, .vz-armed .vz-sankey-band, .vz-armed .vz-node,
.vz-armed .ds-heatmap__cell, .vz-armed .ds-treemap__tile {
  transform: scale(.92); transform-box: fill-box; transform-origin: center; opacity: 0;
}
/* DISPARO — .vz-in roda os keyframes (delay escalonado por --vz-i) */
.vz-armed.vz-in .vz-bar, .vz-armed.vz-in .ds-bar-rect {
  animation: vzGrow var(--vz-dur) var(--vz-ease-out) both;
  animation-delay: calc(var(--vz-i, 0) * var(--vz-stagger));
}
.vz-armed.vz-in .vz-line, .vz-armed.vz-in .vz-spark {
  animation: vzDraw var(--vz-draw-dur) var(--vz-ease-out) forwards;
}
.vz-armed.vz-in .vz-area { animation: vzFade .8s ease .5s forwards; }
.vz-armed.vz-in .vz-mk, .vz-armed.vz-in .vz-dot {
  animation: vzPop .7s var(--vz-ease-spring) both;
  animation-delay: calc(var(--vz-i, 0) * var(--vz-stagger) + .4s);
}
.vz-armed.vz-in .vz-poly, .vz-armed.vz-in .vz-sankey-band, .vz-armed.vz-in .vz-node,
.vz-armed.vz-in .ds-heatmap__cell, .vz-armed.vz-in .ds-treemap__tile {
  animation: vzPop .75s var(--vz-ease-out) both;
  animation-delay: calc(var(--vz-i, 0) * var(--vz-stagger));
}
@keyframes vzGrow { from { transform: scaleY(0); opacity: .001; } to { transform: scaleY(1); opacity: 1; } }
@keyframes vzDraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes vzFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes vzPop  { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* barras HORIZONTAIS (waterfall .wf-seg, .hbar-fill, etc.) — crescem da esquerda */
.vz-growx.vz-armed { transform: scaleX(0); transform-origin: left center; }
.vz-growx.vz-armed.vz-in {
  animation: vzGrowX var(--vz-dur) var(--vz-ease-out) both;
  animation-delay: calc(var(--vz-i, 0) * var(--vz-stagger));
}
@keyframes vzGrowX { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* WIDGETS CSS (Gauge / Distribution / Bullet) — entram junto com os gráficos.
   Gauge: o arco (conic via --val) varre 0→alvo animado no JS (sem keyframe aqui).
   Distribution: barras crescem (scaleY). Bullet: a medida cresce (scaleX) preservando
   o translateY(-50%) de centragem; o alvo aparece com fade. */
.vz-armed.ds-distribution .ds-distribution__bar { transform: scaleY(0); transform-origin: bottom; }
.vz-armed.ds-distribution.vz-in .ds-distribution__bar { animation: vzGrow var(--vz-dur) var(--vz-ease-out) both; }
.vz-armed.ds-bullet .ds-bullet__measure { transform: translateY(-50%) scaleX(0); transform-origin: left center; }
.vz-armed.ds-bullet.vz-in .ds-bullet__measure { animation: vzGrowXc var(--vz-dur) var(--vz-ease-out) both; }
.vz-armed.ds-bullet .ds-bullet__target { opacity: 0; }
.vz-armed.ds-bullet.vz-in .ds-bullet__target { animation: vzFade .5s ease .45s forwards; }
@keyframes vzGrowXc { from { transform: translateY(-50%) scaleX(0); } to { transform: translateY(-50%) scaleX(1); } }

/* bloco de DEMO de animação de entrada (doc): palco do gráfico + botão de repetir.
   Reusável em qualquer site — a animação em si é a do gráfico (acima), nada inline. */
.vz-demo { display: flex; flex-direction: column; align-items: flex-start; gap: var(--spacing-stack-xxxs, 16px); }
.vz-demo__stage { width: 100%; }
.vz-replay::before { content: "↻"; margin-right: .4em; font-size: 1.1em; line-height: 1; }

/* BLINDAGEM — impressão e reduced-motion sempre no estado FINAL (nunca em branco) */
@media print {
  .vz-armed .vz-bar, .vz-armed .ds-bar-rect, .vz-armed .vz-line, .vz-armed .vz-spark,
  .vz-armed .vz-area, .vz-armed .vz-mk, .vz-armed .vz-dot, .vz-armed .vz-poly,
  .vz-armed .vz-sankey-band, .vz-armed .vz-node, .vz-armed .ds-heatmap__cell,
  .vz-armed .ds-treemap__tile, .vz-growx.vz-armed,
  .vz-armed.ds-distribution .ds-distribution__bar, .vz-armed.ds-bullet .ds-bullet__target {
    animation: none !important; opacity: 1 !important; transform: none !important; stroke-dashoffset: 0 !important;
  }
  .vz-armed.ds-bullet .ds-bullet__measure { animation: none !important; opacity: 1 !important; transform: translateY(-50%) !important; }
}
@media (prefers-reduced-motion: reduce) {
  .ds-donut__slice, .ds-bar-rect, .vz-cross, .vz-dot { transition: none; }
  .vz-armed .vz-bar, .vz-armed .ds-bar-rect, .vz-armed .vz-line, .vz-armed .vz-spark,
  .vz-armed .vz-area, .vz-armed .vz-mk, .vz-armed .vz-dot, .vz-armed .vz-poly,
  .vz-armed .vz-sankey-band, .vz-armed .vz-node, .vz-armed .ds-heatmap__cell,
  .vz-armed .ds-treemap__tile, .vz-growx.vz-armed,
  .vz-armed.ds-distribution .ds-distribution__bar, .vz-armed.ds-bullet .ds-bullet__target {
    animation: none !important; opacity: 1 !important; transform: none !important; stroke-dashoffset: 0 !important;
  }
  .vz-armed.ds-bullet .ds-bullet__measure { animation: none !important; opacity: 1 !important; transform: translateY(-50%) !important; }
}
