/* SouthPing — the dashboard, /dashboard/ and /ru/dashboard/.
 *
 * Loaded by that route alone, so the shared stylesheet carries none of it
 * and no other page pays for it. Built on site.css's tokens.
 *
 * Kind colours are the data-viz reference palette's first three slots,
 * validated as a set in all pairs on a light surface (2026-11-05): worst
 * colour-blind separation ΔE 9.2, worst normal-vision ΔE 24.0 [C]. The aqua
 * sits under 3:1 against white, which is why every marker is also a shape
 * and a name, and every chart has a table. Status colours are reserved for
 * status and always come with a word.
 */

.board {
  --measure: 80rem;
  --k-sea: #2a78d6;
  --k-land: #1baf7a;
  --k-bench: #eb6834;
  --k-other: #5a6675;
  --critical: #d03b3b;
  --critical-ink: #9b2318;
  --critical-wash: #fde8e6;
  --warning-ink: #7a5500;
  --warning-mark: #b07d00;
  --warning-wash: #fff4d6;
  --flag: #9aa3ad;
  --sea: #dfeaf1;
  --land: #e5e0d2;
  --ice: #f8fafc;
  --space: #f4f6f8;
}

.k-sea { --kc: var(--k-sea); }
.k-land { --kc: var(--k-land); }
.k-bench { --kc: var(--k-bench); }
.k-other { --kc: var(--k-other); }

.board h1 {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--navy);
  line-height: 1.15;
}

.board-lede {
  color: #3c4654;
  font-size: 0.9375rem;
  margin: 0.35rem 0 1rem;
  max-width: 48rem;
}

.board-note, .board-app > .board-status { font-size: 0.875rem; color: var(--muted); }

/* ---------- the bar: view and probe, one row above everything they scope */

.board-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.seg {
  display: inline-flex;
  border: 1px solid var(--navy);
  border-radius: 0.375rem;
  overflow: hidden;
}

.seg-btn {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--navy);
  background: #fff;
  border: 0;
  padding: 0.35rem 0.9rem;
  cursor: pointer;
}

.seg-btn + .seg-btn { border-left: 1px solid var(--navy); }
.seg-btn[aria-pressed="true"] { background: var(--navy); color: #fff; }

.board-pick {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  max-width: 100%;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--navy);
}

#board-probe {
  font: inherit;
  font-size: 0.875rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 0.375rem;
  background: #fff;
  max-width: 100%;
  min-width: 0;
}

.board .board-status {
  font-size: 0.8125rem;
  color: var(--muted);
  margin: 0.5rem 0 1rem;
}

button:focus-visible, select:focus-visible, input:focus-visible, summary:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

/* ---------- layout */

.board-main { display: grid; gap: 1rem; }
.board-mapcol { min-width: 0; }
.board-cards { display: grid; gap: 0.75rem; align-content: start; min-width: 0; }

@media (min-width: 40rem) {
  .board-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 60rem) {
  .board-main { grid-template-columns: minmax(0, 2fr) minmax(17rem, 1fr); align-items: start; }
  .board-cards { grid-template-columns: minmax(0, 1fr); }
  /* the map stays in view while the cards beside it scroll */
  .board-mapcol { position: sticky; top: 1rem; }
}

/* The dashboard's column is wider than the site's; the site's own rule,
   (100% - measure) / 2, reaches zero at 80rem and would leave the map
   touching the window's edges, so the gutter is its floor. */
@media (min-width: 75rem) {
  main > section.board {
    padding-left: max(var(--gutter), calc((100% - var(--measure)) / 2));
    padding-right: max(var(--gutter), calc((100% - var(--measure)) / 2));
  }
}

/* ---------- the map */

.map {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--space);
}

.map-svg {
  display: block;
  width: 100%;
  height: 22rem;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: grab;
}

.map-svg:active { cursor: grabbing; }

@media (min-width: 48rem) {
  .map-svg { height: 34rem; }
}

