/* Team Northbound's three charts and their replay controls, drawn by
   src/lib/pastCharts.ts into a .charts-and-transport wrapper. Shared by
   every page showing them; each page's own stylesheet adds its layout
   around them. */

.charts-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin: 2rem 0 0.75rem;
}

.chart-panel h2 {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* VCR-style transport row plus scrubber (see team-northbound's spec.md,
   "Replay controls"). Same understated button language as
   cumulative-flow-diagram's own stop-button and scrubber.
   Sized to match one chart panel's own width -- the same (100% - 2 gaps) /
   3 share of .inner that .charts-row's repeat(3, 1fr) columns resolve to
   -- and centered under the row as a block via the auto side margins,
   rather than sized to fit the 5 buttons' own narrower combined width. The
   scrubber below, at width: 100% of this wrapper, then always spans
   exactly as wide as the transport itself, chart-width included. */
.replay-transport {
  width: calc((100% - 2 * 1.5rem) / 3);
  margin: 0 auto 1.5rem;
}

.replay-controls {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.replay-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  background: #fff;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.replay-button svg {
  fill: currentColor;
}

.replay-button:not(:disabled):hover {
  border-color: var(--accent);
  color: var(--accent);
}

.replay-button:disabled {
  opacity: 0.35;
  cursor: default;
}

/* The window lengths to pick from, where a page offers them: after the
   replay buttons in their one row, a small segmented group, the one on show
   marked. Where the transport is too narrow for both at full size (a phone's
   pinned bar, a narrow desktop column), the replay buttons narrow down to
   make room rather than the row wrapping or running wider than the
   transport; the presets keep their size, their labels being text. */
.replay-controls .replay-button {
  flex: 0 1 2.25rem;
  min-width: 1.5rem;
}

.replay-window {
  display: inline-flex;
  flex-shrink: 0;
  margin-left: 0.25rem;
}

.replay-window-button {
  height: 2.25rem;
  padding: 0 0.45rem;
  background: #fff;
  color: var(--muted);
  border: 1px solid var(--border);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.replay-window-button + .replay-window-button {
  margin-left: -1px;
}

.replay-window-button:first-child {
  border-radius: 6px 0 0 6px;
}

.replay-window-button:last-child {
  border-radius: 0 6px 6px 0;
}

.replay-window-button:hover {
  position: relative;
  border-color: var(--accent);
  color: var(--accent);
}

.replay-window-button[aria-pressed="true"] {
  position: relative;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.replay-window-button:focus-visible {
  position: relative;
  z-index: 1;
}

/* The scrubber spans the whole timeline. The band is the window the
   charts show (drag it to pan), the handle is the playhead inside it (drag
   it to scrub), and the fill is the part of the window drawn so far.
   pastCharts.ts positions all three on every change; the values here are
   only starting values. Same touch-action treatment as cumulative-flow-diagram's own
   scrubber. */
.replay-scrubber {
  position: relative;
  height: 1rem;
  cursor: pointer;
  touch-action: none;
}

.replay-scrubber-dragging,
.replay-scrubber-dragging .replay-scrubber-band,
.replay-scrubber-dragging .replay-scrubber-handle {
  cursor: grabbing;
}

/* No lag while actively dragging -- the band/fill/handle should track the
   pointer 1:1, not ease toward it a beat behind. The transition stays for
   every other move (a button click or a play tick), where a little motion
   reads as "something changed" rather than as input lag. */
.replay-scrubber-dragging .replay-scrubber-band,
.replay-scrubber-dragging .replay-scrubber-fill,
.replay-scrubber-dragging .replay-scrubber-handle {
  transition: none;
}

.replay-scrubber-track {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 6px;
  border-radius: 999px;
  background: var(--border);
  transform: translateY(-50%);
}

.replay-scrubber-band {
  position: absolute;
  top: 50%;
  left: 66%;
  width: 34%;
  height: 14px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text) 14%, transparent);
  transform: translateY(-50%);
  cursor: grab;
  transition: left 0.15s, width 0.15s;
}

.replay-scrubber-fill {
  position: absolute;
  top: 50%;
  left: 66%;
  width: 34%;
  height: 6px;
  border-radius: 999px;
  background: var(--text);
  transform: translateY(-50%);
  transition: left 0.15s, width 0.15s;
}

.replay-scrubber-handle {
  position: absolute;
  top: 50%;
  left: 100%;
  width: 16px;
  height: 16px;
  margin-left: -8px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--text);
  transform: translateY(-50%);
  cursor: grab;
  transition: left 0.15s;
}

