/* =========================================================================
   Bar chart — animated, interactive, no library.

   Two orientations, named for the direction the BARS grow:

     .cht--v   bars grow upward   (categories along the bottom)
     .cht--h   bars grow rightward (categories down the left)

   Bars are elements, not SVG. An SVG chart has to fight its own viewBox to
   keep label text at a sane size, and every hit target needs building by
   hand; laid out as elements, the type scales with the page, hover and focus
   come free, and the whole thing reflows responsively without recomputation.

   One custom property per bar does the work: --cht-len, a percentage of the
   plot area. The grow animation is that property going 0 -> value, so nothing
   animates layout.

   Behaviour: assets/js/chart.js. Markup: chart() in scripts/study.mjs.
   ========================================================================= */
@property --cht-len {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.cht {
  margin: 0;
  --cht-gap: 14px;          /* between bars within a group */
  --cht-group-gap: 32px;    /* between category groups */
  --cht-plot: 260px;        /* length of the value axis */
  /* Series colours. Ink and the site accent first, then two hues far enough
     from both to stay separable. Deliberately its own small palette rather
     than borrowing a project's gradient — a chart's series are categories,
     and tying them to one company's colours would imply a link that isn't
     there. --pill-pos-ink is shared because a positive series and a positive
     delta genuinely mean the same thing. */
  --cht-1: var(--ink);
  --cht-2: var(--accent);
  --cht-3: #22b5e9;
  --cht-4: var(--pill-pos-ink);
}

.cht__head { margin-bottom: var(--space-m); }
.cht__title {
  font-size: 16px; font-weight: 600; letter-spacing: -.01em;
  color: var(--body-text, var(--ink));
}
.cht__sub { margin-top: var(--space-3xs); font-size: 14px; line-height: 21px; color: var(--ink-faint); }

/* -------------------------------- legend ------------------------------- */
.cht__legend {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs) var(--space-m);
  margin-bottom: var(--space-m); padding: 0; list-style: none;
}
.cht__legend li {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  font-size: 13px; color: var(--ink-soft);
}
.cht__swatch {
  width: 10px; height: 10px; border-radius: 3px; flex: none;
  background: var(--cht-c);
}

/* --------------------------------- plot -------------------------------- */
.cht__plot { position: relative; }

/* Gridlines sit behind the bars and are decoration — the values are on the
   bars themselves and in the table, so nothing is lost by hiding these. */
.cht__grid { position: absolute; inset: 0; pointer-events: none; }
.cht__grid span {
  position: absolute; background: var(--line);
}
.cht--v .cht__grid span { left: 0; right: 0; height: 1px; }
.cht--h .cht__grid span { top: 0; bottom: 0; width: 1px; }

/* ---- vertical: a row of category cells, bars growing up from a shared
   baseline. The axis line goes on .cht__bars so it runs unbroken across the
   gaps between cells; per-cell borders would draw it dashed. Labels therefore
   live outside the plot, in .cht__cats. */
.cht--v .cht__bars {
  position: relative; display: flex; align-items: flex-end;
  gap: var(--cht-group-gap);
  height: var(--cht-plot);
  border-bottom: 1px solid var(--ink);
}
.cht--v .cht__cell {
  flex: 1 1 0; min-width: 0; height: 100%;
  display: flex; align-items: flex-end;
}
.cht--v .cht__cat { display: none; }          /* .cht__cats carries these */
.cht--v .cht__group {
  flex: 1 1 0; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; justify-content: center;
  gap: var(--cht-gap);
}
.cht--v .cht__bar {
  position: relative; flex: 1 1 0; min-width: 0; max-width: 72px;
  height: var(--cht-len);
  background: var(--cht-c);
  border-radius: 4px 4px 0 0;
}

/* ---- horizontal: a stack of cells, bars growing right, each cell captioned
   directly above its own bars. */