.map-space { fill: var(--space); }
.map-sea { fill: var(--sea); }
.map-land { fill: var(--land); }
.map-ice { fill: var(--ice); stroke: #c9d3dc; stroke-width: 0.6; }

.map-grat-line { fill: none; stroke: #fff; stroke-width: 1; opacity: 0.7; }
.map-grat-label {
  font-size: 10px;
  fill: var(--muted);
  paint-order: stroke;
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 3px;
  stroke-linejoin: round;
  pointer-events: none;
}

.map-place {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  fill: #77705f;
  paint-order: stroke;
  stroke: var(--land);
  stroke-width: 3px;
  pointer-events: none;
}

.map-place-sea {
  font-size: 12px;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.03em;
  text-transform: none;
  fill: #4f6e83;
  stroke: var(--sea);
}

.map-track {
  fill: none;
  stroke: var(--kc);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  opacity: 0.9;
}

.map-track-gap { stroke-dasharray: 4 5; opacity: 0.65; }
.map-track-start { fill: #fff; stroke: var(--kc); stroke-width: 2; }

/* A gateway estimate is its error circle, dashed and washed, never a
   filled mark: it must not look like a fix (contract §6, anti-goals). */
.map-cep {
  fill: var(--kc);
  fill-opacity: 0.08;
  stroke: var(--kc);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
}

.map-cep-centre { fill: none; stroke: var(--kc); stroke-width: 1.5; stroke-linecap: round; }

.mk { stroke-width: 2; stroke-linejoin: round; }
.mk-fix { fill: var(--kc); stroke: #fff; }
.mk-gateway { fill: #fff; stroke: var(--kc); stroke-dasharray: 3 2.5; }
.mk-site { fill: #fff; stroke: var(--kc); stroke-dasharray: 1.5 2.2; }
.mk-hit { fill: transparent; }
.mk-alarm { fill: var(--critical); stroke: #fff; stroke-width: 1.5; }

.map-probe, .map-offscreen { cursor: pointer; }
.map-probe.is-selected .mk-fix { stroke: var(--navy); }

/* Overdue: faded and dashed, and the label says so in words. */
.is-overdue .mk { opacity: 0.45; }
.is-overdue .mk-fix { stroke: var(--kc); stroke-dasharray: 2 2; fill-opacity: 0.6; }

.mk-label {
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink);
  paint-order: stroke;
  stroke: #fff;
  stroke-width: 3px;
  stroke-linejoin: round;
}

.map-chevron { fill: var(--kc); stroke: #fff; stroke-width: 1.5; }

.map-scale-bar { fill: none; stroke: var(--ink); stroke-width: 1.5; }
.map-scale-label {
  font-size: 11px;
  fill: var(--ink);
  paint-order: stroke;
  stroke: #fff;
  stroke-width: 3px;
}

.map-tools {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
}

.map-btn {
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--navy);
  background: #fff;
  border: 1px solid #cfd6de;
  border-radius: 0.375rem;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.5rem;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(24, 32, 44, 0.12);
}

.map-btn:hover { border-color: var(--navy); }

.map-stamp {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  max-width: calc(100% - 9rem);
  font-size: 0.875rem;
  font-weight: 800;
  color: var(--navy);
  background: rgba(255, 255, 255, 0.92);
  border-radius: 0.25rem;
  padding: 0.2rem 0.5rem;
  pointer-events: none;
}

.map-credit {
  position: absolute;
  right: 0.4rem;
  bottom: 0.3rem;
  font-size: 0.6875rem;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.75);
  border-radius: 0.2rem;
  padding: 0 0.3rem;
  pointer-events: none;
}

.map-views {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var(--muted);
}

.map-views .map-btn { box-shadow: none; }

.map-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var(--muted);
}

.map-legend li { display: flex; align-items: center; gap: 0.35rem; }
.legend-mark { flex: none; overflow: visible; }

/* ---------- the cards */

.card {
  min-width: 0;
  background: #fff;
  border: 1px solid var(--rule);
  border-top: 0.25rem solid var(--kc);
  border-radius: 0.375rem;
  padding: 0.75rem 0.9rem;
}

.card.is-overdue { border-top-style: dashed; background: #fafbfc; }
.card.is-selected { border-color: var(--kc); }

.card-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.45rem; }
.card-head h3 { font-size: 1.0625rem; font-weight: 800; color: var(--navy); }
.card-mark { flex: none; overflow: visible; }
.card-kind { font-size: 0.8125rem; color: var(--muted); }

.card-state {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid #c5ccd4;
  border-radius: 0.2rem;
  padding: 0 0.3rem;
}

.card-age { font-size: 0.875rem; margin-top: 0.35rem; overflow-wrap: anywhere; }

.badge {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 800;
  border-radius: 0.2rem;
  padding: 0.05rem 0.4rem;
  margin-left: 0.35rem;
  background: var(--paper);
  color: var(--muted);
}

.badge-overdue { background: var(--critical-wash); color: var(--critical-ink); }
.badge-overdue::before, .hl-alarm::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  margin-right: 0.3rem;
  vertical-align: 0.05rem;
}

.card-cadence { font-size: 0.75rem; color: var(--muted); margin-top: 0.15rem; }
.card-when { font-size: 0.75rem; color: var(--muted); margin-top: 0.55rem; }

.card-readings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.2rem 0.75rem;
  margin-top: 0.15rem;
}

.rd { min-width: 0; }
.rd dt { font-size: 0.75rem; color: var(--muted); }
.rd dd { font-size: 0.9375rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rd.is-flagged dd { color: #6b7480; }
.rd-none { font-weight: 400; color: var(--muted); }

/* A flagged value: greyed and named, never hidden (contract §5). */
.qc-tag {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #4d5866;
  background: #eef1f4;
  border: 1px solid #c5ccd4;
  border-radius: 0.2rem;
  padding: 0 0.25rem;
  margin-left: 0.3rem;
  vertical-align: 0.05rem;
}

.card-where { font-size: 0.8125rem; color: #3c4654; margin-top: 0.5rem; overflow-wrap: anywhere; }
.card-where.is-flagged { color: #6b7480; }

.card-health { list-style: none; display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.5rem; }
.card-health li {
  font-size: 0.75rem;
  border-radius: 0.2rem;
  padding: 0.1rem 0.4rem;
  background: var(--paper);
  color: #3c4654;
}

.card-health .hl-alarm { background: var(--critical-wash); color: var(--critical-ink); font-weight: 800; }
.card-health .hl-warn { background: var(--warning-wash); color: var(--warning-ink); font-weight: 700; }
.hl-warn::before {
  content: "";
  display: inline-block;
  width: 0.55rem;
  height: 0.5rem;
  background: currentColor;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  margin-right: 0.3rem;
}

.card-unknown { font-size: 0.75rem; color: var(--muted); margin-top: 0.35rem; }

.card-pick {
  margin-top: 0.65rem;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--navy);
  background: #fff;
  border: 1px solid var(--navy);
  border-radius: 0.25rem;
  padding: 0.25rem 0.6rem;
  cursor: pointer;
}

.card-pick[aria-pressed="true"] { background: var(--navy); color: #fff; }

/* ---------- the replay */

.replay {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding: 0.75rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 0.5rem;
}

.replay[hidden] { display: none; }

.replay-range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--navy);
}

.replay-range input, .replay-speed {
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--ink);
  background: #fff;
  border: 1px solid #cfd6de;
  border-radius: 0.25rem;
  padding: 0.2rem 0.35rem;
  min-width: 0;
  max-width: 100%;
}

.replay-utc { font-weight: 400; color: var(--muted); }
.replay-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }

.replay-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--navy);
  background: #fff;
  border: 1px solid #cfd6de;
  border-radius: 0.25rem;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
}