/* Chart basics shared by all three panels. own-data.css's
   .scatter-dot-size repeats this width, and own-data's wide-screen chart
   width, to size the present's and Estimates' dots by the scatter plot's: change them
   together. */
.chart {
  width: 100%;
  max-width: 400px;
  height: auto;
}

.chart .axis {
  stroke: var(--border);
  stroke-width: 1;
}

.chart .tick {
  stroke: var(--border);
  stroke-width: 1;
}

.chart .tick-label {
  fill: var(--muted);
  font-size: 8px;
  text-anchor: middle;
}

.chart .tick-label-y {
  text-anchor: end;
}

.chart .axis-label {
  fill: var(--muted);
  font-size: 9px;
  text-anchor: middle;
}

.chart .legend-label {
  fill: var(--muted);
  font-size: 8px;
}

/* Cumulative flow diagram: three cumulative boundary lines with translucent
   fills between them, matching the style of the team's own real dashboard
   tool -- a full bounding box and horizontal gridlines rather than just a
   pair of axes, since that's how that tool frames its own charts too. */
.chart .cfd-border {
  fill: none;
  stroke: var(--border);
  stroke-width: 1;
}

.chart .cfd-gridline {
  stroke: var(--border);
  stroke-width: 1;
}

.chart .cfd-line {
  fill: none;
  stroke-width: 1.75;
}

/* The phase colours are variables in ../styles.css, Done's being --accent. */
.chart .cfd-line-todo {
  stroke: var(--phase-todo);
}

.chart .cfd-line-doing {
  stroke: var(--phase-doing);
}

.chart .cfd-line-done {
  stroke: var(--accent);
}

.chart .cfd-fill {
  stroke: none;
}

.chart .cfd-fill-doing {
  fill: var(--phase-doing);
  fill-opacity: 0.18;
}

.chart .cfd-fill-done {
  fill: var(--accent);
  fill-opacity: 0.18;
}

/* The CFD with its states shown: each state's band a shade of its phase's
   colour, set by pastCharts.ts, a little stronger than a phase's fill so
   neighbouring shades still read apart. The lines between states of one
   phase are thinner than the lines between phases. */
.chart .cfd-fill-shaded {
  fill-opacity: 0.3;
}

.chart .cfd-line-inner {
  stroke-width: 0.75;
}

/* The CFD's legend grouped by phase: each column's heading names its phase. */
.chart .legend-heading {
  fill: var(--text);
  font-weight: 600;
}

/* The CFD's "Show states" switch, to the right of its heading, outside the
   chart. Placed over the heading's line rather than beside it in the flow,
   so the CFD's heading stays as tall as the other two charts' and the three
   plot areas still line up. */
.chart-panel {
  position: relative;
}

.cfd-state-switch {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  height: 1.5rem;
  padding: 0;
  border: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}

.cfd-state-switch:focus {
  outline: none;
}

/* The sentences a page puts under the CFD, below its month labels, each in
   a CFD line's colour set inline. Under the chart, so the three plot areas
   above still line up; they wrap within the chart's width. */
