/* Dashboard v2 (app/dashboard.js, docs/dashboard-v2.md "Layout").
   The header with the mode switch under the title, one scope row, eight
   compact tiles, then two columns: the shot map on the left; the ranking and
   the selected summary on the right. From 900 px wide and 640 px tall the
   page fills the viewport, both columns take the height left under the tiles
   and the tables scroll inside their panels (DASH-015, 074, 135); 1024–1366 px
   (iPad browsers) keeps the columns side by side. Narrower, the columns stack.
   Every control is at least 44 CSS px (DASH-136). Colours are tokens; the
   value colours (cyan good, amber middling) follow VALUE_TONES in
   app/dashboard-model.js. */

.dash2 {
  /* The nine hex bands (DASH-043..052): four blues, neutral, four reds, a
     diverging scale that stays readable for red-green colour blindness. The
     court floor is near-black in both themes (live-court.css), so the glyphs
     read the same on it; the light-theme values only tune the legend. */
  --hex-band-1: #1f5fa8;
  --hex-band-2: #3f8fc6;
  --hex-band-3: #8cc1de;
  --hex-band-4: #cfe4f1;
  --hex-band-5: #f5f3ef;
  --hex-band-6: #fbd5c0;
  --hex-band-7: #f29e78;
  --hex-band-8: #d2563f;
  --hex-band-9: #a3122a;
  --hex-edge: color-mix(in srgb, #000 55%, transparent);
  --hex-unrated: color-mix(in srgb, var(--court-line) 80%, transparent);
  /* The court floor shade of live-court.css, behind the drawing so the court
     reads as filling its panel at any aspect ratio. */
  --dash-floor: #121110;
  --dash-accent: var(--brand-ink);
  --dash-target: 44px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 100%;
}
[data-theme="light"] .dash2,
.screen.light .dash2 {
  --hex-band-1: #1d5799;
  --hex-band-2: #3b88bf;
  --hex-band-3: #86bcda;
  --hex-band-4: #cbe1ef;
  --hex-band-5: #f7f5f1;
  --hex-band-6: #f9d0b9;
  --hex-band-7: #ef976f;
  --hex-band-8: #cc4f39;
  --hex-band-9: #9b1027;
}

/* The page gets the whole content height (the shell pads #app inline). */
.dash2 {
  container: dash / inline-size;
}
#app.content:has(.dash2) {
  padding-top: var(--space-4) !important;
  padding-bottom: var(--space-4) !important;
}

/* ---- Header: title, team, mode switch; Export on the right ---- */
.dash2-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
}
.dash2-title {
  display: grid;
  justify-items: start;
  gap: 2px;
  min-width: 0;
}
.dash2-title .page-title {
  margin: 0;
}
.dash2-team {
  margin: 0;
  color: var(--ink-muted);
  font-size: 16px;
  line-height: 20px;
  font-weight: 500;
}
.dash2-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}
.dash2 .btn,
.dash2 .btn.small {
  min-height: var(--dash-target);
}
.dash2-export {
  border-color: var(--dash-accent);
}
.dash2 .seg {
  padding: 2px;
}
.dash2 .seg button {
  min-height: var(--dash-target);
}
/* ---- Mode switch on the left, scope filters right-aligned on the same row ---- */
.dash2-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}
.dash2-modes {
  /* Identical position and size in both modes (DASH-002). */
  flex: 0 1 400px;
  min-width: 340px;
}
.dash2-modes button {
  font-size: 15px;
  white-space: nowrap;
}

/* ---- Scope row: type chips | Sessions, Dates ---- */
.dash2-scope {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-left: auto;
}
.dash2-types {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.dash2-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--dash-target);
  padding: 0 var(--space-4) 0 var(--space-3);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--ink-muted);
  font: 600 14px/18px var(--font-body);
  cursor: pointer;
}
.dash2-chip:hover {
  color: var(--ink);
}
.dash2-chip[aria-pressed="true"] {
  border-color: var(--dash-accent);
  background: var(--brand);
  color: var(--on-brand);
}
.dash2-chip-box {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
}
.dash2-chip.is-disabled {
  color: var(--ink-subtle);
  cursor: not-allowed;
}
.dash2-chip.is-disabled .dash2-chip-box {
  border: 1.5px solid currentColor;
  border-radius: 50%;
}
.dash2-divider {
  align-self: stretch;
  width: 1px;
  margin: 6px var(--space-1);
  background: var(--line);
}
.dash2-scope-caption {
  color: var(--ink-subtle);
  font-size: 14px;
}
#dashTeamName + .dash2-scope-caption::before {
  content: " · ";
}