/* The right gutter holds the value labels, which sit outside their bar at
   `left: 100% + 8px`. Without it a full-length bar prints its label past the
   plot and, on a phone, past the viewport — "4,830" was losing its last digit
   at 375px. `--cht-val-w` is measured from the longest string the chart will
   actually print and set on the figure by the renderer, so the reservation is
   exact rather than a guess. The fallback keeps a bare `.cht--h` sane. */
.cht--h .cht__bars {
  position: relative; display: flex; flex-direction: column;
  gap: var(--cht-group-gap);
  border-left: 1px solid var(--ink);
  padding-right: var(--cht-val-w, 5ch);   /* audit-ok: measured from the longest value at build time */
}
.cht--h .cht__cats { display: none; }         /* .cht__cat carries these */
.cht--h .cht__group { display: flex; flex-direction: column; gap: var(--cht-gap); }
.cht--h .cht__bar {
  position: relative;
  height: 22px; width: var(--cht-len);
  background: var(--cht-c);
  border-radius: 0 4px 4px 0;
}

/* The animation is the custom property, not width/height directly, so the
   browser interpolates a single registered value instead of relayouting. */
.cht__bar {
  transition: --cht-len .9s cubic-bezier(.22, 1, .36, 1), filter .15s ease;
  cursor: default;
}
/* Bars start collapsed and are released together once the chart is on screen;
   the per-bar delay is set inline by chart.js so the stagger follows document
   order regardless of how many series there are. */
.cht:not(.is-shown) .cht__bar { --cht-len: 0%; }

.cht__bar:hover { filter: brightness(1.12); }

/* -------------------------------- values ------------------------------- */
/* Printed on the bar, so the chart is readable without hovering anything —
   the tooltip is for precision, not for the basic reading. */
.cht__val {
  position: absolute; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--body-text, var(--ink));
  font-variant-numeric: tabular-nums;
}
.cht--v .cht__val { bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); }
.cht--h .cht__val { left: calc(100% + 8px); top: 50%; transform: translateY(-50%); }

/* ------------------------------- categories ---------------------------- */
/* The UA list padding would push every label 40px right of the group it
   names, so the reset here is load-bearing, not tidiness. */
.cht__cats {
  display: flex; gap: var(--cht-group-gap);
  margin: var(--space-xs) 0 0; padding: 0; list-style: none;
}
.cht__cats li {
  flex: 1 1 0; min-width: 0; text-align: center;
  font-size: 13px; line-height: 1.35; color: var(--ink-soft);
}
.cht--h .cht__cat {
  font-size: 13px; line-height: 1.35; color: var(--ink-soft);
  margin-bottom: var(--space-2xs);
}

/* -------------------------------- tooltip ------------------------------ */
.cht__tip {
  position: absolute; z-index: 3; pointer-events: none;
  padding: var(--pad-pill); border-radius: var(--radius-s);
  background: var(--ink); color: var(--paper);
  font-size: 12px; font-weight: 600; white-space: nowrap;
  box-shadow: var(--shadow-raised-hi);
  opacity: 0; transform: translate(-50%, -6px);
  transition: opacity .14s ease;
}
.cht__tip.is-on { opacity: 1; }

/* The visual chart is aria-hidden and a real table carries the data, so a
   screen reader gets figures it can navigate rather than a wall of divs.
   The hiding itself is `.u-sr` in site.css. */

@media (prefers-reduced-motion: reduce) {
  .cht__bar { transition: none; }
  .cht:not(.is-shown) .cht__bar { --cht-len: var(--cht-final); }
}

/* Narrow: horizontal reads better than a row of hairline columns, so the
   vertical variant borrows the horizontal layout below the breakpoint.
   Handled in chart.js by swapping the modifier class, because the two use
   genuinely different box models rather than the same one reflowed. */
@media (max-width: 560px) {
  .cht { --cht-group-gap: 22px; --cht-gap: var(--space-2xs); }
}