.cfd-notes {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.cfd-note + .cfd-note {
  margin-top: 0.25rem;
}

.cfd-state-switch:focus-visible .cfd-state-switch-track {
  outline: 2px solid var(--accent-dark);
  outline-offset: 1px;
}

.cfd-state-switch-track {
  position: relative;
  width: 1.75rem;
  height: 1rem;
  border-radius: 0.5rem;
  background: var(--border);
  transition: background 0.15s;
}

.cfd-state-switch[aria-checked="true"] .cfd-state-switch-track {
  background: var(--accent);
}

.cfd-state-switch-knob {
  position: absolute;
  top: 0.125rem;
  left: 0.125rem;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  background: #fff;
  transition: left 0.15s;
}

.cfd-state-switch[aria-checked="true"] .cfd-state-switch-knob {
  left: 0.875rem;
}

/* Card markers: one card's own history traced across the boundary lines on
   hover -- same styling as cumulative-flow-diagram.css's own card markers. */
.chart .card-marker-circle {
  fill: none;
  stroke: var(--accent-dark);
  stroke-width: 1.75;
}

.chart .card-marker-arrow {
  stroke: var(--accent-dark);
  stroke-width: 1.5;
}

.chart .card-marker-arrowhead {
  fill: var(--accent-dark);
}

/* A white halo (paint-order + stroke) keeps each arrow's duration legible
   over any line or fill it happens to cross. */
.chart .card-marker-label {
  fill: var(--accent-dark);
  font-size: 7.5px;
  font-weight: 600;
  paint-order: stroke;
  stroke: #fff;
  stroke-width: 2.5px;
  stroke-linejoin: round;
}

.chart .legend-swatch-todo {
  stroke: var(--phase-todo);
}

.chart .legend-swatch-doing {
  stroke: var(--phase-doing);
}

.chart .legend-swatch-done {
  stroke: var(--accent);
}

.chart .legend-swatch {
  stroke-width: 2;
}

/* Each dot in the colour of the CFD line its phase sits under: a finished
   item's in Done's blue, a still-in-Doing item's in Doing's orange, so the
   two charts read as the same phases rather than introducing unrelated
   colours. */
.chart .dot.frozen {
  fill: var(--accent);
  fill-opacity: 1;
  stroke: none;
  cursor: pointer;
}

.chart .dot.active {
  fill: var(--phase-doing);
  fill-opacity: 1;
  stroke: none;
  cursor: pointer;
}

/* Translucent, so where dots stack the colour reads darker and a partial
   overlap shows too. The pointed-at dot is drawn whole. */
.chart.translucent-dots .dot.frozen,
.chart.translucent-dots .dot.active {
  fill-opacity: 0.5;
}

.chart .dot.highlighted,
.chart.translucent-dots .dot.highlighted {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(1.6);
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.35));
  fill-opacity: 1;
}

/* Pointing at a histogram bar dims the dots of longer buckets on the
   scatter plot, rather than highlighting the covered ones -- those dots
   already read as the normal, undimmed color, so where they land in time
   stands out by everything else fading back instead. */
.chart .dot.dimmed,
.chart.translucent-dots .dot.dimmed {
  fill-opacity: 0.2;
}

/* While a replay plays or its scrubber is dragged, dots can't be pointed at. */
.chart.pointing-off .dot,
.chart.pointing-off .dot-link {
  pointer-events: none;
  cursor: default;
}

/* A pile's list: the same quiet chip as a dot's title, a line per dot. */
.chart .pile-list-bg {
  fill: rgba(255, 255, 255, 0.94);
  stroke: var(--border);
  stroke-width: 1;
}

.chart .pile-count,
.chart .pile-row-text {
  fill: var(--text);
  font-size: 7.5px;
}

.chart .pile-count {
  fill: var(--muted);
  font-weight: 600;
}

.chart .pile-row {
  cursor: pointer;
}

.chart .pile-row-bg {
  fill: transparent;
}

.chart .pile-row:hover .pile-row-bg {
  fill: #e6f6ff;
}

/* A row with no address to open isn't a link. */
.chart a.pile-row:not([href]) {
  cursor: default;
}

/* Dotted guide lines from a highlighted dot to both axes, plus the pill tag
   on the y-axis carrying that dot's own value -- same styling as
   cycle-time-scatter-plot.css, so a hovered dot here reads the same way. */
.chart .guide {
  stroke: var(--muted);
  stroke-width: 1;
  stroke-dasharray: 2 2;
}

.chart .guide-tag-bg {
  fill: #e6f6ff;
}

.chart .guide-tag-text {
  fill: var(--accent);
  font-size: 8px;
  font-weight: 700;
}

.chart .guide-tag.frozen .guide-tag-bg {
  fill: var(--accent-dark);
}

.chart .guide-tag.frozen .guide-tag-text {
  fill: #fff;
}

/* Cycle time histogram bars. */
.chart .histogram-bar {
  fill: var(--accent);
  fill-opacity: 0.75;
}

/* Pointing at a bar dims the longer buckets' bars, the same treatment their
   dots get on the scatter plot above. */
