/*
 * As telas que têm desenho próprio: gráfico, cascata de rastro, backtrace, log, medidor de
 * consumo. O sistema base (tokens, cartão, botão, tabela) está em application.css.
 *
 * Separado porque são coisas de UMA tela cada, e misturar com o sistema faria parecer que
 * `.waterfall-bar` é um componente reutilizável — não é, é o desenho da amostra.
 */

/* ---------------------------------------------------------------- gráfico -- */
/*
 * A anatomia: `.chart-plot` é uma grade de três peças — rótulos do eixo vertical à esquerda,
 * `.chart-canvas` (o SVG) no meio, rótulos do eixo horizontal embaixo.
 *
 * O SVG estica (`preserveAspectRatio="none"`), e é por isso que NADA de texto e nenhuma bolinha
 * vivem dentro dele: esticado, texto sai gordo no desktop e ilegível no celular, e círculo vira
 * elipse. Rótulo, cursor e dica são HTML posicionados em porcentagem — o mesmo sistema de
 * coordenadas, sem a distorção. Traço fino se mantém por `vector-effect: non-scaling-stroke`.
 */
.chart { position: relative; }

.chart-plot {
  position: relative;
  padding-left: 46px;
  padding-bottom: 20px;
  height: calc(var(--plot-height, 190px) + 20px);
}

.chart-canvas { position: relative; height: 100%; }

.chart-svg { width: 100%; height: 100%; display: block; }

.chart-axis-y {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 20px;
  width: 40px;
}

.chart-axis-y span {
  position: absolute;
  right: 0;
  transform: translateY(-50%);
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.chart-axis-x { position: absolute; left: 46px; right: 0; bottom: 0; height: 18px; }

.chart-axis-x span {
  position: absolute;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--text-faint);
  white-space: nowrap;
}

/* O primeiro e o último rótulo do eixo do tempo encostam nas bordas; sem isto, metade de cada
   um fica fora do gráfico. */
.chart-axis-x span:first-child { transform: none; }
.chart-axis-x span:last-child { transform: translateX(-100%); }

.chart-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}

.chart-title { font-size: 13.5px; font-weight: 600; }
.chart-subtitle { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

.chart-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; padding-left: 46px; }

.chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
}

.chart-legend-swatch {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  flex-shrink: 0;
  background: currentColor;
}

/* Grade e marcadores. A grade existe para dar escala, não para ser lida. */
.chart-grid line { stroke: var(--chart-grid); stroke-width: 1; }
.chart-marker line { stroke: var(--accent-line); stroke-width: 1; stroke-dasharray: 3 3; }

/* A opacidade da área é token: sobre branco, 0.16 já dá corpo; sobre preto precisa de mais. */
.chart-area { opacity: var(--chart-area); }
.chart-line { fill: none; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.chart-line-soft { stroke-width: 1.4; stroke-dasharray: 4 3; opacity: 0.8; }
.chart-bar { opacity: 0.85; }

/* As faixas que capturam o mouse cobrem a altura toda: acertar uma curva de 2 px é impossível. */
.chart-hover rect { fill: transparent; }
.chart-hover rect:hover { fill: var(--surface-hover); }

.chart-cursor-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
  pointer-events: none;
}

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

.chart-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 2px var(--surface);
}

.chart-tooltip {
  position: absolute;
  z-index: 20;
  min-width: 150px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: var(--bg-panel);
  box-shadow: var(--shadow-lg);
  font-size: 12px;
  pointer-events: none;
  transform: translate(-50%, calc(-100% - 10px));
}

.chart-tooltip-time { color: var(--text-faint); font-size: 11px; margin-bottom: 5px; white-space: nowrap; }
.chart-tooltip-row { display: flex; align-items: center; gap: 10px; justify-content: space-between; }
.chart-tooltip-row .label { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); }
.chart-tooltip-row .swatch { width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
.chart-tooltip-row .value { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }

.chart-empty {
  display: grid;
  place-items: center;
  min-height: 120px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--text-faint);
  font-size: 12.5px;
}

/* A linha fina do cartão de app: sem eixo, sem grade, só a forma. */
.sparkline { height: 34px; width: 100%; }

/* Barra proporcional dentro de célula de tabela — o "impacto" na lista de desempenho e a
   participação de cada grupo de evento. */
.bar {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--surface-solid);
  overflow: hidden;
  min-width: 40px;
}

.bar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--accent); }
.bar-fill-info { background: var(--info); }
.bar-fill-violet { background: var(--violet); }
.bar-fill-teal { background: var(--teal); }
.bar-fill-warning { background: var(--warning); }
.bar-fill-success { background: var(--success); }
.bar-fill-muted { background: var(--text-faint); }

