/* ══ THE COACH ROSTER — TRIAGE FIRST ════════════════════════════════════════
   js/11-skill-coach.js, markup in index.html (#coach-roster). Numbered 20 so it
   lands last; the NN- prefix is the cascade.

   THE WEIGHT ORDER IS THE POINT. Real scale is ~200 SAT / ~100 AP, and a
   teacher reads this between periods, so the screen has to do the scanning:

     triage   who needs you today. Display scale, a heavy stop-press rule, a
              coloured rule down the side of every entry. Four or five entries,
              never two hundred.
     roster   everyone, by section. Agate — ruled box-score, not cards. It is
              the reference table you consult, not the thing you read first.

   Uniform cards at one weight would make "csnyder has not worked in nine days"
   and "gcook, 7 sessions, 61%" the same announcement, which is the failure this
   layout exists to avoid.
   ═══════════════════════════════════════════════════════════════════════════ */

/* NO inner scroller on this screen — the same defect 19-verticals.css records.
   #screen-coach carried `overflow-y: auto` (06-progress.css:417), which inside
   a `height: 100%` flex column made the SCREEN its own scroll container:
   MEASURED clientHeight 805 against scrollHeight 16893, so the document
   reported a 900px page while ~16,000px of coach view sat rendered, present in
   the DOM, and invisible to a full-page screenshot. Every other page screen
   (.training-body, .coach-body, .vh-wrap, .lb-body) lets the document scroll;
   this restores that. */
#screen-coach { overflow-y: visible; }

/* Removing that scroller also removed a HORIZONTAL clip nobody knew was there.
   `overflow-y: auto` with `overflow-x: visible` computes the x axis to `auto`
   too, so #screen-coach had been quietly absorbing two pre-existing overflows
   in the sections below — MEASURED, at 320: .tsb-table has a 345px minimum
   against a 264px column, and .student-stats-row sets five figures in a flex
   row that does not wrap, so "Rapid guesses" (54px min-content) pushed 22px
   past the card at 1024 as well.

   Fixed here rather than in 06-progress.css because this file is what exposed
   them, and fixed rather than re-clipped because the re-clip is the trap: on a
   `height: 100%` screen you cannot set `overflow-x: hidden` without the y axis
   computing back to `auto` and truncating the page all over again. */
#screen-coach .student-stats-row { flex-wrap: wrap; }
#screen-coach #team-scoreboard { overflow-x: auto; }

.bs .cr {
  /* The coach page is one column of .coach-body, which already carries the
     page measure and gutter (15-bs-shared.css). Nothing to re-centre here. */
  /* The roster zone steps IN from the triage band above it. Same idea as the
     weight drop: the bulletin gets the whole measure because it is the news,
     the reference table sits in a narrower column beneath it. */
  --cr-measure: 800px;
  padding-bottom: 8px;
  margin-bottom: 44px;
  border-bottom: 1px solid var(--bs-rule);
}

/* ── the head ──
   Was a baseline flex ROW (title beside its counts) with a private
   clamp(27px, 3.4vw, 38px) ramp — the only screen that set its title and its
   instrumentation on one line, and the smallest of the six ramps at 38px
   against a 34px wordmark, close enough to read as a competing pair rather
   than a step. Both are .page-head's now (02-chrome.css): the counts drop
   beneath the title into the folio, the way every other screen sets them. */
.bs .cr-dateline {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
}

/* ── the four verticals ──
   Toggle buttons, not an ARIA tablist: there is one region and it is refetched,
   so `aria-pressed` describes what actually happens and does not promise a
   tabpanel that is not there. */
.bs .cr-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-bottom: 2px solid var(--bs-ink);
  margin: 18px 0 0;
}
.bs .cr-tab {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  background: transparent;
  border: 0;
  border-bottom: 3px solid transparent;
  border-radius: 0;
  margin-bottom: -2px;
  padding: 11px 17px 9px;
  cursor: pointer;
  transition: color .12s ease, background .12s ease;
}
.bs .cr-tab:hover { color: var(--bs-ink); background: var(--bs-stock-2); }
.bs .cr-tab:focus-visible { outline: 2px solid var(--bs-blue); outline-offset: -3px; }
.bs .cr-tab.is-active {
  color: var(--bs-ink);
  border-bottom-color: var(--bs-ink);
}
.bs .cr-tab[disabled] { cursor: progress; opacity: .55; }

