/* =========================================================================
   pv.css — the player card's Possession Value tab

   A list of labelled bars (base skills, or phases grouped the way the match
   report's Phases tab groups them) plus bipolar tendency sliders. Everything
   here is CSS-only; there is no JavaScript.
   ========================================================================= */

.pv-tab {
  --pv-hi: #00846b;              /* cool_green  — strong */
  --pv-mid: #c9922f;             /* amber       — ordinary */
  --pv-lo: #954d4e;              /* cool_red    — weak */
  --pv-na: rgba(0, 0, 0, 0.22);
  --pv-track: rgba(0, 0, 0, 0.07);
  /* The card colour behind the sliders. The split-centre variant punches a gap
     through the track with it, so it has to match the card, not the page. */
  --pv-card-bg: #fff;
}

/* --- panel columns -------------------------------------------------------- */
/* Flex instead of the 12-col grid so each card has a real pixel target AND a
   floor: `flex-basis` is the preferred width, `min-width` is the narrowest
   the bars stay readable at. Below the combined minimums the tendencies card
   wraps under the ratings card rather than crushing both. */
.pv-cols {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}
.pv-col-ratings { flex: 0 1 440px; min-width: min(380px, 100%); }
/* The tendencies column is a uiOutput WRAPPER, and Shiny renders those as
   `display: contents` (boxless) - which would hand the flex slot to the card
   inside, whose `width: 100%` then wraps it onto its own full-width row.
   Forcing a real box keeps the wrapper itself the flex column. The child
   selector outranks Shiny's `.shiny-html-output` rule at any load order.
   Also: NEVER add `:empty { display: none }` here - the wrapper is empty
   until its first render, so hiding it suspends the output
   (suspendWhenHidden) and it deadlocks unrendered. The box makes the empty
   PP state cost only invisible reserved space, with nothing to its right. */
.pv-cols > .pv-col-tend {
  display: block;
  flex: 0 1 560px;
  min-width: min(470px, 100%);
}

/* --- PV map column -------------------------------------------------------- */
/* The maps are the THIRD item in the same wrapping row, not a row of their
   own. It is the only one that GROWS (flex-grow 1 against the others' 0), so
   it absorbs whatever width is left over rather than the tab trailing dead
   space to its right - which is what the two fixed-width cards used to do on a
   wide screen.

   Its basis is deliberately smaller than the width two rinks want. That makes
   the degradation happen INSIDE the card first (the rinks stack, see
   .pv-map-cols) before the card itself is pushed onto its own line, so a
   medium screen still gets three columns rather than a half-empty row. */
.pv-cols > .pv-map-row {
  flex: 1 1 600px;
  min-width: min(560px, 100%);
}
/* The toolbar's own box ends flush, so the 24px card-body gap below it is
   pure air on top of the panel heads' 32px row - pull the panels back up. */
.pv-map-card .shot-toolbar:first-of-type {
  padding-top: 4px;
  margin-bottom: -12px;
}

/* Action | Value, side by side where there is room. Below the combined minimum
   the value rink wraps UNDER the action rink instead of both being crushed -
   stacked-but-legible beats side-by-side-but-tiny, and a rink stacked at the
   card's full width is still wider than one squeezed into half of it. */
.pv-map-cols {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.pv-map-cols > .pv-map-panel {
  flex: 1 1 440px;
  min-width: min(400px, 100%);
}
/* Panel title and (on the value side) its measure switch share one row, so the
   two rinks start at the same y even though only one has a control. nowrap
   because the switch dropping below the title would offset them by a line. */
/* min-height MATCHES the rendered height of the segmented switch below, so the
   title-only left head is exactly as tall as the right one and the two rinks
   start on the same line. Change --to-ctl-h and this has to follow. */
.pv-map-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: nowrap;
  min-height: 32px;
  margin-bottom: 4px;
}
.pv-map-title {
  font-weight: 700;
  font-size: 0.95rem;
  white-space: nowrap;
}
/* Same segmented pill styling as the Skills/Phases switch - and the same
   requirement: .to-seg reads --to-ctl-h off an ancestor, so it has to be set
   here too or the pills collapse to zero height. Slightly shorter than the
   ratings switch: this one sits on a panel title, not its own row. */