.chart .histogram-bar.dimmed {
  fill-opacity: 0.2;
}

/* The line across the bars a pointed-at bar covers, labeled with how many
   finished within it -- the Monte Carlo page's promise line. A white halo
   keeps the label legible over any gridline or line it sits on. Scoped to
   the histogram: the forecast fan has a .forecast-line of its own. */
[data-histogram-chart] .forecast-line {
  stroke: var(--accent-dark);
  stroke-width: 1.5;
}

[data-histogram-chart] .forecast-line-label {
  fill: var(--accent-dark);
  font-size: 8px;
  font-weight: 700;
  paint-order: stroke;
  stroke: #fff;
  stroke-width: 2.5px;
  stroke-linejoin: round;
}

.chart .histogram-percent-label {
  fill: var(--accent-dark);
  font-size: 9px;
  font-weight: 700;
  text-anchor: middle;
}

/* p50/p85/p95 reference lines on the scatter plot and histogram: a fixed
   backdrop rather than a hover effect, so a muted dashed stroke distinct
   from the accent-colored hover .guide. */
.chart .reference-line {
  stroke: var(--muted);
  stroke-width: 1;
  stroke-dasharray: 3 2;
}

/* A white halo (paint-order + stroke) keeps a label legible where a dot or
   bar happens to sit right behind it. */
.chart .reference-line-label {
  fill: var(--muted);
  font-size: 7.5px;
  font-weight: 600;
  paint-order: stroke;
  stroke: #fff;
  stroke-width: 2.5px;
  stroke-linejoin: round;
}

/* CFD hover: dotted, not dashed -- reads distinctly from the solid boundary
   lines and stays visible crossing the Done fill, same reasoning as
   cumulative-flow-diagram.css's own hover-line. mix-blend-mode inverts
   against whatever it's drawn over instead of needing a fixed color that
   would wash out against the translucent fills here. */
.chart .hover-line {
  stroke: #fff;
  stroke-width: 1.25;
  stroke-dasharray: 1 2;
  mix-blend-mode: difference;
}

/* A quiet, near-white chip regardless of which band it sits over -- reads as
   a label sitting on top of the chart, not a badge shouting over it. Same
   as cumulative-flow-diagram.css's own band-tag styling. */
.chart .band-tag-bg {
  fill: rgba(255, 255, 255, 0.82);
}

.chart .band-tag-text {
  fill: var(--text);
  font-size: 7.5px;
  font-weight: 500;
}

/* Joins a tag pushed away from a thin band back to it. */
.chart .band-tag-leader {
  stroke: var(--muted);
  stroke-width: 0.75;
}

/* The scatter plot's own title tooltip gets a border on top of the shared
   band-tag chip styling above -- it can land over a dense cluster of dots,
   and a border keeps its edge legible there instead of just the fill. */
.chart .title-tag .band-tag-bg {
  stroke: var(--border);
  stroke-width: 1;
}

@media (max-width: 1024px) {
  .charts-row {
    grid-template-columns: 1fr;
  }

  /* Matches .charts-row's own single-column collapse above -- a chart
     panel is the full column width here, not a third of it, so the
     transport sized to match one should be too. Same 400px cap as
     .chart's own, since a chart itself doesn't stretch past that even in
     a full-width column. position: sticky, not fixed -- scoped to
     .charts-and-transport (the page's own wrapper), not the whole page,
     so it stays pinned to the bottom of the screen while scrolling
     through the charts, then releases back into normal in-flow position
     exactly where that wrapper ends, right as whatever follows begins,
     instead of staying stuck in front of it for the rest of the
     page. Centering stays the same margin: 0 auto already in normal flow
     uses -- sticky keeps an element's own horizontal position, only the
     vertical offset is special, so no left/right centering trick is
     needed the way position: fixed would require. The env() term adds
     clearance for a phone's own home-indicator/safe-area inset, so the
     bar doesn't sit flush under it while stuck. */
  .replay-transport {
    width: 100%;
    max-width: 400px;
    position: sticky;
    bottom: 0;
    margin: 0 auto;
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
    background: var(--bg-alt);
    border-top: 1px solid var(--border);
    z-index: 50;
  }
}
