/* ATM-Bench-Hard price-performance chart.
   Shared by index.html and leaderboard.html; paired with static/js/price_perf.js.
   Relies on the page-level tokens --ink, --muted, --line and --panel-shadow,
   which both pages define identically in :root.

   --pp-c1..c9 are chart series colors, NOT page accents. The page has five
   accents and this chart draws nine models at once, so a hue would have to
   serve two models. The first seven were validated against the card surface
   (#fdfbf8) on the adjacent pairlist: worst colour-vision-deficiency separation
   dE 9.1, worst normal-vision dE 19.6, both above their floors. Legend order is
   palette order — reordering series without re-validating can introduce an
   unchecked pair. Five slots sit under 3:1 contrast against the surface, which
   is allowed only because every series carries a direct label.

   --pp-c8 (brown) and --pp-c9 (near-black) were added 2026-08-23 for the Gemini
   3.7 Flash and Qwen3.8-27B ladders, and the check follows the precedent set
   for --ppf-c7 below: the original validator is not in the repo and
   tools/palette_validator.py does not reproduce the 9.1/19.6 figures above, so
   those numbers are NOT comparable to anything measured now. What one
   consistent method does establish is the part an addition can affect. Measured
   on the adjacent pairlist this palette actually uses, the seven-colour worst
   case is CVD dE 4.21 (#eda100 vs #e87ba4, tritan) and normal dE 43.16; adding
   these two leaves both EXACTLY there — neither new hue is ever the limiting
   pair. The worst pair involving a new colour is dE 14.56 (#008300 vs #795548
   under deutan), 3.5x the existing floor. Both also clear the neutral grey
   --pp-c0 used for single-configuration diamonds (dE 18.6 and 25.5) so a line
   marker never reads as a diamond. Contrast vs surface: 6.34 and 12.23.
   Re-measure the same way before adding a tenth:
     python3 tools/palette_validator.py  (all-pairs — the scatter's test)
   with the adjacent-pair variant described here for this chart. */

.pp-wrap {
  border-radius: 14px;
  border: 1px solid rgba(31, 36, 48, 0.10);
  background: rgba(255, 255, 255, 0.96);
  padding: 1rem 1.1rem 0.9rem;
  --pp-c1: #2a78d6; --pp-c2: #eb6834; --pp-c3: #1baf7a; --pp-c4: #eda100;
  --pp-c5: #e87ba4; --pp-c6: #008300; --pp-c7: #4a3aa7; --pp-c8: #795548;
  --pp-c9: #333333; --pp-c0: #7d7a72;
  --pp-surface: #fdfbf8;
}

.pp-title { text-align: center; margin-bottom: 0.75rem; }

.pp-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  align-items: center;
  margin-bottom: 0.35rem;
}

.pp-lgi {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  padding: 0.15rem 0.45rem;
  border-radius: 7px;
}

.pp-lgi:hover { background: rgba(31, 36, 48, 0.05); color: var(--ink); }
.pp-lgi[data-off="1"] { opacity: 0.34; }
.pp-lgi .pp-key { width: 26px; height: 12px; flex: none; }

.pp-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  align-items: center;
  margin: 0.5rem 0 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
  font-size: 0.76rem;
  color: var(--muted);
}

.pp-sub .pp-item { display: inline-flex; align-items: center; gap: 0.4rem; white-space: nowrap; }
.pp-sizes { display: inline-flex; align-items: flex-end; gap: 3px; }

.pp-plot { position: relative; }
.pp-plot svg { display: block; width: 100%; height: auto; overflow: hidden; }

.pp-grid line { stroke: rgba(31, 36, 48, 0.08); stroke-width: 1; shape-rendering: crispEdges; }
.pp-axis line { stroke: var(--line); stroke-width: 1; }
.pp-axis text { fill: var(--muted); font-size: 12px; }
.pp-axis-title { fill: var(--ink); font-size: 13px; font-weight: 700; }
.pp-curve { fill: none; stroke-width: 2.8; stroke-linejoin: round; stroke-linecap: round; }
.pp-mark { cursor: pointer; }
.pp-faded { opacity: 0.12; }

.pp-tier {
  font-size: 10.5px; font-weight: 600; pointer-events: none; fill: var(--muted);
  paint-order: stroke fill; stroke: var(--pp-surface); stroke-width: 3.5; stroke-linejoin: round;
}

.pp-name {
  font-size: 12.5px; font-weight: 700; pointer-events: none;
  paint-order: stroke fill; stroke: var(--pp-surface); stroke-width: 4; stroke-linejoin: round;
}