/* Pills: triggers, selects and number fields share one control look. */
.dash2-trigger,
.dash2-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--dash-target);
  max-width: 320px;
  padding: 0 var(--space-3);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--ink);
  font: 500 14px/18px var(--font-body);
  white-space: nowrap;
}
.dash2-trigger {
  cursor: pointer;
}
.dash2-trigger b {
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
}
.dash2-trigger-label,
.dash2-pill > span {
  color: var(--ink-muted);
}
.dash2-trigger[aria-expanded="true"] {
  border-color: var(--line-strong);
}
.dash2-pill select,
.dash2-pill input {
  min-width: 0;
  min-height: calc(var(--dash-target) - 2px);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 600 14px/18px var(--font-body);
  appearance: none;
}
.dash2-pill.is-select select {
  padding-right: 22px;
  cursor: pointer;
}
.dash2-pill.is-select > svg:last-child {
  position: absolute;
  right: var(--space-3);
  pointer-events: none;
}
.dash2-pill.is-number input {
  width: 4ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
  appearance: textfield;
}
.dash2-pill.is-number input::-webkit-inner-spin-button,
.dash2-pill.is-number input::-webkit-outer-spin-button {
  margin: 0;
  -webkit-appearance: none;
}
.dash2-pill.is-date input {
  font-weight: 500;
}
.dash2-pill.is-static {
  color: var(--ink-muted);
  background: transparent;
}
.dash2-pill:focus-within {
  border-color: var(--line-strong);
}

.dash2-hint {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  color: var(--ink-muted);
  font-size: 13px;
  line-height: 18px;
}
.dash2-hint.is-warning {
  color: var(--warning);
}
.dash2-hint.is-small {
  font-size: 12px;
  line-height: 16px;
}
.dash2-hint.is-note {
  font-style: italic;
}
.dash2-sub {
  margin: 0;
  color: var(--ink-muted);
  font-size: 13px;
  line-height: 18px;
}

/* ---- Popovers (sessions, players, tags, info) ---- */
.dash2-pop {
  position: relative;
}
.dash2-popover {
  position: absolute;
  z-index: 40;
  top: calc(100% + 6px);
  left: 0;
  display: grid;
  gap: var(--space-2);
  width: min(340px, calc(100vw - 32px));
  max-height: min(60vh, 460px);
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-pop);
  color: var(--ink);
  font-size: 14px;
  line-height: 20px;
  text-align: left;
  white-space: normal;
  text-transform: none;
  letter-spacing: 0;
}
.dash2-popover[hidden] {
  display: none;
}
.dash2-popover.is-up {
  top: auto;
  bottom: calc(100% + 6px);
}
.dash2-popover.is-right {
  left: auto;
  right: 0;
}
.dash2-popover p {
  margin: 0;
}
.dash2-pop-actions,
.dash2-pop-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.dash2-search {
  min-height: var(--dash-target);
  padding: 0 var(--space-3);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-md);
  background-color: var(--sunken);
  color: var(--ink);
  font: 500 14px/18px var(--font-body);
}
.dash2-session-list,
.dash2-check-list {
  display: grid;
  gap: 2px;
  max-height: 300px;
  overflow: auto;
}
.dash2-session-day {
  margin: var(--space-2) 0 2px;
  color: var(--ink-muted);
  font-size: 12px;
  font-weight: 600;
}
.dash2-session-option,
.dash2-check {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--dash-target);
  padding: 4px var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.dash2-session-option:hover,
