/* =============================================================================
   UNICHAT-DASHBOARD-VISUAL-ASSISTED-CONVERGENCE-01 — gramática visual dos gráficos

   Uma folha, uma régua. O produto não tem biblioteca de gráficos: cada cartão desenhava o
   próprio (SVG com números mágicos, div+width, conic-gradient, div+height), e o resultado eram
   quatro gramáticas vizinhas sem eixo, sem grid e com tooltip nativo do navegador.

   Tudo aqui sai de token canônico. Nenhum valor literal de cor, tipografia, raio ou camada.

   PALETA DE SÉRIES — restrita e semântica (adendo §9). Uma série mantém a identidade quando
   reaparece em outro gráfico: "recebidas" é sempre a mesma cor, "enviadas" também. Verde e
   vermelho ficam reservados para ganho/perda e resolvido/vencido — não são a terceira e a quarta
   cor de uma sequência.
   ============================================================================= */

:root {
    --uni-chart-series-1: var(--crm-color-primary);
    --uni-chart-series-2: #0e9f6e;
    --uni-chart-series-3: #7c6cf0;
    --uni-chart-grid: color-mix(in srgb, var(--crm-color-border) 70%, transparent);
    --uni-chart-axis-text: var(--crm-color-text-muted);
    --uni-chart-band-hover: color-mix(in srgb, var(--crm-color-primary) 7%, transparent);
    --uni-chart-bar-radius: 3px;
    --uni-chart-line-width: 2px;
}

/* VL-28 / VL-46 — o par escuro é declarado, não derivado. As séries clareiam para manter
   contraste sobre a superfície escura, e a gridline escurece para não virar protagonista. */
:root[data-crm-theme="dark"] {
    --uni-chart-series-1: #6aa8ff;
    --uni-chart-series-2: #34d399;
    --uni-chart-series-3: #a99cf7;
    --uni-chart-grid: color-mix(in srgb, var(--crm-color-border) 85%, transparent);
    --uni-chart-band-hover: color-mix(in srgb, var(--crm-color-primary) 14%, transparent);
}

/* -----------------------------------------------------------------------------
   Cartão de módulo (VL-15)
   ----------------------------------------------------------------------------- */

.uni-chart-card {
    grid-column: span var(--uni-chart-span, 1);
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 20px; /* EX-01 */
    border: 1px solid var(--crm-color-border);
    border-radius: var(--uni-radius-lg);
    background: var(--crm-color-surface);
}

.uni-chart-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--uni-space-3);
    margin-bottom: var(--uni-space-4);
}

.uni-chart-card-heading { min-width: 0; }

.uni-chart-card-heading h3 {
    display: flex;
    align-items: center;
    gap: var(--uni-space-1);
    margin: 0;
    font-size: var(--uni-font-size-lg);
    font-weight: 600;
    line-height: 1.2;
    color: var(--crm-color-text);
}

.uni-chart-card-heading p {
    margin: var(--uni-space-1) 0 0;
    font-size: var(--uni-font-size-xs);
    line-height: 1.4;
    color: var(--crm-color-text-muted);
}

.uni-chart-card-aside {
    display: flex;
    align-items: center;
    gap: var(--uni-space-2);
    flex: 0 0 auto;
}

.uni-chart-card-meta {
    padding: 2px 10px;
    border-radius: var(--uni-radius-pill);
    background: var(--uni-color-neutral-soft);
    font-size: var(--uni-font-size-2xs);
    font-weight: 600;
    color: var(--crm-color-text-muted);
    white-space: nowrap;
    user-select: none; /* VL-25 — é chrome */
}

.uni-chart-card-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.uni-chart-card-foot {
    margin-top: var(--uni-space-4);
    padding-top: var(--uni-space-3);
    border-top: 1px solid var(--crm-color-border);
}

/* Rodapé sem conteúdo não desenha régua nem ocupa altura: um módulo que suprime o resumo por
   não ter dados deixaria, senão, uma linha solta sob o estado vazio. */
.uni-chart-card-foot:not(:has(*)) {
    display: none;
}

/* -----------------------------------------------------------------------------
   Moldura: eixo de valor · plot · eixo de categoria
   ----------------------------------------------------------------------------- */