.pp-dot-name {
  font-size: 11.5px; font-weight: 700; pointer-events: none; fill: var(--ink);
  paint-order: stroke fill; stroke: var(--pp-surface); stroke-width: 4; stroke-linejoin: round;
}

/* max-width matters: the tooltip is absolutely positioned with an inline `left`,
   and a hidden one still contributes to the page's scrollable width. Paired with
   hide() clearing that inline position, it can never widen the page. */
.pp-tip {
  position: absolute; pointer-events: none; opacity: 0; transition: opacity 0.1s;
  background: #fffdfa; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--panel-shadow); padding: 0.7rem 0.85rem;
  min-width: 200px; max-width: 100%; z-index: 20;
}

.pp-tip[data-show="1"] { opacity: 1; }
.pp-tip .pp-tt { font-size: 0.85rem; font-weight: 700; display: flex; align-items: center; gap: 0.45rem; }
.pp-tip .pp-tt i { width: 15px; height: 3px; border-radius: 2px; flex: none; }
.pp-tip .pp-ts { font-size: 0.72rem; color: var(--muted); margin: 0.15rem 0 0.5rem; }
.pp-tip .pp-row {
  display: flex; justify-content: space-between; gap: 1.1rem;
  font-size: 0.78rem; padding: 0.12rem 0; font-variant-numeric: tabular-nums;
}
.pp-tip .pp-row span:first-child { color: var(--muted); }
.pp-tip .pp-row span:last-child { color: var(--ink); font-weight: 700; }
.pp-tip .pp-big { font-size: 1.05rem; }

.pp-more { text-align: center; margin-top: 0.9rem; font-size: 0.92rem; }
.pp-more a { color: var(--accent-rust); font-weight: 700; }

/* --- Full scatter (leaderboard only; static/js/price_perf_full.js) ---------
   Its own palette, and it has to be: --pp-c1..c7 above were validated on the
   ADJACENT pairlist, which is all a line chart needs. Here every point can land
   beside every other, so the set below was validated over ALL pairs against
   #fdfbf8. Two slots sit under 3:1 contrast, which is allowed because the
   frontier is directly labelled, every point is hoverable, and the same numbers
   are in the table directly above.

   A seventh slot (--ppf-c7, Antigravity) was added 2026-08-06. The original
   validator was not in the repo, so the check was re-implemented from the
   description above — CIEDE2000 over all unordered pairs, under normal vision
   and under Vienot-1999 protan/deutan plus a tritan approximation. That
   re-implementation does not reproduce the dE 11.0 / 15.6 figures this comment
   previously quoted (it scores the SIX-colour set at worst-CVD 8.54, worst-
   normal 22.24), so those numbers came from a different method and the absolute
   values below are not comparable to them. What it does establish is the part
   that matters for an addition: measured on one consistent method, #7b2ff2
   leaves both worst-case pairs EXACTLY where the six-colour set already sat
   (8.54 / 22.24) — the new hue is never the limiting pair, and it clears 3:1
   contrast at 5.76. Re-measure with this same method before adding an eighth.
   Validator: tools/palette_validator.py (run it with the seven hex values). */
.ppf-wrap {
  --ppf-c1: #0072B2; --ppf-c2: #D55E00; --ppf-c3: #009E73;
  --ppf-c4: #E69F00; --ppf-c5: #56B4E9; --ppf-c6: #b0175f;
  --ppf-c7: #7b2ff2;
}

.ppf-wrap .pp-lgi .pp-key { width: 14px; height: 12px; }

.ppf-front {
  fill: none; stroke: var(--muted); stroke-width: 1.8;
  stroke-dasharray: 5 4; stroke-linejoin: round; opacity: 0.7;
}

/* Ties a frontier label back to its dot when the placer had to push it well
   clear. Deliberately fainter and thinner than .ppf-front so it never reads as
   part of the staircase. */
.ppf-leader { stroke: var(--muted); stroke-width: 1; opacity: 0.4; }

@media screen and (max-width: 640px) {
  .pp-sub .pp-item { white-space: normal; }

  /* 70 points scaled to a phone's width put the frontier labels below reading
     size. Give this chart a floor and let it scroll sideways inside its own
     box instead — the page itself still never scrolls horizontally. The
     focused chart at the top is sparse enough to keep shrinking. */
  .ppf-wrap .pp-plot { overflow-x: auto; }
  .ppf-wrap .pp-plot svg { min-width: 660px; }

  /* Same treatment, different reason: the harness chart carries five named
     agent labels across its foot, and those cannot shrink below reading size
     without colliding with each other. */
  .hx-wrap .pp-plot { overflow-x: auto; }
  .hx-wrap .pp-plot svg { min-width: 640px; }
}