.dash2-check:hover {
  background: var(--hover);
}
.dash2-session-option span {
  display: grid;
  min-width: 0;
}
.dash2-session-option b {
  overflow: hidden;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-session-option small,
.dash2-check small {
  color: var(--ink-muted);
  font-size: 12px;
}
.dash2-check span {
  flex: 1 1 auto;
}
.dash2-check small {
  font-variant-numeric: tabular-nums;
}
/* Multi-select dropdowns (app/dashboard-menu.js, decision 21): the All or
   Select All row over the list, then Cancel and Apply pinned to the bottom. */
.dash2-check.is-all {
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  font-weight: 600;
}
.dash2-check input[type="checkbox"],
.dash2-session-option input[type="checkbox"] {
  flex: none;
  width: 18px;
  height: 18px;
  accent-color: var(--dash-accent);
}
.dash2-menu-foot {
  position: sticky;
  bottom: calc(-1 * var(--space-3));
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin: 0 calc(-1 * var(--space-3)) calc(-1 * var(--space-3));
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.dash2-menu-foot .btn {
  min-height: var(--dash-target);
  min-width: 88px;
}
.dash2-empty-line {
  margin: 0;
  padding: var(--space-3);
  color: var(--ink-muted);
  font-size: 14px;
}

/* ---- Top statistics: eight compact tiles with a red accent bar ---- */
.dash2-stats {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: var(--space-2);
}
.dash2-stat,
.dash2-card {
  position: relative;
  display: grid;
  align-content: center;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-highlight);
}
.dash2-stat::before,
.dash2-card::before {
  content: "";
  position: absolute;
  top: 10px;
  bottom: 10px;
  left: 8px;
  width: 4px;
  border-radius: 2px;
  background: var(--dash-accent);
}
.dash2-stat {
  min-height: 64px;
  padding: 6px var(--space-3) 6px 22px;
}
.dash2-stat-label,
.dash2-card > span {
  overflow: hidden;
  color: var(--ink-muted);
  font-size: 13px;
  line-height: 16px;
  font-weight: 500;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-stat strong {
  overflow: hidden;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(20px, 1.7vw, 30px);
  line-height: 1.1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-stat-sub {
  color: var(--ink-muted);
  font-size: 12px;
  line-height: 14px;
  font-variant-numeric: tabular-nums;
}
/* A partial or unavailable state: a small marker; the tooltip and the
   accessible text say why. */
.dash2-stat-flag {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warning);
}

/* ---- Body: map left, ranking and summary right ---- */
.dash2-main {
  display: grid;
  grid-template-columns: minmax(0, 55fr) minmax(0, 45fr);
  gap: var(--space-3);
  flex: 1 1 auto;
  min-height: 0;
}
.dash2[data-dash-mode="shooting"] .dash2-main {
  grid-template-columns: minmax(0, 57fr) minmax(0, 43fr);
}
.dash2-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.dash2-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  min-height: 0;
  padding: var(--space-3) var(--space-4);
}
.dash2-map-head h2,
.dash2-panel-head h2,
.dash2-summary-head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 28px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* ---- Shot map panel ---- */
.dash2-map {
  container: dash-map / inline-size;
}
.dash2-map-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--space-2) var(--space-3);
}
.dash2-map-head h2 {
  padding-top: 8px;
}
/* The map's controls are compact so all of them share the title's row. */
.dash2-map-head .dash2-seg button,
.dash2-map-head .dash2-trigger {
  min-width: 0;
  padding: 0 8px;
  font-size: 13px;
}
.dash2-map-head .dash2-map-controls {
  gap: 6px;
}
.dash2-map-head .dash2-trigger {
  gap: 6px;
}
.dash2-map-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
}
.dash2-seg button {
  padding: 0 var(--space-3);
}
.dash2-seg.is-small button {
  min-width: 64px;
}
/* Our team | Opponents ▾ (decisions 15, 16): each segment as wide as its
   words; the Opponents segment carries the choice and opens the team list. */
.dash2-side-seg > button,
.dash2-side-seg > .dash2-pop,
.dash2-side-seg > .dash2-pop > button {
  flex: 0 0 auto;
}
.dash2-side-seg > .dash2-pop {
  display: flex;
}
.dash2-side-opponents {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.dash2-side-opponents b {
  overflow: hidden;
  max-width: 14ch;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash2-side-opponents svg {
  flex: none;
  transition: transform var(--dur) var(--ease);
}
.dash2-side-opponents[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
.dash2 .dash2-side-seg .dash2-side-opponents.active {
  border-color: color-mix(in srgb, var(--defense) 45%, var(--line));
  background: color-mix(in srgb, var(--defense) 18%, transparent);
  color: var(--defense);
}
.dash2-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.dash2-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--dash-target);
  padding: 0 var(--space-3);
  border: 1px solid color-mix(in srgb, var(--brand-ink) 40%, var(--line));
  border-radius: var(--radius-pill);
  background: var(--brand-tint);
  color: var(--ink);
  font: 600 13px/16px var(--font-body);
  cursor: pointer;
}
.dash2-filter-chip.is-tag {
  border-style: dashed;
}
/* The ranking's selected player the map is narrowed to (decision 19). */
.dash2-map-focus {
  color: var(--brand-ink);
  font: 600 13px/16px var(--font-body);
}
.dash2-map-head .dash2-trigger:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.dash2-count {
  margin-left: auto;
  color: var(--ink-muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.dash2-court {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 50 / 47;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--dash-floor);
}
.dash2-court svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}
/* The court is a picture here: no region hover, numbers or hit areas. */
.dash2-court #shot-regions {
  pointer-events: none;
}
.dash2-court .label {
  display: none;
}
.dash2-overlay {
  pointer-events: auto;
}