/* Barra empilhada de uma linha: a divisão do tempo por grupo de evento. */
.stackbar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--surface-solid); }
.stackbar > span { display: block; height: 100%; }

/* ------------------------------------------------------- cascata do rastro -- */
/*
 * A amostra desenhada no tempo. Cada linha é um evento; a posição e a largura da barra são o
 * início e a duração dele dentro da requisição.
 *
 * O recuo vem de `--level` (o aninhamento que o agente mandou) em vez de elemento aninhado:
 * assim a lista continua sendo uma tabela, e alinhar as barras de níveis diferentes no mesmo
 * eixo de tempo é o que faz a cascata ser legível.
 */
.waterfall { display: flex; flex-direction: column; }

.waterfall-row {
  display: grid;
  grid-template-columns: minmax(220px, 42%) 1fr;
  align-items: center;
  gap: 14px;
  padding: 7px 22px;
  border-bottom: 1px solid var(--line);
  transition: background var(--ease);
}

.waterfall-row:last-child { border-bottom: 0; }
.waterfall-row:hover { background: var(--surface-hover); }

.waterfall-label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding-left: calc(var(--level, 0) * 14px);
  font-size: 12.5px;
}

.waterfall-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.waterfall-track { position: relative; height: 18px; }

.waterfall-bar {
  position: absolute;
  top: 3px;
  height: 12px;
  min-width: 2px;
  border-radius: 3px;
  background: var(--info);
}

.waterfall-bar-duration {
  position: absolute;
  top: 0;
  left: calc(100% + 6px);
  font-size: 11px;
  line-height: 12px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Barra que chega perto da borda direita: o número vai para dentro dela, alinhado à direita. */
.waterfall-bar-duration.is-inside {
  left: auto;
  right: 6px;
  color: #fff;
  font-weight: 600;
}

/* Uma cor por grupo de evento. As mesmas cores da legenda do tempo por grupo, para a divisão
   e a cascata se lerem como a mesma informação. */
.group-active_record .waterfall-bar, .swatch-active_record { background: var(--info); }
.group-action_view .waterfall-bar, .swatch-action_view { background: var(--violet); }
.group-action_controller .waterfall-bar, .swatch-action_controller { background: var(--accent); }
.group-net_http .waterfall-bar, .swatch-net_http { background: var(--teal); }
.group-cache .waterfall-bar, .swatch-cache { background: var(--warning); }
.group-active_job .waterfall-bar, .swatch-active_job { background: var(--success); }
.group-app .waterfall-bar, .swatch-app { background: var(--text-faint); }
.group-custom .waterfall-bar, .swatch-custom { background: var(--text-muted); }

/* ----------------------------------------------------------- backtrace -- */
/*
 * As linhas de gem ficam apagadas e as do app em destaque. É a única coisa que faz um
 * backtrace de 80 linhas ser útil: a primeira linha nossa é onde se começa a olhar, e ela
 * costuma estar na posição 14, atrás de treze frames de middleware.
 */
.backtrace {
  margin: 0;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--code-bg);
  overflow: hidden;
}

.backtrace-line {
  display: flex;
  gap: 12px;
  padding: 5px 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.backtrace-line:nth-child(odd) { background: var(--code-stripe); }
.backtrace-index { flex: none; width: 22px; text-align: right; color: var(--text-faint); }

.backtrace-line.is-app {
  color: var(--text);
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent);
}

.backtrace-line.is-app .backtrace-index { color: var(--accent); }

/* ---------------------------------------------------------------- logs -- */
.logs {
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--code-bg);
  overflow: hidden;
}

.logline {
  display: grid;
  grid-template-columns: 74px 62px 1fr;
  gap: 12px;
  padding: 6px 14px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.55;
  transition: background var(--ease);
}

.logline:last-child { border-bottom: 0; }
.logline:hover { background: var(--surface-hover); }
.logline-time { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.logline-level { font-weight: 600; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; }
.logline-message { color: var(--text-soft); overflow-wrap: anywhere; white-space: pre-wrap; }
.logline-meta { color: var(--text-faint); font-size: 11px; margin-top: 2px; display: flex; gap: 10px; flex-wrap: wrap; }

.level-debug   { color: var(--text-faint); }
.level-info    { color: var(--info); }
.level-warn    { color: var(--warning); }
.level-error   { color: var(--danger); }
.level-fatal   { color: var(--danger); font-weight: 700; background: var(--danger-soft); border-radius: 4px; padding: 0 4px; }
.level-unknown { color: var(--text-muted); }

.logline.is-problem { background: var(--danger-soft); }

/* A linha nova que entra no rabo ao vivo. Piscada curta: o suficiente para o olho achar a
   linha nova numa tela que se move. */
.logline.is-new { animation: log-in 1.2s ease; }

@keyframes log-in {
  from { background: var(--accent-line); }
  to   { background: transparent; }
}

/* ---------------------------------------------------------- distribuição -- */
/* O histograma de duração: quantas transações em cada faixa. É o que mostra que uma média de
   120 ms é "quase tudo em 40 ms e uma cauda em 2 s". */
.histogram { display: flex; align-items: flex-end; gap: 2px; height: 90px; }

.histogram-bar {
  flex: 1;
  min-width: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--accent-soft);
  border-top: 2px solid var(--accent);
  position: relative;
}