.uni-chart {
    display: flex;
    flex-direction: column;
    gap: var(--uni-space-3);
    margin: 0;
    min-width: 0;
}

.uni-chart-frame {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: var(--uni-chart-plot-height, 200px) auto;
    column-gap: var(--uni-space-2);
    row-gap: var(--uni-space-2);
}

/* Os rótulos do eixo de valor distribuem-se na mesma altura do plot, então cada um encosta na
   gridline correspondente. Alinhados à direita para o dígito ficar perto da linha que descreve. */
.uni-chart-axis-y {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: flex-end;
    padding-block: 0;
    font-size: var(--uni-font-size-2xs);
    line-height: 1;
    color: var(--uni-chart-axis-text);
    font-variant-numeric: tabular-nums;
    user-select: none;
    white-space: nowrap;
}

/* O primeiro e o último rótulo recuam meia linha para o texto centrar na gridline em vez de
   ficar apoiado nela. */
.uni-chart-axis-y > span:first-child { transform: translateY(-0.35em); }
.uni-chart-axis-y > span:last-child { transform: translateY(0.35em); }

.uni-chart-plot {
    position: relative;
    min-width: 0;
    border-bottom: 1px solid var(--crm-color-border);
}

/* Só gridlines HORIZONTAIS: o apoio quantitativo que estes gráficos pedem é o do eixo de valor.
   Somar verticais faria o papel quadriculado que o adendo §6 proíbe. */
.uni-chart-grid {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    pointer-events: none;
}

.uni-chart-grid > span {
    display: block;
    height: 1px;
    background: var(--uni-chart-grid);
}

/* A linha do zero é a base do plot, já desenhada pela borda do container. */
.uni-chart-grid > span:last-child { background: transparent; }

.uni-chart-axis-x {
    grid-column: 2;
    display: flex;
    justify-content: space-between;
    gap: var(--uni-space-1);
    font-size: var(--uni-font-size-2xs);
    line-height: 1;
    color: var(--uni-chart-axis-text);
    font-variant-numeric: tabular-nums;
    user-select: none;
}

/* Contém o transbordo dos rótulos. Com 30 dias em 390px cada coluna do eixo mede ~13px, e um
   "13/08" centralizado vaza para os lados: medido, isso esticava o documento de 390 para 410 e
   criava rolagem horizontal do body. O vazamento é desejável para o rótulo ficar legível — o que
   não pode é empurrar a página. */
.uni-chart-axis-x { overflow: hidden; }

.uni-chart-axis-x > span {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
    white-space: nowrap;
}

/* As pontas ancoram na borda em vez de centralizar: centralizado, metade do primeiro e do último
   rótulo cairia fora da área contida e sumiria no corte. */
.uni-chart-axis-x > span:first-child { text-align: left; }
.uni-chart-axis-x > span:last-child { text-align: right; }

/* Rótulo amostrado: sai da vista sem sair do documento — o dado continua no tooltip e no rótulo
   acessível da faixa, então nada é removido em silêncio (adendo §17). */
.uni-chart-axis-x > span.is-sparse { visibility: hidden; }

/* -----------------------------------------------------------------------------
   Barras agrupadas
   ----------------------------------------------------------------------------- */

.uni-chart-bars {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    gap: var(--uni-space-1);
}

.uni-chart-bar-group {
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
}

/* Largura elegante: a barra cresce com o espaço até um teto, em vez de virar uma faixa gorda
   quando há poucas categorias ou um fio quando há muitas (adendo §11). */
.uni-chart-bar {
    flex: 1 1 auto;
    max-width: 18px;
    min-height: 2px;
    border-radius: var(--uni-chart-bar-radius) var(--uni-chart-bar-radius) 0 0;
    background: var(--uni-chart-series-1);
    transition: opacity 140ms ease;
}

/* Zero não desenha nada. O piso de 2px existe para o valor pequeno-mas-real continuar visível;
   aplicado ao zero, ele inventa presença. */
.uni-chart-bar.is-zero { min-height: 0; }

.uni-chart-bar.series-resolved,
.uni-chart-bar.series-outbound,
.uni-chart-bar.series-won,
.uni-chart-bar.series-closed { background: var(--uni-chart-series-2); }

.uni-chart-bar.series-lost { background: var(--crm-color-danger); }

