/* ============================================================
   STARBOARD — Admiral Design System
   charts-interactive.css  ·  the live layer on top of charts.css

   Additions only — every static primitive (.ch-*) comes from
   charts.css. This file adds the mandatory ChartFrame wrapper,
   the KPI tile rhythm, the interaction states, motion classes
   and loading/error scaffolding that chart-core.js composes.
   No new hues, no raw hex, no gradients on data.
   ============================================================ */
@import url('../../charts.css');

/* ── ChartFrame — the mandatory wrapper for every chart ─────
      section.ad-chart-frame
        header.ad-chart-header
          div > h3.ad-chart-title + p.ad-chart-description
          div.ad-chart-meta
        div.ad-chart-body
      Builds on the .ch-card / .ch-head primitives — same card
      rhythm: white bg, 1px neutral border, --radius-lg,
      shadow-xs. Padding 16–24px desktop, 12–16px mobile. ──── */
.ad-chart-frame {
  display: block;
  background: var(--bg-elevated);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.ad-chart-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md) var(--space-2xs);
}
/* title/description wrapper takes the available width */
.ad-chart-header > div:first-child { flex: 1 1 auto; min-width: 0; }
.ad-chart-title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--text-sm-size); line-height: var(--text-sm-lh);
  color: var(--fg-strong); letter-spacing: -0.01em;
}
.ad-chart-description {
  margin: 2px 0 0;
  font-family: var(--font-body); font-weight: 400;
  font-size: var(--text-xs-size); line-height: var(--text-xs-lh);
  color: var(--fg-muted);
}
.ad-chart-meta {
  display: flex; align-items: center; gap: var(--space-3xs); flex: none;
  font-size: var(--text-xs-size); color: var(--fg-muted);
}
.ad-chart-body { padding: 0 var(--space-md) var(--space-sm); }
.ad-chart-body svg { width: 100%; height: auto; display: block; overflow: visible; }
@media (max-width: 768px) {
  .ad-chart-header { padding: var(--space-xs) var(--space-sm) var(--space-3xs); }
  .ad-chart-body   { padding: 0 var(--space-sm) var(--space-xs); }
}

/* ── KPI tile — fixed 3-row structure ───────────────────────
      (1) label left + optional status icon right
      (2) big value + delta
      (3) sparkline, fixed 36px, inside a padded spark frame.
      Rhythm is fixed on the 4–6–8px scale; hover/focus lifts
      ONLY the container (standard card lift), never the text
      or sparkline styling. ───────────────────────────────── */
.ad-kpi-tile {
  background: var(--bg-elevated);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-sm) var(--space-md);
  transition: border-color var(--duration-5) var(--ease-out),
              box-shadow var(--duration-5) var(--ease-out);
}
.ad-kpi-tile:hover,
.ad-kpi-tile:focus-within {
  border-color: var(--neutral-300);
  box-shadow: var(--shadow-sm);
}
.ad-kpi-tile__top {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2xs); /* one fixed 8px icon↔text gap */
}
.ad-kpi-tile__label {
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--text-xs-size); line-height: var(--text-xs-lh);
  color: var(--fg-muted);
}
.ad-kpi-tile__icon {
  width: 1rem; height: 1rem; flex: none;   /* 16px — on the 4px grid */
  display: grid; place-items: center;
  color: var(--fg-muted);
}
.ad-kpi-tile__value-row {
  display: flex; align-items: baseline; gap: var(--space-2xs);
  margin-top: 4px;
}
/* sparkline frame — full width, fixed 36px line, never touches
   the tile edges (≥4px top/bottom padding), no axes, no grid */
.ad-kpi-tile__spark { margin-top: 8px; padding: 4px 0; }
.ad-kpi-tile__spark svg { display: block; width: 100%; }