.pv-map-head .pv-map-switch {
  --to-ctl-h: 28px;
  flex: 0 0 auto;
  margin-bottom: 0;
}
.pv-map-head .pv-map-switch .shiny-input-container { margin-bottom: 0; }

/* --- hero + view switch row ----------------------------------------------- */
/* One row: hero on the left, the Skills/Phases switch in the dead space to
   its right. The rule under the row moved here from .pv-hero so it spans the
   switch too. Deliberately nowrap: the switch never drops below the hero -
   the hero meta is written short enough to guarantee the fit (see pv_hero()),
   and the hero slot is the side that gives way if space runs out. */
/* Negative bottom margin, same trick as .pv-ctx: the card body's 24px flex
   gap does not collapse with margins, so it alone would hold the phase list
   well off the hero's rule. Net spacing below the rule ~10px. */
.pv-ratings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: nowrap;
  padding: 2px 2px 8px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  margin-bottom: -14px;
}
/* Same boxless-uiOutput story as .pv-col-tend: without a forced box the hero
   itself becomes the flex child and the slot's sizing is void. */
.pv-ratings-head > .pv-hero-slot {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
}
.pv-ratings-head .pv-switch { flex: 0 0 auto; }
.pv-ratings-head .pv-hero {
  border-bottom: none;
  margin-bottom: 0;
  padding: 0;
}
.pv-ratings-head .pv-switch { margin-bottom: 0; }

/* --- hero ---------------------------------------------------------------- */
.pv-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 2px 2px 14px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  margin-bottom: 12px;
}
.pv-hero-badge {
  flex: 0 0 auto;
  min-width: 62px;
  padding: 6px 12px;
  border-radius: 12px;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.pv-hero-badge.pv-hi { background: var(--pv-hi); }
.pv-hero-badge.pv-mid { background: var(--pv-mid); }
.pv-hero-badge.pv-lo { background: var(--pv-lo); }
.pv-hero-badge.pv-na { background: var(--pv-na); }
.pv-hero-meta { min-width: 0; }
.pv-hero-title {
  font-size: 14px;
  font-weight: 700;
  color: #3a3e5b;
  line-height: 1.2;
}
.pv-hero-sub {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.55);
  margin-top: 2px;
}
.pv-hero-warn {
  font-size: 11px;
  font-weight: 600;
  color: #8a4b12;
  margin-top: 3px;
}

/* --- bar rows ------------------------------------------------------------ */
.pv-list { display: flex; flex-direction: column; gap: 11px; }

.pv-row { min-width: 0; }
.pv-row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}
.pv-row-name {
  font-size: 13.5px;
  color: #3a3e5b;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pv-row-val {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.pv-row-val.pv-hi { color: var(--pv-hi); }
.pv-row-val.pv-mid { color: var(--pv-mid); }
.pv-row-val.pv-lo { color: var(--pv-lo); }
.pv-row-val.pv-na { color: var(--pv-na); }

.pv-track {
  position: relative;
  height: 8px;
  border-radius: 9999px;
  background: var(--pv-track);
  overflow: hidden;
}
.pv-fill {
  height: 100%;
  border-radius: 9999px;
  transition: width 0.25s ease;
}
.pv-fill.pv-hi { background: var(--pv-hi); }
.pv-fill.pv-mid { background: var(--pv-mid); }
.pv-fill.pv-lo { background: var(--pv-lo); }
.pv-fill.pv-na { background: transparent; }

/* --- phase groups --------------------------------------------------------- */
/* The phases list segments exactly like the match report's Phases table:
   Breakouts / NZ / OZ. Each group is led by its own combined bar (bold name,
   full-size track) with the phases indented under a rule as sub-elements, so
   a group reads as one rating that opens up into its parts. */
.pv-phase-list { gap: 15px; }
.pv-group {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.pv-row-grp .pv-row-name { font-weight: 600; }
.pv-group-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-left: 10px;
  padding-left: 12px;
  border-left: 2px solid rgba(0, 0, 0, 0.08);
}
.pv-group-body .pv-row-name { font-size: 12.5px; color: rgba(0, 0, 0, 0.62); }
.pv-group-body .pv-row-val { font-size: 12.5px; }
.pv-group-body .pv-track { height: 6px; }

/* --- tendencies ---------------------------------------------------------- */
/* No row titles - the poles name the axis - so the rows need a bit more air
   between them to stay legible as separate scales. */
.pv-tend-list { display: flex; flex-direction: column; gap: 13px; }

.pv-tend-poles {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}
.pv-pole {
  font-size: 13px;
  color: rgba(0, 0, 0, 0.35);
}
/* The pole the player leans toward carries the emphasis. */
.pv-pole-on {
  color: #3a3e5b;
  font-weight: 600;
}

.pv-tend-track {
  position: relative;
  height: 8px;
  border-radius: 9999px;
  background: var(--pv-track);
}
/* Centre reference: the centre is a GAP, not a mark. Splitting the track into
   two lanes makes the bipolarity structural - each pole owns a lane and the
   fill grows out of one of them - so nothing extra competes with the knob and
   the team-mate dots. Painted OVER the fill (hence the card colour and the
   z-index) so the cut runs all the way through. */
.pv-tend-mid {
  position: absolute;
  left: 50%;
  top: -1px;
  width: 4px;
  height: calc(100% + 2px);
  margin-left: -2px;
  background: var(--pv-card-bg);
  z-index: 2;
}
.pv-tend-fill {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--pv-hi);
  opacity: 0.85;
  border-radius: 9999px;
  transition: left 0.25s ease, width 0.25s ease;
}
/* Markers carry no negative margin: their `left` is inset by their own width
   in .pv_marker_left(), so 0 and 100 sit flush inside the rail. */