/* -----------------------------------------------------------------------------
   Linhas
   ----------------------------------------------------------------------------- */

.uni-chart-lines {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* `vector-effect: non-scaling-stroke` no markup mantém a espessura constante apesar do
   `preserveAspectRatio="none"`, que de outro modo esticaria o traço junto com o eixo. */
.uni-chart-line {
    fill: none;
    stroke: var(--uni-chart-series-1);
    stroke-width: var(--uni-chart-line-width);
    stroke-linecap: round;
    stroke-linejoin: round;
}

.uni-chart-line.series-handle { stroke: var(--uni-chart-series-3); }

.uni-chart-dots { position: absolute; inset: 0; pointer-events: none; }

/* Marcadores discretos: 5px, o suficiente para localizar o ponto sem virar uma fileira de
   bolinhas competindo com a linha (adendo §10). */
.uni-chart-dot {
    position: absolute;
    width: 5px;
    height: 5px;
    margin: -2.5px 0 0 -2.5px;
    border-radius: var(--uni-radius-pill);
    background: var(--crm-color-surface);
    border: 2px solid var(--uni-chart-series-1);
    transform: translateY(50%);
}

.uni-chart-dot.series-handle { border-color: var(--uni-chart-series-3); }

/* -----------------------------------------------------------------------------
   Faixas de leitura + tooltip canônico
   ----------------------------------------------------------------------------- */

.uni-chart-bands {
    position: absolute;
    inset: 0;
    display: flex;
}

.uni-chart-band {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    cursor: default;
}

.uni-chart-band:hover,
.uni-chart-band:focus-visible { background: var(--uni-chart-band-hover); }

/* VL-24 — o foco é alcançável por teclado, então o conteúdo do hover não é exclusivo do mouse. */
.uni-chart-band:focus-visible {
    outline: 2px solid var(--uni-color-focus-ring);
    outline-offset: -2px;
}

.uni-chart-tip {
    position: absolute;
    left: 50%;
    bottom: calc(100% - 8px);
    transform: translateX(-50%);
    z-index: var(--uni-z-tooltip);
    min-width: 148px;
    padding: 10px 12px;
    border: 1px solid var(--crm-color-border);
    border-radius: var(--uni-radius-md);
    background: var(--crm-color-surface);
    box-shadow: var(--uni-shadow-md);
    pointer-events: none;

    /* `display: none`, não `visibility: hidden`.
       Medido no DOM: com `visibility` o painel continua tendo CAIXA, e o tooltip da última banda
       — 148px a partir da borda direita do gráfico — esticava o `scrollWidth` do documento de
       1440 para 1466, criando rolagem horizontal do body (proibição 10 / VL-27). Um elemento
       invisível não pode empurrar a página. Aberto ele cabe: medido em 1440 na última banda. */
    display: none;
}

.uni-chart-band:hover .uni-chart-tip,
.uni-chart-band:focus-visible .uni-chart-tip {
    display: block;
}

/* Nas pontas o tooltip ancora pela borda em vez de vazar para fora do cartão. */
.uni-chart-band:first-child .uni-chart-tip { left: 0; transform: none; }
.uni-chart-band:last-child .uni-chart-tip { left: auto; right: 0; transform: none; }

.uni-chart-tip-title {
    margin: 0 0 var(--uni-space-2);
    font-size: var(--uni-font-size-xs);
    font-weight: 600;
    color: var(--crm-color-text);
    white-space: nowrap;
}

.uni-chart-tip dl {
    display: flex;
    flex-direction: column;
    gap: var(--uni-space-1);
    margin: 0;
}

.uni-chart-tip dl > div {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--uni-space-4);
}

.uni-chart-tip dt {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--uni-font-size-xs);
    color: var(--crm-color-text-muted);
    white-space: nowrap;
}

.uni-chart-tip dd {
    margin: 0;
    font-size: var(--uni-font-size-xs);
    font-weight: 600;
    color: var(--crm-color-text);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.uni-chart-tip .is-total {
    margin-top: 2px;
    padding-top: var(--uni-space-1);
    border-top: 1px solid var(--crm-color-border);
}

.uni-chart-tip i {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--uni-chart-series-1);
    flex: 0 0 auto;
}