.replay-play[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.icon { flex: none; fill: currentColor; }

.replay-time {
  margin-left: auto;
  font-size: 0.875rem;
  font-weight: 800;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.replay-slider { width: 100%; accent-color: var(--navy); }

/* ---------- one probe */

.board-detail:empty { display: none; }

.detail {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}

.detail h2 { font-size: 1.375rem; font-weight: 800; color: var(--navy); }

.detail h3 {
  margin-top: 1.25rem;
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
}

.detail-meta { font-size: 0.875rem; color: var(--muted); margin-top: 0.25rem; }

.readout {
  min-height: 1.9rem;
  margin: 0.5rem 0;
  padding: 0.35rem 0.6rem;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  background: var(--paper);
  border-radius: 0.25rem;
  overflow-wrap: anywhere;
}

.charts { display: grid; gap: 1rem 16px; }
.charts.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.charts-health { margin-top: 0.75rem; }

.chart { min-width: 0; }
.chart-title { font-size: 0.8125rem; font-weight: 700; margin-bottom: 0.15rem; }
.chart-svg { display: block; width: 100%; height: auto; overflow: visible; }
.chart-svg:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.chart-grid line { stroke: var(--rule); stroke-width: 1; }
.chart-ytick, .chart-xtick { font-size: 10.5px; fill: var(--muted); font-variant-numeric: tabular-nums; }

.chart-line {
  fill: none;
  stroke: var(--kc);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.chart-flag { fill: var(--flag); stroke: #fff; stroke-width: 2; }
.chart-hover { stroke: var(--ink); stroke-width: 1; opacity: 0.45; }
.chart-cursor { stroke: var(--navy); stroke-width: 1.5; }
.chart-dot { fill: var(--kc); stroke: #fff; stroke-width: 2; }
.chart-dot.is-flagged { fill: var(--flag); }
.chart-hit { fill: transparent; cursor: crosshair; }

.chart-empty {
  font-size: 0.8125rem;
  color: var(--muted);
  border: 1px dashed #cfd6de;
  border-radius: 0.25rem;
  padding: 0.75rem;
}

.lane-rule { stroke: var(--rule); stroke-width: 1; }
.lane-msg { stroke: var(--kc); stroke-width: 2; stroke-linecap: round; }
.lane-msg.is-backlog { stroke-width: 3.5; }
.lane-failed { fill: var(--warning-mark); }
.lane-unknown { font-size: 10.5px; font-style: italic; fill: var(--muted); }

.glyph-leak { fill: var(--critical); }
.glyph-reset { fill: var(--warning-mark); }
.glyph-nofix { fill: #fff; stroke: var(--ink); stroke-width: 1.2; }
.glyph-cold { fill: var(--navy); }
.glyph-sensor { fill: #fff; stroke: var(--critical); stroke-width: 1.5; }

.chart-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  margin-top: 0.3rem;
  font-size: 0.75rem;
  color: var(--muted);
}

.glyph {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  margin-right: 0.3rem;
  border-radius: 50%;
  vertical-align: -0.05rem;
  box-sizing: border-box;
}

.glyph.glyph-backlog { width: 0.2rem; height: 0.8rem; border-radius: 0.1rem; background: var(--k-other); vertical-align: -0.15rem; }
.glyph.glyph-leak { background: var(--critical); }
.glyph.glyph-reset { background: var(--warning-mark); border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.glyph.glyph-nofix { background: #fff; border: 1.5px solid var(--ink); }
.glyph.glyph-cold { background: var(--navy); }
.glyph.glyph-sensor { background: #fff; border: 2px solid var(--critical); }

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.stat { border: 1px solid var(--rule); border-radius: 0.25rem; padding: 0.4rem 0.6rem; min-width: 0; }
.stat dt { font-size: 0.75rem; color: var(--muted); }
.stat dd { font-size: 1.125rem; font-weight: 800; color: var(--navy); }

/* The table twins: every value on the charts, reachable without a pointer.
   They scroll inside their own box, which guard 9 reports apart. */
.twin { margin-top: 1rem; }
.twin summary { cursor: pointer; font-size: 0.875rem; font-weight: 700; color: var(--navy); }

.twin-scroll {
  max-height: 24rem;
  overflow: auto;
  margin-top: 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 0.25rem;
}

.twin table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.twin th, .twin td { text-align: left; padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--rule); white-space: nowrap; }
.twin thead th { position: sticky; top: 0; background: #fff; color: var(--navy); }
.twin tbody th { font-weight: 400; }
.twin td.is-flagged { color: #6b7480; }

/* ---------- no data yet */

.board-empty {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 0.25rem solid var(--yellow);
  border-radius: 0.375rem;
  padding: 1rem 1.25rem;
}

.board-empty h2 { font-size: 1.25rem; font-weight: 800; color: var(--navy); }
.board-empty p { margin-top: 0.4rem; color: #3c4654; }
.board-empty h3 { margin-top: 0.9rem; font-size: 0.875rem; color: var(--navy); }
.board-empty-list { margin: 0.3rem 0 0 1.1rem; font-size: 0.9375rem; }

@media (min-width: 48rem) {
  .board h1 { font-size: 2.25rem; }
}

.map-legend .legend-note { flex-basis: 100%; font-size: 0.75rem; }

/* ---------- the demonstration banner, over everything while the data is
   not the probes' own (the lead, 2026-11-05) */

.board-demo {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.6rem 1rem;
  margin-bottom: 1.25rem;
  padding: 1rem 1.25rem;
  color: var(--navy-deep);
  background: var(--yellow);
  border: 2px solid var(--yellow-dark);
  border-radius: 0.5rem;
}

.board-demo-tag {
  flex: none;
  font-size: 0.875rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--yellow);
  background: var(--navy-deep);
  border-radius: 0.25rem;
  padding: 0.3rem 0.65rem;
}

.board-demo-text { flex: 1 1 16rem; min-width: 0; }
.board-demo-head { font-size: 1.25rem; font-weight: 800; line-height: 1.25; }
.board-demo-body { font-size: 0.9375rem; margin-top: 0.3rem; }

@media (min-width: 48rem) {
  .board-demo-head { font-size: 1.5rem; }
}