.histogram-bar-empty { border-top-color: transparent; background: var(--surface-solid); }

.histogram-bar:hover { background: var(--accent-line); }

/* ------------------------------------------------------------- cobrança -- */
.meter { display: flex; flex-direction: column; gap: 7px; }

.meter-track {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: var(--surface-solid);
  overflow: hidden;
}

.meter-fill { position: absolute; inset: 0 auto 0 0; border-radius: 5px; background: var(--success); }
.meter-fill.is-warning { background: var(--warning); }
.meter-fill.is-over { background: var(--danger); }

/* A marca da projeção: onde o mês deve terminar no ritmo atual. Traço, e não preenchimento,
   porque projeção não é consumo — misturar as duas coisas na mesma barra faria a tela mentir. */
.meter-projection {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--text-soft);
  border-radius: 1px;
}

.meter-labels { display: flex; justify-content: space-between; font-size: 12px; color: var(--text-muted); }

.plans { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.plan {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
}

.plan { box-shadow: var(--shadow-card); }
.plan.is-current { border-color: var(--accent-line); background: var(--accent-soft); }
.plan.is-suggested { border-color: color-mix(in srgb, var(--success) 38%, transparent); }
.plan-name { font-size: 15px; font-weight: 650; }
.plan-price { font-size: 26px; font-weight: 700; letter-spacing: -0.03em; }
.plan-price small { font-size: 13px; font-weight: 500; color: var(--text-muted); }
.plan-features { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: var(--text-muted); }
.plan-features li { display: flex; gap: 7px; align-items: flex-start; }
.plan-features svg { flex: none; margin-top: 3px; color: var(--success); }

/* --------------------------------------------------------- estados/faixas -- */
/* A faixa de aviso no topo da tela: teste terminando, plano estourado, coleta pausada. */
.banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  margin-bottom: 20px;
  border-radius: var(--radius);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  font-size: 13.5px;
}

.banner-warning { border-color: color-mix(in srgb, var(--warning) 32%, transparent); background: var(--warning-soft); }
.banner-danger { border-color: color-mix(in srgb, var(--danger) 32%, transparent); background: var(--danger-soft); }
.banner-info { border-color: color-mix(in srgb, var(--info) 32%, transparent); background: var(--info-soft); }
.banner svg { flex: none; }
.banner .btn { margin-left: auto; }

/* Ponto de estado das máquinas e dos monitores de uptime. */
.state { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 550; }
.state-ok { color: var(--success); }
.state-warning { color: var(--warning); }
.state-critical { color: var(--danger); }
.state-idle { color: var(--text-faint); }
.state-unknown { color: var(--text-faint); }

/* A régua de disponibilidade: um traço por verificação, verde ou vermelho, na ordem do tempo.
   É a leitura que responde "ficou fora quando?" sem gráfico e sem eixo. */
.uptime-strip { display: flex; gap: 2px; align-items: stretch; height: 30px; }

.uptime-tick {
  flex: 1;
  min-width: 2px;
  border-radius: 2px;
  background: var(--success-soft);
  border-top: 2px solid var(--success);
}

.uptime-tick.is-down { background: var(--danger-soft); border-top-color: var(--danger); }
.uptime-tick.is-empty { background: var(--surface-solid); border-top-color: transparent; }

/* -------------------------------------------------------- cartão de app -- */
.appcard {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  transition: background var(--ease), border-color var(--ease);
}

.appcard:hover { background: var(--surface-hover); border-color: var(--line-strong); }
.appcard { box-shadow: var(--shadow-card); }
.appcard.is-critical { border-color: color-mix(in srgb, var(--danger) 32%, transparent); }
.appcard.is-warning { border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.appcard-metrics { display: flex; gap: 18px; flex-wrap: wrap; }
.appcard-metric { display: flex; flex-direction: column; gap: 1px; }
.appcard-metric .value { font-size: 17px; font-weight: 650; font-variant-numeric: tabular-nums; }
.appcard-metric .label { font-size: 11px; color: var(--text-faint); }

@media (max-width: 720px) {
  .waterfall-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .logline { grid-template-columns: 1fr; gap: 2px; }
  .logline-time, .logline-level { display: inline-block; }
}