.uni-chart-tip i.series-resolved,
.uni-chart-tip i.series-outbound,
.uni-chart-tip i.series-won,
.uni-chart-tip i.series-closed { background: var(--uni-chart-series-2); }

.uni-chart-tip i.series-handle { background: var(--uni-chart-series-3); }
.uni-chart-tip i.series-lost { background: var(--crm-color-danger); }

/* -----------------------------------------------------------------------------
   Legenda
   ----------------------------------------------------------------------------- */

.uni-chart-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--uni-space-2) var(--uni-space-4);
    margin: 0;
    padding-left: var(--uni-space-5);
    font-size: var(--uni-font-size-xs);
    color: var(--crm-color-text-muted);
    user-select: none;
}

.uni-chart-legend span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.uni-chart-legend i {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    background: var(--uni-chart-series-1);
}

.uni-chart-legend i.series-resolved,
.uni-chart-legend i.series-outbound,
.uni-chart-legend i.series-won,
.uni-chart-legend i.series-closed { background: var(--uni-chart-series-2); }

.uni-chart-legend i.series-handle { background: var(--uni-chart-series-3); }
.uni-chart-legend i.series-lost { background: var(--crm-color-danger); }

/* -----------------------------------------------------------------------------
   Ranking horizontal
   ----------------------------------------------------------------------------- */

.uni-rank-chart {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--uni-space-3);
}

.uni-rank-chart > li {
    display: grid;
    grid-template-columns: minmax(72px, 0.9fr) minmax(0, 2fr) auto;
    align-items: center;
    gap: var(--uni-space-3);
    min-width: 0;
}

.uni-rank-label {
    min-width: 0;
    font-size: var(--uni-font-size-sm);
    color: var(--crm-color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.uni-rank-track {
    position: relative;
    height: 10px;
    min-width: 0;
    border-radius: var(--uni-radius-pill);
    background: var(--uni-color-neutral-soft);
    overflow: hidden;
}

.uni-rank-fill {
    display: block;
    height: 100%;
    border-radius: var(--uni-radius-pill);
    background: var(--uni-chart-series-1);
}

.uni-rank-fill.tone-success { background: var(--uni-chart-series-2); }
.uni-rank-fill.tone-danger { background: var(--crm-color-danger); }
.uni-rank-fill.tone-warning { background: var(--crm-color-warning); }
.uni-rank-fill.tone-info { background: var(--uni-chart-series-3); }
.uni-rank-fill.tone-neutral { background: var(--crm-color-border-strong); }

.uni-rank-value {
    display: flex;
    align-items: baseline;
    gap: 6px;
    justify-content: flex-end;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.uni-rank-value strong {
    font-size: var(--uni-font-size-sm);
    font-weight: 600;
    color: var(--crm-color-text);
}

.uni-rank-value small {
    font-size: var(--uni-font-size-2xs);
    color: var(--crm-color-text-muted);
}

/* -----------------------------------------------------------------------------
   Donut
   ----------------------------------------------------------------------------- */

.uni-donut {
    display: flex;
    align-items: center;
    gap: var(--uni-space-5);
    flex-wrap: wrap;
}

.uni-donut-figure {
    position: relative;
    flex: 0 0 auto;
    width: 132px;
    height: 132px;
}

.uni-donut-figure svg {
    width: 100%;
    height: 100%;
    transform: rotate(0deg);
}

/* Espessura equilibrada: nem anel fino demais para carregar cor, nem torta com furo (adendo §12). */
.uni-donut-rail,
.uni-donut-slice { stroke-width: 5.2; }

.uni-donut-rail { stroke: var(--uni-color-neutral-soft); }

.uni-donut-slice.tone-warning { stroke: var(--crm-color-warning); }
.uni-donut-slice.tone-primary { stroke: var(--uni-chart-series-1); }
.uni-donut-slice.tone-success { stroke: var(--uni-chart-series-2); }
.uni-donut-slice.tone-danger { stroke: var(--crm-color-danger); }
.uni-donut-slice.tone-neutral { stroke: var(--crm-color-border-strong); }

.uni-donut-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    pointer-events: none;
}

.uni-donut-center strong {
    font-size: var(--uni-font-size-xl);
    font-weight: 600;
    line-height: 1.1;
    color: var(--crm-color-text);
    font-variant-numeric: tabular-nums;
}

.uni-donut-center small {
    font-size: var(--uni-font-size-2xs);
    color: var(--crm-color-text-muted);
    text-align: center;
}

.uni-donut-legend {
    flex: 1 1 160px;
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--uni-space-2);
    min-width: 0;
}

.uni-donut-legend li {
    display: grid;
    grid-template-columns: 10px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--uni-space-2);
    font-size: var(--uni-font-size-sm);
}