/* ── Container ───────────────────────────────────────────── */
.chx-wrap { position: relative; }
.chx-wrap svg { display: block; width: 100%; overflow: visible; }
.chx-wrap svg:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* ── Floating live tooltip — .ch-tip, repositioned by transform ── */
.chx-tip {
  position: absolute;
  top: 0; left: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 4;
  /* rises 4px as it appears; transform is split: the wrapper
     translate comes from JS (--chx-tx/--chx-ty), the rise here */
  transform: translate(var(--chx-tx, 0px), calc(var(--chx-ty, 0px) + 4px));
  transition: opacity var(--duration-3) var(--ease-out),
              transform var(--duration-3) var(--ease-out);
  will-change: transform, opacity;
}
.chx-tip.is-visible {
  opacity: 1;
  transform: translate(var(--chx-tx, 0px), var(--chx-ty, 0px));
}

/* ── Crosshair ───────────────────────────────────────────── */
.chx-crosshair {
  stroke: var(--neutral-400);
  stroke-width: 0.75;
  stroke-dasharray: 3 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--duration-3) var(--ease-out);
}
.chx-crosshair.is-visible { opacity: 1; }
.chx-crosshair-ring {
  fill: none;
  stroke: var(--neutral-400);
  stroke-width: 1;
  pointer-events: none;
}

/* ── Focus dot — hovered / keyboard-focused datum ────────── */
.chx-focus-dot {
  stroke: #fff;             /* matches .ch-dot white ring */
  stroke-width: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--duration-3) var(--ease-out);
}
.chx-focus-dot.is-visible { opacity: 1; }

/* ── Legend as toggle buttons ────────────────────────────── */
.ch-legend__item[role="button"],
button.ch-legend__item {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font-family: var(--font-body);
  cursor: pointer;
  transition: color var(--duration-4) var(--ease-out),
              opacity var(--duration-4) var(--ease-out);
}
button.ch-legend__item:hover { color: var(--fg-strong); }
button.ch-legend__item .ch-legend__dot {
  transition: background var(--duration-4) var(--ease-out),
              box-shadow var(--duration-4) var(--ease-out);
}
button.ch-legend__item.is-off { opacity: 0.4; }
button.ch-legend__item.is-off .ch-legend__dot {
  background: transparent !important;
  box-shadow: inset 0 0 0 1.5px currentColor; /* hollow swatch */
}
button.ch-legend__item:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
.chx-legend-more {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  color: var(--fg-muted);
  align-self: center;
}

/* Series fade while a legend toggle re-scales (JS adds/removes) */
.chx-series { transition: opacity var(--duration-4) var(--ease-out); }
.chx-series.is-fading { opacity: 0; }

/* ── Brush selection ─────────────────────────────────────── */
.chx-brush {
  fill: var(--primary-500);
  fill-opacity: 0.08;
  stroke: none;
  pointer-events: none;
}
.chx-brush-side {
  stroke: var(--primary-300);
  stroke-width: 1;
  pointer-events: none;
}
.chx-reset-zoom {
  position: absolute;
  top: 0.25rem; right: 0.25rem;
  z-index: 5;
  font-family: var(--font-body); font-weight: 500; font-size: 0.6875rem;
  padding: var(--space-3xs) var(--space-2xs);
  border: 1px solid var(--primary-200); border-radius: var(--radius-sm);
  background: var(--primary-50); color: var(--primary-700);
  cursor: pointer;
  animation: ad-fade-in var(--duration-4) var(--ease-out) both;
}
.chx-reset-zoom:hover { background: var(--primary-100); }

/* ── Skeleton — ONE shared ChartSkeleton structure ──────────
      Same ad-shimmer bones, same structure and spacing for
      every chart family — never bespoke per chart. ────────── */
.chx-skeleton {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2xs);
  padding: var(--space-2xs) 0;
}
.chx-skeleton .chx-bone {
  flex: 1;
  border-radius: 3px;
  background: linear-gradient(90deg,
    var(--neutral-200) 25%, var(--neutral-100) 50%, var(--neutral-200) 75%);
  background-size: 200% 100%;
  animation: ad-shimmer 1.4s linear infinite;
}

/* ── Inline error block — shares the .ch-empty layout exactly
      (icon · title · description on the system empty-state
      rhythm; no custom padding). chart-core renders
      .ch-empty.chx-error, so only the icon tint and the ghost
      retry button live here. ───────────────────────────────── */