/* ══ TRIAGE ═════════════════════════════════════════════════════════════════ */

/* The stop-press band. A 3px rule and a display numeral, because the count is
   the one thing that has to survive a five-second glance. */
.bs .cr-triage {
  border-top: 3px solid var(--bs-ink);
  margin-top: 30px;
  padding-top: 13px;
}
.bs .cr-triage-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 16px;
}
.bs .cr-triage-n {
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: clamp(34px, 5vw, 50px);
  line-height: .9;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
/* The calm branch sets a WORD here rather than a digit — "Nobody" at 50px reads
   as shouting, and the news is good. */
.bs .cr-triage-n.is-calm {
  font-size: clamp(23px, 3vw, 31px);
  letter-spacing: -.02em;
  color: var(--bs-ok);
}
.bs .cr-triage-kicker {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
/* Marginalia, in the app's hand. Sits at the end of the band on a wide window
   and drops below it when the band wraps. */
.bs .cr-triage-hand {
  font-family: var(--bs-hand);
  font-size: 19px;
  line-height: 1;
  color: var(--bs-ink-3);
  margin-left: auto;
  transform: rotate(-1.2deg);
}

.bs .cr-flags {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* One flagged student.
   THE THREE CLASSES ARE NOT TOLD APART BY HUE. Each carries a different WORD in
   its stamp, a different stamp FILL (solid / outlined / dashed outline) and a
   different left-rule STYLE (solid / double / dashed) as well as a different
   colour — so the distinction survives greyscale, a projector, and the ~8% of
   men who would otherwise be reading three identical cards. */
.bs .cr-flag {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "stamp name   fig"
    "stamp detail fig";
  align-items: start;
  gap: 3px 18px;
  background: var(--bs-sheet);
  border: 1px solid var(--bs-rule);
  border-left-width: 7px;
  border-radius: 0;
  padding: 15px 18px 15px 16px;
  transition: box-shadow .12s ease;
}
.bs .cr-flag:hover { box-shadow: 3px 3px 0 var(--bs-rule); }

.bs .cr-stamp {
  grid-area: stamp;
  align-self: start;
  margin-top: 3px;
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 5px 9px 4px;
  border: 1.5px solid currentColor;
}

/* gone dark — the heaviest. Solid rule, SOLID stamp, and a recessed stock so
   the entry reads as an absence rather than as a performance. */
.bs .cr-flag[data-kind="gone_dark"] {
  border-left-style: solid;
  border-left-color: var(--bs-ink);
  background: var(--bs-stock-2);
}
.bs .cr-flag[data-kind="gone_dark"] .cr-stamp {
  background: var(--bs-ink);
  color: var(--bs-sheet);
  border-color: var(--bs-ink);
}
/* sliding — the red pen, and a double rule: two marks going the same way. */
.bs .cr-flag[data-kind="sliding"] {
  border-left-style: double;
  border-left-color: var(--bs-pen);
}
.bs .cr-flag[data-kind="sliding"] .cr-stamp { color: var(--bs-pen); }
/* guessing — dashed, twice over. Nothing is solid about a 4-second answer. */
.bs .cr-flag[data-kind="rapid_guessing"] {
  border-left-style: dashed;
  border-left-color: var(--bs-blue);
}
.bs .cr-flag[data-kind="rapid_guessing"] .cr-stamp {
  color: var(--bs-blue);
  border-style: dashed;
}

.bs .cr-flag-name {
  grid-area: name;
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: 23px;
  line-height: 1.1;
  letter-spacing: -.018em;
  color: var(--bs-ink);
  overflow-wrap: anywhere;
}
.bs .cr-flag-detail {
  grid-area: detail;
  font-family: var(--bs-ui);
  font-size: 14px;
  line-height: 1.45;
  color: var(--bs-ink-2);
  max-width: 62ch;
}
.bs .cr-flag-sec {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  display: block;
  margin-bottom: 3px;
}
.bs .cr-flag-fig {
  grid-area: fig;
  text-align: right;
  align-self: center;
}
.bs .cr-flag-fig-val {
  font-family: var(--bs-mono);
  font-size: 20px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
.bs .cr-flag-fig-lbl {
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-top: 5px;
}

/* Nobody flagged. Deliberately NOT the empty-state treatment used for "we have
   no data" — a quiet triage band is the best news on this screen, and it is set
   as a sentence, in green, with a note in the margin. */
.bs .cr-calm {
  font-family: var(--bs-ui);
  font-size: 14px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  max-width: 60ch;
  margin-top: 10px;
}
.bs .cr-calm-hand {
  font-family: var(--bs-hand);
  font-size: 20px;
  color: var(--bs-ok);
  display: block;
  margin-top: 6px;
  transform: rotate(-1deg);
  transform-origin: left center;
}

/* Load failure. One line and a way back — never a silent empty band, which
   would read as "nobody needs you". */
.bs .cr-fail {
  font-family: var(--bs-ui);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  border-left: 2px solid var(--bs-pen);
  padding-left: 13px;
  margin-top: 12px;
  max-width: 58ch;
}
.bs .cr-retry {
  display: inline-block;
  margin-top: 8px;
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  background: transparent;
  border: 1.5px solid var(--bs-ink);
  border-radius: 0;
  padding: 6px 12px 5px;
  cursor: pointer;
}
.bs .cr-retry:hover { background: var(--bs-ink); color: var(--bs-sheet); }
.bs .cr-retry:focus-visible { outline: 2px solid var(--bs-blue); outline-offset: 2px; }

/* ══ THE ROSTER ═════════════════════════════════════════════════════════════ */

.bs .cr-roster-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 26px;
  margin: 40px 0 0;
  max-width: var(--cr-measure);
  border-bottom: 1px solid var(--bs-rule);
  padding-bottom: 9px;
}
.bs .cr-kicker {
  font-family: var(--bs-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

/* A ruled writing line, not a boxed control — the device the answer field, the
   calculator entry and the vertical homepages all use. */
.bs .cr-find { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bs .cr-find-lbl {
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
.bs .cr-find-input {
  width: 232px;
  max-width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--bs-ink);
  border-radius: 0;
  padding: 3px 2px 5px;
  font-family: var(--bs-ui);
  font-size: 15px;
  font-weight: 600;
  color: var(--bs-ink);
}
.bs .cr-find-input::placeholder { color: var(--bs-ink-3); font-weight: 400; }
.bs .cr-find-input:focus { outline: none; border-bottom-color: var(--bs-blue); }
.bs .cr-find-meta {
  font-family: var(--bs-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-blue);
  font-variant-numeric: tabular-nums;
  max-width: var(--cr-measure);
  text-align: right;
  margin-top: 7px;
}
.bs .cr-find-meta:empty { margin-top: 0; }

.bs .cr-sec { margin-top: 26px; }
/* THE BOX SCORE IS ONE GRID, NOT FIVE.
   With auto layout every section sized its own columns from its own names —
   MEASURED, on one competition roster: Student ran 208→718 in the first section
   and 208→602 in the third, so five tables stacked down the page on five
   different grids and the figures did not line up between them. `fixed` plus a
   width on each figure column is what makes them one table read as one table.

   And it is CAPPED, not full measure. At 1024 the name column was taking 510px
   to set a twelve-character handle, which parked RATING more than half a page
   from the student it belongs to — the exact eye-travel this screen exists to
   remove. 800px is the same order as .tsb-table's 720 above it. */
.bs .cr-table {
  width: 100%;
  max-width: var(--cr-measure);
  table-layout: fixed;
  border-collapse: collapse;
}
/* NOT `display: flex` — that strips the element of its `caption` display type,
   which drops `caption-side` on the floor and lets the anonymous-table fixup
   place the section heading BELOW its own column heads. Measured at 715 against
   a thead at 694. Inline spans and a margin do the same job and stay a caption. */
.bs .cr-sec-cap {
  caption-side: top;
  text-align: left;
  padding-bottom: 6px;
}
.bs .cr-sec-name {
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: 17px;
  letter-spacing: -.012em;
  color: var(--bs-ink);
}
.bs .cr-sec-n {
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
  margin-left: 11px;
}
/* Agate column heads, repeated per section — the box-score convention. At 8.5px
   five of these read as a rule, not as five headings. */
.bs .cr-h {
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  text-align: left;
  padding: 0 10px 6px 0;
  border-bottom: 2px solid var(--bs-ink);
  white-space: nowrap;
}
.bs .cr-h.cr-num, .bs .cr-table td.cr-num { text-align: right; }
/* `table-layout: fixed` reads the widths off this row, so this is what pins
   every section's grid to the same one. The name column takes what is left. */
.bs .cr-h.cr-num { width: 108px; padding-right: 0; padding-left: 10px; }

.bs .cr-row { transition: background .1s ease; }
.bs .cr-row:hover {
  background: var(--bs-stock-2);
  box-shadow: inset 3px 0 0 var(--bs-camel);
}
.bs .cr-row:hover .cr-name { color: var(--bs-blue); }
.bs .cr-table td, .bs .cr-table th.cr-name {
  border-bottom: 1px solid var(--bs-rule);
  padding: 8px 10px 8px 0;
  vertical-align: baseline;
}
.bs .cr-name {
  font-family: var(--bs-ui);
  font-size: 15px;
  font-weight: 700;
  color: var(--bs-ink);
  text-align: left;
  overflow-wrap: anywhere;
  transition: color .1s ease;
}
.bs .cr-table td.cr-num { padding: 8px 0 8px 10px; white-space: nowrap; }
.bs .cr-val {
  font-family: var(--bs-mono);
  font-size: 14px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
.bs .cr-val.is-none { color: var(--bs-ink-3); }
/* Shown only when the table collapses; at table widths the thead carries this. */
.bs .cr-lbl { display: none; }

/* The search hid everything. Says so, names the term, and offers the way out —
   an empty roster with no explanation is indistinguishable from a broken fetch. */
.bs .cr-noresults {
  font-family: var(--bs-ui);
  font-size: 14px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  border-left: 2px solid var(--bs-rule);
  padding-left: 14px;
  margin-top: 26px;
  max-width: 58ch;
}
.bs .cr-noresults strong { color: var(--bs-ink); font-weight: 700; }
.bs .cr-clear {
  display: block;
  margin-top: 9px;
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  background: transparent;
  border: 0;
  border-bottom: 1.5px solid var(--bs-ink);
  border-radius: 0;
  padding: 0 0 2px;
  cursor: pointer;
}
.bs .cr-clear:hover { color: var(--bs-blue); border-bottom-color: var(--bs-blue); }
.bs .cr-clear:focus-visible { outline: 2px solid var(--bs-blue); outline-offset: 3px; }

.bs .cr-empty {
  font-family: var(--bs-ui);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  border-left: 2px solid var(--bs-rule);
  padding-left: 14px;
  margin-top: 24px;
  max-width: 58ch;
}

/* ── narrow ──
   The box score collapses to stacked entries and every figure grows the label
   the thead was carrying. Below this width five columns cannot be set without
   either overflowing the page or crushing the names to two characters. */
@media (max-width: 700px) {
  .bs .cr-table, .bs .cr-table caption, .bs .cr-table tbody, .bs .cr-table tr { display: block; }
  .bs .cr-table thead { display: none; }
  .bs .cr-row {
    border-bottom: 1px solid var(--bs-rule);
    padding: 9px 0 11px;
  }
  .bs .cr-row:hover { box-shadow: inset 3px 0 0 var(--bs-camel); }
  .bs .cr-table th.cr-name {
    display: block;
    border: 0;
    padding: 0 0 5px;
  }
  .bs .cr-table td, .bs .cr-table td.cr-num {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    border: 0;
    padding: 1px 18px 1px 0;
    text-align: left;
  }
  .bs .cr-lbl {
    display: inline;
    font-family: var(--bs-mono);
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--bs-ink-3);
  }
  .bs .cr-val { font-size: 13px; }
}

@media (max-width: 620px) {
  /* The stamp goes above the name: at 320 a 116px stamp column leaves ~150px
     for a display-weight name, which sets one word per line. */
  .bs .cr-flag {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "stamp  fig"
      "name   name"
      "detail detail";
    gap: 7px 14px;
    padding: 13px 14px 14px 13px;
  }
  .bs .cr-stamp { margin-top: 0; justify-self: start; }
  .bs .cr-flag-fig { align-self: start; }
  .bs .cr-flag-fig-val { font-size: 17px; }
  .bs .cr-flag-name { font-size: 20px; }
  .bs .cr-triage-hand { margin-left: 0; }
  .bs .cr-tab { padding: 10px 11px 8px; letter-spacing: .14em; }
  .bs .cr-find-input { width: 100%; }
  .bs .cr-roster-head { align-items: flex-start; }
}