/* Shots: shape, not colour, tells made from missed (DASH-024). */
.dash2-made {
  fill: var(--mark-make);
  stroke: #121110;
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.dash2-missed {
  fill: none;
  stroke: var(--mark-miss);
  stroke-width: 2.6px;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.is-opponent .dash2-made {
  fill: var(--mark-def-make);
}
.is-opponent .dash2-missed {
  stroke: var(--mark-def-miss);
}
.dash2-shot {
  cursor: pointer;
  outline: none;
}
.dash2-shot-hit {
  fill: transparent;
  stroke: none;
}
.dash2-shot:hover .dash2-shot-hit,
.dash2-shot:focus-visible .dash2-shot-hit {
  fill: color-mix(in srgb, var(--court-line) 35%, transparent);
  stroke: var(--focus);
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
}

/* Hex heat (DASH-028..064): the glyph is a scaled hexagon at the fixed cell centre. */
.dash2-hex {
  cursor: pointer;
  outline: none;
}
.dash2-hex-cell {
  fill: transparent;
  stroke: none;
}
.dash2-hex-glyph {
  stroke: var(--hex-edge);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}
.dash2-hex.is-band-1 .dash2-hex-glyph { fill: var(--hex-band-1); }
.dash2-hex.is-band-2 .dash2-hex-glyph { fill: var(--hex-band-2); }
.dash2-hex.is-band-3 .dash2-hex-glyph { fill: var(--hex-band-3); }
.dash2-hex.is-band-4 .dash2-hex-glyph { fill: var(--hex-band-4); }
.dash2-hex.is-band-5 .dash2-hex-glyph { fill: var(--hex-band-5); }
.dash2-hex.is-band-6 .dash2-hex-glyph { fill: var(--hex-band-6); }
.dash2-hex.is-band-7 .dash2-hex-glyph { fill: var(--hex-band-7); }
.dash2-hex.is-band-8 .dash2-hex-glyph { fill: var(--hex-band-8); }
.dash2-hex.is-band-9 .dash2-hex-glyph { fill: var(--hex-band-9); }
/* Unrated (1–4 attempts): hatched and dashed, never the neutral band (DASH-056). */
.dash2-hex.is-unrated .dash2-hex-glyph {
  fill: url(#dashHexHatch);
  stroke: var(--hex-unrated);
  stroke-dasharray: 3 2;
}
.dash2-hatch-line {
  stroke: var(--hex-unrated);
  stroke-width: 0.14;
}
/* No baseline: counts only, a plain outline (DASH-058). */
.dash2-hex.is-uncompared .dash2-hex-glyph {
  fill: color-mix(in srgb, var(--court-line) 18%, transparent);
  stroke: var(--court-line);
}
.dash2-hex:hover .dash2-hex-cell {
  fill: color-mix(in srgb, var(--court-line) 25%, transparent);
}
.dash2-hex:focus-visible .dash2-hex-cell,
.dash2-hex.is-selected .dash2-hex-cell {
  stroke: var(--focus);
  stroke-width: 3px;
  vector-effect: non-scaling-stroke;
}
.dash2-hex.is-selected .dash2-hex-cell {
  fill: color-mix(in srgb, var(--court-line) 30%, transparent);
}

/* Map footer: our team baseline on the left, the legend on the right. */
.dash2-map-foot {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  container-type: inline-size;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding-top: var(--space-2);
  border-top: 1px solid var(--line);
}
.dash2-baseline {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 var(--space-1);
  padding-right: var(--space-4);
  border-right: 1px solid var(--line);
}
.dash2-baseline-caption {
  grid-column: 1 / -1;
  color: var(--ink-muted);
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.dash2-baseline strong {
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 28px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dash2-info,
.dash2-icon-btn {
  display: inline-grid;
  place-items: center;
  width: var(--dash-target);
  height: var(--dash-target);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}
.dash2-info:hover,
.dash2-icon-btn:hover {
  background: var(--hover);
  color: var(--ink);
}
.dash2-legend {
  display: grid;
  justify-items: center;
  gap: 2px;
  min-width: 0;
  color: var(--ink-muted);
  font-size: clamp(11px, 1.9cqi, 12px);
  line-height: 15px;
  text-align: center;
}
/* Each phrase keeps together; a narrow footer wraps between phrases. */
.dash2-legend-line > span {
  white-space: nowrap;
}
.dash2-legend-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 var(--space-2);
  margin: 0;
}
.dash2-legend-keys {
  display: flex;
  gap: var(--space-4);
  color: var(--ink);
  font-size: 13px;
}
.dash2-legend-scale {
  display: grid;
  gap: 2px;
  width: min(100%, 300px);
}
.dash2-legend-ends {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  line-height: 14px;
}
.dash2-swatches {
  display: flex;
  justify-content: space-between;
  gap: 3px;
}
.dash2-key {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dash2-key-svg {
  width: 16px;
  height: 16px;
}
.dash2-swatch {
  display: inline-block;
  width: 24px;
  height: 21px;
  flex: 0 0 auto;
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  background: var(--line-strong);
}
.dash2-legend-line .dash2-swatch {
  width: 16px;
  height: 14px;
}
.dash2-swatch.band-1 { background: var(--hex-band-1); }
.dash2-swatch.band-2 { background: var(--hex-band-2); }
.dash2-swatch.band-3 { background: var(--hex-band-3); }
.dash2-swatch.band-4 { background: var(--hex-band-4); }
.dash2-swatch.band-5 { background: var(--hex-band-5); }
.dash2-swatch.band-6 { background: var(--hex-band-6); }
.dash2-swatch.band-7 { background: var(--hex-band-7); }
.dash2-swatch.band-8 { background: var(--hex-band-8); }
.dash2-swatch.band-9 { background: var(--hex-band-9); }
.dash2-swatch.is-unrated {
  background: repeating-linear-gradient(45deg, var(--ink-subtle) 0 2px, transparent 2px 5px);
  outline: 1px dashed var(--ink-subtle);
  outline-offset: -2px;
}
.dash2-swatch.is-uncompared {
  background: var(--sunken);
  box-shadow: inset 0 0 0 1px var(--ink-muted);
}
.dash2-threshold-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.dash2-threshold-table caption {
  margin-bottom: var(--space-1);
  font-weight: 600;
  text-align: left;
}
.dash2-threshold-table th,
.dash2-threshold-table td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.dash2-map-notes {
  display: grid;
  gap: 2px;
}
.dash2-geometry {
  overflow: hidden;
  margin: 0;
  color: var(--ink-subtle);
  font-size: 11px;
  line-height: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---- Ranking panel ---- */
.dash2-side {
  container-type: inline-size;
}
.dash2-panel-head {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
}
.dash2-panel-head > div {
  min-width: 0;
}
.dash2-rank-tools .dash2-pill {
  min-height: 36px;
}
.dash2-rank-tools {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
}
.dash2-sizes button {
  padding: 0 var(--space-2);
}
.dash2-rank {
  flex: 0 1 auto;
  max-height: 420px;
  min-height: 132px;
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--sunken);
}
.dash2-rank-head,
.dash2-rank-row {
  display: grid;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
}
.dash2-rank-head.is-lineup,
.dash2-rank-row.is-lineup {
  grid-template-columns: 22px minmax(0, 1fr) 56px 72px 96px;
}
.dash2-rank-head.is-player,
.dash2-rank-row.is-player {
  grid-template-columns: 32px minmax(0, 1fr) 76px 60px 60px;
}
.dash2-rank-head.is-player.has-extra,
.dash2-rank-row.is-player.has-extra {
  grid-template-columns: 32px minmax(0, 1fr) 72px 56px 56px 60px;
}
.dash2-rank-row .dash2-num {
  white-space: nowrap;
}
.dash2-rank-head {
  position: sticky;
  top: 0;
  z-index: 1;
  min-height: 36px;
  border-bottom: 1px solid var(--line);
  background: var(--sunken);
  color: var(--ink-muted);
  font-size: 13px;
  font-weight: 500;
}
.dash2-rank-head span:nth-child(n + 3) {
  text-align: right;
}
.dash2-rank-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.dash2-rank-row {
  width: 100%;
  min-height: 48px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: 500 15px/18px var(--font-body);
  text-align: left;
  cursor: pointer;
}
.dash2-rank-row.is-lineup {
  min-height: 64px;
  padding-top: 6px;
  padding-bottom: 6px;
}
.dash2-rank-row:hover {
  background: var(--hover);
}
/* Lineup combinations (decision 20): the top 10, five rows at a time. Rows
   are one fixed height so the table shows exactly five and scrolls to the
   rest; under pressure the table gives up height before the page grows. */
.dash2-side[data-kind="lineups"] {
  --dash-lineup-row: 52px;
  --dash-lineup-head: 37px;
}
.dash2-side[data-kind="lineups"] .dash2-rank {
  flex: 0 1 auto;
  height: calc(var(--dash-lineup-head) + 5 * var(--dash-lineup-row) + 2px);
  max-height: none;
  min-height: calc(var(--dash-lineup-head) + 2.5 * var(--dash-lineup-row));
}
.dash2-side[data-kind="lineups"] .dash2-rank-row.is-lineup {
  height: var(--dash-lineup-row);
  min-height: var(--dash-lineup-row);
  padding-top: 2px;
  padding-bottom: 2px;
}
.dash2-side[data-kind="lineups"] .dash2-jersey {
  width: 32px;
  height: 32px;
  font-size: 16px;
}
.dash2-side[data-kind="lineups"] .dash2-member {
  gap: 1px;
}
/* The selected row is outlined in the accent; the top-ranked row the
   summary describes while nothing is selected gets a dashed outline. */
.dash2-rank-row.is-selected {
  border-radius: var(--radius-sm);
  background: var(--brand-tint);
  outline: 2px solid var(--dash-accent);
  outline-offset: -2px;
}
.dash2-rank-row.is-shown {
  border-radius: var(--radius-sm);
  outline: 1px dashed var(--dash-accent);
  outline-offset: -2px;
}
.dash2-rank-n {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dash2-player-name {
  overflow: hidden;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-five {
  display: flex;
  gap: 4px;
  min-width: 0;
}
.dash2-member {
  display: grid;
  justify-items: center;
  gap: 2px;
  flex: 1 1 0;
  min-width: 0;
  max-width: 64px;
}
.dash2-jersey {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 2px solid var(--dash-accent);
  border-radius: 50%;
  background: var(--brand-tint);
  color: var(--ink);
  font: 700 17px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
}
/* The Opponent view's ranking and summary are drawn in the opponent's blue
   (our red stays for our team). */
.dash2-panel.is-opponent {
  --dash-accent: var(--defense);
}
.dash2-panel.is-opponent .dash2-jersey,
.dash2-panel.is-opponent .dash2-rank-row.is-selected {
  background: color-mix(in srgb, var(--defense) 18%, transparent);
}
.dash2-member-name {
  overflow: hidden;
  max-width: 100%;
  color: var(--ink-muted);
  font-size: 11px;
  line-height: 13px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.dash2-num.is-big {
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 28px;
  font-weight: 700;
}
.dash2-poss {
  display: grid;
  justify-items: end;
  color: var(--ink-muted);
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
}
.dash2-sub.is-foot {
  font-size: 12px;
}
.dash2-coverage {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0 0 0 var(--space-4);
  color: var(--ink-muted);
  font-size: 11px;
  line-height: 14px;
}

/* Value colours (VALUE_TONES in app/dashboard-model.js). */
.dash2-num.tone-good,
.dash2-card.tone-good strong {
  color: var(--value-good);
}
.dash2-num.tone-middling,
.dash2-card.tone-middling strong {
  color: var(--value-middling);
}

/* A narrow ranking panel (iPad portrait halves, 1024 px landscape): smaller
   circles, names in the tooltip, group sizes as numbers. */
@container (max-width: 560px) {
  .dash2-sizes-word {
    display: none;
  }
  .dash2-sizes button {
    min-width: 40px;
  }
}
@container (max-width: 460px) {
  .dash2-rank-head.is-lineup,
  .dash2-rank-row.is-lineup {
    grid-template-columns: 18px minmax(0, 1fr) 44px 52px 76px;
    gap: var(--space-1);
    padding: 0 var(--space-2);
  }
  .dash2-member-name {
    display: none;
  }
  .dash2-jersey,
  .dash2-side[data-kind="lineups"] .dash2-jersey {
    width: 28px;
    height: 28px;
    border-width: 1.5px;
    font-size: 14px;
  }
  .dash2-num.is-big {
    font-size: 20px;
    line-height: 24px;
  }
  .dash2-poss {
    font-size: 11px;
  }
  .dash2-rank-head.is-player,
  .dash2-rank-row.is-player {
    grid-template-columns: 28px minmax(0, 1fr) 68px 54px 54px;
    gap: var(--space-1);
    padding: 0 var(--space-2);
  }
  .dash2-rank-head.is-player.has-extra,
  .dash2-rank-row.is-player.has-extra {
    grid-template-columns: 24px minmax(0, 1fr) 48px 50px 50px 50px;
    font-size: 14px;
  }
}

/* ---- Selected summary panel: ten tiles in two rows of five ---- */
.dash2-summary {
  flex: 0 0 auto;
  container-type: inline-size;
}
.dash2-summary.is-empty {
  justify-content: center;
  min-height: 64px;
}
.dash2-summary-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-1) var(--space-3);
}
.dash2-summary-name {
  margin: 0;
  color: var(--ink);
  font-size: 16px;
  line-height: 20px;
  font-weight: 600;
}
.dash2-sub.is-aside {
  max-width: 42%;
  text-align: right;
}
.dash2-cards {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-2);
}
.dash2-card {
  align-content: start;
  gap: 0;
  padding: 6px var(--space-2) 6px 18px;
  background: var(--raised);
}
.dash2-card::before {
  left: 7px;
  width: 3px;
}
.dash2-card > span {
  font-size: clamp(10px, 2.3cqi, 13px);
  line-height: 1.25;
  letter-spacing: 0.01em;
}
.dash2-card strong {
  overflow: hidden;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(17px, 4.4cqi, 26px);
  line-height: 1.15;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-card small {
  color: var(--ink-muted);
  font-size: clamp(10px, 2.1cqi, 12px);
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
/* The compact lineup summary (decision 20): no heading, each card its name
   and value only, two rows of five in the same colours. */
.dash2-summary.is-compact {
  padding: var(--space-2) var(--space-3);
}
.dash2-summary.is-compact .dash2-untracked {
  inset: 0;
}
.dash2-cards.is-compact {
  gap: 6px;
}
.dash2-cards.is-compact .dash2-card {
  padding: 3px 6px 4px 13px;
}
.dash2-cards.is-compact .dash2-card::before {
  top: 7px;
  bottom: 7px;
  left: 6px;
}
/* Five to a row in a narrow panel: the name keeps every letter it can. */
.dash2-cards.is-compact .dash2-card > span {
  font-size: clamp(9.5px, 2.2cqi, 12px);
  letter-spacing: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}
.dash2-cards.is-compact .dash2-card strong {
  font-size: clamp(14px, 3.6cqi, 24px);
  line-height: 1.1;
}

/* A narrow summary panel (beside the app's sidebar): the aside drops under
   the name, and tiles tighten before their numbers shrink. */
@container (max-width: 560px) {
  .dash2-summary-head {
    display: block;
  }
  /* The panel's own subtitle already says whose results these are. */
  .dash2-sub.is-aside {
    display: none;
  }
  .dash2-summary-name {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }
  .dash2-cards {
    gap: 6px;
  }
  .dash2-card {
    padding: 4px 6px 5px 14px;
  }
  .dash2-card::before {
    top: 8px;
    bottom: 8px;
  }
  .dash2-card::before {
    left: 6px;
  }
  .dash2-card strong {
    font-size: clamp(15px, 3.7cqi, 22px);
  }
}

/* ---- Not tracked (decision 18): the panel keeps its drawn layout behind a
   blur, out of reach (inert, aria-hidden), under one centred line. The title
   row stays sharp and usable. ---- */
.dash2-panel.is-untracked {
  position: relative;
}
.dash2-veiled {
  filter: blur(6px);
  opacity: 0.55;
  pointer-events: none;
  user-select: none;
}
.dash2-untracked {
  position: absolute;
  inset: 56px 0 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  pointer-events: none;
}
.dash2-summary .dash2-untracked {
  inset: 40px 0 0;
}
.dash2-untracked-line {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  padding: 8px var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  box-shadow: var(--shadow-pop);
  color: var(--ink);
  font: 600 14px/18px var(--font-body);
  text-align: center;
}
.dash2-untracked-line svg {
  flex: none;
  color: var(--ink-muted);
}
.dash2-rank-row.is-ghost {
  cursor: default;
}
.dash2-rank-row.is-ghost .dash2-jersey {
  color: var(--ink-subtle);
}

/* ---- Focus (DASH-136) ---- */
.dash2 button:focus-visible,
.dash2 input:focus-visible,
.dash2 select:focus-visible,
.dash2-rank:focus-visible,
.dash2-dialog button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.dash2 .dash2-rank-row:focus-visible {
  outline-offset: -2px;
}

/* ---- Dialogs (DASH-137): within the viewport, lists scroll inside ---- */
/* Dialogs are appended to the body, outside .dash2: they get its accent here. */
.dash2-scrim {
  --dash-accent: var(--brand-ink);
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, #000 55%, transparent);
  overscroll-behavior: contain;
  touch-action: none;
}
.dash2-dialog {
  display: flex;
  flex-direction: column;
  width: min(560px, 100%);
  max-height: calc(100dvh - 2 * var(--space-4));
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-pop);
  color: var(--ink);
  touch-action: auto;
  outline: none;
}
.dash2-dialog-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-3) 0 var(--space-5);
}
.dash2-dialog-head .btn {
  margin-left: calc(var(--space-3) * -1);
}
.dash2-dialog-title {
  flex: 1 1 auto;
  margin: 0;
  font-family: var(--font-display);
  font-size: 28px;
  line-height: 32px;
  font-weight: 700;
}
.dash2-dialog-body {
  display: grid;
  gap: var(--space-3);
  min-height: 0;
  overflow: auto;
  padding: var(--space-2) var(--space-5) var(--space-4);
}
.dash2-dialog-intro {
  display: grid;
  gap: 2px;
}
.dash2-dialog-sub {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: 17px;
  line-height: 22px;
  font-weight: 500;
}
.dash2-dialog-section {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 26px;
}
.dash2-dialog-section small {
  color: var(--ink-muted);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
}
/* Selected hexagon: the cell's FG%, the baseline row, two facts, the band. */
.dash2-hex-fg,
.dash2-hex-fact {
  position: relative;
  display: grid;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--raised);
}
.dash2-hex-fg::before,
.dash2-hex-fact::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 12px;
  width: 5px;
  border-radius: 3px;
  background: var(--dash-accent);
}
.dash2-hex-fg {
  padding: var(--space-3) var(--space-4) var(--space-3) 32px;
}
.dash2-hex-fg strong {
  font-family: var(--font-display);
  font-size: 44px;
  line-height: 48px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dash2-hex-fg span,
.dash2-hex-fact span {
  color: var(--ink-muted);
  font-size: 15px;
  line-height: 20px;
}
.dash2-hex-baseline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
}
.dash2-hex-baseline span {
  padding-right: var(--space-4);
  border-right: 1px solid var(--line);
  color: var(--ink-muted);
}
.dash2-hex-baseline b {
  font-variant-numeric: tabular-nums;
}
.dash2-hex-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
}
.dash2-hex-fact {
  padding: var(--space-2) var(--space-3) var(--space-2) 30px;
}
.dash2-hex-fact strong {
  font-family: var(--font-display);
  font-size: 30px;
  line-height: 34px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.dash2-hex-band {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: 15px;
}
.dash2-hex-band .dash2-swatch {
  width: 30px;
  height: 26px;
}
.dash2-shot-list {
  display: grid;
  gap: 0;
  max-height: min(36vh, 300px);
  margin: 0;
  padding: 0;
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  list-style: none;
}
.dash2-shot-list li + li {
  border-top: 1px solid var(--line);
}
.dash2-shot-list button {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0 var(--space-3);
  width: 100%;
  min-height: var(--dash-target);
  padding: var(--space-2) var(--space-3);
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 500 14px/18px var(--font-body);
  text-align: left;
  cursor: pointer;
}
.dash2-dialog.is-chooser .dash2-shot-list button {
  grid-template-columns: minmax(0, 1fr);
}
.dash2-shot-list button:hover {
  background: var(--hover);
}
.dash2-shot-who {
  display: grid;
  min-width: 0;
}
.dash2-shot-who b {
  overflow: hidden;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.dash2-shot-who small {
  color: var(--ink-muted);
  font-size: 12px;
  line-height: 16px;
}
.dash2-shot-result {
  white-space: nowrap;
}
.dash2-shot-mark {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}
.dash2-shot-mark.is-made {
  background: var(--mark-make);
}
.dash2-shot-mark.is-missed {
  background: var(--mark-miss);
}
.dash2-facts {
  display: grid;
  gap: 0;
  margin: 0;
}
.dash2-facts div {
  display: grid;
  grid-template-columns: minmax(110px, 40%) 1fr;
  gap: var(--space-3);
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.dash2-facts dt {
  color: var(--ink-muted);
  font-size: 13px;
}
.dash2-facts dd {
  margin: 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.dash2-tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}
.dash2-tag-chips em {
  padding: 2px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: 12px;
  font-style: normal;
}
.dash2-tag-chips em.is-flag {
  border-color: var(--warning);
  color: var(--warning);
}
.dash2-dialog-foot {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-2) var(--space-5) var(--space-4);
  border-top: 1px solid var(--line);
}
.dash2-dialog-foot.is-wide {
  border-top: 0;
}
.dash2-dialog-foot.is-wide .btn {
  flex: 1 1 auto;
}

/* ---- Fill the viewport: both columns take the height under the tiles and
   only the tables scroll (DASH-074). The body keeps a floor, so a very
   short window scrolls the page instead of crushing the court. ---- */
@media (min-width: 900px) and (min-height: 640px) {
  .dash2 {
    height: 100%;
    min-height: 0;
  }
  .dash2-main {
    min-height: 440px;
  }
  .dash2-map .dash2-court {
    flex: 1 1 0;
    min-height: 220px;
    aspect-ratio: auto;
  }
  .dash2-side {
    flex: 1 1 0;
    min-height: 220px;
  }
  .dash2-rank {
    flex: 1 1 0;
    max-height: none;
    min-height: 150px;
  }
}

/* ---- Narrower: adapt rows and columns before shrinking (DASH-135) ---- */
/* A narrow map panel: the baseline sits over the legend. */
@container dash-map (max-width: 620px) {
  .dash2-side-opponents b {
    max-width: 9ch;
  }
}
@container dash-map (max-width: 520px) {
  .dash2-map-foot {
    grid-template-columns: minmax(0, 1fr);
  }
  .dash2-baseline {
    padding-right: 0;
    border-right: 0;
  }
}
/* The dashboard's own width (beside the app's sidebar, or in a narrow window):
   below ~960 px the columns stack, the map first, and the page scrolls. */
@container dash (max-width: 960px) {
  .dash2-main,
  .dash2[data-dash-mode="shooting"] .dash2-main {
    flex: none;
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: auto;
    min-height: 0;
  }
  .dash2-map,
  .dash2-col {
    min-height: auto;
  }
  .dash2-map .dash2-court {
    flex: none;
    width: min(100%, 720px);
    min-height: 0;
    margin: 0 auto;
    aspect-ratio: 50 / 34;
  }
  .dash2-side,
  .dash2-summary {
    flex: none;
  }
  .dash2-side .dash2-rank {
    flex: none;
    max-height: 360px;
  }
}
@media (max-width: 899px) {
  .dash2-stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .dash2-stat strong {
    font-size: 26px;
  }
}
@media (max-width: 560px) {
  .dash2-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .dash2-cards {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  }
  .dash2-divider {
    display: none;
  }
  .dash2-sub.is-aside {
    max-width: none;
    text-align: left;
  }
  .dash2-hex-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Decision 19: a ranked player outside the map's Players filter stays in the
   table, dimmed, and can't be selected. */
.dash2-rank-row.is-blocked {
  color: var(--ink-subtle);
  cursor: not-allowed;
}
.dash2-rank-row.is-blocked .dash2-num,
.dash2-rank-row.is-blocked .dash2-rank-n {
  color: var(--ink-subtle);
}
.dash2-rank-row.is-blocked:hover {
  background: transparent;
}
