/*
 * Charts, with no charting library. A library would weigh more than the entire rest of the front
 * end and would invite chart types this data does not support: a smoothed line over a series whose
 * whole point is discontinuity, an area fill implying a quantity where there is a ratio.
 *
 * Everything with a continuous x-axis is server-rendered inline SVG. Everything that is a set of
 * magnitudes is CSS boxes with inline widths — the CSP permits inline style and blocks inline
 * script, which is exactly the right way round for this.
 */
.fig {
  margin: var(--s5) 0;
  padding: var(--s4);
}

.fig__head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-bottom: var(--s3);
}

.fig__ticker { font-size: 17px; font-weight: 600; color: var(--fg); }

.fig svg { width: 100%; height: auto; display: block; }

.fig__ground { fill: var(--panel-deep); }

/* The stall bands. Drawn first and full height: a long stall is a wide band you see before you read
   anything. Windows past the headline bar are stronger, so the six-hour threshold is visible
   without a legend. */
/*
 * ── THE STALLS MOVED OUT OF THE PLOT AND UNDER IT ───────────────────────────────────────────────
 *
 * These were full-height fills at 10% and 20% opacity. That reads as a mark while stalls are the
 * exception; measured on AAPLc they covered 77% of the frame, at which point the shading is not on
 * the chart, it IS the chart — a brown ground with a line lost in it.
 *
 * Solid, in a strip of its own, on a track that is visible when empty. Full strength because it no
 * longer sits behind anything: a stall is now the most saturated thing in the figure, which is what
 * the original full-height band was reaching for and could not have while it was translucent.
 */
.fig__ribbon-track { fill: var(--on-panel-4); fill-opacity: 0.25; }
.fig__stall { fill: var(--frozen); fill-opacity: 0.55; }
.fig__stall--long { fill-opacity: 1; }

.fig__zero { stroke: var(--fg-5); stroke-width: 1; }
.fig__guide { stroke: var(--fg-5); stroke-width: 1; stroke-dasharray: 3 4; opacity: 0.6; }

/* The alert threshold. Solid where the guides are dashed, in the breach hue, because it is the one
   horizontal here that means something outside this chart. */
.fig__alert { stroke: var(--breach); stroke-width: 1; opacity: 0.75; }

.fig__tick { fill: var(--fg-3); font: 500 10px var(--font-mono); letter-spacing: 0.08em; }

/* The line's colour reports feed state, so the state needs no legend. */
.fig__line { stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.fig__line--fresh { stroke: var(--live); }
.fig__line--stalled { stroke: var(--frozen); }

.fig__note {
  margin: var(--s3) 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--fg-2);
  max-width: var(--measure);
}

.fig__empty {
  padding: var(--s5) var(--s4);
  border: var(--hair) dashed var(--panel-rule);
  text-align: center;
}

.fig__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s3);
  align-items: center;
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: var(--hair) solid var(--panel-rule);
}

.fig__perma { color: var(--fg-3); }

/*
 * ── NARROW: A FLOOR AND A PAN, NOT A SHRINK ─────────────────────────────────────────────────────
 *
 * This block used to say "a chart gets SIMPLER at narrow widths, never smaller" and then do
 * nothing of the kind. The svg is a fixed viewBox at width:100%, so every tick label scaled down
 * with the frame: on a 390px phone the axis rendered at roughly four pixels.
 * `vector-effect="non-scaling-stroke"` protects STROKES. Nothing protects text, and raising
 * font-size does not help, because that size is in user units and scales too.
 *
 * So the plot keeps a legible floor and pans inside its own scroller. At 700px against a ~360px
 * content width the labels land near 9px instead of 4px. Same move as .well-block__body in
 * 10-base.css, which is the house pattern for content that cannot be made narrower without
 * becoming unreadable.
 */
.fig__plot { overflow-x: auto; }

@media (max-width: 720px) {
  .fig { padding: var(--s3); }
  .fig__line { stroke-width: 2.5; }
  .fig__tick { font-size: 13px; }
  .fig__plot svg { min-width: 700px; }
}

/*
 * ── THE FIGURE'S COUNTS ─────────────────────────────────────────────────────────────────────────
 *
 * Four figures on a hairline strip under the plot, in one block with it rather than in a header
 * above it. They are what the removed second series was for: the shape says WHEN the oracle was
 * silent, these say how much priced against it meanwhile.
 *
 * THE BOX IS CLOSED. It carried `border-top: 0` on the claim that it was welded to the bottom of
 * the plot — and it never was: `.fig` sets `margin: var(--s5) 0`, so the strip has always floated
 * 32px clear of the figure above it. The result was a rectangle with three sides, its left and
 * right rules running up to nothing. Either weld it or close it; closing it is the smaller change
 * and keeps the figure's own margin doing what every other block on the page relies on.
 *
 * IT WAS SIX, AND SIX READ AS A WALL. Two of them were the product's own claim stated as a
 * contrast — the average difference while the underlying market was open against the average while
 * it was closed — and a contrast set in the same type as four unrelated statistics is not read as
 * one. Those two are a sentence under the strip now, where the labels have room to say what "open"
 * and "closed" mean. They are still side by side and still never blended into one mean.
 *
 * Four divides evenly at every breakpoint, so no row is ever left with a single orphan cell.
 *
 * EVERY VALUE IS --fg. The two that used to carry --breach-ink and --frozen-ink were statistics,
 * not states: colour on a 30-day mean says a threshold was crossed when none was, and the red drew
 * the eye to the largest number rather than the relevant one.
 */