.uni-donut-legend i {
    width: 10px;
    height: 10px;
    border-radius: 3px;
}

.uni-donut-legend i.tone-warning { background: var(--crm-color-warning); }
.uni-donut-legend i.tone-primary { background: var(--uni-chart-series-1); }
.uni-donut-legend i.tone-success { background: var(--uni-chart-series-2); }
.uni-donut-legend i.tone-danger { background: var(--crm-color-danger); }
.uni-donut-legend i.tone-neutral { background: var(--crm-color-border-strong); }

.uni-donut-legend span {
    min-width: 0;
    color: var(--crm-color-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.uni-donut-legend strong {
    font-weight: 600;
    color: var(--crm-color-text);
    font-variant-numeric: tabular-nums;
}

.uni-donut-legend small {
    font-size: var(--uni-font-size-2xs);
    color: var(--crm-color-text-muted);
    font-variant-numeric: tabular-nums;
}

/* -----------------------------------------------------------------------------
   Vazio de módulo
   ----------------------------------------------------------------------------- */

.uni-chart-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--uni-space-2);
    padding: var(--uni-space-5) var(--uni-space-4);
    text-align: center;
}

.uni-chart-empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--uni-radius-pill);
    background: var(--uni-color-neutral-soft);
    color: var(--uni-color-text-subtle);
}

.uni-chart-empty-icon .crm-icon { width: 18px; height: 18px; }

.uni-chart-empty-title {
    margin: 0;
    font-size: var(--uni-font-size-md);
    font-weight: 600;
    color: var(--crm-color-text);
}

.uni-chart-empty-text {
    margin: 0;
    max-width: 320px;
    font-size: var(--uni-font-size-xs);
    line-height: 1.45;
    color: var(--crm-color-text-muted);
}

/* -----------------------------------------------------------------------------
   Mobile — não é o desktop espremido (adendo §17)
   ----------------------------------------------------------------------------- */

@media (max-width: 767px) {
    .uni-chart-card { padding: var(--uni-space-4); }

    /* Menos ticks e barra mais estreita: a mesma densidade do desktop vira mancha em 390px. */
    .uni-chart-axis-x > span:nth-child(even) { visibility: hidden; }
    .uni-chart-bar { max-width: 12px; }

    /* Tooltip por toque: ancorado à TELA, não à banda.
       Com 30 dias em 390px cada banda mede ~11px — um painel de 132px preso a ela vaza para fora
       da janela em quase toda posição, e foi o que a medição mostrou (409px de scrollWidth para
       390px de viewport, e o painel cortado). Preso ao rodapé da tela ele cabe sempre, fica no
       polegar e não empurra a página. `fixed` funciona porque nenhum ancestral tem `transform`. */
    .uni-chart-tip,
    .uni-chart-band:first-child .uni-chart-tip,
    .uni-chart-band:last-child .uni-chart-tip {
        position: fixed;
        left: var(--uni-space-3);
        right: var(--uni-space-3);
        bottom: var(--uni-space-3);
        top: auto;
        transform: none;
        min-width: 0;
        max-width: none;
    }

    .uni-chart-tip dl > div { justify-content: space-between; }

    .uni-donut { gap: var(--uni-space-4); justify-content: center; }
    .uni-donut-figure { width: 112px; height: 112px; }
    .uni-donut-legend { flex-basis: 100%; }

    .uni-rank-chart > li {
        grid-template-columns: minmax(64px, 1fr) minmax(0, 1.4fr) auto;
        gap: var(--uni-space-2);
    }
}

/* Um eixo com poucas categorias não precisa esconder rótulo nenhum no celular. */
@media (max-width: 767px) {
    .uni-chart-axis-x:has(> span:nth-child(-n + 5):last-child) > span { visibility: visible; }
}