.pv-tend-knob {
  position: absolute;
  top: 50%;
  /* border-box so the 2px ring counts INSIDE the 13px the inset reserves for
     it; with content-box the knob is really 17px and spills past the rail end. */
  box-sizing: border-box;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--pv-hi);
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
  transform: translateY(-50%);
  transition: left 0.25s ease;
  z-index: 4;
}
/* Team-mates at the same position: deliberately quiet. They give the player's
   knob a reference distribution ("is he unusual for this room?") and must never
   compete with it - hence the small dot and no solid colour.
   The hairline white ring is what lets them read on BOTH the pale track and the
   teal fill; without it a translucent navy dot goes muddy over the fill. Alpha
   lives in the colours, not in `opacity`, so the ring keeps its own strength. */
.pv-tend-peer {
  position: absolute;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(58, 62, 91, 0.34);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.55);
  transform: translateY(-50%);
  z-index: 3;
  transition: background 0.12s ease;
}
/* A 7px dot is a small hover target, so grow the hit area without growing the
   dot. The pseudo-element is invisible and carries no pointer styling of its
   own - it just makes the name tooltip easy to summon. */
.pv-tend-peer::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
}
.pv-tend-peer:hover {
  background: rgba(58, 62, 91, 0.72);
}

/* "Add team context" toggle: a quiet control, not a headline. */
/* Negative BOTTOM margin: the card body is a flex column with bslib's gap
   between children (24px here - 1.5rem, NOT the 16 you might assume), and
   margins stack on top of that gap rather than collapsing into it - so
   pulling the next child up is the only way to bring the intro text closer
   to the checkbox. Net spacing ~7px. */
.pv-ctx { margin: -2px 0 -17px; }
.pv-ctx .shiny-input-container { margin-bottom: 0; width: auto !important; }
.pv-ctx .checkbox label { font-size: 12px; color: rgba(0, 0, 0, 0.55); }
.pv-ctx .checkbox { margin: 0; }

.pv-tend-intro {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.5);
  /* Negative: the intro and the slider list are separate flex children of the
     card body (the uiOutput wrapper is display:contents), so the 24px card gap
     sits between them. Net spacing below the rule ~9px. */
  margin-bottom: -15px;
  padding-bottom: 7px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

/* --- misc ---------------------------------------------------------------- */
.pv-empty {
  padding: 26px 18px;
  text-align: center;
  font-size: 13px;
  color: rgba(0, 0, 0, 0.45);
}
/* Segmented Skills/Situations switch: reuses the Team Overview pill styling
   (.to-seg), which needs the control-height var defined on an ancestor. */
.pv-switch {
  --to-ctl-h: 32px;
  display: flex;
  justify-content: center;
  margin-bottom: 14px;
}
.pv-switch .shiny-input-container { margin-bottom: 0; }