.figstats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--hair);
  background: var(--rule-soft);
  border: var(--hair) solid var(--rule-firm);
}
.figstats > div { background: var(--card); padding: 13px 15px; }
.figstats .label { display: block; margin-bottom: 6px; }
.figstats .datum { font: 500 19px/1.2 var(--font-mono); color: var(--fg); font-variant-numeric: tabular-nums; }

@media (max-width: 720px) { .figstats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/*
 * ── THE STACKED VENUE CHART ─────────────────────────────────────────────────────────────────────
 *
 * One hue stepped by lightness, not five hues. The four signal tokens each MEAN a feed state, so a
 * band borrowing one would read as a reading; and at five categorical hues an instrument turns into
 * a pie chart. Stepping --series-1..5 puts identity in POSITION rather than in colour, which is
 * what carries it through colour-blindness, greyscale print and a phone at low brightness. The
 * steps were contrast-checked against --panel-deep, which is this figure's ground in both themes.
 */
.fig__band--1 { fill: var(--series-1); }
.fig__band--2 { fill: var(--series-2); }
.fig__band--3 { fill: var(--series-3); }
.fig__band--4 { fill: var(--series-4); }
.fig__band--5 { fill: var(--series-5); }

/* The browser's own <title> hover needs no help, but a pointer cue makes it discoverable. */
.fig__band { cursor: help; }

.fig__range { color: var(--on-panel-3); font-size: 12px; margin-left: auto; }

/*
 * THE LEGEND IS NOT OPTIONAL. Identity is never colour alone, so it is always rendered for a
 * multi-series figure, and in stack order from the top band down so a reader walks it against the
 * chart rather than translating between two orders.
 *
 * It WRAPS rather than scrolling. The plot pans because its text cannot be made smaller without
 * becoming unreadable; the legend is real HTML text and reflows, so on a phone it becomes a short
 * list instead of a row that runs off the edge with the chart.
 */
.fig__legend {
  list-style: none;
  margin: var(--s3) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
}

/*
 * `min-width: 0` IS LOAD-BEARING, and its absence broke the whole page rather than this component.
 *
 * A flex item defaults to `min-width: auto`, so it refuses to shrink below its content. The
 * rolled-up band's note is a comma list of six ticker keys, which made this item about 480px wide
 * and unshrinkable. It pushed .fig wider than .container, which pushed the DOCUMENT wider than a
 * 390px viewport: every paragraph on the post clipped mid-sentence and the nav stopped wrapping.
 *
 * The plot next to it survives that because it pans inside its own scroller. This is real text and
 * has to reflow instead, so the item wraps internally and the note breaks where it must.
 */
.fig__legend-item {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  min-width: 0;
  gap: var(--s2);
  font-size: 12px;
  color: var(--on-panel-2);
}

.fig__swatch {
  width: 10px;
  height: 10px;
  flex: 0 0 auto;
  /* Square. The design has exactly one radius and it is zero, and spec/design_system_spec.rb says
     so; a rounded swatch beside square bars would also be lying about the mark it stands for. */
  /* Baseline-aligned with the label beside it rather than centred on the line box, so a wrapped
     legend keeps its swatches on the text's baseline grid. */
  transform: translateY(1px);
}

.fig__swatch--1 { background: var(--series-1); }
.fig__swatch--2 { background: var(--series-2); }
.fig__swatch--3 { background: var(--series-3); }
.fig__swatch--4 { background: var(--series-4); }
.fig__swatch--5 { background: var(--series-5); }

.fig__legend-label { font-family: var(--font-mono); letter-spacing: 0.02em; }

/* A rolled-up band names its members: "6 pools opened 3 September" is not something a reader can
   look up, and the whole point of grouping them was to avoid six unreadable slivers. */
.fig__legend-note {
  color: var(--on-panel-3);
  font-size: 11px;
  min-width: 0;
  overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  /* The stack needs less width than the divergence plot: its x-axis is 26 bars rather than 900
     path commands, and its labels are dates rather than signed basis points. */
  .fig--growth .fig__plot svg { min-width: 560px; }
  .fig__range { margin-left: 0; width: 100%; }
  .fig__head { flex-wrap: wrap; }
  .fig__legend { gap: var(--s2) var(--s3); }
}
