/* roster.css
   The FBS depth chart, the FCS roster, and the player element they share.

   Part of the Teleport stylesheet, split by concern. index.html links these
   in source order; keep that order, the cascade depends on it. */

/* ── Loading ────────────────────────────────────────────────────────── */
.roster-loading {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 54px 20px; color: var(--label-2); font-size: 13px;
}
/* Same two-tone ring as .spinner (base.css), just small enough to sit
   inline beside a line of text — one loading language at two sizes. */
.mini-spin {
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--border); border-top-color: var(--accent); border-right-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
.roster-hint { font-size: 11.5px; color: var(--label-3); }
.roster-body { padding: 4px 12px 14px; }

/* ── The player element ─────────────────────────────────────────────────
   One control shared by both layouts, and always a link: every player on a
   depth chart or roster has a working page whether or not anything has been
   saved about him. His grade dot (if any) is what tells that story; the row
   itself doesn't change colour. */
.dp {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 10px; border-radius: var(--r-sm); text-align: left;
  background: var(--surface-2); border: 1px solid transparent;
  font-family: var(--font); font-size: 13px; color: var(--label);
  cursor: pointer; min-width: 0;
  transition: background 0.13s, border-color 0.13s, transform 0.08s, box-shadow 0.13s;
}
.dp:hover { background: var(--surface); border-color: var(--accent); box-shadow: var(--shadow-sm); }
.dp:active { transform: scale(0.985); }

.dp-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dp-name {
  font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dp-sub {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 11px; color: var(--label-2);
}
.dp-pos { font-weight: 700; letter-spacing: 0.02em; }

/* Jersey number — tabular so a column of them lines up. Pulled in tight against
   the face; the row's normal 8px gap is too loose between a face and the number
   right next to it. Every row has a face now, so this applies to all of them. */
.dp-num {
  flex-shrink: 0; min-width: 24px; text-align: right;
  font-size: 12px; font-weight: 700; color: var(--label-3);
  font-variant-numeric: tabular-nums;
  margin-left: -4px;
}

.dp-tr {
  font-size: 9.5px; font-weight: 750; letter-spacing: 0.04em;
  padding: 0 4px; border-radius: 3px;
  background: var(--gold-light); color: var(--gold);
}

.dp-add { flex-shrink: 0; display: inline-flex; color: var(--label-3); opacity: 0; transition: opacity 0.13s, color 0.13s; }
.dp-add svg { width: 14px; height: 14px; }
.dp:hover .dp-add { opacity: 1; color: var(--accent); }

.dp-grade { flex-shrink: 0; }
.dp-grade.dot { width: 9px; height: 9px; }
.dp-grade--none {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px dashed var(--label-3); box-sizing: border-box;
}

/* ── Nudging a row into a new depth order ───────────────────────────────
   Any coach can re-rank a position group — see wireRosterMove in
   views/roster.js. Two small stacked buttons, not a drag handle: both
   `.dc-players` and `.rs-players` are CSS grids several players wide, where
   "the previous player" is as often to the left as it is above, and a drag
   gesture has no single direction to track there. A tap has no such
   ambiguity. `.dp-row` is what actually sits in the grid now (both grids are
   unchanged otherwise); `.dp` inside it still fills the rest of the row
   exactly as it did on its own. */
.dp-row { display: flex; align-items: center; gap: 2px; min-width: 0; }
.dp-row .dp { flex: 1; min-width: 0; }
.dp-move {
  display: flex; flex-direction: column; flex-shrink: 0;
  width: 16px; align-items: stretch;
}
.dp-move-btn {
  display: flex; align-items: center; justify-content: center;
  width: 16px; height: 14px; padding: 0; border: none; background: none;
  color: var(--label-3); cursor: pointer; border-radius: 4px;
}
.dp-move-btn:hover { color: var(--label-2); background: var(--border-2); }
.dp-move-btn:disabled { opacity: 0.25; cursor: default; pointer-events: none; }
.dp-move-btn svg { width: 10px; height: 10px; }
/* The glyph is a down chevron; flipping it is cheaper than a second icon. */
.dp-move-up svg { transform: rotate(180deg); }

/* ── Depth chart (FBS) ──────────────────────────────────────────────── */
.dc-unit + .dc-unit { margin-top: 22px; }
.dc-unit-head {
  display: flex; align-items: baseline; gap: 9px;
  padding: 8px 2px 10px; border-bottom: 1px solid var(--border-2); margin-bottom: 10px;
}
.dc-unit-name { font-size: 14px; font-weight: 750; letter-spacing: -0.015em; }
/* The scheme is half of what a depth chart tells you about an opponent. */
.dc-scheme {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--accent-deep); background: var(--accent-light);
  padding: 2px 8px; border-radius: var(--r-full);
}
:root[data-theme="dark"] .dc-scheme { color: var(--accent); }
.dc-unit-count { font-size: 11.5px; color: var(--label-3); margin-left: auto; }