.chx-error__icon {        /* tint override on .ch-empty__icon */
  background: var(--error-100);
  color: var(--error-700);
}
.chx-error__retry {
  margin-top: var(--space-xs);
  /* ghost button — standard ghost padding/radius, never primary */
  font-family: var(--font-body); font-weight: 600; font-size: 0.75rem;
  padding: 7px 14px;
  border: 1px solid var(--neutral-300); border-radius: var(--radius-sm);
  background: transparent; color: var(--fg-default); cursor: pointer;
  transition: background var(--duration-4) var(--ease-out),
              color var(--duration-4) var(--ease-out);
}
.chx-error__retry:hover { color: var(--fg-strong); background: var(--neutral-50); }

/* ── Enter animations (chart-core skips these entirely under
      prefers-reduced-motion — and the global collapse in
      colors_and_type.css backstops them anyway) ───────────── */
.chx-anim-bar {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: ad-grow-y var(--duration-8) var(--ease-out) both;
  /* stagger via inline animation-delay, capped at 8 × --stagger-step */
}
.chx-anim-bar--down { transform-origin: top center; } /* diverging negatives grow downward */
.chx-anim-line {
  animation: ad-draw 400ms var(--ease-out) both;
  /* JS sets stroke-dasharray + --ad-draw-length from getTotalLength() */
}
.chx-anim-fade {
  animation: ad-fade-in var(--duration-7) var(--ease-out) 300ms both;
  /* area fills appear after the line draw completes */
}
.chx-anim-cell {
  animation: ad-fade-in var(--duration-7) var(--ease-out) both;
}
.chx-anim-rise {
  transform-box: fill-box;
  animation: ad-fade-up var(--duration-7) var(--ease-out) both;
}
/* Donut / gauge segments grow via stroke-dasharray transition (JS) */
.chx-anim-seg { transition: stroke-dasharray var(--duration-8) var(--ease-out); }

/* ── Per-segment hover states (donut / gauge / heatmap / …) ── */
.chx-dimmable { transition: opacity var(--duration-4) var(--ease-out); }
.chx-dimmable.is-dim { opacity: 0.35; }
.chx-cell { transition: opacity var(--duration-4) var(--ease-out); }
/* hover ring: 1px primary-600 inset — the cell text colour never
   changes on hover, so contrast never drops */
.chx-cell.is-hover { stroke: var(--primary-600); stroke-width: 1; }
.chx-cell-val {
  /* same UI text size as the other chart labels — never smaller.
     Fill comes from the HEATMAP_BUCKETS text mapping (JS). */
  font-family: var(--font-mono); font-size: 9px; font-weight: 500;
  pointer-events: none;
}

/* Combo right axis — visibly lighter than the left (left stays
   --chart-axis / neutral-500; right drops to neutral-400, one
   step smaller) */
.chx-axis-right { fill: var(--neutral-400); font-size: 8px; }

/* Funnel / treemap labels */
.chx-stage-label { font-family: var(--font-body); font-size: 10px; font-weight: 500; fill: var(--fg-default); }
.chx-stage-val   { font-family: var(--font-mono); font-size: 10px; font-weight: 500; fill: var(--fg-strong); }
.chx-stage-conv  { font-family: var(--font-mono); font-size: 8px; fill: var(--chart-axis); }
.chx-tm-label { font-family: var(--font-body); font-size: 10px; font-weight: 500; fill: var(--fg-strong); pointer-events: none; }
.chx-tm-val   { font-family: var(--font-mono); font-size: 9px; font-weight: 500; fill: var(--fg-muted); pointer-events: none; }

/* KPI tile value cross-fade (Charts.jsx KpiTile) — 180ms
   --motion-status-change on change ONLY; no snaps, no scale */
.chx-kpi-value { transition: opacity var(--motion-status-change); }
.chx-kpi-value.is-swapping { opacity: 0; }

/* Internal sr-only live region (when a11y.js isn't loaded) */
.chx-sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); overflow: hidden; white-space: nowrap;
}