.dc-rows { display: flex; flex-direction: column; gap: 6px; }
.dc-row { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 10px; align-items: start; }
.dc-pos {
  font-size: 11.5px; font-weight: 750; letter-spacing: 0.02em;
  color: var(--label-2); text-align: right; padding-top: 13px;
  overflow: hidden; text-overflow: ellipsis;
}
/* Depth runs left to right: the starter first, then everyone behind him.
   The track count is FIXED, not auto-fit, so every card is the same width down
   the whole chart — a position with two players leaves the remaining columns
   empty instead of stretching two cards across the full row. Ragged card widths
   made the chart read as though the shallow positions were somehow bigger.
   Five is the true worst case: no position in the 2026 data is deeper (Temple's
   QB room is the only 5), so the grid never wraps either.
   --dc-cols is the one knob; the breakpoints below only change its value. */
.dc-players {
  display: grid;
  grid-template-columns: repeat(var(--dc-cols, 5), minmax(0, 1fr));
  gap: 6px; min-width: 0;
}

/* ── Roster (FCS) ───────────────────────────────────────────────────── */
.rs-group + .rs-group { margin-top: 20px; }

/* The team page's Tracked tab groups by position and borrows this heading, so a
   position group reads the same whether you're looking at the whole roster or
   only the players on your board. Its body is a .plist of full board rows rather
   than the tile grid below, which is the one thing that differs. */
.tp-group + .tp-group { margin-top: 18px; }
.tp-group .plist { margin-top: -4px; }

.rs-group-head {
  display: flex; align-items: baseline; gap: 8px;
  padding: 8px 2px 9px; border-bottom: 1px solid var(--border-2); margin-bottom: 10px;
}
.rs-group-name { font-size: 13.5px; font-weight: 720; letter-spacing: -0.01em; }
.rs-group-count {
  font-size: 10.5px; font-weight: 700; color: var(--label-3);
  background: var(--surface-2); padding: 1px 7px; border-radius: var(--r-full);
}
.rs-players { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 6px; }

/* ── Evaluated, but no longer on the download ───────────────────────────
   A safety net rather than part of the chart (see offRosterSection in
   views/roster.js), so it sits below everything behind a rule of its own and
   is absent entirely on the overwhelming majority of teams, where it's empty.
   The heading is deliberately the same .rs-group-head every other group uses —
   these are real players with real evaluations, not an error state. */
.rs-group--off { margin-top: 28px; padding-top: 4px; border-top: 1px dashed var(--border-2); }
.rs-off-note {
  font-size: 11.5px; line-height: 1.55; color: var(--label-3);
  margin: -4px 2px 10px; max-width: 62ch;
}

/* ── Team cards with nothing behind them ────────────────────────────── */
.team-card.no-data .team-count { color: var(--label-3); font-style: italic; }

/* ── The face on a roster row ───────────────────────────────────────────
   A 26px circle, always present: the headshot when ESPN had one, the school's
   mark at the same size when it didn't (see `.face` in team-mark.css). It used
   to be rendered only for players with photos, which shifted the number and the
   name on every row that lacked one.

   The tile's own drop shadow is too heavy at this size next to 30-odd rows, so
   only the hairline is kept. */
.dp .face { --face-size: 26px; }
.dp .face-mark {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
:root[data-theme="dark"] .dp .face-mark {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
